From a607a492872070a18e6adcaa48fd3119e9e2efee Mon Sep 17 00:00:00 2001 From: Snider Date: Fri, 13 Mar 2026 10:06:58 +0000 Subject: [PATCH] =?UTF-8?q?refactor:=20consolidate=20plugin=20marketplace?= =?UTF-8?q?=20=E2=80=94=20remove=20duplicates,=20add=20repo-native=20plugi?= =?UTF-8?q?ns?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove claude/qa/ and claude/ci/ plugins (replaced by go-build and go-devops repo-native plugins). Strip duplicate qa command from code plugin. Marketplace now references plugins at their source repos. Co-Authored-By: Virgil --- .claude-plugin/marketplace.json | 24 ++-- claude/ci/.claude-plugin/plugin.json | 8 -- claude/ci/commands/ci.md | 54 --------- claude/ci/commands/fix.md | 47 -------- claude/ci/commands/run.md | 33 ------ claude/ci/commands/status.md | 63 ---------- claude/ci/commands/workflow.md | 87 -------------- claude/ci/hooks.json | 17 --- claude/ci/scripts/detect-forge.sh | 21 ---- claude/ci/scripts/post-push-ci.sh | 23 ---- claude/code/.claude-plugin/plugin.json | 11 +- claude/code/commands/qa.md | 155 ------------------------- claude/code/scripts/qa-filter.sh | 62 ---------- claude/code/scripts/qa-verify.sh | 44 ------- claude/qa/.claude-plugin/plugin.json | 8 -- claude/qa/commands/check.md | 74 ------------ claude/qa/commands/fix.md | 57 --------- claude/qa/commands/lint.md | 78 ------------- claude/qa/commands/qa.md | 66 ----------- claude/qa/hooks.json | 17 --- claude/qa/scripts/qa-filter.sh | 62 ---------- claude/qa/scripts/qa-verify.sh | 44 ------- 22 files changed, 19 insertions(+), 1036 deletions(-) delete mode 100644 claude/ci/.claude-plugin/plugin.json delete mode 100644 claude/ci/commands/ci.md delete mode 100644 claude/ci/commands/fix.md delete mode 100644 claude/ci/commands/run.md delete mode 100644 claude/ci/commands/status.md delete mode 100644 claude/ci/commands/workflow.md delete mode 100644 claude/ci/hooks.json delete mode 100755 claude/ci/scripts/detect-forge.sh delete mode 100755 claude/ci/scripts/post-push-ci.sh delete mode 100644 claude/code/commands/qa.md delete mode 100755 claude/code/scripts/qa-filter.sh delete mode 100755 claude/code/scripts/qa-verify.sh delete mode 100644 claude/qa/.claude-plugin/plugin.json delete mode 100644 claude/qa/commands/check.md delete mode 100644 claude/qa/commands/fix.md delete mode 100644 claude/qa/commands/lint.md delete mode 100644 claude/qa/commands/qa.md delete mode 100644 claude/qa/hooks.json delete mode 100755 claude/qa/scripts/qa-filter.sh delete mode 100755 claude/qa/scripts/qa-verify.sh diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 3855c14..6868c41 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -9,14 +9,14 @@ { "name": "code", "source": "./claude/code", - "description": "Core development plugin - hooks, scripts, data collection skills", - "version": "0.1.0" + "description": "Core development hooks, auto-approve workflow, and research data collection", + "version": "0.2.0" }, { "name": "review", "source": "./claude/review", "description": "Code review automation - PR review, security checks", - "version": "0.1.0" + "version": "0.2.0" }, { "name": "verify", @@ -25,15 +25,21 @@ "version": "0.1.0" }, { - "name": "qa", - "source": "./claude/qa", - "description": "Quality assurance - iterative fix loops, lint enforcement", + "name": "core-php", + "source": "forge.lthn.ai/core/php", + "description": "PHP/Laravel development skills, API generation, and formatting", "version": "0.1.0" }, { - "name": "ci", - "source": "./claude/ci", - "description": "CI integration - GitHub Actions, test automation", + "name": "go-build", + "source": "forge.lthn.ai/core/go-build", + "description": "Go QA pipeline, build tooling, and development skills", + "version": "0.1.0" + }, + { + "name": "devops", + "source": "forge.lthn.ai/core/go-devops", + "description": "CI/CD, deployment, issue tracking, and Coolify integration", "version": "0.1.0" } ] diff --git a/claude/ci/.claude-plugin/plugin.json b/claude/ci/.claude-plugin/plugin.json deleted file mode 100644 index 47d3a00..0000000 --- a/claude/ci/.claude-plugin/plugin.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "ci", - "description": "CI integration - GitHub Actions status, workflow management", - "version": "0.1.0", - "author": { - "name": "Lethean" - } -} diff --git a/claude/ci/commands/ci.md b/claude/ci/commands/ci.md deleted file mode 100644 index ee0e2e2..0000000 --- a/claude/ci/commands/ci.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -name: ci -description: Check CI status and manage workflows -args: [status|run|logs|fix] ---- - -# CI Integration - -Check CI status and manage workflows using the `core` CLI (supports Forgejo and GitHub). - -## Commands - -### Status (default) -``` -/ci:ci -/ci:ci status -``` -```bash -core dev ci -core dev ci --branch $(git branch --show-current) -core dev ci --failed -``` - -### List workflows -``` -/ci:ci workflows -``` -```bash -core dev workflow list -``` - -### Issues -``` -/ci:ci issues -``` -```bash -core dev issues -core dev issues --assignee @me -``` - -### Reviews / PRs -``` -/ci:ci reviews -``` -```bash -core dev reviews -core dev reviews --all -``` - -### Fix failing CI -``` -/ci:ci fix -``` -Analyse failing CI and suggest fixes. See `/ci:fix`. diff --git a/claude/ci/commands/fix.md b/claude/ci/commands/fix.md deleted file mode 100644 index 6690416..0000000 --- a/claude/ci/commands/fix.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -name: fix -description: Analyse and fix failing CI ---- - -# Fix CI - -Analyse failing CI runs and suggest/apply fixes. - -## Process - -1. **Get failing runs** - ```bash - core dev ci --failed - ``` - -2. **Analyse failure** - - Parse error messages from CI output - - Identify root cause - - Check if local issue or CI-specific - -3. **Reproduce locally** - ```bash - core go test - core go lint - core go vet - ``` - -4. **Suggest fix** - - Code changes if needed - - CI config changes if needed - -5. **Apply fix** (if approved) - -## Common CI Failures - -### Test Failures -→ Run `core go test --run TestFoo`, fix the test, push - -### Lint Failures -→ Run `core go lint`, fix lint issues - -### Build Failures -→ Run `core build`, check imports, run `core go fmt` - -### Dependency Issues -→ Check go.mod, `core go fmt`, retry diff --git a/claude/ci/commands/run.md b/claude/ci/commands/run.md deleted file mode 100644 index b84c2f0..0000000 --- a/claude/ci/commands/run.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: run -description: Trigger a CI workflow run -args: [workflow-name] ---- - -# Run Workflow - -Trigger a CI workflow or view available workflows. - -## Usage - -``` -/ci:run # List available workflows -/ci:run tests # Trigger specific workflow -``` - -## Commands - -```bash -# List available workflows -core dev workflow list - -# Sync workflows across repos -core dev workflow sync -``` - -## Notes - -- Forgejo Actions uses `.forgejo/workflows/` or `.github/workflows/` (both supported) -- Workflows are triggered automatically on push/PR/tag -- Manual dispatch: use the Forgejo web UI at `forge.lthn.ai/{owner}/{repo}/actions` -- Runner: `build-noc` on the noc server diff --git a/claude/ci/commands/status.md b/claude/ci/commands/status.md deleted file mode 100644 index b866891..0000000 --- a/claude/ci/commands/status.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -name: status -description: Show CI status for current branch ---- - -# CI Status - -Show CI status for the current branch. - -## Usage - -``` -/ci:status -``` - -## Detection - -Detect the CI provider from git remote, then use the appropriate method: - -```bash -REMOTE_URL=$(git remote get-url origin 2>/dev/null) -``` - -### Forgejo (forge.lthn.ai) - -```bash -# Extract owner/repo from remote -OWNER_REPO=$(git remote get-url origin 2>/dev/null | sed -E 's#.*forge\.lthn\.ai[:/]+([0-9]+/)?##; s#\.git$##') - -# List recent workflow runs (requires FORGEJO_TOKEN or use web UI) -curl -s "https://forge.lthn.ai/api/v1/repos/${OWNER_REPO}/actions/tasks?limit=10&state=running" - -# Or just open the Actions page -echo "https://forge.lthn.ai/${OWNER_REPO}/actions" -``` - -### GitHub (fallback, requires gh CLI) - -```bash -core dev ci -core dev ci --branch $(git branch --show-current) -core dev ci --failed -``` - -## Output - -Present results as a status table: - -```markdown -## CI Status: main - -| Workflow | Status | When | -|----------|--------|------| -| Tests | pass | 5m ago | -| Build | pass | 5m ago | - -**All checks passing** -``` - -If no API token available, output the web URL: -``` -View CI status: https://forge.lthn.ai/{owner}/{repo}/actions -``` diff --git a/claude/ci/commands/workflow.md b/claude/ci/commands/workflow.md deleted file mode 100644 index 8f95a4b..0000000 --- a/claude/ci/commands/workflow.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -name: workflow -description: Create or update CI workflow -args: ---- - -# Workflow Generator - -Create or update CI workflows. Forgejo Actions uses the same YAML format as GitHub Actions. - -## Usage - -``` -/ci:workflow test -/ci:workflow lint -/ci:workflow release -``` - -## List existing workflows - -```bash -core dev workflow list -``` - -## Sync workflows across repos - -```bash -core dev workflow sync -``` - -## Workflow directory - -Forgejo supports both: -- `.forgejo/workflows/` (preferred) -- `.github/workflows/` (also works) - -## Templates - -### Go Test Workflow -```yaml -name: Tests - -on: - push: - branches: [main] - pull_request: - branches: [main] - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: go.mod - - run: go test -v -race ./... -``` - -### Go Release Workflow (core build) -```yaml -name: Release - -on: - push: - tags: ['v*'] - -jobs: - release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: actions/setup-go@v5 - with: - go-version-file: go.mod - - name: Build and release - run: core build release --we-are-go-for-launch -``` - -## Forgejo Notes - -- Runner label: `ubuntu-latest` (maps to Forgejo runner labels) -- Secrets: Set via repo Settings → Actions → Secrets -- Runner: `build-noc` on the noc server -- Web UI: `forge.lthn.ai/{owner}/{repo}/actions` diff --git a/claude/ci/hooks.json b/claude/ci/hooks.json deleted file mode 100644 index 97354d9..0000000 --- a/claude/ci/hooks.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "https://claude.ai/schemas/hooks.json", - "hooks": { - "PostToolUse": [ - { - "matcher": "tool == \"Bash\" && tool_input.command matches \"^git push\"", - "hooks": [ - { - "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/scripts/post-push-ci.sh" - } - ], - "description": "Show CI status after push" - } - ] - } -} diff --git a/claude/ci/scripts/detect-forge.sh b/claude/ci/scripts/detect-forge.sh deleted file mode 100755 index 5f31710..0000000 --- a/claude/ci/scripts/detect-forge.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -# Detect CI provider from git remote -# Outputs: "forgejo" or "github" or "unknown" -# Also exports FORGE_API, FORGE_OWNER, FORGE_REPO - -REMOTE_URL=$(git remote get-url origin 2>/dev/null) - -if echo "$REMOTE_URL" | grep -q "forge.lthn.ai"; then - echo "forgejo" - # Extract owner/repo from SSH or HTTPS URL - # SSH: ssh://git@forge.lthn.ai:2223/core/go.git - # HTTPS: https://forge.lthn.ai/core/go.git - OWNER_REPO=$(echo "$REMOTE_URL" | sed -E 's#.*forge\.lthn\.ai[:/]+([0-9]+/)?##; s#\.git$##') - export FORGE_API="https://forge.lthn.ai/api/v1" - export FORGE_OWNER=$(echo "$OWNER_REPO" | cut -d'/' -f1) - export FORGE_REPO=$(echo "$OWNER_REPO" | cut -d'/' -f2) -elif echo "$REMOTE_URL" | grep -qE "github\.com"; then - echo "github" -else - echo "unknown" -fi diff --git a/claude/ci/scripts/post-push-ci.sh b/claude/ci/scripts/post-push-ci.sh deleted file mode 100755 index 86dbc3b..0000000 --- a/claude/ci/scripts/post-push-ci.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# Show CI status hint after push - -read -r input -EXIT_CODE=$(echo "$input" | jq -r '.tool_response.exit_code // 0') - -if [ "$EXIT_CODE" = "0" ]; then - # Check if repo has workflows (Forgejo or GitHub) - if [ -d ".forgejo/workflows" ] || [ -d ".github/workflows" ]; then - cat << 'EOF' -{ - "hookSpecificOutput": { - "hookEventName": "PostToolUse", - "additionalContext": "Push successful. CI workflows will run shortly.\n\nRun `/ci:status` to check progress or `core dev ci` to view status." - } -} -EOF - else - echo "$input" - fi -else - echo "$input" -fi diff --git a/claude/code/.claude-plugin/plugin.json b/claude/code/.claude-plugin/plugin.json index d177e58..57f634b 100644 --- a/claude/code/.claude-plugin/plugin.json +++ b/claude/code/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "code", - "description": "Advanced Claude Code plugin for Host UK monorepo - core CLI integration, data collection skills, and autonomous workflows", - "version": "0.1.3", + "description": "Core development hooks, auto-approve workflow, and cryptocurrency research data collection skills", + "version": "0.2.0", "author": { "name": "Lethean", "email": "hello@host.uk.com" @@ -10,11 +10,8 @@ "repository": "https://forge.lthn.ai/core/agent.git", "license": "EUPL-1.2", "keywords": [ - "devops", - "monorepo", - "go", - "php", - "laravel", + "hooks", + "auto-approve", "data-collection", "cryptocurrency", "archive" diff --git a/claude/code/commands/qa.md b/claude/code/commands/qa.md deleted file mode 100644 index 8137441..0000000 --- a/claude/code/commands/qa.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -name: qa -description: Run QA checks and fix all issues iteratively -hooks: - PostToolUse: - - matcher: "Bash" - hooks: - - type: command - command: "${CLAUDE_PLUGIN_ROOT}/scripts/qa-filter.sh" - Stop: - - hooks: - - type: command - command: "${CLAUDE_PLUGIN_ROOT}/scripts/qa-verify.sh" - once: true ---- - -# QA Fix Loop - -Run the full QA pipeline and fix all issues. - -## Detection - -First, detect the project type: -- If `go.mod` exists → Go project → `core go qa` -- If `composer.json` exists → PHP project → `core php qa` -- If both exist → ask user or check current directory - -## Process - -1. **Run QA**: Execute `core go qa` or `core php qa` -2. **Parse issues**: Extract failures from output (see format below) -3. **Fix each issue**: Address one at a time, simplest first -4. **Re-verify**: After fixes, re-run QA -5. **Repeat**: Until all checks pass -6. **Report**: Summary of what was fixed - -## Issue Priority - -Fix in this order (fastest feedback first): -1. **fmt** - formatting issues (auto-fix with `core go fmt`) -2. **lint** - static analysis (usually quick fixes) -3. **test** - failing tests (may need more investigation) -4. **build** - compilation errors (fix before tests can run) - -## Output Parsing - -### Go QA Output -``` -=== FMT === -FAIL: pkg/api/handler.go needs formatting - -=== LINT === -pkg/api/handler.go:42:15: undefined: ErrNotFound (typecheck) -pkg/api/handler.go:87:2: ineffectual assignment to err (ineffassign) - -=== TEST === ---- FAIL: TestCreateUser (0.02s) - handler_test.go:45: expected 200, got 500 -FAIL - -=== RESULT === -fmt: FAIL -lint: FAIL (2 issues) -test: FAIL (1 failed) -``` - -### PHP QA Output -``` -=== PINT === -FAIL: 2 files need formatting - -=== STAN === -src/Http/Controller.php:42 - Undefined variable $user - -=== TEST === -✗ CreateUserTest::testSuccess - Expected status 200, got 500 - -=== RESULT === -pint: FAIL -stan: FAIL (1 error) -test: FAIL (1 failed) -``` - -## Fixing Strategy - -**Formatting (fmt/pint):** -- Just run `core go fmt` or `core php fmt` -- No code reading needed - -**Lint errors:** -- Read the specific file:line -- Understand the error type -- Make minimal fix - -**Test failures:** -- Read the test file to understand expectation -- Read the implementation -- Fix the root cause (not just the symptom) - -**Build errors:** -- Usually missing imports or typos -- Fix before attempting other checks - -## Stop Condition - -Only stop when: -- All QA checks pass, OR -- User explicitly cancels, OR -- Same error repeats 3 times (stuck - ask for help) - -## Example Session - -``` -Detecting project type... Found go.mod → Go project - -Running: core go qa - -## QA Issues - -pkg/api/handler.go:42:15: undefined: ErrNotFound ---- FAIL: TestCreateUser (0.02s) - -**Summary:** lint: FAIL (1) | test: FAIL (1) - ---- - -Fixing lint issue: undefined ErrNotFound -Reading pkg/api/handler.go... -Adding error variable definition. - -Running: core go qa - -## QA Issues - ---- FAIL: TestCreateUser (0.02s) - expected 200, got 404 - -**Summary:** lint: PASS | test: FAIL (1) - ---- - -Fixing test issue: expected 200, got 404 -Reading test setup... -Correcting test data. - -Running: core go qa - -✓ All checks passed! - -**Summary:** -- Fixed: undefined ErrNotFound (added error variable) -- Fixed: TestCreateUser (corrected test setup) -- 2 issues resolved, all checks passing -``` diff --git a/claude/code/scripts/qa-filter.sh b/claude/code/scripts/qa-filter.sh deleted file mode 100755 index 6a83930..0000000 --- a/claude/code/scripts/qa-filter.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -# Filter QA output to show only actionable issues during /core:qa mode -# -# PostToolUse hook that processes QA command output and extracts -# only the failures, hiding verbose success output. - -read -r input -COMMAND=$(echo "$input" | jq -r '.tool_input.command // empty') -OUTPUT=$(echo "$input" | jq -r '.tool_response.stdout // .tool_response.output // empty') -EXIT_CODE=$(echo "$input" | jq -r '.tool_response.exit_code // 0') - -# Only process QA-related commands -case "$COMMAND" in - "core go qa"*|"core php qa"*|"core go test"*|"core php test"*|"core go lint"*|"core php stan"*) - ;; - *) - # Not a QA command, pass through unchanged - echo "$input" - exit 0 - ;; -esac - -# Extract failures from output -FAILURES=$(echo "$OUTPUT" | grep -E "^(FAIL|---\s*FAIL|✗|ERROR|undefined:|error:|panic:)" | head -20) -SUMMARY=$(echo "$OUTPUT" | grep -E "^(fmt:|lint:|test:|pint:|stan:|=== RESULT ===)" | tail -5) - -# Also grab specific error lines with file:line references -FILE_ERRORS=$(echo "$OUTPUT" | grep -E "^[a-zA-Z0-9_/.-]+\.(go|php):[0-9]+:" | head -10) - -if [ -z "$FAILURES" ] && [ "$EXIT_CODE" = "0" ]; then - # All passed - show brief confirmation - cat << 'EOF' -{ - "suppressOutput": true, - "hookSpecificOutput": { - "hookEventName": "PostToolUse", - "additionalContext": "✓ QA passed" - } -} -EOF -else - # Combine failures and file errors - ISSUES="$FAILURES" - if [ -n "$FILE_ERRORS" ]; then - ISSUES="$ISSUES -$FILE_ERRORS" - fi - - # Escape for JSON - ISSUES_ESCAPED=$(echo "$ISSUES" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g') - SUMMARY_ESCAPED=$(echo "$SUMMARY" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/ | /g') - - cat << EOF -{ - "suppressOutput": true, - "hookSpecificOutput": { - "hookEventName": "PostToolUse", - "additionalContext": "## QA Issues\n\n\`\`\`\n$ISSUES_ESCAPED\n\`\`\`\n\n**Summary:** $SUMMARY_ESCAPED" - } -} -EOF -fi diff --git a/claude/code/scripts/qa-verify.sh b/claude/code/scripts/qa-verify.sh deleted file mode 100755 index c9257a2..0000000 --- a/claude/code/scripts/qa-verify.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash -# Verify QA passes before stopping during /core:qa mode -# -# Stop hook that runs QA checks and blocks if any failures exist. -# Ensures Claude fixes all issues before completing the task. - -read -r input -STOP_ACTIVE=$(echo "$input" | jq -r '.stop_hook_active // false') - -# Prevent infinite loop -if [ "$STOP_ACTIVE" = "true" ]; then - exit 0 -fi - -# Detect project type and run QA -if [ -f "go.mod" ]; then - PROJECT="go" - RESULT=$(core go qa 2>&1) || true -elif [ -f "composer.json" ]; then - PROJECT="php" - RESULT=$(core php qa 2>&1) || true -else - # Not a Go or PHP project, allow stop - exit 0 -fi - -# Check if QA passed -if echo "$RESULT" | grep -qE "FAIL|ERROR|✗|panic:|undefined:"; then - # Extract top issues for context - ISSUES=$(echo "$RESULT" | grep -E "^(FAIL|ERROR|✗|undefined:|panic:)|^[a-zA-Z0-9_/.-]+\.(go|php):[0-9]+:" | head -5) - - # Escape for JSON - ISSUES_ESCAPED=$(echo "$ISSUES" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g') - - cat << EOF -{ - "decision": "block", - "reason": "QA still has issues:\n\n$ISSUES_ESCAPED\n\nPlease fix these before stopping." -} -EOF -else - # QA passed, allow stop - exit 0 -fi diff --git a/claude/qa/.claude-plugin/plugin.json b/claude/qa/.claude-plugin/plugin.json deleted file mode 100644 index 27d6228..0000000 --- a/claude/qa/.claude-plugin/plugin.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "qa", - "description": "Quality assurance - iterative fix loops, lint enforcement, test coverage", - "version": "0.1.0", - "author": { - "name": "Lethean" - } -} diff --git a/claude/qa/commands/check.md b/claude/qa/commands/check.md deleted file mode 100644 index 29f34f6..0000000 --- a/claude/qa/commands/check.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -name: check -description: Run QA checks without fixing (report only) -args: [--go|--php|--all] ---- - -# QA Check - -Run QA pipeline and report issues without fixing them. - -## Usage - -``` -/qa:check # Auto-detect project type -/qa:check --go # Force Go checks -/qa:check --php # Force PHP checks -/qa:check --all # Run both if applicable -``` - -## Process - -1. **Detect project type** -2. **Run QA pipeline** -3. **Parse and report issues** -4. **Do NOT fix anything** - -## Go Checks - -```bash -core go qa -``` - -Runs: -- `go fmt` - Formatting -- `go vet` - Static analysis -- `golangci-lint` - Linting -- `go test` - Tests - -## PHP Checks - -```bash -core php qa -``` - -Runs: -- `pint` - Formatting -- `phpstan` - Static analysis -- `pest` - Tests - -## Output - -```markdown -## QA Report - -**Project**: Go (go.mod detected) -**Status**: 3 issues found - -### Formatting -✗ 2 files need formatting -- pkg/api/handler.go -- pkg/auth/token.go - -### Linting -✗ 1 issue -- pkg/api/handler.go:42 - undefined: ErrNotFound - -### Tests -✓ All passing (47/47) - ---- -**Summary**: fmt: FAIL | lint: FAIL | test: PASS - -Run `/qa:qa` to fix these issues automatically. -``` diff --git a/claude/qa/commands/fix.md b/claude/qa/commands/fix.md deleted file mode 100644 index ece31cb..0000000 --- a/claude/qa/commands/fix.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -name: fix -description: Fix a specific QA issue -args: ---- - -# Fix Issue - -Fix a specific issue from QA output. - -## Usage - -``` -/qa:fix undefined: ErrNotFound in pkg/api/handler.go:42 -/qa:fix TestCreateUser failing - expected 200, got 500 -/qa:fix pkg/api/handler.go needs formatting -``` - -## Process - -1. **Parse the issue**: Extract file, line, error type -2. **Read context**: Read the file around the error line -3. **Understand**: Determine root cause -4. **Fix**: Make minimal change to resolve -5. **Verify**: Run relevant test/lint check - -## Issue Types - -### Undefined variable/type -``` -undefined: ErrNotFound -``` -→ Add missing import or define the variable - -### Test failure -``` -expected 200, got 500 -``` -→ Read test and implementation, fix logic - -### Formatting -``` -file needs formatting -``` -→ Run `core go fmt` or `core php fmt` - -### Lint warning -``` -ineffectual assignment to err -``` -→ Use the variable or remove assignment - -### Type error -``` -cannot use X as Y -``` -→ Fix type conversion or function signature diff --git a/claude/qa/commands/lint.md b/claude/qa/commands/lint.md deleted file mode 100644 index 7ea8746..0000000 --- a/claude/qa/commands/lint.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -name: lint -description: Run linter and fix issues -args: [--check|--fix] ---- - -# Lint - -Run linter and optionally fix issues. - -## Usage - -``` -/qa:lint # Run lint, report issues -/qa:lint --check # Check only, no fixes -/qa:lint --fix # Auto-fix where possible -``` - -## Process - -### Go -```bash -# Check -core go lint - -# Some issues can be auto-fixed -golangci-lint run --fix -``` - -### PHP -```bash -# Check -core php stan - -# PHPStan doesn't auto-fix, but can suggest fixes -``` - -## Common Issues - -### Go - -| Issue | Fix | -|-------|-----| -| `undefined: X` | Add import or define variable | -| `ineffectual assignment` | Use variable or remove | -| `unused parameter` | Use `_` prefix or remove | -| `error return value not checked` | Handle the error | - -### PHP - -| Issue | Fix | -|-------|-----| -| `Undefined variable` | Define or check existence | -| `Parameter $x has no type` | Add type hint | -| `Method has no return type` | Add return type | - -## Output - -```markdown -## Lint Results - -**Linter**: golangci-lint -**Issues**: 3 - -### Errors -1. **pkg/api/handler.go:42** - undefined: ErrNotFound - → Add `var ErrNotFound = errors.New("not found")` - -2. **pkg/api/handler.go:87** - error return value not checked - → Handle error: `if err != nil { return err }` - -### Warnings -1. **pkg/api/handler.go:15** - unused parameter ctx - → Rename to `_` or use it - ---- -Run `/qa:lint --fix` to auto-fix where possible. -``` diff --git a/claude/qa/commands/qa.md b/claude/qa/commands/qa.md deleted file mode 100644 index 0d82c6e..0000000 --- a/claude/qa/commands/qa.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -name: qa -description: Run full QA pipeline and fix all issues iteratively -hooks: - PostToolUse: - - matcher: "Bash" - hooks: - - type: command - command: "${CLAUDE_PLUGIN_ROOT}/scripts/qa-filter.sh" - Stop: - - hooks: - - type: command - command: "${CLAUDE_PLUGIN_ROOT}/scripts/qa-verify.sh" - once: true ---- - -# QA Fix Loop - -Run the full QA pipeline and fix all issues until everything passes. - -## Detection - -First, detect the project type: -- If `go.mod` exists → Go project → `core go qa` -- If `composer.json` exists → PHP project → `core php qa` -- If both exist → check current directory or ask - -## Process - -1. **Run QA**: Execute `core go qa` or `core php qa` -2. **Parse issues**: Extract failures from output -3. **Fix each issue**: Address one at a time, simplest first -4. **Re-verify**: After fixes, re-run QA -5. **Repeat**: Until all checks pass -6. **Report**: Summary of what was fixed - -## Issue Priority - -Fix in this order (fastest feedback first): -1. **fmt** - formatting (auto-fix with `core go fmt`) -2. **lint** - static analysis (usually quick fixes) -3. **test** - failing tests (may need investigation) -4. **build** - compilation errors (fix before tests can run) - -## Fixing Strategy - -**Formatting (fmt/pint):** -- Just run `core go fmt` or `core php fmt` -- No code reading needed - -**Lint errors:** -- Read the specific file:line -- Understand the error type -- Make minimal fix - -**Test failures:** -- Read the test file to understand expectation -- Read the implementation -- Fix the root cause (not just the symptom) - -## Stop Condition - -Only stop when: -- All QA checks pass, OR -- User explicitly cancels, OR -- Same error repeats 3 times (stuck - ask for help) diff --git a/claude/qa/hooks.json b/claude/qa/hooks.json deleted file mode 100644 index 0b463ec..0000000 --- a/claude/qa/hooks.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "https://claude.ai/schemas/hooks.json", - "hooks": { - "PostToolUse": [ - { - "matcher": "tool == \"Bash\" && tool_input.command matches \"^core (go|php) (qa|test|lint|stan)\"", - "hooks": [ - { - "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/scripts/qa-filter.sh" - } - ], - "description": "Filter QA output to show only actionable issues" - } - ] - } -} diff --git a/claude/qa/scripts/qa-filter.sh b/claude/qa/scripts/qa-filter.sh deleted file mode 100755 index 6a83930..0000000 --- a/claude/qa/scripts/qa-filter.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -# Filter QA output to show only actionable issues during /core:qa mode -# -# PostToolUse hook that processes QA command output and extracts -# only the failures, hiding verbose success output. - -read -r input -COMMAND=$(echo "$input" | jq -r '.tool_input.command // empty') -OUTPUT=$(echo "$input" | jq -r '.tool_response.stdout // .tool_response.output // empty') -EXIT_CODE=$(echo "$input" | jq -r '.tool_response.exit_code // 0') - -# Only process QA-related commands -case "$COMMAND" in - "core go qa"*|"core php qa"*|"core go test"*|"core php test"*|"core go lint"*|"core php stan"*) - ;; - *) - # Not a QA command, pass through unchanged - echo "$input" - exit 0 - ;; -esac - -# Extract failures from output -FAILURES=$(echo "$OUTPUT" | grep -E "^(FAIL|---\s*FAIL|✗|ERROR|undefined:|error:|panic:)" | head -20) -SUMMARY=$(echo "$OUTPUT" | grep -E "^(fmt:|lint:|test:|pint:|stan:|=== RESULT ===)" | tail -5) - -# Also grab specific error lines with file:line references -FILE_ERRORS=$(echo "$OUTPUT" | grep -E "^[a-zA-Z0-9_/.-]+\.(go|php):[0-9]+:" | head -10) - -if [ -z "$FAILURES" ] && [ "$EXIT_CODE" = "0" ]; then - # All passed - show brief confirmation - cat << 'EOF' -{ - "suppressOutput": true, - "hookSpecificOutput": { - "hookEventName": "PostToolUse", - "additionalContext": "✓ QA passed" - } -} -EOF -else - # Combine failures and file errors - ISSUES="$FAILURES" - if [ -n "$FILE_ERRORS" ]; then - ISSUES="$ISSUES -$FILE_ERRORS" - fi - - # Escape for JSON - ISSUES_ESCAPED=$(echo "$ISSUES" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g') - SUMMARY_ESCAPED=$(echo "$SUMMARY" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/ | /g') - - cat << EOF -{ - "suppressOutput": true, - "hookSpecificOutput": { - "hookEventName": "PostToolUse", - "additionalContext": "## QA Issues\n\n\`\`\`\n$ISSUES_ESCAPED\n\`\`\`\n\n**Summary:** $SUMMARY_ESCAPED" - } -} -EOF -fi diff --git a/claude/qa/scripts/qa-verify.sh b/claude/qa/scripts/qa-verify.sh deleted file mode 100755 index c9257a2..0000000 --- a/claude/qa/scripts/qa-verify.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash -# Verify QA passes before stopping during /core:qa mode -# -# Stop hook that runs QA checks and blocks if any failures exist. -# Ensures Claude fixes all issues before completing the task. - -read -r input -STOP_ACTIVE=$(echo "$input" | jq -r '.stop_hook_active // false') - -# Prevent infinite loop -if [ "$STOP_ACTIVE" = "true" ]; then - exit 0 -fi - -# Detect project type and run QA -if [ -f "go.mod" ]; then - PROJECT="go" - RESULT=$(core go qa 2>&1) || true -elif [ -f "composer.json" ]; then - PROJECT="php" - RESULT=$(core php qa 2>&1) || true -else - # Not a Go or PHP project, allow stop - exit 0 -fi - -# Check if QA passed -if echo "$RESULT" | grep -qE "FAIL|ERROR|✗|panic:|undefined:"; then - # Extract top issues for context - ISSUES=$(echo "$RESULT" | grep -E "^(FAIL|ERROR|✗|undefined:|panic:)|^[a-zA-Z0-9_/.-]+\.(go|php):[0-9]+:" | head -5) - - # Escape for JSON - ISSUES_ESCAPED=$(echo "$ISSUES" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g') - - cat << EOF -{ - "decision": "block", - "reason": "QA still has issues:\n\n$ISSUES_ESCAPED\n\nPlease fix these before stopping." -} -EOF -else - # QA passed, allow stop - exit 0 -fi