@bonesofspring/ai-rules 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -5
- package/README.md +13 -1
- package/bin/cli.js +2 -0
- package/package.json +8 -1
- package/presets/_shared/README.md +47 -0
- package/presets/_shared/core/agent-team/agent-team-intake.md +9 -0
- package/presets/_shared/core/agent-team/agent-team-orchestrator.md +142 -0
- package/presets/_shared/core/architecture/feature-delivery-workflow.md +46 -0
- package/presets/_shared/core/architecture/reference-features.template.md +31 -0
- package/presets/_shared/core/meta/preset-layering.md +25 -0
- package/presets/_shared/core/meta/preset-no-cross-stack-leakage.md +43 -0
- package/presets/_shared/core/meta/preset-pr-checklist.md +28 -0
- package/presets/_shared/core/meta/preset-token-budget.md +30 -0
- package/presets/_shared/core/meta/preset-twin-sync.md +31 -0
- package/presets/_shared/core/quality/code-quality-and-refactoring.md +58 -0
- package/presets/_shared/core/quality/design-guidance.md +97 -0
- package/presets/_shared/core/review/code-review-mr.md +29 -0
- package/presets/_shared/core/review/technical-retro.md +7 -0
- package/presets/claude/go/CLAUDE.md +10 -0
- package/presets/claude/go/MCP.md +16 -0
- package/presets/claude/go/README.md +34 -0
- package/presets/claude/go/agents/README.md +15 -0
- package/presets/claude/go/agents/api-contract-reviewer.md +23 -0
- package/presets/claude/go/agents/build-verifier.md +30 -0
- package/presets/claude/go/agents/ci-investigator.md +17 -0
- package/presets/claude/go/agents/code-reviewer.md +40 -0
- package/presets/claude/go/agents/debugger.md +25 -0
- package/presets/claude/go/agents/feature-developer.md +30 -0
- package/presets/claude/go/agents/integration-test-generator.md +22 -0
- package/presets/claude/go/agents/integration-test-healer.md +22 -0
- package/presets/claude/go/agents/integration-test-planner.md +22 -0
- package/presets/claude/go/agents/migration-specialist.md +31 -0
- package/presets/claude/go/agents/performance-auditor.md +22 -0
- package/presets/claude/go/agents/qa-tester.md +24 -0
- package/presets/claude/go/agents/security-reviewer.md +20 -0
- package/presets/claude/go/agents/solution-architect.md +28 -0
- package/presets/claude/go/agents/task-analyst.md +25 -0
- package/presets/claude/go/agents/task-router.md +69 -0
- package/presets/claude/go/agents/tech-writer.md +15 -0
- package/presets/claude/go/agents/unit-test-generator.md +21 -0
- package/presets/claude/go/agents/unit-test-healer.md +13 -0
- package/presets/claude/go/agents/unit-test-planner.md +26 -0
- package/presets/claude/go/commands/README.md +13 -0
- package/presets/claude/go/commands/feature-continue.md +51 -0
- package/presets/claude/go/commands/feature-start.md +30 -0
- package/presets/claude/go/commands/task-continue.md +49 -0
- package/presets/claude/go/commands/task.md +49 -0
- package/presets/claude/go/commands/technical-retro.md +58 -0
- package/presets/claude/go/hooks/README.md +10 -0
- package/presets/claude/go/hooks/chain-team-phases.sh +381 -0
- package/presets/claude/go/hooks/guard-shell-command.sh +79 -0
- package/presets/claude/go/mcp.json +12 -0
- package/presets/claude/go/rules/README.md +60 -0
- package/presets/claude/go/rules/api-and-data/README.md +14 -0
- package/presets/claude/go/rules/api-and-data/adapters-driven.md +34 -0
- package/presets/claude/go/rules/api-and-data/adapters-driving.md +35 -0
- package/presets/claude/go/rules/api-and-data/api-grpc.md +27 -0
- package/presets/claude/go/rules/api-and-data/api-http.md +26 -0
- package/presets/claude/go/rules/api-and-data/messaging-adapters.md +21 -0
- package/presets/claude/go/rules/api-and-data/persistence-adapters.md +28 -0
- package/presets/claude/go/rules/architecture/README.md +16 -0
- package/presets/claude/go/rules/architecture/application-usecases.md +29 -0
- package/presets/claude/go/rules/architecture/boundaries.md +29 -0
- package/presets/claude/go/rules/architecture/composition-root.md +28 -0
- package/presets/claude/go/rules/architecture/domain-layer.md +32 -0
- package/presets/claude/go/rules/architecture/feature-delivery.md +51 -0
- package/presets/claude/go/rules/architecture/module-public-api.md +23 -0
- package/presets/claude/go/rules/architecture/ports-interfaces.md +34 -0
- package/presets/claude/go/rules/architecture/reference-features.md +30 -0
- package/presets/claude/go/rules/stack/README.md +10 -0
- package/presets/claude/go/rules/stack/go-app-core.md +31 -0
- package/presets/claude/go/rules/stack/go-conventions.md +24 -0
- package/presets/claude/go/rules/testing/README.md +11 -0
- package/presets/claude/go/rules/testing/e2e.md +18 -0
- package/presets/claude/go/rules/testing/integration.md +23 -0
- package/presets/claude/go/rules/testing/unit.md +24 -0
- package/presets/claude/go/rules/tooling-and-review/README.md +21 -0
- package/presets/claude/go/rules/tooling-and-review/agent-team-intake.md +25 -0
- package/presets/claude/go/rules/tooling-and-review/agent-team-orchestrator.md +161 -0
- package/presets/claude/go/rules/tooling-and-review/code-quality.md +72 -0
- package/presets/claude/go/rules/tooling-and-review/code-review.md +48 -0
- package/presets/claude/go/rules/tooling-and-review/design-guidance.md +110 -0
- package/presets/claude/go/rules/tooling-and-review/go-tooling.md +38 -0
- package/presets/claude/go/rules/tooling-and-review/post-change-test.md +32 -0
- package/presets/claude/go/rules/tooling-and-review/preset-layering.md +36 -0
- package/presets/claude/go/rules/tooling-and-review/preset-no-cross-stack-leakage.md +58 -0
- package/presets/claude/go/rules/tooling-and-review/preset-pr-checklist.md +39 -0
- package/presets/claude/go/rules/tooling-and-review/preset-token-budget.md +41 -0
- package/presets/claude/go/rules/tooling-and-review/preset-twin-sync.md +42 -0
- package/presets/claude/go/rules/tooling-and-review/security-go.md +22 -0
- package/presets/claude/go/rules/tooling-and-review/technical-retro.md +19 -0
- package/presets/claude/go/rules/ui-and-accessibility/README.md +3 -0
- package/presets/claude/go/skills/README.md +5 -0
- package/presets/claude/go/skills/ci-investigation/SKILL.md +11 -0
- package/presets/claude/go/skills/code-review/SKILL.md +16 -0
- package/presets/claude/go/skills/debug-investigation/SKILL.md +15 -0
- package/presets/claude/go/skills/feature-delivery/SKILL.md +26 -0
- package/presets/claude/go/skills/integration-testing/SKILL.md +15 -0
- package/presets/claude/go/skills/technical-retro/SKILL.md +10 -0
- package/presets/claude/go/skills/unit-testing/SKILL.md +14 -0
- package/presets/claude/go/team/README.md +27 -0
- package/presets/claude/go/team/fixtures/bugfix-standard.json +37 -0
- package/presets/claude/go/team/fixtures/feature-full.json +43 -0
- package/presets/claude/go/team/fixtures/feature-light.json +17 -0
- package/presets/claude/ios-swift/README.md +7 -0
- package/presets/claude/ios-swift/agents/build-verifier.md +17 -8
- package/presets/claude/ios-swift/agents/code-reviewer.md +4 -0
- package/presets/claude/ios-swift/agents/debugger.md +4 -0
- package/presets/claude/ios-swift/agents/feature-developer.md +4 -0
- package/presets/claude/ios-swift/agents/migration-specialist.md +4 -0
- package/presets/claude/ios-swift/agents/performance-auditor.md +4 -0
- package/presets/claude/ios-swift/agents/qa-tester.md +4 -0
- package/presets/claude/ios-swift/agents/solution-architect.md +4 -0
- package/presets/claude/ios-swift/agents/task-analyst.md +4 -0
- package/presets/claude/ios-swift/agents/unit-test-generator.md +4 -0
- package/presets/claude/ios-swift/agents/unit-test-healer.md +4 -0
- package/presets/claude/ios-swift/agents/unit-test-planner.md +4 -0
- package/presets/claude/ios-swift/rules/README.md +24 -2
- package/presets/claude/ios-swift/rules/architecture/feature-delivery.md +5 -0
- package/presets/claude/ios-swift/rules/architecture/reference-features.md +5 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/agent-team-intake.md +2 -2
- package/presets/claude/ios-swift/rules/tooling-and-review/agent-team-orchestrator.md +7 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/code-quality.md +53 -20
- package/presets/claude/ios-swift/rules/tooling-and-review/code-review.md +29 -35
- package/presets/claude/ios-swift/rules/tooling-and-review/design-guidance.md +110 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/preset-layering.md +36 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/preset-no-cross-stack-leakage.md +54 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/preset-pr-checklist.md +39 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/preset-token-budget.md +41 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/preset-twin-sync.md +42 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/technical-retro.md +5 -3
- package/presets/claude/ios-swift/skills/code-review/SKILL.md +4 -0
- package/presets/claude/ios-swift/skills/debug-investigation/SKILL.md +4 -0
- package/presets/claude/ios-swift/skills/feature-delivery/SKILL.md +4 -0
- package/presets/claude/next/README.md +9 -1
- package/presets/claude/next/agents/build-verifier.md +24 -0
- package/presets/claude/next/agents/code-reviewer.md +4 -0
- package/presets/claude/next/agents/debugger.md +4 -0
- package/presets/claude/next/agents/feature-developer.md +4 -0
- package/presets/claude/next/agents/migration-specialist.md +4 -0
- package/presets/claude/next/agents/performance-auditor.md +4 -0
- package/presets/claude/next/agents/qa-tester.md +4 -0
- package/presets/claude/next/agents/solution-architect.md +4 -0
- package/presets/claude/next/agents/task-analyst.md +4 -0
- package/presets/claude/next/agents/unit-test-generator.md +4 -0
- package/presets/claude/next/agents/unit-test-healer.md +4 -0
- package/presets/claude/next/agents/unit-test-planner.md +4 -0
- package/presets/claude/next/rules/README.md +74 -21
- package/presets/claude/next/rules/architecture/feature-delivery-workflow.md +5 -0
- package/presets/claude/next/rules/architecture/reference-features.md +5 -0
- package/presets/claude/next/rules/tooling-and-review/agent-team-intake.md +2 -0
- package/presets/claude/next/rules/tooling-and-review/agent-team-orchestrator.md +7 -0
- package/presets/claude/next/rules/tooling-and-review/code-quality.md +48 -20
- package/presets/claude/next/rules/tooling-and-review/code-review-mr.md +17 -8
- package/presets/claude/next/rules/tooling-and-review/design-guidance.md +110 -0
- package/presets/claude/next/rules/tooling-and-review/preset-layering.md +36 -0
- package/presets/claude/next/rules/tooling-and-review/preset-no-cross-stack-leakage.md +54 -0
- package/presets/claude/next/rules/tooling-and-review/preset-pr-checklist.md +39 -0
- package/presets/claude/next/rules/tooling-and-review/preset-token-budget.md +41 -0
- package/presets/claude/next/rules/tooling-and-review/preset-twin-sync.md +42 -0
- package/presets/claude/next/rules/tooling-and-review/technical-retro.md +16 -0
- package/presets/claude/next/skills/code-review/SKILL.md +4 -0
- package/presets/claude/next/skills/debug-investigation/SKILL.md +4 -0
- package/presets/claude/next/skills/feature-delivery/SKILL.md +4 -0
- package/presets/cursor/go/AGENTS.md +24 -0
- package/presets/cursor/go/BUGBOT.md +9 -0
- package/presets/cursor/go/MCP.md +16 -0
- package/presets/cursor/go/README.md +38 -0
- package/presets/cursor/go/agents/README.md +15 -0
- package/presets/cursor/go/agents/api-contract-reviewer.md +23 -0
- package/presets/cursor/go/agents/build-verifier.md +30 -0
- package/presets/cursor/go/agents/ci-investigator.md +17 -0
- package/presets/cursor/go/agents/code-reviewer.md +40 -0
- package/presets/cursor/go/agents/debugger.md +25 -0
- package/presets/cursor/go/agents/feature-developer.md +30 -0
- package/presets/cursor/go/agents/integration-test-generator.md +22 -0
- package/presets/cursor/go/agents/integration-test-healer.md +22 -0
- package/presets/cursor/go/agents/integration-test-planner.md +22 -0
- package/presets/cursor/go/agents/migration-specialist.md +31 -0
- package/presets/cursor/go/agents/performance-auditor.md +22 -0
- package/presets/cursor/go/agents/qa-tester.md +24 -0
- package/presets/cursor/go/agents/security-reviewer.md +20 -0
- package/presets/cursor/go/agents/solution-architect.md +28 -0
- package/presets/cursor/go/agents/task-analyst.md +25 -0
- package/presets/cursor/go/agents/task-router.md +69 -0
- package/presets/cursor/go/agents/tech-writer.md +15 -0
- package/presets/cursor/go/agents/unit-test-generator.md +21 -0
- package/presets/cursor/go/agents/unit-test-healer.md +13 -0
- package/presets/cursor/go/agents/unit-test-planner.md +26 -0
- package/presets/cursor/go/commands/README.md +54 -0
- package/presets/cursor/go/commands/feature-continue.md +19 -0
- package/presets/cursor/go/commands/feature-start.md +33 -0
- package/presets/cursor/go/commands/task-continue.md +49 -0
- package/presets/cursor/go/commands/task.md +49 -0
- package/presets/cursor/go/commands/technical-retro.md +81 -0
- package/presets/cursor/go/hooks/README.md +8 -0
- package/presets/cursor/go/hooks/chain-team-phases.sh +381 -0
- package/presets/cursor/go/hooks/guard-shell-command.sh +79 -0
- package/presets/cursor/go/hooks.json +17 -0
- package/presets/cursor/go/mcp.json +11 -0
- package/presets/cursor/go/rules/README.md +89 -0
- package/presets/cursor/go/rules/adapters-driven.mdc +35 -0
- package/presets/cursor/go/rules/adapters-driving.mdc +36 -0
- package/presets/cursor/go/rules/agent-team-intake.mdc +20 -0
- package/presets/cursor/go/rules/agent-team-orchestrator.mdc +156 -0
- package/presets/cursor/go/rules/api-grpc.mdc +28 -0
- package/presets/cursor/go/rules/api-http.mdc +27 -0
- package/presets/cursor/go/rules/application-usecases.mdc +30 -0
- package/presets/cursor/go/rules/architecture-boundaries.mdc +30 -0
- package/presets/cursor/go/rules/code-quality-and-refactoring.mdc +73 -0
- package/presets/cursor/go/rules/code-review-mr.mdc +43 -0
- package/presets/cursor/go/rules/composition-root.mdc +29 -0
- package/presets/cursor/go/rules/design-guidance.mdc +111 -0
- package/presets/cursor/go/rules/domain-layer.mdc +33 -0
- package/presets/cursor/go/rules/feature-delivery-workflow.mdc +46 -0
- package/presets/cursor/go/rules/go-app-core.mdc +32 -0
- package/presets/cursor/go/rules/go-conventions.mdc +25 -0
- package/presets/cursor/go/rules/go-tooling.mdc +33 -0
- package/presets/cursor/go/rules/messaging-adapters.mdc +22 -0
- package/presets/cursor/go/rules/module-public-api.mdc +24 -0
- package/presets/cursor/go/rules/persistence-adapters.mdc +29 -0
- package/presets/cursor/go/rules/ports-interfaces.mdc +35 -0
- package/presets/cursor/go/rules/post-change-test.mdc +27 -0
- package/presets/cursor/go/rules/preset-layering.mdc +36 -0
- package/presets/cursor/go/rules/preset-no-cross-stack-leakage.mdc +58 -0
- package/presets/cursor/go/rules/preset-pr-checklist.mdc +39 -0
- package/presets/cursor/go/rules/preset-token-budget.mdc +41 -0
- package/presets/cursor/go/rules/preset-twin-sync.mdc +42 -0
- package/presets/cursor/go/rules/reference-features.mdc +31 -0
- package/presets/cursor/go/rules/security-go.mdc +23 -0
- package/presets/cursor/go/rules/technical-retro.mdc +14 -0
- package/presets/cursor/go/rules/tests-e2e.mdc +19 -0
- package/presets/cursor/go/rules/tests-integration.mdc +24 -0
- package/presets/cursor/go/rules/tests-unit.mdc +25 -0
- package/presets/cursor/go/skills/README.md +5 -0
- package/presets/cursor/go/skills/ci-investigation/SKILL.md +11 -0
- package/presets/cursor/go/skills/code-review/SKILL.md +16 -0
- package/presets/cursor/go/skills/debug-investigation/SKILL.md +15 -0
- package/presets/cursor/go/skills/feature-delivery/SKILL.md +26 -0
- package/presets/cursor/go/skills/integration-testing/SKILL.md +15 -0
- package/presets/cursor/go/skills/technical-retro/SKILL.md +10 -0
- package/presets/cursor/go/skills/unit-testing/SKILL.md +14 -0
- package/presets/cursor/go/team/README.md +31 -0
- package/presets/cursor/go/team/fixtures/bugfix-standard.json +37 -0
- package/presets/cursor/go/team/fixtures/feature-full.json +43 -0
- package/presets/cursor/go/team/fixtures/feature-light.json +17 -0
- package/presets/cursor/ios-swift/README.md +7 -0
- package/presets/cursor/ios-swift/agents/build-verifier.md +17 -8
- package/presets/cursor/ios-swift/agents/code-reviewer.md +4 -0
- package/presets/cursor/ios-swift/agents/debugger.md +4 -0
- package/presets/cursor/ios-swift/agents/feature-developer.md +4 -0
- package/presets/cursor/ios-swift/agents/migration-specialist.md +4 -0
- package/presets/cursor/ios-swift/agents/performance-auditor.md +4 -0
- package/presets/cursor/ios-swift/agents/qa-tester.md +4 -0
- package/presets/cursor/ios-swift/agents/solution-architect.md +4 -0
- package/presets/cursor/ios-swift/agents/task-analyst.md +4 -0
- package/presets/cursor/ios-swift/agents/unit-test-generator.md +4 -0
- package/presets/cursor/ios-swift/agents/unit-test-healer.md +4 -0
- package/presets/cursor/ios-swift/agents/unit-test-planner.md +4 -0
- package/presets/cursor/ios-swift/rules/README.md +23 -2
- package/presets/cursor/ios-swift/rules/agent-team-intake.mdc +2 -2
- package/presets/cursor/ios-swift/rules/agent-team-orchestrator.mdc +8 -2
- package/presets/cursor/ios-swift/rules/code-quality-and-refactoring.mdc +53 -20
- package/presets/cursor/ios-swift/rules/code-review-mr.mdc +32 -0
- package/presets/cursor/ios-swift/rules/design-guidance.mdc +111 -0
- package/presets/cursor/ios-swift/rules/feature-delivery-workflow.mdc +6 -0
- package/presets/cursor/ios-swift/rules/preset-layering.mdc +36 -0
- package/presets/cursor/ios-swift/rules/preset-no-cross-stack-leakage.mdc +54 -0
- package/presets/cursor/ios-swift/rules/preset-pr-checklist.mdc +39 -0
- package/presets/cursor/ios-swift/rules/preset-token-budget.mdc +41 -0
- package/presets/cursor/ios-swift/rules/preset-twin-sync.mdc +42 -0
- package/presets/cursor/ios-swift/rules/reference-features.mdc +6 -0
- package/presets/cursor/ios-swift/rules/technical-retro.mdc +4 -2
- package/presets/cursor/ios-swift/skills/code-review/SKILL.md +4 -0
- package/presets/cursor/ios-swift/skills/debug-investigation/SKILL.md +4 -0
- package/presets/cursor/ios-swift/skills/feature-delivery/SKILL.md +4 -0
- package/presets/cursor/next/README.md +46 -0
- package/presets/cursor/next/agents/build-verifier.md +24 -0
- package/presets/cursor/next/agents/code-reviewer.md +4 -0
- package/presets/cursor/next/agents/debugger.md +4 -0
- package/presets/cursor/next/agents/feature-developer.md +4 -0
- package/presets/cursor/next/agents/migration-specialist.md +4 -0
- package/presets/cursor/next/agents/performance-auditor.md +4 -0
- package/presets/cursor/next/agents/qa-tester.md +4 -0
- package/presets/cursor/next/agents/solution-architect.md +4 -0
- package/presets/cursor/next/agents/task-analyst.md +4 -0
- package/presets/cursor/next/agents/unit-test-generator.md +4 -0
- package/presets/cursor/next/agents/unit-test-healer.md +4 -0
- package/presets/cursor/next/agents/unit-test-planner.md +4 -0
- package/presets/cursor/next/commands/README.md +1 -1
- package/presets/cursor/next/rules/README.md +21 -1
- package/presets/cursor/next/rules/agent-team-intake.mdc +2 -0
- package/presets/cursor/next/rules/agent-team-orchestrator.mdc +8 -2
- package/presets/cursor/next/rules/code-quality-and-refactoring.mdc +45 -18
- package/presets/cursor/next/rules/code-review-mr.mdc +32 -0
- package/presets/cursor/next/rules/design-guidance.mdc +111 -0
- package/presets/cursor/next/rules/feature-delivery-workflow.mdc +6 -0
- package/presets/cursor/next/rules/preset-layering.mdc +36 -0
- package/presets/cursor/next/rules/preset-no-cross-stack-leakage.mdc +54 -0
- package/presets/cursor/next/rules/preset-pr-checklist.mdc +39 -0
- package/presets/cursor/next/rules/preset-token-budget.mdc +41 -0
- package/presets/cursor/next/rules/preset-twin-sync.mdc +42 -0
- package/presets/cursor/next/rules/reference-features.mdc +6 -0
- package/presets/cursor/next/rules/technical-retro.mdc +5 -3
- package/presets/cursor/next/skills/code-review/SKILL.md +4 -0
- package/presets/cursor/next/skills/debug-investigation/SKILL.md +4 -0
- package/presets/cursor/next/skills/feature-delivery/SKILL.md +4 -0
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# preset: go (hexagonal) — chain handoffs use integration-test-* + go test
|
|
3
|
+
# Chains agent team steps from pipeline.json after subagentStop.
|
|
4
|
+
# Falls back to legacy phase-based flow when pipeline.json is absent.
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
input=$(cat)
|
|
9
|
+
|
|
10
|
+
INPUT="$input" node <<'NODE'
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
|
|
14
|
+
const TEAM_ROOT = path.join(process.cwd(), '.claude', 'team');
|
|
15
|
+
|
|
16
|
+
const inputRaw = process.env.INPUT || '';
|
|
17
|
+
let hookInput;
|
|
18
|
+
try {
|
|
19
|
+
hookInput = JSON.parse(inputRaw);
|
|
20
|
+
} catch {
|
|
21
|
+
process.stdout.write('{}');
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (hookInput.status !== 'completed') {
|
|
26
|
+
process.stdout.write('{}');
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const activePath = path.join(TEAM_ROOT, 'active-task.json');
|
|
31
|
+
|
|
32
|
+
if (!fs.existsSync(activePath)) {
|
|
33
|
+
process.stdout.write('{}');
|
|
34
|
+
process.exit(0);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let active;
|
|
38
|
+
try {
|
|
39
|
+
active = JSON.parse(fs.readFileSync(activePath, 'utf8'));
|
|
40
|
+
} catch {
|
|
41
|
+
process.stdout.write('{}');
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const slug = active.slug;
|
|
46
|
+
if (!slug) {
|
|
47
|
+
process.stdout.write('{}');
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const taskDir = path.join(TEAM_ROOT, 'tasks', slug);
|
|
52
|
+
const statusPath = path.join(taskDir, 'status.json');
|
|
53
|
+
const pipelinePath = path.join(taskDir, 'pipeline.json');
|
|
54
|
+
|
|
55
|
+
if (!fs.existsSync(statusPath)) {
|
|
56
|
+
process.stdout.write('{}');
|
|
57
|
+
process.exit(0);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let status;
|
|
61
|
+
try {
|
|
62
|
+
status = JSON.parse(fs.readFileSync(statusPath, 'utf8'));
|
|
63
|
+
} catch {
|
|
64
|
+
process.stdout.write('{}');
|
|
65
|
+
process.exit(0);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const now = new Date().toISOString();
|
|
69
|
+
|
|
70
|
+
function writeStatus(next) {
|
|
71
|
+
status = { ...status, ...next, slug, updatedAt: now };
|
|
72
|
+
fs.writeFileSync(statusPath, JSON.stringify(status, null, 2) + '\n');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function out(message) {
|
|
76
|
+
process.stdout.write(JSON.stringify({ followup_message: message }));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function readArtifact(name) {
|
|
80
|
+
const p = path.join(taskDir, name);
|
|
81
|
+
if (!fs.existsSync(p)) return '';
|
|
82
|
+
try {
|
|
83
|
+
return fs.readFileSync(p, 'utf8');
|
|
84
|
+
} catch {
|
|
85
|
+
return '';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function getStepAgents(step) {
|
|
90
|
+
if (!step) return [];
|
|
91
|
+
return Array.isArray(step.agent) ? step.agent : [step.agent];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function skipIfMatches(skipIf, dir) {
|
|
95
|
+
if (!skipIf) return false;
|
|
96
|
+
if (skipIf === 'debugger.fixed') {
|
|
97
|
+
const text = readArtifact('debug-report.md');
|
|
98
|
+
return /fixApplied:\s*true/i.test(text) || /\*\*Fix applied:\*\*\s*true/i.test(text);
|
|
99
|
+
}
|
|
100
|
+
if (skipIf === 'ci-investigator.resolved') {
|
|
101
|
+
const text = readArtifact('ci-report.md');
|
|
102
|
+
return /fixApplied:\s*true/i.test(text) || /## Verdict\s*\nPASS/i.test(text);
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function findNextExecutableStep(steps, startIdx, dir) {
|
|
108
|
+
for (let i = startIdx; i < steps.length; i++) {
|
|
109
|
+
if (!skipIfMatches(steps[i].skipIf, dir)) {
|
|
110
|
+
return { step: steps[i], index: i };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const AGENT_HANDOFF = {
|
|
117
|
+
'task-analyst': (s) =>
|
|
118
|
+
`Invoke task-analyst for slug "${s}". Write brief.md and decomposition.md under .claude/team/tasks/${s}/. ` +
|
|
119
|
+
`Set status.json: phase executing, state awaiting_approval if human gate applies. Do not use legacy phase analysis.`,
|
|
120
|
+
debugger: (s) =>
|
|
121
|
+
`Invoke debugger subagent for slug "${s}". Investigate root cause with go test/logs; write debug-report.md with fixApplied: true/false. ` +
|
|
122
|
+
`Update status.json when done.`,
|
|
123
|
+
'solution-architect': (s) =>
|
|
124
|
+
`Invoke solution-architect for slug "${s}". Read brief.md; write architecture.md for Go hexagonal layers. Update status.json when done.`,
|
|
125
|
+
'migration-specialist': (s) =>
|
|
126
|
+
`Invoke migration-specialist for slug "${s}". Read brief.md; write migration-plan.md for Go module/toolchain. Update status.json when done.`,
|
|
127
|
+
'api-contract-reviewer': (s) =>
|
|
128
|
+
`Invoke api-contract-reviewer (readonly) for slug "${s}". Review OpenAPI/Protobuf vs adapters; write api-contract-review.md. Update status.json when done.`,
|
|
129
|
+
'ci-investigator': (s) =>
|
|
130
|
+
`Invoke ci-investigator for slug "${s}". Diagnose CI failure (go test/vet/lint or preset-structure); write ci-report.md; apply minimal fix. ` +
|
|
131
|
+
`Use ci-investigation skill. Update status.json when done.`,
|
|
132
|
+
'feature-developer': (s) =>
|
|
133
|
+
`Invoke feature-developer for slug "${s}". Read brief.md, decomposition.md, validation-report.md, review.md, architecture.md, migration-plan.md, api-contract-review.md, debug-report.md if present. ` +
|
|
134
|
+
`Follow feature-delivery-workflow.mdc and reference-features.mdc. Prefer internal/domain|application|adapters and cmd/ composition root. ` +
|
|
135
|
+
`Include table-driven go test coverage for domain/use cases before handoff. Update status.json when done.`,
|
|
136
|
+
'build-verifier': (s) =>
|
|
137
|
+
`Invoke build-verifier (readonly) for slug "${s}". Follow go-tooling.mdc and post-change-test.mdc. ` +
|
|
138
|
+
`Run go test ./..., go vet ./..., and golangci-lint/staticcheck if configured — never yarn/ESLint/Stylelint. ` +
|
|
139
|
+
`For preset packaging: yarn check:preset-structure. Write validation-report.md. Set state completed or validation_failed. Do not edit production code.`,
|
|
140
|
+
'performance-auditor': (s) =>
|
|
141
|
+
`Invoke performance-auditor (readonly) for slug "${s}". Audit Go hot paths/allocs/DB N+1/pprof risks; write perf-report.md. Update status.json when done.`,
|
|
142
|
+
'code-reviewer': (s) =>
|
|
143
|
+
`Invoke code-reviewer subagent (readonly) for slug "${s}". Review git diff vs brief.md per code-review-mr.mdc (hexagonal boundaries). ` +
|
|
144
|
+
`Update status.json when done.`,
|
|
145
|
+
'security-reviewer': (s) =>
|
|
146
|
+
`Invoke security-reviewer (readonly) for slug "${s}". Follow security-go.mdc; write security-review.md. Update status.json when done.`,
|
|
147
|
+
'qa-tester': (s, scope) =>
|
|
148
|
+
`Invoke qa-tester for slug "${s}"${scope ? ` (scope: ${scope})` : ''}. ` +
|
|
149
|
+
`Add/update go unit and integration tests per brief. Follow tests-unit.mdc, tests-integration.mdc, and skill integration-testing. Update status.json when done.`,
|
|
150
|
+
'unit-test-planner': (s) =>
|
|
151
|
+
`Invoke unit-test-planner for slug "${s}". Write unit-test-plan.md for table-driven go test. Use unit-testing skill. Update status.json when done.`,
|
|
152
|
+
'unit-test-generator': (s) =>
|
|
153
|
+
`Invoke unit-test-generator for slug "${s}". Implement *_test.go from unit-test-plan.md. Use unit-testing skill. Update status.json when done.`,
|
|
154
|
+
'unit-test-healer': (s) =>
|
|
155
|
+
`Invoke unit-test-healer for slug "${s}". Fix failing unit tests. Use unit-testing and debug-investigation skills. Update status.json when done.`,
|
|
156
|
+
'integration-test-planner': (s) =>
|
|
157
|
+
`Invoke integration-test-planner for slug "${s}". Create/update integration test plans (httptest/testcontainers/adapter contracts). ` +
|
|
158
|
+
`Follow tests-integration.mdc and the integration-testing skill. Do not use browser e2e tooling. Update status.json when done.`,
|
|
159
|
+
'integration-test-generator': (s) =>
|
|
160
|
+
`Invoke integration-test-generator for slug "${s}". Generate/update *_integration_test.go from plans. ` +
|
|
161
|
+
`Follow tests-integration.mdc and the integration-testing skill. Do not use browser e2e tooling. Update status.json when done.`,
|
|
162
|
+
'integration-test-healer': (s) =>
|
|
163
|
+
`Invoke integration-test-healer for slug "${s}". Fix failing/flaky integration tests while preserving plan assertions. ` +
|
|
164
|
+
`Follow tests-integration.mdc, integration-testing, and debug-investigation. Do not use browser e2e tooling. Update status.json when done.`,
|
|
165
|
+
'tech-writer': (s) =>
|
|
166
|
+
`Invoke tech-writer for slug "${s}". Write documentation.md from task artifacts. Update status.json when done.`,
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const REVIEW_AGENTS = new Set([
|
|
170
|
+
'code-reviewer',
|
|
171
|
+
'security-reviewer',
|
|
172
|
+
'api-contract-reviewer',
|
|
173
|
+
]);
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
function handoffForAgent(agent, scope) {
|
|
177
|
+
const fn = AGENT_HANDOFF[agent];
|
|
178
|
+
return fn ? fn(slug, scope) : `Invoke ${agent} subagent for slug "${slug}". Update status.json when done.`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function handoffForParallelStep(step) {
|
|
182
|
+
const agents = getStepAgents(step);
|
|
183
|
+
return (
|
|
184
|
+
`Invoke IN PARALLEL (one message, multiple Task calls): ${agents.join(' AND ')} for slug "${slug}". ` +
|
|
185
|
+
`Each agent writes its artifact and appends itself to status.json parallelCompleted when done.`
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function hasGateAfter(agent, humanGates) {
|
|
190
|
+
return Array.isArray(humanGates) && humanGates.includes(`after:${agent}`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function hasGateAfterStep(step, humanGates) {
|
|
194
|
+
return getStepAgents(step).some((a) => hasGateAfter(a, humanGates));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function legacyFlow() {
|
|
198
|
+
if (status.phase === 'analysis') {
|
|
199
|
+
process.stdout.write('{}');
|
|
200
|
+
process.exit(0);
|
|
201
|
+
}
|
|
202
|
+
if (status.phase === 'development' && (status.state === 'completed' || status.state === 'in_progress')) {
|
|
203
|
+
writeStatus({ phase: 'executing', state: 'in_progress', currentAgent: 'build-verifier' });
|
|
204
|
+
out(handoffForAgent('build-verifier'));
|
|
205
|
+
process.exit(0);
|
|
206
|
+
}
|
|
207
|
+
if (status.currentAgent === 'build-verifier' && status.state === 'completed') {
|
|
208
|
+
writeStatus({ phase: 'executing', state: 'in_progress', currentAgent: 'code-reviewer' });
|
|
209
|
+
out(handoffForAgent('code-reviewer'));
|
|
210
|
+
process.exit(0);
|
|
211
|
+
}
|
|
212
|
+
if (status.phase === 'review' && status.state === 'completed') {
|
|
213
|
+
writeStatus({ phase: 'executing', state: 'in_progress', currentAgent: 'qa-tester' });
|
|
214
|
+
out(handoffForAgent('qa-tester'));
|
|
215
|
+
process.exit(0);
|
|
216
|
+
}
|
|
217
|
+
if (status.state === 'changes_requested' && REVIEW_AGENTS.has(status.currentAgent)) {
|
|
218
|
+
writeStatus({
|
|
219
|
+
currentAgent: 'feature-developer',
|
|
220
|
+
state: 'in_progress',
|
|
221
|
+
phase: 'executing',
|
|
222
|
+
retryAfterFix: status.currentAgent,
|
|
223
|
+
});
|
|
224
|
+
out(
|
|
225
|
+
handoffForAgent('feature-developer') +
|
|
226
|
+
` After fixes, re-run ${status.currentAgent}.`,
|
|
227
|
+
);
|
|
228
|
+
process.exit(0);
|
|
229
|
+
}
|
|
230
|
+
if (status.state === 'validation_failed' && status.currentAgent === 'build-verifier') {
|
|
231
|
+
writeStatus({
|
|
232
|
+
currentAgent: 'feature-developer',
|
|
233
|
+
state: 'in_progress',
|
|
234
|
+
phase: 'executing',
|
|
235
|
+
retryAfterFix: 'build-verifier',
|
|
236
|
+
});
|
|
237
|
+
out(
|
|
238
|
+
handoffForAgent('feature-developer') +
|
|
239
|
+
` Read validation-report.md. After fixes, re-run build-verifier.`,
|
|
240
|
+
);
|
|
241
|
+
process.exit(0);
|
|
242
|
+
}
|
|
243
|
+
if (status.state === 'completed' && status.retryAfterFix) {
|
|
244
|
+
const retry = status.retryAfterFix;
|
|
245
|
+
writeStatus({ currentAgent: retry, state: 'in_progress', retryAfterFix: null });
|
|
246
|
+
out(handoffForAgent(retry));
|
|
247
|
+
process.exit(0);
|
|
248
|
+
}
|
|
249
|
+
if (status.phase === 'testing' && status.state === 'completed') {
|
|
250
|
+
writeStatus({ phase: 'done', state: 'completed' });
|
|
251
|
+
out(`Pipeline complete for "${slug}". Run /technical-retro ${slug}.`);
|
|
252
|
+
process.exit(0);
|
|
253
|
+
}
|
|
254
|
+
process.stdout.write('{}');
|
|
255
|
+
process.exit(0);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (!fs.existsSync(pipelinePath)) {
|
|
259
|
+
legacyFlow();
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
let pipeline;
|
|
263
|
+
try {
|
|
264
|
+
pipeline = JSON.parse(fs.readFileSync(pipelinePath, 'utf8'));
|
|
265
|
+
} catch {
|
|
266
|
+
legacyFlow();
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const steps = pipeline.steps || [];
|
|
270
|
+
if (steps.length === 0 || pipeline.autoChain === false) {
|
|
271
|
+
process.stdout.write('{}');
|
|
272
|
+
process.exit(0);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (status.awaitingHumanGate || status.state === 'awaiting_approval') {
|
|
276
|
+
process.stdout.write('{}');
|
|
277
|
+
process.exit(0);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (status.state === 'changes_requested' && REVIEW_AGENTS.has(status.currentAgent)) {
|
|
281
|
+
const reviewer = status.currentAgent;
|
|
282
|
+
writeStatus({
|
|
283
|
+
currentAgent: 'feature-developer',
|
|
284
|
+
state: 'in_progress',
|
|
285
|
+
phase: 'executing',
|
|
286
|
+
retryAfterFix: reviewer,
|
|
287
|
+
});
|
|
288
|
+
out(
|
|
289
|
+
handoffForAgent('feature-developer') +
|
|
290
|
+
` After fixes, re-run ${reviewer}.`,
|
|
291
|
+
);
|
|
292
|
+
process.exit(0);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (status.state === 'validation_failed' && status.currentAgent === 'build-verifier') {
|
|
296
|
+
writeStatus({
|
|
297
|
+
currentAgent: 'feature-developer',
|
|
298
|
+
state: 'in_progress',
|
|
299
|
+
phase: 'executing',
|
|
300
|
+
retryAfterFix: 'build-verifier',
|
|
301
|
+
});
|
|
302
|
+
out(
|
|
303
|
+
handoffForAgent('feature-developer') +
|
|
304
|
+
` Read validation-report.md. After fixes, re-run build-verifier.`,
|
|
305
|
+
);
|
|
306
|
+
process.exit(0);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (status.state === 'completed' && status.retryAfterFix) {
|
|
310
|
+
const retry = status.retryAfterFix;
|
|
311
|
+
writeStatus({ currentAgent: retry, state: 'in_progress', retryAfterFix: null });
|
|
312
|
+
out(handoffForAgent(retry));
|
|
313
|
+
process.exit(0);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const idx = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
|
|
317
|
+
const currentStep = steps[idx];
|
|
318
|
+
if (!currentStep) {
|
|
319
|
+
writeStatus({ phase: 'done', state: 'completed', currentAgent: null });
|
|
320
|
+
out(`Pipeline complete for "${slug}". Run /technical-retro ${slug}.`);
|
|
321
|
+
process.exit(0);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const completedAgent = status.currentAgent || getStepAgents(currentStep)[0];
|
|
325
|
+
const stepAgents = getStepAgents(currentStep);
|
|
326
|
+
|
|
327
|
+
if (currentStep.parallel && stepAgents.length > 1) {
|
|
328
|
+
const done = [...(status.parallelCompleted || [])];
|
|
329
|
+
if (completedAgent && !done.includes(completedAgent)) {
|
|
330
|
+
done.push(completedAgent);
|
|
331
|
+
}
|
|
332
|
+
writeStatus({ parallelCompleted: done });
|
|
333
|
+
const remaining = stepAgents.filter((a) => !done.includes(a));
|
|
334
|
+
if (remaining.length > 0) {
|
|
335
|
+
process.stdout.write('{}');
|
|
336
|
+
process.exit(0);
|
|
337
|
+
}
|
|
338
|
+
writeStatus({ parallelCompleted: [] });
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (hasGateAfterStep(currentStep, pipeline.humanGates)) {
|
|
342
|
+
writeStatus({
|
|
343
|
+
awaitingHumanGate: true,
|
|
344
|
+
state: 'awaiting_approval',
|
|
345
|
+
currentAgent: completedAgent,
|
|
346
|
+
});
|
|
347
|
+
process.stdout.write('{}');
|
|
348
|
+
process.exit(0);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const next = findNextExecutableStep(steps, idx + 1, taskDir);
|
|
352
|
+
if (!next) {
|
|
353
|
+
writeStatus({
|
|
354
|
+
pipelineIndex: steps.length,
|
|
355
|
+
phase: 'done',
|
|
356
|
+
state: 'completed',
|
|
357
|
+
currentAgent: null,
|
|
358
|
+
awaitingHumanGate: false,
|
|
359
|
+
});
|
|
360
|
+
out(`Pipeline complete for "${slug}". Run /technical-retro ${slug}.`);
|
|
361
|
+
process.exit(0);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const { step: nextStep, index: nextIdx } = next;
|
|
365
|
+
const nextAgents = getStepAgents(nextStep);
|
|
366
|
+
|
|
367
|
+
writeStatus({
|
|
368
|
+
pipelineIndex: nextIdx,
|
|
369
|
+
currentAgent: nextAgents[0],
|
|
370
|
+
phase: 'executing',
|
|
371
|
+
state: 'in_progress',
|
|
372
|
+
awaitingHumanGate: false,
|
|
373
|
+
parallelCompleted: [],
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
if (nextStep.parallel && nextAgents.length > 1) {
|
|
377
|
+
out(handoffForParallelStep(nextStep));
|
|
378
|
+
} else {
|
|
379
|
+
out(handoffForAgent(nextAgents[0], nextStep.scope));
|
|
380
|
+
}
|
|
381
|
+
NODE
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Lightweight shell guard for Claude Code projects using this preset.
|
|
3
|
+
# Go: do NOT blanket-block go test / go vet / golangci-lint / staticcheck.
|
|
4
|
+
# Package-manager mismatch checks apply only when a JS lockfile/package.json exists.
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
input=$(cat)
|
|
9
|
+
|
|
10
|
+
INPUT="$input" node <<'NODE'
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
|
|
13
|
+
const raw = process.env.INPUT || '';
|
|
14
|
+
let event;
|
|
15
|
+
try {
|
|
16
|
+
event = JSON.parse(raw);
|
|
17
|
+
} catch {
|
|
18
|
+
process.stdout.write('{ "permission": "allow" }');
|
|
19
|
+
process.exit(0);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const command = String(event.command || event.input?.command || '');
|
|
23
|
+
if (!command.trim()) {
|
|
24
|
+
process.stdout.write('{ "permission": "allow" }');
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function out(permission, userMessage, agentMessage) {
|
|
29
|
+
process.stdout.write(JSON.stringify({
|
|
30
|
+
permission,
|
|
31
|
+
user_message: userMessage,
|
|
32
|
+
agent_message: agentMessage || userMessage,
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const dangerousGit = /\bgit\s+(reset\s+--hard|clean\s+-[^\n]*f|push\s+--force|push\s+-f|checkout\s+--\s+)/;
|
|
37
|
+
if (dangerousGit.test(command)) {
|
|
38
|
+
out(
|
|
39
|
+
'ask',
|
|
40
|
+
'This command looks destructive for git state. Review it before continuing.',
|
|
41
|
+
'A project hook flagged a destructive git command. Ask the user before running it.',
|
|
42
|
+
);
|
|
43
|
+
process.exit(0);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const managerByFile = [
|
|
47
|
+
['yarn.lock', 'yarn'],
|
|
48
|
+
['pnpm-lock.yaml', 'pnpm'],
|
|
49
|
+
['package-lock.json', 'npm'],
|
|
50
|
+
].find(([file]) => fs.existsSync(file));
|
|
51
|
+
|
|
52
|
+
let expected = managerByFile?.[1];
|
|
53
|
+
if (!expected && fs.existsSync('package.json')) {
|
|
54
|
+
try {
|
|
55
|
+
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
56
|
+
const pm = typeof pkg.packageManager === 'string' ? pkg.packageManager : '';
|
|
57
|
+
expected = pm.split('@')[0] || undefined;
|
|
58
|
+
} catch {
|
|
59
|
+
// Ignore invalid package.json in the hook; the agent can diagnose it later.
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!expected) {
|
|
64
|
+
process.stdout.write('{ "permission": "allow" }');
|
|
65
|
+
process.exit(0);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const used = command.match(/(^|[;&|]\s*)(npm|yarn|pnpm)\s+/)?.[2];
|
|
69
|
+
if (used && used !== expected) {
|
|
70
|
+
out(
|
|
71
|
+
'ask',
|
|
72
|
+
`This repository appears to use ${expected}, but the command uses ${used}. Confirm before continuing.`,
|
|
73
|
+
`Use ${expected} for package scripts and installs unless the user explicitly approves ${used}.`,
|
|
74
|
+
);
|
|
75
|
+
process.exit(0);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
process.stdout.write('{ "permission": "allow" }');
|
|
79
|
+
NODE
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# `.claude/rules` (preset go)
|
|
2
|
+
|
|
3
|
+
Claude topic `.md` files are **derived** from Cursor SoT `presets/cursor/go/rules/*.mdc`.
|
|
4
|
+
|
|
5
|
+
## SoT sync
|
|
6
|
+
|
|
7
|
+
| Principle | Detail |
|
|
8
|
+
|-----------|--------|
|
|
9
|
+
| **SoT** | `presets/cursor/go/rules/*.mdc` |
|
|
10
|
+
| **Derive** | Claude topic `.md` + `paths:` (drop `alwaysApply`) |
|
|
11
|
+
| **Checklist** | change Cursor → update Claude twin **same PR** (**FAIL** if missing — next, ios-swift, and go; see `preset-twin-sync` / build-verifier) |
|
|
12
|
+
|
|
13
|
+
## Loading budget
|
|
14
|
+
|
|
15
|
+
- **Session-start (no `paths:`):** exactly **3** — `go-app-core`, `boundaries`, `code-quality`
|
|
16
|
+
- All others — with `paths:`
|
|
17
|
+
- **Twin depth:** domain rules target ≥15 body lines; thin aliases: `agent-team-intake`, `technical-retro`; checklist **stubs** documented in Cursor `presets/cursor/go/rules/README.md` Catalog (Depth column)
|
|
18
|
+
|
|
19
|
+
## Cursor → Claude mapping
|
|
20
|
+
|
|
21
|
+
| Cursor `.mdc` (SoT) | Claude topic |
|
|
22
|
+
|---------------------|--------------|
|
|
23
|
+
| `adapters-driven.mdc` | `api-and-data/adapters-driven.md` |
|
|
24
|
+
| `adapters-driving.mdc` | `api-and-data/adapters-driving.md` |
|
|
25
|
+
| `agent-team-intake.mdc` | `tooling-and-review/agent-team-intake.md` |
|
|
26
|
+
| `agent-team-orchestrator.mdc` | `tooling-and-review/agent-team-orchestrator.md` |
|
|
27
|
+
| `api-grpc.mdc` | `api-and-data/api-grpc.md` |
|
|
28
|
+
| `api-http.mdc` | `api-and-data/api-http.md` |
|
|
29
|
+
| `application-usecases.mdc` | `architecture/application-usecases.md` |
|
|
30
|
+
| `architecture-boundaries.mdc` | `architecture/boundaries.md` |
|
|
31
|
+
| `code-quality-and-refactoring.mdc` | `tooling-and-review/code-quality.md` |
|
|
32
|
+
| `design-guidance.mdc` | `tooling-and-review/design-guidance.md` |
|
|
33
|
+
| `code-review-mr.mdc` | `tooling-and-review/code-review.md` |
|
|
34
|
+
| `composition-root.mdc` | `architecture/composition-root.md` |
|
|
35
|
+
| `domain-layer.mdc` | `architecture/domain-layer.md` |
|
|
36
|
+
| `feature-delivery-workflow.mdc` | `architecture/feature-delivery.md` |
|
|
37
|
+
| `go-app-core.mdc` | `stack/go-app-core.md` |
|
|
38
|
+
| `go-conventions.mdc` | `stack/go-conventions.md` |
|
|
39
|
+
| `go-tooling.mdc` | `tooling-and-review/go-tooling.md` |
|
|
40
|
+
| `messaging-adapters.mdc` | `api-and-data/messaging-adapters.md` |
|
|
41
|
+
| `module-public-api.mdc` | `architecture/module-public-api.md` |
|
|
42
|
+
| `persistence-adapters.mdc` | `api-and-data/persistence-adapters.md` |
|
|
43
|
+
| `ports-interfaces.mdc` | `architecture/ports-interfaces.md` |
|
|
44
|
+
| `post-change-test.mdc` | `tooling-and-review/post-change-test.md` |
|
|
45
|
+
| `preset-layering.mdc` | `tooling-and-review/preset-layering.md` |
|
|
46
|
+
| `preset-no-cross-stack-leakage.mdc` | `tooling-and-review/preset-no-cross-stack-leakage.md` |
|
|
47
|
+
| `preset-pr-checklist.mdc` | `tooling-and-review/preset-pr-checklist.md` |
|
|
48
|
+
| `preset-token-budget.mdc` | `tooling-and-review/preset-token-budget.md` |
|
|
49
|
+
| `preset-twin-sync.mdc` | `tooling-and-review/preset-twin-sync.md` |
|
|
50
|
+
| `reference-features.mdc` | `architecture/reference-features.md` |
|
|
51
|
+
| `security-go.mdc` | `tooling-and-review/security-go.md` |
|
|
52
|
+
| `technical-retro.mdc` | `tooling-and-review/technical-retro.md` |
|
|
53
|
+
| `tests-e2e.mdc` | `testing/e2e.md` |
|
|
54
|
+
| `tests-integration.mdc` | `testing/integration.md` |
|
|
55
|
+
| `tests-unit.mdc` | `testing/unit.md` |
|
|
56
|
+
|
|
57
|
+
## Topics
|
|
58
|
+
|
|
59
|
+
`architecture/`, `stack/`, `api-and-data/`, `testing/`, `tooling-and-review/`.
|
|
60
|
+
`ui-and-accessibility/` — README stub only (N/A backend).
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# API and data
|
|
2
|
+
|
|
3
|
+
Driving/driven adapters. Index only.
|
|
4
|
+
|
|
5
|
+
| File | Cursor SoT |
|
|
6
|
+
|------|------------|
|
|
7
|
+
| [`adapters-driving.md`](./adapters-driving.md) | `adapters-driving.mdc` |
|
|
8
|
+
| [`adapters-driven.md`](./adapters-driven.md) | `adapters-driven.mdc` |
|
|
9
|
+
| [`api-http.md`](./api-http.md) | `api-http.mdc` |
|
|
10
|
+
| [`api-grpc.md`](./api-grpc.md) | `api-grpc.mdc` |
|
|
11
|
+
| [`persistence-adapters.md`](./persistence-adapters.md) | `persistence-adapters.mdc` |
|
|
12
|
+
| [`messaging-adapters.md`](./messaging-adapters.md) | `messaging-adapters.mdc` |
|
|
13
|
+
|
|
14
|
+
Full map: [`../README.md`](../README.md).
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Driven adapters (persistence, cache, messaging) for Go hexagonal services
|
|
3
|
+
paths:
|
|
4
|
+
- internal/adapters/persistence/**/*
|
|
5
|
+
- **/adapters/persistence/**/*
|
|
6
|
+
- **/adapters/cache/**/*
|
|
7
|
+
- **/adapters/messaging/**/*
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Driven adapters
|
|
12
|
+
|
|
13
|
+
- Implement application **outbound ports**.
|
|
14
|
+
- Map storage/broker models → domain at the boundary; never return ORM structs to application.
|
|
15
|
+
- Handle retries/timeouts/idempotency here when infrastructure-specific.
|
|
16
|
+
- Wrap driver errors with context; translate to domain/application errors when meaningful.
|
|
17
|
+
- Honor `context.Context` cancellation and deadlines from the application call.
|
|
18
|
+
|
|
19
|
+
## Persistence
|
|
20
|
+
|
|
21
|
+
- See `persistence-adapters.md` for SQL/transactions.
|
|
22
|
+
- Keep SQL/query builders inside the adapter package; application sees only port methods.
|
|
23
|
+
|
|
24
|
+
## Cache / messaging
|
|
25
|
+
|
|
26
|
+
- Cache keys and serialization are adapter concerns.
|
|
27
|
+
- Publishers implement port `PublishX`; consumers are driving adapters if they trigger use cases.
|
|
28
|
+
- Prefer idempotent publish/consume handlers when brokers may redeliver.
|
|
29
|
+
|
|
30
|
+
## Forbidden
|
|
31
|
+
|
|
32
|
+
- Calling other driven adapters bypassing application (hidden coupling).
|
|
33
|
+
- Leaking `*sql.Rows` / Redis types through port signatures.
|
|
34
|
+
- Embedding business invariants that belong in domain (e.g. discount rules in SQL only).
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Driving adapters (HTTP, gRPC, CLI) for Go hexagonal services
|
|
3
|
+
paths:
|
|
4
|
+
- internal/adapters/http/**/*
|
|
5
|
+
- **/adapters/http/**/*
|
|
6
|
+
- **/adapters/grpc/**/*
|
|
7
|
+
- cmd/**/*
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Driving adapters
|
|
12
|
+
|
|
13
|
+
- Translate transport → application calls → transport response.
|
|
14
|
+
- Map request/response DTOs at the edge; do not pass framework types into use cases.
|
|
15
|
+
- AuthN/AuthZ and validation of wire format belong here (or dedicated middleware); domain validation stays in domain.
|
|
16
|
+
- Errors: map domain/application errors to status codes once (central mapper preferred).
|
|
17
|
+
- Keep handlers thin: decode → call use case → encode; no multi-step workflows in the adapter.
|
|
18
|
+
|
|
19
|
+
## HTTP
|
|
20
|
+
|
|
21
|
+
- See `api-http.md`. Prefer thin handlers; routing table in one place.
|
|
22
|
+
- Framework examples (chi/gin/echo) are optional — match the repo.
|
|
23
|
+
- Bind path/query/body into request DTOs before calling application.
|
|
24
|
+
|
|
25
|
+
## gRPC / CLI
|
|
26
|
+
|
|
27
|
+
- Same mapping rules; see thin `api-grpc.md` for protobuf notes.
|
|
28
|
+
- CLI `cmd` tools may call composition root or inbound ports — no SQL in `main`.
|
|
29
|
+
- Propagate cancellation from the transport `context` into use-case calls.
|
|
30
|
+
|
|
31
|
+
## Forbidden
|
|
32
|
+
|
|
33
|
+
- SQL or business invariants inside handlers.
|
|
34
|
+
- Importing persistence packages from HTTP handlers (wire via application).
|
|
35
|
+
- Swallowing errors without mapping to a transport status / log field.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Thin gRPC/protobuf extension notes for Go hexagonal services (HTTP-first v1)
|
|
3
|
+
paths:
|
|
4
|
+
- **/*.proto
|
|
5
|
+
- **/adapters/grpc/**/*
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# gRPC adapters (extension stub)
|
|
10
|
+
|
|
11
|
+
HTTP is the **v1 SoT** for this preset. gRPC is supported as an optional driving adapter with the same hexagonal rules.
|
|
12
|
+
|
|
13
|
+
## Requirements when adding gRPC
|
|
14
|
+
|
|
15
|
+
1. Keep protobuf messages in the adapter (or `api/proto`); map to domain/application at the edge.
|
|
16
|
+
2. Implement the same inbound ports / use cases as HTTP — do not fork business logic.
|
|
17
|
+
3. Map gRPC status codes from domain/application errors (parity with HTTP mapper).
|
|
18
|
+
4. Generate code via repo-standard `buf` / `protoc` scripts — do not hand-edit `*.pb.go` unless the repo requires it.
|
|
19
|
+
|
|
20
|
+
## Non-goals (v1)
|
|
21
|
+
|
|
22
|
+
- Full protobuf style guide and streaming patterns — extend this rule when the consumer repo adopts gRPC widely.
|
|
23
|
+
- Mandating gRPC over HTTP.
|
|
24
|
+
|
|
25
|
+
## Ports
|
|
26
|
+
|
|
27
|
+
- Prefer shared application use cases; gRPC service struct is a driving adapter only.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: HTTP API adapter conventions for Go hexagonal services
|
|
3
|
+
paths:
|
|
4
|
+
- **/adapters/http/**/*
|
|
5
|
+
- **/*handler*.go
|
|
6
|
+
- **/*router*.go
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# HTTP API adapters
|
|
11
|
+
|
|
12
|
+
- Handlers call inbound ports / use cases; return mapped status + body.
|
|
13
|
+
- Use consistent error envelope; map domain errors centrally.
|
|
14
|
+
- Version routes if the repo already versions (`/v1/...`).
|
|
15
|
+
- Prefer `net/http` interfaces so tests can use `httptest` without a full framework.
|
|
16
|
+
- Timeouts: set server read/write timeouts; propagate request context.
|
|
17
|
+
|
|
18
|
+
## Testing
|
|
19
|
+
|
|
20
|
+
- Prefer `httptest` against handler/router with mocked use cases (unit of adapter).
|
|
21
|
+
- Integration: real router + test doubles or testcontainers behind driven ports.
|
|
22
|
+
|
|
23
|
+
## Forbidden
|
|
24
|
+
|
|
25
|
+
- Business rules or SQL in handlers.
|
|
26
|
+
- Ignoring `ctx` cancelation from `r.Context()`.
|