@bonesofspring/ai-rules 0.2.19 → 0.2.21
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 +42 -0
- package/README.md +17 -2
- package/bin/cli.js +83 -6
- package/package.json +5 -2
- package/presets/_shared/README.md +4 -3
- package/presets/_shared/assets/docs-specs/INDEX.md +4 -1
- package/presets/_shared/core/agent-team/agent-artifact-contracts.md +13 -0
- package/presets/_shared/core/agent-team/agent-task-metrics.md +1 -1
- package/presets/_shared/core/agent-team/agent-team-orchestrator.md +1 -3
- package/presets/_shared/core/agent-team/task-classification.md +21 -0
- package/presets/_shared/core/meta/preset-pr-checklist.md +5 -1
- package/presets/_shared/core/meta/preset-token-budget.md +7 -3
- package/presets/_shared/core/meta/preset-twin-sync.md +2 -0
- package/presets/_shared/core/quality/debug-investigation.md +24 -0
- package/presets/_shared/core/quality/verification-before-completion.md +25 -0
- package/presets/_shared/core/review/receiving-code-review.md +24 -0
- package/presets/_shared/core/testing/testing-principles.md +70 -0
- package/presets/claude/android-kotlin/agents/README.md +2 -1
- package/presets/claude/android-kotlin/agents/build-verifier.md +6 -0
- package/presets/claude/android-kotlin/agents/ci-investigator.md +1 -0
- package/presets/claude/android-kotlin/agents/code-reviewer.md +2 -0
- package/presets/claude/android-kotlin/agents/debugger.md +5 -0
- package/presets/claude/android-kotlin/agents/feature-developer.md +8 -1
- package/presets/claude/android-kotlin/agents/openspec-author.md +163 -0
- package/presets/claude/android-kotlin/agents/task-analyst.md +11 -1
- package/presets/claude/android-kotlin/agents/task-router.md +19 -1
- package/presets/claude/android-kotlin/agents/tech-writer.md +4 -0
- package/presets/claude/android-kotlin/commands/README.md +0 -2
- package/presets/claude/android-kotlin/commands/task-continue.md +1 -1
- package/presets/claude/android-kotlin/commands/task.md +1 -5
- package/presets/claude/android-kotlin/commands/technical-retro.md +2 -2
- package/presets/claude/android-kotlin/hooks/chain-team-phases.sh +54 -2
- package/presets/claude/android-kotlin/rules/README.md +1 -0
- package/presets/claude/android-kotlin/rules/tooling-and-review/agent-team-orchestrator.md +7 -4
- package/presets/claude/android-kotlin/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/android-kotlin/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/android-kotlin/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/android-kotlin/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/android-kotlin/skills/code-review/SKILL.md +6 -0
- package/presets/claude/android-kotlin/skills/debug-investigation/SKILL.md +33 -5
- package/presets/claude/go/README.md +1 -1
- package/presets/claude/go/agents/README.md +3 -2
- package/presets/claude/go/agents/build-verifier.md +6 -0
- package/presets/claude/go/agents/ci-investigator.md +1 -0
- package/presets/claude/go/agents/code-reviewer.md +2 -0
- package/presets/claude/go/agents/debugger.md +7 -0
- package/presets/claude/go/agents/feature-developer.md +7 -0
- package/presets/claude/go/agents/openspec-author.md +163 -0
- package/presets/claude/go/agents/task-analyst.md +10 -0
- package/presets/claude/go/agents/task-router.md +19 -1
- package/presets/claude/go/agents/tech-writer.md +4 -0
- package/presets/claude/go/commands/README.md +0 -2
- package/presets/claude/go/commands/task-continue.md +1 -1
- package/presets/claude/go/commands/task.md +1 -4
- package/presets/claude/go/hooks/chain-team-phases.sh +54 -3
- package/presets/claude/go/rules/README.md +1 -0
- package/presets/claude/go/rules/tooling-and-review/agent-team-orchestrator.md +2 -4
- package/presets/claude/go/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/go/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/go/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/go/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/go/skills/code-review/SKILL.md +6 -0
- package/presets/claude/go/skills/debug-investigation/SKILL.md +32 -4
- package/presets/claude/ios-swift/agents/README.md +3 -2
- package/presets/claude/ios-swift/agents/build-verifier.md +6 -0
- package/presets/claude/ios-swift/agents/ci-investigator.md +1 -0
- package/presets/claude/ios-swift/agents/code-reviewer.md +2 -0
- package/presets/claude/ios-swift/agents/debugger.md +5 -0
- package/presets/claude/ios-swift/agents/feature-developer.md +8 -1
- package/presets/claude/ios-swift/agents/openspec-author.md +163 -0
- package/presets/claude/ios-swift/agents/task-analyst.md +11 -1
- package/presets/claude/ios-swift/agents/task-router.md +19 -1
- package/presets/claude/ios-swift/agents/tech-writer.md +4 -0
- package/presets/claude/ios-swift/commands/README.md +0 -2
- package/presets/claude/ios-swift/commands/task-continue.md +1 -1
- package/presets/claude/ios-swift/commands/task.md +1 -5
- package/presets/claude/ios-swift/commands/technical-retro.md +2 -2
- package/presets/claude/ios-swift/hooks/chain-team-phases.sh +54 -2
- package/presets/claude/ios-swift/rules/README.md +1 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/agent-team-orchestrator.md +7 -4
- package/presets/claude/ios-swift/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/ios-swift/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/ios-swift/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/ios-swift/skills/code-review/SKILL.md +6 -0
- package/presets/claude/ios-swift/skills/debug-investigation/SKILL.md +33 -5
- package/presets/claude/java/CLAUDE.md +1 -1
- package/presets/claude/java/agents/README.md +3 -2
- package/presets/claude/java/agents/build-verifier.md +6 -0
- package/presets/claude/java/agents/ci-investigator.md +1 -0
- package/presets/claude/java/agents/code-reviewer.md +2 -0
- package/presets/claude/java/agents/debugger.md +7 -0
- package/presets/claude/java/agents/feature-developer.md +7 -0
- package/presets/claude/java/agents/openspec-author.md +163 -0
- package/presets/claude/java/agents/task-analyst.md +10 -0
- package/presets/claude/java/agents/task-router.md +19 -1
- package/presets/claude/java/agents/tech-writer.md +4 -0
- package/presets/claude/java/commands/README.md +0 -2
- package/presets/claude/java/commands/task-continue.md +1 -1
- package/presets/claude/java/commands/task.md +1 -4
- package/presets/claude/java/hooks/chain-team-phases.sh +54 -3
- package/presets/claude/java/rules/README.md +1 -0
- package/presets/claude/java/rules/tooling-and-review/agent-team-orchestrator.md +2 -4
- package/presets/claude/java/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/java/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/java/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/java/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/java/skills/code-review/SKILL.md +6 -0
- package/presets/claude/java/skills/debug-investigation/SKILL.md +32 -4
- package/presets/claude/mcp-ts/agents/build-verifier.md +6 -0
- package/presets/claude/mcp-ts/agents/feature-developer.md +7 -0
- package/presets/claude/mcp-ts/agents/task-analyst.md +11 -1
- package/presets/claude/mcp-ts/agents/task-router.md +14 -0
- package/presets/claude/mcp-ts/commands/README.md +0 -2
- package/presets/claude/mcp-ts/commands/task-continue.md +1 -1
- package/presets/claude/mcp-ts/commands/task.md +1 -4
- package/presets/claude/mcp-ts/commands/technical-retro.md +2 -2
- package/presets/claude/mcp-ts/hooks/chain-team-phases.sh +40 -9
- package/presets/claude/mcp-ts/rules/README.md +1 -0
- package/presets/claude/mcp-ts/rules/tooling-and-review/agent-team-orchestrator.md +2 -4
- package/presets/claude/mcp-ts/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/mcp-ts/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/mcp-ts/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/mcp-ts/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/mcp-ts/skills/code-review/SKILL.md +6 -0
- package/presets/claude/mcp-ts/skills/debug-investigation/SKILL.md +31 -3
- package/presets/claude/next/README.md +1 -0
- package/presets/claude/next/agents/README.md +2 -2
- package/presets/claude/next/agents/build-verifier.md +17 -1
- package/presets/claude/next/agents/ci-investigator.md +1 -0
- package/presets/claude/next/agents/code-reviewer.md +2 -0
- package/presets/claude/next/agents/debugger.md +5 -0
- package/presets/claude/next/agents/feature-developer.md +8 -1
- package/presets/claude/next/agents/openspec-author.md +163 -0
- package/presets/claude/next/agents/task-analyst.md +12 -2
- package/presets/claude/next/agents/task-router.md +19 -1
- package/presets/claude/next/agents/tech-writer.md +4 -0
- package/presets/claude/next/commands/README.md +0 -2
- package/presets/claude/next/commands/task-continue.md +1 -1
- package/presets/claude/next/commands/task.md +1 -4
- package/presets/claude/next/hooks/chain-team-phases.sh +54 -2
- package/presets/claude/next/rules/README.md +1 -0
- package/presets/claude/next/rules/testing/README.md +6 -0
- package/presets/claude/next/rules/testing/tests-e2e-structure.md +84 -48
- package/presets/claude/next/rules/testing/tests-unit.md +79 -50
- package/presets/claude/next/rules/tooling-and-review/agent-team-orchestrator.md +3 -4
- package/presets/claude/next/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/next/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/next/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/next/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/next/skills/code-review/SKILL.md +6 -0
- package/presets/claude/next/skills/debug-investigation/SKILL.md +29 -14
- package/presets/claude/next/team/README.md +0 -3
- package/presets/claude/nuxt/agents/README.md +1 -1
- package/presets/claude/nuxt/agents/build-verifier.md +6 -0
- package/presets/claude/nuxt/agents/ci-investigator.md +1 -0
- package/presets/claude/nuxt/agents/code-reviewer.md +2 -0
- package/presets/claude/nuxt/agents/debugger.md +5 -0
- package/presets/claude/nuxt/agents/feature-developer.md +8 -1
- package/presets/claude/nuxt/agents/openspec-author.md +163 -0
- package/presets/claude/nuxt/agents/task-analyst.md +12 -2
- package/presets/claude/nuxt/agents/task-router.md +19 -1
- package/presets/claude/nuxt/agents/tech-writer.md +4 -0
- package/presets/claude/nuxt/commands/README.md +0 -2
- package/presets/claude/nuxt/commands/task-continue.md +1 -1
- package/presets/claude/nuxt/commands/task.md +1 -5
- package/presets/claude/nuxt/commands/technical-retro.md +2 -2
- package/presets/claude/nuxt/hooks/chain-team-phases.sh +54 -2
- package/presets/claude/nuxt/rules/README.md +1 -0
- package/presets/claude/nuxt/rules/testing/README.md +6 -0
- package/presets/claude/nuxt/rules/testing/tests-e2e-structure.md +86 -43
- package/presets/claude/nuxt/rules/testing/tests-unit.md +58 -45
- package/presets/claude/nuxt/rules/tooling-and-review/agent-team-orchestrator.md +8 -5
- package/presets/claude/nuxt/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/nuxt/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/nuxt/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/nuxt/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/nuxt/skills/code-review/SKILL.md +6 -0
- package/presets/claude/nuxt/skills/debug-investigation/SKILL.md +29 -12
- package/presets/claude/nuxt/team/README.md +0 -3
- package/presets/claude/php-hexagonal/CLAUDE.md +1 -1
- package/presets/claude/php-hexagonal/agents/README.md +3 -2
- package/presets/claude/php-hexagonal/agents/build-verifier.md +6 -0
- package/presets/claude/php-hexagonal/agents/ci-investigator.md +1 -0
- package/presets/claude/php-hexagonal/agents/code-reviewer.md +2 -0
- package/presets/claude/php-hexagonal/agents/debugger.md +7 -0
- package/presets/claude/php-hexagonal/agents/feature-developer.md +7 -0
- package/presets/claude/php-hexagonal/agents/openspec-author.md +163 -0
- package/presets/claude/php-hexagonal/agents/task-analyst.md +10 -0
- package/presets/claude/php-hexagonal/agents/task-router.md +19 -1
- package/presets/claude/php-hexagonal/agents/tech-writer.md +4 -0
- package/presets/claude/php-hexagonal/commands/README.md +0 -2
- package/presets/claude/php-hexagonal/commands/task-continue.md +1 -1
- package/presets/claude/php-hexagonal/commands/task.md +1 -4
- package/presets/claude/php-hexagonal/hooks/chain-team-phases.sh +54 -3
- package/presets/claude/php-hexagonal/rules/README.md +1 -0
- package/presets/claude/php-hexagonal/rules/tooling-and-review/agent-team-orchestrator.md +2 -4
- package/presets/claude/php-hexagonal/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/php-hexagonal/skills/code-review/SKILL.md +6 -0
- package/presets/claude/php-hexagonal/skills/debug-investigation/SKILL.md +32 -4
- package/presets/claude/php-laravel/agents/README.md +3 -2
- package/presets/claude/php-laravel/agents/build-verifier.md +6 -0
- package/presets/claude/php-laravel/agents/ci-investigator.md +1 -0
- package/presets/claude/php-laravel/agents/code-reviewer.md +2 -0
- package/presets/claude/php-laravel/agents/debugger.md +7 -0
- package/presets/claude/php-laravel/agents/feature-developer.md +7 -0
- package/presets/claude/php-laravel/agents/openspec-author.md +163 -0
- package/presets/claude/php-laravel/agents/task-analyst.md +10 -0
- package/presets/claude/php-laravel/agents/task-router.md +19 -1
- package/presets/claude/php-laravel/agents/tech-writer.md +4 -0
- package/presets/claude/php-laravel/commands/README.md +0 -2
- package/presets/claude/php-laravel/commands/task-continue.md +1 -1
- package/presets/claude/php-laravel/commands/task.md +1 -4
- package/presets/claude/php-laravel/hooks/chain-team-phases.sh +54 -3
- package/presets/claude/php-laravel/rules/README.md +1 -0
- package/presets/claude/php-laravel/rules/tooling-and-review/agent-team-orchestrator.md +2 -4
- package/presets/claude/php-laravel/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/php-laravel/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/php-laravel/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/php-laravel/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/php-laravel/skills/code-review/SKILL.md +6 -0
- package/presets/claude/php-laravel/skills/debug-investigation/SKILL.md +32 -4
- package/presets/claude/svelte/agents/README.md +1 -1
- package/presets/claude/svelte/agents/build-verifier.md +6 -0
- package/presets/claude/svelte/agents/ci-investigator.md +1 -0
- package/presets/claude/svelte/agents/code-reviewer.md +2 -0
- package/presets/claude/svelte/agents/debugger.md +5 -0
- package/presets/claude/svelte/agents/feature-developer.md +8 -1
- package/presets/claude/svelte/agents/openspec-author.md +163 -0
- package/presets/claude/svelte/agents/task-analyst.md +12 -2
- package/presets/claude/svelte/agents/task-router.md +19 -1
- package/presets/claude/svelte/agents/tech-writer.md +4 -0
- package/presets/claude/svelte/commands/README.md +0 -2
- package/presets/claude/svelte/commands/task-continue.md +1 -1
- package/presets/claude/svelte/commands/task.md +1 -5
- package/presets/claude/svelte/commands/technical-retro.md +2 -2
- package/presets/claude/svelte/hooks/chain-team-phases.sh +54 -2
- package/presets/claude/svelte/rules/README.md +1 -0
- package/presets/claude/svelte/rules/testing/README.md +6 -0
- package/presets/claude/svelte/rules/testing/tests-e2e-structure.md +87 -45
- package/presets/claude/svelte/rules/testing/tests-unit.md +70 -23
- package/presets/claude/svelte/rules/tooling-and-review/agent-team-orchestrator.md +8 -5
- package/presets/claude/svelte/rules/tooling-and-review/ai-local-overlay.md +48 -0
- package/presets/claude/svelte/rules/tooling-and-review/preset-pr-checklist.md +5 -1
- package/presets/claude/svelte/rules/tooling-and-review/preset-token-budget.md +7 -3
- package/presets/claude/svelte/rules/tooling-and-review/preset-twin-sync.md +2 -0
- package/presets/claude/svelte/skills/code-review/SKILL.md +6 -0
- package/presets/claude/svelte/skills/debug-investigation/SKILL.md +29 -12
- package/presets/claude/svelte/team/README.md +0 -3
- package/presets/cursor/android-kotlin/agents/README.md +2 -1
- package/presets/cursor/android-kotlin/agents/build-verifier.md +6 -0
- package/presets/cursor/android-kotlin/agents/ci-investigator.md +1 -0
- package/presets/cursor/android-kotlin/agents/code-reviewer.md +2 -0
- package/presets/cursor/android-kotlin/agents/debugger.md +5 -0
- package/presets/cursor/android-kotlin/agents/feature-developer.md +8 -1
- package/presets/cursor/android-kotlin/agents/openspec-author.md +164 -0
- package/presets/cursor/android-kotlin/agents/task-analyst.md +11 -1
- package/presets/cursor/android-kotlin/agents/task-router.md +19 -1
- package/presets/cursor/android-kotlin/agents/tech-writer.md +4 -0
- package/presets/cursor/android-kotlin/commands/README.md +0 -2
- package/presets/cursor/android-kotlin/commands/task-continue.md +1 -1
- package/presets/cursor/android-kotlin/commands/task.md +1 -5
- package/presets/cursor/android-kotlin/commands/technical-retro.md +2 -2
- package/presets/cursor/android-kotlin/hooks/chain-team-phases.sh +54 -2
- package/presets/cursor/android-kotlin/rules/agent-team-orchestrator.mdc +7 -4
- package/presets/cursor/android-kotlin/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/android-kotlin/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/android-kotlin/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/android-kotlin/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/android-kotlin/skills/code-review/SKILL.md +6 -0
- package/presets/cursor/android-kotlin/skills/debug-investigation/SKILL.md +33 -5
- package/presets/cursor/go/README.md +6 -6
- package/presets/cursor/go/agents/README.md +3 -2
- package/presets/cursor/go/agents/build-verifier.md +6 -0
- package/presets/cursor/go/agents/ci-investigator.md +1 -0
- package/presets/cursor/go/agents/code-reviewer.md +2 -0
- package/presets/cursor/go/agents/debugger.md +7 -0
- package/presets/cursor/go/agents/feature-developer.md +7 -0
- package/presets/cursor/go/agents/openspec-author.md +164 -0
- package/presets/cursor/go/agents/task-analyst.md +10 -0
- package/presets/cursor/go/agents/task-router.md +19 -1
- package/presets/cursor/go/agents/tech-writer.md +4 -0
- package/presets/cursor/go/commands/README.md +0 -2
- package/presets/cursor/go/commands/task-continue.md +1 -1
- package/presets/cursor/go/commands/task.md +1 -4
- package/presets/cursor/go/commands/technical-retro.md +2 -2
- package/presets/cursor/go/hooks/chain-team-phases.sh +54 -3
- package/presets/cursor/go/rules/agent-team-orchestrator.mdc +2 -4
- package/presets/cursor/go/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/go/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/go/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/go/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/go/skills/code-review/SKILL.md +6 -0
- package/presets/cursor/go/skills/debug-investigation/SKILL.md +32 -4
- package/presets/cursor/ios-swift/README.md +6 -6
- package/presets/cursor/ios-swift/agents/README.md +3 -2
- package/presets/cursor/ios-swift/agents/build-verifier.md +6 -0
- package/presets/cursor/ios-swift/agents/ci-investigator.md +1 -0
- package/presets/cursor/ios-swift/agents/code-reviewer.md +2 -0
- package/presets/cursor/ios-swift/agents/debugger.md +5 -0
- package/presets/cursor/ios-swift/agents/feature-developer.md +8 -1
- package/presets/cursor/ios-swift/agents/openspec-author.md +164 -0
- package/presets/cursor/ios-swift/agents/task-analyst.md +11 -1
- package/presets/cursor/ios-swift/agents/task-router.md +19 -1
- package/presets/cursor/ios-swift/agents/tech-writer.md +4 -0
- package/presets/cursor/ios-swift/commands/README.md +1 -3
- package/presets/cursor/ios-swift/commands/task-continue.md +1 -1
- package/presets/cursor/ios-swift/commands/task.md +1 -5
- package/presets/cursor/ios-swift/commands/technical-retro.md +2 -2
- package/presets/cursor/ios-swift/hooks/chain-team-phases.sh +54 -2
- package/presets/cursor/ios-swift/rules/agent-team-orchestrator.mdc +7 -4
- package/presets/cursor/ios-swift/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/ios-swift/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/ios-swift/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/ios-swift/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/ios-swift/skills/code-review/SKILL.md +6 -0
- package/presets/cursor/ios-swift/skills/debug-investigation/SKILL.md +33 -5
- package/presets/cursor/java/AGENTS.md +1 -1
- package/presets/cursor/java/agents/README.md +3 -2
- package/presets/cursor/java/agents/build-verifier.md +6 -0
- package/presets/cursor/java/agents/ci-investigator.md +1 -0
- package/presets/cursor/java/agents/code-reviewer.md +2 -0
- package/presets/cursor/java/agents/debugger.md +7 -0
- package/presets/cursor/java/agents/feature-developer.md +7 -0
- package/presets/cursor/java/agents/openspec-author.md +164 -0
- package/presets/cursor/java/agents/task-analyst.md +10 -0
- package/presets/cursor/java/agents/task-router.md +19 -1
- package/presets/cursor/java/agents/tech-writer.md +4 -0
- package/presets/cursor/java/commands/README.md +0 -2
- package/presets/cursor/java/commands/task-continue.md +1 -1
- package/presets/cursor/java/commands/task.md +1 -4
- package/presets/cursor/java/commands/technical-retro.md +2 -2
- package/presets/cursor/java/hooks/chain-team-phases.sh +54 -3
- package/presets/cursor/java/rules/agent-team-orchestrator.mdc +2 -4
- package/presets/cursor/java/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/java/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/java/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/java/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/java/skills/code-review/SKILL.md +6 -0
- package/presets/cursor/java/skills/debug-investigation/SKILL.md +32 -4
- package/presets/cursor/mcp-ts/agents/build-verifier.md +6 -0
- package/presets/cursor/mcp-ts/agents/feature-developer.md +7 -0
- package/presets/cursor/mcp-ts/agents/task-analyst.md +11 -1
- package/presets/cursor/mcp-ts/agents/task-router.md +14 -0
- package/presets/cursor/mcp-ts/commands/README.md +0 -2
- package/presets/cursor/mcp-ts/commands/task-continue.md +1 -1
- package/presets/cursor/mcp-ts/commands/task.md +1 -4
- package/presets/cursor/mcp-ts/commands/technical-retro.md +2 -2
- package/presets/cursor/mcp-ts/hooks/chain-team-phases.sh +40 -9
- package/presets/cursor/mcp-ts/rules/agent-team-orchestrator.mdc +2 -4
- package/presets/cursor/mcp-ts/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/mcp-ts/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/mcp-ts/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/mcp-ts/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/mcp-ts/skills/code-review/SKILL.md +6 -0
- package/presets/cursor/mcp-ts/skills/debug-investigation/SKILL.md +31 -3
- package/presets/cursor/next/README.md +8 -6
- package/presets/cursor/next/REPO_AGENTS.md +8 -0
- package/presets/cursor/next/agents/README.md +2 -2
- package/presets/cursor/next/agents/build-verifier.md +17 -1
- package/presets/cursor/next/agents/ci-investigator.md +1 -0
- package/presets/cursor/next/agents/code-reviewer.md +2 -0
- package/presets/cursor/next/agents/debugger.md +5 -0
- package/presets/cursor/next/agents/feature-developer.md +8 -1
- package/presets/cursor/next/agents/openspec-author.md +164 -0
- package/presets/cursor/next/agents/task-analyst.md +12 -2
- package/presets/cursor/next/agents/task-router.md +19 -1
- package/presets/cursor/next/agents/tech-writer.md +4 -0
- package/presets/cursor/next/commands/README.md +0 -2
- package/presets/cursor/next/commands/task-continue.md +1 -1
- package/presets/cursor/next/commands/task.md +1 -4
- package/presets/cursor/next/commands/technical-retro.md +2 -2
- package/presets/cursor/next/hooks/chain-team-phases.sh +54 -2
- package/presets/cursor/next/rules/README.md +6 -3
- package/presets/cursor/next/rules/agent-team-orchestrator.mdc +7 -5
- package/presets/cursor/next/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/next/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/next/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/next/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/next/rules/tests-e2e-structure.mdc +83 -43
- package/presets/cursor/next/rules/tests-unit.mdc +78 -45
- package/presets/cursor/next/skills/code-review/SKILL.md +6 -0
- package/presets/cursor/next/skills/debug-investigation/SKILL.md +29 -14
- package/presets/cursor/next/team/README.md +0 -3
- package/presets/cursor/nuxt/README.md +6 -6
- package/presets/cursor/nuxt/agents/README.md +1 -1
- package/presets/cursor/nuxt/agents/build-verifier.md +6 -0
- package/presets/cursor/nuxt/agents/ci-investigator.md +1 -0
- package/presets/cursor/nuxt/agents/code-reviewer.md +2 -0
- package/presets/cursor/nuxt/agents/debugger.md +5 -0
- package/presets/cursor/nuxt/agents/feature-developer.md +8 -1
- package/presets/cursor/nuxt/agents/openspec-author.md +164 -0
- package/presets/cursor/nuxt/agents/task-analyst.md +12 -2
- package/presets/cursor/nuxt/agents/task-router.md +19 -1
- package/presets/cursor/nuxt/agents/tech-writer.md +4 -0
- package/presets/cursor/nuxt/commands/README.md +0 -2
- package/presets/cursor/nuxt/commands/task-continue.md +1 -1
- package/presets/cursor/nuxt/commands/task.md +1 -5
- package/presets/cursor/nuxt/commands/technical-retro.md +2 -2
- package/presets/cursor/nuxt/hooks/chain-team-phases.sh +54 -2
- package/presets/cursor/nuxt/rules/README.md +3 -1
- package/presets/cursor/nuxt/rules/agent-team-orchestrator.mdc +8 -5
- package/presets/cursor/nuxt/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/nuxt/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/nuxt/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/nuxt/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/nuxt/rules/tests-e2e-structure.mdc +87 -43
- package/presets/cursor/nuxt/rules/tests-unit.mdc +62 -47
- package/presets/cursor/nuxt/skills/code-review/SKILL.md +6 -0
- package/presets/cursor/nuxt/skills/debug-investigation/SKILL.md +29 -12
- package/presets/cursor/nuxt/team/README.md +0 -3
- package/presets/cursor/php-hexagonal/AGENTS.md +1 -1
- package/presets/cursor/php-hexagonal/agents/README.md +3 -2
- package/presets/cursor/php-hexagonal/agents/build-verifier.md +6 -0
- package/presets/cursor/php-hexagonal/agents/ci-investigator.md +1 -0
- package/presets/cursor/php-hexagonal/agents/code-reviewer.md +2 -0
- package/presets/cursor/php-hexagonal/agents/debugger.md +7 -0
- package/presets/cursor/php-hexagonal/agents/feature-developer.md +7 -0
- package/presets/cursor/php-hexagonal/agents/openspec-author.md +164 -0
- package/presets/cursor/php-hexagonal/agents/task-analyst.md +10 -0
- package/presets/cursor/php-hexagonal/agents/task-router.md +19 -1
- package/presets/cursor/php-hexagonal/agents/tech-writer.md +4 -0
- package/presets/cursor/php-hexagonal/commands/README.md +0 -2
- package/presets/cursor/php-hexagonal/commands/task-continue.md +1 -1
- package/presets/cursor/php-hexagonal/commands/task.md +1 -4
- package/presets/cursor/php-hexagonal/commands/technical-retro.md +2 -2
- package/presets/cursor/php-hexagonal/hooks/chain-team-phases.sh +54 -3
- package/presets/cursor/php-hexagonal/rules/agent-team-orchestrator.mdc +2 -4
- package/presets/cursor/php-hexagonal/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/php-hexagonal/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/php-hexagonal/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/php-hexagonal/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/php-hexagonal/skills/code-review/SKILL.md +6 -0
- package/presets/cursor/php-hexagonal/skills/debug-investigation/SKILL.md +32 -4
- package/presets/cursor/php-laravel/AGENTS.md +1 -1
- package/presets/cursor/php-laravel/agents/README.md +3 -2
- package/presets/cursor/php-laravel/agents/build-verifier.md +6 -0
- package/presets/cursor/php-laravel/agents/ci-investigator.md +1 -0
- package/presets/cursor/php-laravel/agents/code-reviewer.md +2 -0
- package/presets/cursor/php-laravel/agents/debugger.md +7 -0
- package/presets/cursor/php-laravel/agents/feature-developer.md +7 -0
- package/presets/cursor/php-laravel/agents/openspec-author.md +164 -0
- package/presets/cursor/php-laravel/agents/task-analyst.md +10 -0
- package/presets/cursor/php-laravel/agents/task-router.md +19 -1
- package/presets/cursor/php-laravel/agents/tech-writer.md +4 -0
- package/presets/cursor/php-laravel/commands/README.md +0 -2
- package/presets/cursor/php-laravel/commands/task-continue.md +1 -1
- package/presets/cursor/php-laravel/commands/task.md +1 -4
- package/presets/cursor/php-laravel/commands/technical-retro.md +2 -2
- package/presets/cursor/php-laravel/hooks/chain-team-phases.sh +54 -3
- package/presets/cursor/php-laravel/rules/agent-team-orchestrator.mdc +2 -4
- package/presets/cursor/php-laravel/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/php-laravel/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/php-laravel/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/php-laravel/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/php-laravel/skills/code-review/SKILL.md +6 -0
- package/presets/cursor/php-laravel/skills/debug-investigation/SKILL.md +32 -4
- package/presets/cursor/svelte/README.md +6 -6
- package/presets/cursor/svelte/agents/README.md +1 -1
- package/presets/cursor/svelte/agents/build-verifier.md +6 -0
- package/presets/cursor/svelte/agents/ci-investigator.md +1 -0
- package/presets/cursor/svelte/agents/code-reviewer.md +2 -0
- package/presets/cursor/svelte/agents/debugger.md +5 -0
- package/presets/cursor/svelte/agents/feature-developer.md +8 -1
- package/presets/cursor/svelte/agents/openspec-author.md +164 -0
- package/presets/cursor/svelte/agents/task-analyst.md +12 -2
- package/presets/cursor/svelte/agents/task-router.md +19 -1
- package/presets/cursor/svelte/agents/tech-writer.md +4 -0
- package/presets/cursor/svelte/commands/README.md +0 -2
- package/presets/cursor/svelte/commands/task-continue.md +1 -1
- package/presets/cursor/svelte/commands/task.md +1 -5
- package/presets/cursor/svelte/commands/technical-retro.md +2 -2
- package/presets/cursor/svelte/hooks/chain-team-phases.sh +54 -2
- package/presets/cursor/svelte/rules/README.md +3 -1
- package/presets/cursor/svelte/rules/agent-team-orchestrator.mdc +8 -5
- package/presets/cursor/svelte/rules/ai-local-overlay.mdc +43 -0
- package/presets/cursor/svelte/rules/preset-pr-checklist.mdc +5 -1
- package/presets/cursor/svelte/rules/preset-token-budget.mdc +7 -3
- package/presets/cursor/svelte/rules/preset-twin-sync.mdc +2 -0
- package/presets/cursor/svelte/rules/tests-e2e-structure.mdc +87 -43
- package/presets/cursor/svelte/rules/tests-unit.mdc +72 -23
- package/presets/cursor/svelte/skills/code-review/SKILL.md +6 -0
- package/presets/cursor/svelte/skills/debug-investigation/SKILL.md +29 -12
- package/presets/cursor/svelte/team/README.md +0 -3
- package/scripts/_lib/embed-stems.json +31 -0
- package/scripts/aggregate-agent-task-metrics.mjs +23 -0
- package/scripts/check-chain-hook-coverage.sh +109 -0
- package/scripts/check-local-overlay.sh +136 -0
- package/scripts/check-preset-i18n.sh +2 -2
- package/scripts/check-preset-leakage.sh +4 -1
- package/scripts/check-preset-structure.sh +21 -1
- package/scripts/check-preset-token-budget.sh +20 -10
- package/scripts/check-rule-eval.mjs +16 -0
- package/scripts/check-shared-core-drift.sh +10 -26
- package/scripts/close-agent-task-human-gate.mjs +22 -5
- package/scripts/sync-shared-core-embeds.sh +9 -20
- package/scripts/test-agent-task-metrics-hooks.mjs +1 -1
- package/scripts/test-chain-team-phases-coverage.mjs +411 -0
- package/presets/claude/android-kotlin/commands/feature-continue.md +0 -23
- package/presets/claude/android-kotlin/commands/feature-start.md +0 -41
- package/presets/claude/go/commands/feature-continue.md +0 -23
- package/presets/claude/go/commands/feature-start.md +0 -38
- package/presets/claude/ios-swift/commands/feature-continue.md +0 -23
- package/presets/claude/ios-swift/commands/feature-start.md +0 -41
- package/presets/claude/java/commands/feature-continue.md +0 -23
- package/presets/claude/java/commands/feature-start.md +0 -38
- package/presets/claude/mcp-ts/commands/feature-continue.md +0 -23
- package/presets/claude/mcp-ts/commands/feature-start.md +0 -41
- package/presets/claude/next/commands/feature-continue.md +0 -23
- package/presets/claude/next/commands/feature-start.md +0 -38
- package/presets/claude/nuxt/commands/feature-continue.md +0 -23
- package/presets/claude/nuxt/commands/feature-start.md +0 -41
- package/presets/claude/php-hexagonal/commands/feature-continue.md +0 -23
- package/presets/claude/php-hexagonal/commands/feature-start.md +0 -38
- package/presets/claude/php-laravel/commands/feature-continue.md +0 -23
- package/presets/claude/php-laravel/commands/feature-start.md +0 -38
- package/presets/claude/svelte/commands/feature-continue.md +0 -23
- package/presets/claude/svelte/commands/feature-start.md +0 -41
- package/presets/cursor/android-kotlin/commands/feature-continue.md +0 -23
- package/presets/cursor/android-kotlin/commands/feature-start.md +0 -41
- package/presets/cursor/go/commands/feature-continue.md +0 -23
- package/presets/cursor/go/commands/feature-start.md +0 -41
- package/presets/cursor/ios-swift/commands/feature-continue.md +0 -23
- package/presets/cursor/ios-swift/commands/feature-start.md +0 -41
- package/presets/cursor/java/commands/feature-continue.md +0 -23
- package/presets/cursor/java/commands/feature-start.md +0 -41
- package/presets/cursor/mcp-ts/commands/feature-continue.md +0 -23
- package/presets/cursor/mcp-ts/commands/feature-start.md +0 -41
- package/presets/cursor/next/commands/feature-continue.md +0 -23
- package/presets/cursor/next/commands/feature-start.md +0 -41
- package/presets/cursor/nuxt/commands/feature-continue.md +0 -23
- package/presets/cursor/nuxt/commands/feature-start.md +0 -41
- package/presets/cursor/php-hexagonal/commands/feature-continue.md +0 -23
- package/presets/cursor/php-hexagonal/commands/feature-start.md +0 -41
- package/presets/cursor/php-laravel/commands/feature-continue.md +0 -23
- package/presets/cursor/php-laravel/commands/feature-start.md +0 -41
- package/presets/cursor/svelte/commands/feature-continue.md +0 -23
- package/presets/cursor/svelte/commands/feature-start.md +0 -41
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# FAIL when chain-team-phases.sh has an orphaned entry:
|
|
3
|
+
# - DEFAULT_ARTIFACT_OUTPUT_IDS entry without an AGENT_HANDOFF entry, or
|
|
4
|
+
# - AGENT_HANDOFF entry without a DEFAULT_ARTIFACT_OUTPUT_IDS entry.
|
|
5
|
+
#
|
|
6
|
+
# Also FAIL when a stack ships an agent file that the hook ignores entirely
|
|
7
|
+
# (no entry in either map) AND the stack has a pipeline intent that can route
|
|
8
|
+
# to it — for example, intent `openspec-change` requires `openspec-author` to
|
|
9
|
+
# be wired through both maps or the pipeline silently halts in
|
|
10
|
+
# `awaiting_artifact_receipt`. We check the documented intent-to-agent table in
|
|
11
|
+
# each stack's task-router.md against the hook's actual coverage.
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
|
|
15
|
+
export AI_RULES_PRESETS_ROOT="$ROOT/packages/ai-rules/presets"
|
|
16
|
+
|
|
17
|
+
python3 <<'PY'
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import os
|
|
21
|
+
import re
|
|
22
|
+
import sys
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
|
|
25
|
+
presets = Path(os.environ["AI_RULES_PRESETS_ROOT"])
|
|
26
|
+
|
|
27
|
+
# Stacks that ship a /task pipeline. mcp-ts ships a Phase-1 chain but not the
|
|
28
|
+
# standard openspec-change intent; do not require openspec-author there.
|
|
29
|
+
STACKS_WITH_OPENSPEC = {
|
|
30
|
+
("cursor", "android-kotlin"),
|
|
31
|
+
("cursor", "go"),
|
|
32
|
+
("cursor", "ios-swift"),
|
|
33
|
+
("cursor", "java"),
|
|
34
|
+
("cursor", "next"),
|
|
35
|
+
("cursor", "nuxt"),
|
|
36
|
+
("cursor", "php-hexagonal"),
|
|
37
|
+
("cursor", "php-laravel"),
|
|
38
|
+
("cursor", "svelte"),
|
|
39
|
+
("claude", "android-kotlin"),
|
|
40
|
+
("claude", "go"),
|
|
41
|
+
("claude", "ios-swift"),
|
|
42
|
+
("claude", "java"),
|
|
43
|
+
("claude", "next"),
|
|
44
|
+
("claude", "nuxt"),
|
|
45
|
+
("claude", "php-hexagonal"),
|
|
46
|
+
("claude", "php-laravel"),
|
|
47
|
+
("claude", "svelte"),
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# Agents used only outside the pipeline (no chain hook entry expected).
|
|
51
|
+
PIPELINE_EXEMPT = {"task-router", "codebase-analyzer"}
|
|
52
|
+
|
|
53
|
+
failures: list[str] = []
|
|
54
|
+
checks = 0
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def parse_block(text: str, header_re: str, line_re: str) -> set[str]:
|
|
58
|
+
m = re.search(header_re, text, re.DOTALL)
|
|
59
|
+
if not m:
|
|
60
|
+
return set()
|
|
61
|
+
return {x.group(1) for x in line_re.finditer(m.group(1))}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
for hook in sorted(presets.glob("*/**/hooks/chain-team-phases.sh")):
|
|
65
|
+
rel = hook.relative_to(presets)
|
|
66
|
+
platform, preset = rel.parts[0], rel.parts[1]
|
|
67
|
+
text = hook.read_text(encoding="utf-8")
|
|
68
|
+
|
|
69
|
+
artifact_ids = parse_block(
|
|
70
|
+
text,
|
|
71
|
+
r"const DEFAULT_ARTIFACT_OUTPUT_IDS = \{(.*?)\};\n",
|
|
72
|
+
re.compile(r"^\s*['\"]([a-z][a-z0-9.\-]*)['\"]\s*:\s*['\"][a-z][a-z0-9.\-]*['\"]\s*,?", re.MULTILINE),
|
|
73
|
+
)
|
|
74
|
+
handoff_keys = parse_block(
|
|
75
|
+
text,
|
|
76
|
+
r"const AGENT_HANDOFF = \{(.*?)\n\};\n",
|
|
77
|
+
re.compile(r"^\s*['\"]([a-z][a-z0-9.\-]*)['\"]\s*:\s*\(s", re.MULTILINE),
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
# 1) Symmetric invariant: any entry in either map must appear in the other.
|
|
81
|
+
only_artifact = artifact_ids - handoff_keys
|
|
82
|
+
only_handoff = handoff_keys - artifact_ids
|
|
83
|
+
for agent in sorted(only_artifact - PIPELINE_EXEMPT):
|
|
84
|
+
checks += 1
|
|
85
|
+
failures.append(f"{rel}: DEFAULT_ARTIFACT_OUTPUT_IDS '{agent}' has no AGENT_HANDOFF entry")
|
|
86
|
+
for agent in sorted(only_handoff - PIPELINE_EXEMPT):
|
|
87
|
+
checks += 1
|
|
88
|
+
failures.append(f"{rel}: AGENT_HANDOFF '{agent}' has no DEFAULT_ARTIFACT_OUTPUT_IDS entry")
|
|
89
|
+
|
|
90
|
+
# 2) openspec-author must be in BOTH maps for any stack that ships the
|
|
91
|
+
# agent. The hook without this entry silently breaks the openspec-change
|
|
92
|
+
# intent (the original bug).
|
|
93
|
+
agents_dir = presets / platform / preset / "agents"
|
|
94
|
+
if (platform, preset) in STACKS_WITH_OPENSPEC and (agents_dir / "openspec-author.md").exists():
|
|
95
|
+
checks += 1
|
|
96
|
+
if "openspec-author" not in artifact_ids:
|
|
97
|
+
failures.append(f"{rel}: ships openspec-author.md but hook is missing DEFAULT_ARTIFACT_OUTPUT_IDS['openspec-author'] (openspec-change intent will silently stall in awaiting_artifact_receipt)")
|
|
98
|
+
if "openspec-author" not in handoff_keys:
|
|
99
|
+
failures.append(f"{rel}: ships openspec-author.md but hook is missing AGENT_HANDOFF['openspec-author']")
|
|
100
|
+
|
|
101
|
+
if failures:
|
|
102
|
+
print(f"FAIL: chain-team-phases.sh coverage gap ({len(failures)} issue(s) / {checks} checks):")
|
|
103
|
+
for f in failures:
|
|
104
|
+
print(f" - {f}")
|
|
105
|
+
sys.exit(1)
|
|
106
|
+
|
|
107
|
+
print(f"OK: chain-team-phases.sh hook coverage is consistent ({checks} checks across all hooks)")
|
|
108
|
+
sys.exit(0)
|
|
109
|
+
PY
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Verify that every installable stack ships an `ai-local-overlay` rule on both
|
|
3
|
+
# sides (Cursor `.mdc` and Claude `.md`) and that the body contains the
|
|
4
|
+
# mandatory acknowledgement format.
|
|
5
|
+
#
|
|
6
|
+
# Exit 0 on OK; exit 1 on any FAIL.
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
|
|
10
|
+
export AI_RULES_PRESETS_ROOT="$ROOT/packages/ai-rules/presets"
|
|
11
|
+
|
|
12
|
+
python3 <<'PY'
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import os
|
|
16
|
+
import re
|
|
17
|
+
import sys
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
presets = Path(os.environ["AI_RULES_PRESETS_ROOT"])
|
|
21
|
+
STACKS = (
|
|
22
|
+
"next",
|
|
23
|
+
"nuxt",
|
|
24
|
+
"svelte",
|
|
25
|
+
"ios-swift",
|
|
26
|
+
"android-kotlin",
|
|
27
|
+
"go",
|
|
28
|
+
"java",
|
|
29
|
+
"mcp-ts",
|
|
30
|
+
"php-hexagonal",
|
|
31
|
+
"php-laravel",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
CURSOR_NAME = "ai-local-overlay.mdc"
|
|
35
|
+
CLAUDE_NAME = "ai-local-overlay.md"
|
|
36
|
+
# The body line that the agent MUST emit when it applies the overlay.
|
|
37
|
+
ACK_RE = re.compile(r"Using\s+\.ai\.local:\s+<rule-name>")
|
|
38
|
+
# Sentinel strings that signal the rule is mandatory / explains authoring /
|
|
39
|
+
# points at the consumer guide.
|
|
40
|
+
FRONTMATTER_DESCRIPTION = "MANDATORY"
|
|
41
|
+
POINTER_DOCS = "docs/LOCAL-OVERLAY.md"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def strip_frontmatter(text: str) -> tuple[str, str]:
|
|
45
|
+
if not text.startswith("---\n"):
|
|
46
|
+
return "", text
|
|
47
|
+
end = text.find("\n---\n", 4)
|
|
48
|
+
if end < 0:
|
|
49
|
+
return "", text
|
|
50
|
+
return text[4:end], text[end + 5 :]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
failed = 0
|
|
54
|
+
stack_failed: dict[str, int] = {}
|
|
55
|
+
|
|
56
|
+
print("Local overlay coverage (every stack must ship ai-local-overlay)")
|
|
57
|
+
print(f"Presets: {presets}")
|
|
58
|
+
print()
|
|
59
|
+
|
|
60
|
+
for stack in STACKS:
|
|
61
|
+
print(f"=== {stack} ===")
|
|
62
|
+
cursor_path = presets / "cursor" / stack / "rules" / CURSOR_NAME
|
|
63
|
+
claude_path = presets / "claude" / stack / "rules" / CLAUDE_NAME
|
|
64
|
+
|
|
65
|
+
# Per-stack failure counter — keeps the OK message for healthy stacks
|
|
66
|
+
# even when an earlier stack has failed.
|
|
67
|
+
sf = 0
|
|
68
|
+
|
|
69
|
+
# Cursor must exist + alwaysApply: true + ack format + pointer.
|
|
70
|
+
if not cursor_path.is_file():
|
|
71
|
+
print(f"FAIL: missing {cursor_path}")
|
|
72
|
+
sf += 1
|
|
73
|
+
else:
|
|
74
|
+
text = cursor_path.read_text(encoding="utf-8")
|
|
75
|
+
fm, body = strip_frontmatter(text)
|
|
76
|
+
if "alwaysApply: true" not in fm:
|
|
77
|
+
print(f"FAIL: {cursor_path.name} must have alwaysApply: true")
|
|
78
|
+
sf += 1
|
|
79
|
+
if FRONTMATTER_DESCRIPTION not in fm:
|
|
80
|
+
print(f"FAIL: {cursor_path.name} frontmatter description must include 'MANDATORY'")
|
|
81
|
+
sf += 1
|
|
82
|
+
if not ACK_RE.search(body):
|
|
83
|
+
print(f"FAIL: {cursor_path.name} body missing acknowledgement format `Using .ai.local: <rule-name>`")
|
|
84
|
+
sf += 1
|
|
85
|
+
if POINTER_DOCS not in body:
|
|
86
|
+
print(f"FAIL: {cursor_path.name} body must reference `docs/LOCAL-OVERLAY.md`")
|
|
87
|
+
sf += 1
|
|
88
|
+
if sf == 0:
|
|
89
|
+
print(f" OK: {cursor_path.name} (alwaysApply + MANDATORY + ack + pointer)")
|
|
90
|
+
|
|
91
|
+
# Claude must exist (flat or topic folder) + paths: includes .ai.local + ack format + pointer.
|
|
92
|
+
if not claude_path.is_file():
|
|
93
|
+
# Try to find a topic-folder placement (e.g. tooling-and-review/ai-local-overlay.md).
|
|
94
|
+
candidates = list((presets / "claude" / stack / "rules").rglob(CLAUDE_NAME))
|
|
95
|
+
if candidates:
|
|
96
|
+
claude_path = candidates[0]
|
|
97
|
+
else:
|
|
98
|
+
print(f"FAIL: missing {claude_path}")
|
|
99
|
+
sf += 1
|
|
100
|
+
if claude_path.is_file():
|
|
101
|
+
text = claude_path.read_text(encoding="utf-8")
|
|
102
|
+
fm, body = strip_frontmatter(text)
|
|
103
|
+
if "**/.ai.local/**" not in fm:
|
|
104
|
+
print(f"FAIL: {claude_path.name} frontmatter must include `**/.ai.local/**` in paths")
|
|
105
|
+
sf += 1
|
|
106
|
+
if FRONTMATTER_DESCRIPTION not in fm:
|
|
107
|
+
print(f"FAIL: {claude_path.name} frontmatter description must include 'MANDATORY'")
|
|
108
|
+
sf += 1
|
|
109
|
+
if not ACK_RE.search(body):
|
|
110
|
+
print(f"FAIL: {claude_path.name} body missing acknowledgement format `Using .ai.local: <rule-name>`")
|
|
111
|
+
sf += 1
|
|
112
|
+
if POINTER_DOCS not in body:
|
|
113
|
+
print(f"FAIL: {claude_path.name} body must reference `docs/LOCAL-OVERLAY.md`")
|
|
114
|
+
sf += 1
|
|
115
|
+
if sf == 0:
|
|
116
|
+
print(f" OK: {claude_path.name} (paths + MANDATORY + ack + pointer)")
|
|
117
|
+
|
|
118
|
+
# Twin-map coverage: the Claude twin must be listed in claude/<stack>/rules/README.md.
|
|
119
|
+
claude_readme = presets / "claude" / stack / "rules" / "README.md"
|
|
120
|
+
if claude_readme.is_file():
|
|
121
|
+
readme_text = claude_readme.read_text(encoding="utf-8")
|
|
122
|
+
if CURSOR_NAME not in readme_text:
|
|
123
|
+
print(f"FAIL: {claude_readme} mapping table must include `{CURSOR_NAME}`")
|
|
124
|
+
sf += 1
|
|
125
|
+
|
|
126
|
+
stack_failed[stack] = sf
|
|
127
|
+
failed += sf
|
|
128
|
+
print()
|
|
129
|
+
|
|
130
|
+
if failed:
|
|
131
|
+
print(f"Result: FAIL ({failed} issue(s) across {sum(1 for v in stack_failed.values() if v > 0)} stack(s))")
|
|
132
|
+
sys.exit(1)
|
|
133
|
+
|
|
134
|
+
print("Result: OK")
|
|
135
|
+
sys.exit(0)
|
|
136
|
+
PY
|
|
@@ -54,8 +54,8 @@ if len(violations) > 50:
|
|
|
54
54
|
print(f" ... and {len(violations) - 50} more")
|
|
55
55
|
|
|
56
56
|
if violations and (fail or not soft):
|
|
57
|
-
if fail:
|
|
58
|
-
|
|
57
|
+
print("Result: FAIL (unmarked Cyrillic)" if fail else "Result: WARN (soft)")
|
|
58
|
+
sys.exit(1)
|
|
59
59
|
print("Result:", "WARN (soft)" if violations else "OK")
|
|
60
60
|
sys.exit(0)
|
|
61
61
|
PY
|
|
@@ -278,7 +278,10 @@ def line_is_negation(line: str) -> bool:
|
|
|
278
278
|
|
|
279
279
|
|
|
280
280
|
def is_forbidden_agent(name: str, bad_stems: tuple[str, ...]) -> bool:
|
|
281
|
-
|
|
281
|
+
# Exact match, or kebab-case prefix (so `playwright-test-planner` matches
|
|
282
|
+
# `playwright-test-planner-foo` too — kebab-case is the only naming style in
|
|
283
|
+
# use across all presets, so the naive `startswith` is intentional).
|
|
284
|
+
return name in bad_stems or any(name.startswith(s + "-") or name == s for s in bad_stems)
|
|
282
285
|
|
|
283
286
|
|
|
284
287
|
def collect_step_agents(steps) -> list[str]:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Orchestrator: twin map + token budget + leakage + hook-only lifecycle + shared-core drift + i18n (hard).
|
|
2
|
+
# Orchestrator: twin map + token budget + leakage + hook-only lifecycle + local-overlay + shared-core drift + i18n (hard).
|
|
3
3
|
# All gates exit non-zero on FAIL.
|
|
4
4
|
set -euo pipefail
|
|
5
5
|
|
|
@@ -33,7 +33,9 @@ run_gate "twin-map" "$SCRIPT_DIR/check-preset-twin-map.sh"
|
|
|
33
33
|
run_gate "token-budget" "$SCRIPT_DIR/check-preset-token-budget.sh"
|
|
34
34
|
run_gate "leakage" "$SCRIPT_DIR/check-preset-leakage.sh"
|
|
35
35
|
run_gate "hook-only-lifecycle" "$SCRIPT_DIR/check-hook-only-lifecycle.sh"
|
|
36
|
+
run_gate "local-overlay" "$SCRIPT_DIR/check-local-overlay.sh"
|
|
36
37
|
run_gate "shared-core-drift" "$SCRIPT_DIR/check-shared-core-drift.sh" AI_RULES_DRIFT_FAIL=1
|
|
38
|
+
run_gate "chain-hook-coverage" "$SCRIPT_DIR/check-chain-hook-coverage.sh"
|
|
37
39
|
run_gate "i18n" "$SCRIPT_DIR/check-preset-i18n.sh" AI_RULES_I18N_FAIL=1 AI_RULES_I18N_SOFT=0
|
|
38
40
|
|
|
39
41
|
echo ">>> cli-mcp-merge"
|
|
@@ -45,6 +47,24 @@ else
|
|
|
45
47
|
fi
|
|
46
48
|
echo
|
|
47
49
|
|
|
50
|
+
echo ">>> chain-team-phases coverage"
|
|
51
|
+
if node "$SCRIPT_DIR/test-chain-team-phases-coverage.mjs"; then
|
|
52
|
+
echo "<<< chain-team-phases coverage: OK"
|
|
53
|
+
else
|
|
54
|
+
echo "<<< chain-team-phases coverage: FAIL"
|
|
55
|
+
status=1
|
|
56
|
+
fi
|
|
57
|
+
echo
|
|
58
|
+
|
|
59
|
+
echo ">>> agent-task-metrics hooks"
|
|
60
|
+
if node "$SCRIPT_DIR/test-agent-task-metrics-hooks.mjs"; then
|
|
61
|
+
echo "<<< agent-task-metrics hooks: OK"
|
|
62
|
+
else
|
|
63
|
+
echo "<<< agent-task-metrics hooks: FAIL"
|
|
64
|
+
status=1
|
|
65
|
+
fi
|
|
66
|
+
echo
|
|
67
|
+
|
|
48
68
|
# Soft WARN: dogfood product-specs (never fails the orchestrator).
|
|
49
69
|
# Default check-product-specs exits 0 even when issues are found unless --strict.
|
|
50
70
|
# Use --strict here only to surface problems as WARN in logs; do not flip status.
|
|
@@ -16,7 +16,8 @@ from pathlib import Path
|
|
|
16
16
|
|
|
17
17
|
presets = Path(os.environ["AI_RULES_PRESETS_ROOT"])
|
|
18
18
|
STACKS = ("next", "nuxt", "svelte", "ios-swift", "android-kotlin", "go", "java", "mcp-ts", "php-hexagonal", "php-laravel")
|
|
19
|
-
BODY_CAP = 140
|
|
19
|
+
BODY_CAP = 140 # applied to 3-rule trios (Claude session-start, Cursor trio when len==3)
|
|
20
|
+
BODY_CAP_CURSOR_4 = 170 # Cursor now allows 4 always-on (next-app-core, package-manager, code-quality, ai-local-overlay)
|
|
20
21
|
MARKER_LINE_RE = re.compile(r"^<!--\s*shared-core:\s*[^>]+?\s*-->\s*$")
|
|
21
22
|
ALWAYS_APPLY_RE = re.compile(r"(?m)^alwaysApply:\s*true\s*$")
|
|
22
23
|
PATHS_RE = re.compile(r"(?m)^paths:\s*")
|
|
@@ -70,7 +71,7 @@ failed = 0
|
|
|
70
71
|
|
|
71
72
|
print("Preset token / session-start budget (Option A)")
|
|
72
73
|
print(f"Presets: {presets}")
|
|
73
|
-
print(f"Body line cap (trio
|
|
74
|
+
print(f"Body line cap (Claude trio): {BODY_CAP}; (Cursor 4-set): {BODY_CAP_CURSOR_4}")
|
|
74
75
|
print()
|
|
75
76
|
|
|
76
77
|
for stack in STACKS:
|
|
@@ -87,9 +88,15 @@ for stack in STACKS:
|
|
|
87
88
|
print(f"FAIL: meta preset-* must not be alwaysApply: {p.name}")
|
|
88
89
|
failed += 1
|
|
89
90
|
|
|
90
|
-
if len(always)
|
|
91
|
-
print(f"FAIL: Cursor alwaysApply count is {len(always)}, expected
|
|
91
|
+
if len(always) not in (3, 4):
|
|
92
|
+
print(f"FAIL: Cursor alwaysApply count is {len(always)}, expected 3 or 4 (4th slot reserved for ai-local-overlay)")
|
|
92
93
|
failed += 1
|
|
94
|
+
elif len(always) == 4:
|
|
95
|
+
# 4-set: ensure the 4th rule is ai-local-overlay (or declares itself as such).
|
|
96
|
+
extra = [p for p in always if p.stem not in {"code-quality-and-refactoring", "package-manager", "next-app-core", "nuxt-app-core", "svelte-app-core", "ios-app-core", "android-app-core", "go-app-core", "java-app-core", "mcp-ts-app-core", "php-app-core", "laravel-app-core", "architecture-boundaries", "mcp-server-boundaries"}]
|
|
97
|
+
if not any(p.stem == "ai-local-overlay" for p in always) and extra:
|
|
98
|
+
print(f"FAIL: Cursor alwaysApply=4 but no ai-local-overlay.mdc; the 4th slot is reserved for the local overlay rule")
|
|
99
|
+
failed += 1
|
|
93
100
|
|
|
94
101
|
# --- Claude no-paths (excl README) ---
|
|
95
102
|
session = claude_session_start(claude_rules)
|
|
@@ -108,10 +115,12 @@ for stack in STACKS:
|
|
|
108
115
|
)
|
|
109
116
|
failed += 1
|
|
110
117
|
|
|
111
|
-
# --- Body sum of intended
|
|
112
|
-
#
|
|
118
|
+
# --- Body sum of intended session-start set (Cursor alwaysApply + Claude session) ---
|
|
119
|
+
# Cursor allows 3 or 4 rules (4th slot reserved for ai-local-overlay); Claude is exactly 3.
|
|
113
120
|
for label, files in (("Cursor", always), ("Claude", session)):
|
|
114
|
-
if len(files)
|
|
121
|
+
if label == "Cursor" and len(files) not in (3, 4):
|
|
122
|
+
continue
|
|
123
|
+
if label == "Claude" and len(files) != 3:
|
|
115
124
|
continue
|
|
116
125
|
total = 0
|
|
117
126
|
for path in files:
|
|
@@ -121,10 +130,11 @@ for stack in STACKS:
|
|
|
121
130
|
total += n
|
|
122
131
|
name = path.name if label == "Cursor" else path.relative_to(claude_rules).as_posix()
|
|
123
132
|
print(f" {label} body lines {name}: {n}")
|
|
124
|
-
|
|
125
|
-
|
|
133
|
+
cap = BODY_CAP_CURSOR_4 if label == "Cursor" and len(always) == 4 else BODY_CAP
|
|
134
|
+
print(f" {label} session-start body sum: {total} (cap {cap}, files={len(files)})")
|
|
135
|
+
if total > cap:
|
|
126
136
|
print(
|
|
127
|
-
f"FAIL: {label} session-start body sum {total} > {
|
|
137
|
+
f"FAIL: {label} session-start body sum {total} > {cap} ({stack})"
|
|
128
138
|
)
|
|
129
139
|
failed += 1
|
|
130
140
|
|
|
@@ -99,6 +99,22 @@ function checkFile(relPath, minPairs, requireImpact) {
|
|
|
99
99
|
) && ok;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
// Order check: each Incorrect heading must precede its matching Correct heading.
|
|
103
|
+
// Without this, an agent reading the rule may learn a "correct" pattern before
|
|
104
|
+
// seeing the "incorrect" example it contrasts with.
|
|
105
|
+
if (incorrectCount > 0 && correctCount > 0) {
|
|
106
|
+
const incRe = /^#{2,3}\s+Incorrect\s*$/gim;
|
|
107
|
+
const corRe = /^#{2,3}\s+Correct\s*$/gim;
|
|
108
|
+
const firstInc = text.search(incRe);
|
|
109
|
+
const firstCor = text.search(corRe);
|
|
110
|
+
if (firstInc >= 0 && firstCor >= 0 && firstInc >= firstCor) {
|
|
111
|
+
ok =
|
|
112
|
+
fail(
|
|
113
|
+
`${relPath}: first "Incorrect" heading (offset ${firstInc}) must precede first "Correct" heading (offset ${firstCor})`,
|
|
114
|
+
) && ok;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
102
118
|
const incorrectBodies = sectionBodies(text, 'Incorrect');
|
|
103
119
|
const correctBodies = sectionBodies(text, 'Correct');
|
|
104
120
|
for (let i = 0; i < Math.min(incorrectBodies.length, correctBodies.length); i++) {
|
|
@@ -7,42 +7,26 @@ set -euo pipefail
|
|
|
7
7
|
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
|
|
8
8
|
export AI_RULES_PRESETS_ROOT="$ROOT/packages/ai-rules/presets"
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
11
|
+
EMBED_LIST_FILE="$SCRIPT_DIR/_lib/embed-stems.json"
|
|
12
|
+
|
|
13
|
+
python3 - "$EMBED_LIST_FILE" <<'PY'
|
|
11
14
|
from __future__ import annotations
|
|
12
15
|
|
|
16
|
+
import json
|
|
13
17
|
import os
|
|
14
18
|
import re
|
|
15
19
|
import sys
|
|
16
20
|
from pathlib import Path
|
|
17
21
|
|
|
22
|
+
embed_list_file = Path(sys.argv[1])
|
|
23
|
+
_stems = json.loads(embed_list_file.read_text(encoding="utf-8"))
|
|
24
|
+
EMBED = _stems["embed"]
|
|
25
|
+
LINEAGE = _stems["lineage"]
|
|
26
|
+
|
|
18
27
|
presets = Path(os.environ["AI_RULES_PRESETS_ROOT"])
|
|
19
28
|
core_root = presets / "_shared" / "core"
|
|
20
29
|
|
|
21
|
-
EMBED = [
|
|
22
|
-
"quality/code-quality-and-refactoring.md",
|
|
23
|
-
"quality/anti-sycophancy-discipline.md",
|
|
24
|
-
"quality/design-guidance.md",
|
|
25
|
-
"quality/mcp-usage.md",
|
|
26
|
-
"meta/preset-layering.md",
|
|
27
|
-
"meta/preset-twin-sync.md",
|
|
28
|
-
"meta/preset-token-budget.md",
|
|
29
|
-
"meta/preset-pr-checklist.md",
|
|
30
|
-
"meta/preset-no-cross-stack-leakage.md",
|
|
31
|
-
"review/code-review-mr.md",
|
|
32
|
-
"review/technical-retro.md",
|
|
33
|
-
"review/mockup-review.md",
|
|
34
|
-
"review/ux-design.md",
|
|
35
|
-
"agent-team/agent-team-intake.md",
|
|
36
|
-
"architecture/product-specs.md",
|
|
37
|
-
"architecture/product-specs-authoring.md",
|
|
38
|
-
]
|
|
39
|
-
|
|
40
|
-
LINEAGE = [
|
|
41
|
-
"architecture/feature-delivery-workflow.md",
|
|
42
|
-
"architecture/reference-features.template.md",
|
|
43
|
-
"agent-team/agent-team-orchestrator.md",
|
|
44
|
-
]
|
|
45
|
-
|
|
46
30
|
# Full-line sync marker only (do not strip prose that *mentions* the marker).
|
|
47
31
|
MARKER_LINE_RE = re.compile(r"^<!--\s*shared-core:\s*[^>]+?\s*-->\s*$")
|
|
48
32
|
|
|
@@ -13,18 +13,35 @@ import path from 'node:path';
|
|
|
13
13
|
|
|
14
14
|
function parseArgs(argv) {
|
|
15
15
|
const options = { cwd: process.cwd(), platform: 'cursor', slug: null };
|
|
16
|
+
// Read the next token from argv for value-taking flags. Returns the value or null
|
|
17
|
+
// when the flag is missing its value; the caller exits with a friendly error.
|
|
18
|
+
function nextValue(flag, i) {
|
|
19
|
+
const next = argv[i + 1];
|
|
20
|
+
if (next === undefined || next.startsWith('-')) {
|
|
21
|
+
console.error(`Missing value for ${flag} (use ${flag} <value>)`);
|
|
22
|
+
process.exit(2);
|
|
23
|
+
}
|
|
24
|
+
return next;
|
|
25
|
+
}
|
|
16
26
|
for (let i = 2; i < argv.length; i += 1) {
|
|
17
27
|
const arg = argv[i];
|
|
18
|
-
if (arg === '--cwd')
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
else if (arg === '--
|
|
28
|
+
if (arg === '--cwd') {
|
|
29
|
+
options.cwd = path.resolve(nextValue(arg, i));
|
|
30
|
+
i += 1;
|
|
31
|
+
} else if (arg === '--platform') {
|
|
32
|
+
options.platform = nextValue(arg, i);
|
|
33
|
+
i += 1;
|
|
34
|
+
} else if (arg === '--slug') {
|
|
35
|
+
options.slug = nextValue(arg, i);
|
|
36
|
+
i += 1;
|
|
37
|
+
} else if (arg === '--activate-next') {
|
|
22
38
|
/* always activate via hook payload */
|
|
23
39
|
} else if (arg === '--team-root') {
|
|
24
40
|
// Compatibility with earlier docs: derive platform + cwd from team root.
|
|
25
|
-
const teamRoot = path.resolve(
|
|
41
|
+
const teamRoot = path.resolve(nextValue(arg, i));
|
|
26
42
|
options.cwd = path.resolve(teamRoot, '..', '..');
|
|
27
43
|
options.platform = path.basename(path.dirname(teamRoot)) === '.claude' ? 'claude' : 'cursor';
|
|
44
|
+
i += 1;
|
|
28
45
|
} else {
|
|
29
46
|
console.error(`Unknown argument: ${arg}`);
|
|
30
47
|
process.exit(2);
|
|
@@ -8,35 +8,24 @@ set -euo pipefail
|
|
|
8
8
|
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
|
|
9
9
|
export AI_RULES_PRESETS_ROOT="$ROOT/packages/ai-rules/presets"
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
12
|
+
EMBED_LIST_FILE="$SCRIPT_DIR/_lib/embed-stems.json"
|
|
13
|
+
|
|
14
|
+
python3 - "$EMBED_LIST_FILE" <<'PY'
|
|
12
15
|
from __future__ import annotations
|
|
13
16
|
|
|
17
|
+
import json
|
|
14
18
|
import os
|
|
15
19
|
import re
|
|
20
|
+
import sys
|
|
16
21
|
from pathlib import Path
|
|
17
22
|
|
|
23
|
+
embed_list_file = Path(sys.argv[1])
|
|
24
|
+
EMBED = json.loads(embed_list_file.read_text(encoding="utf-8"))["embed"]
|
|
25
|
+
|
|
18
26
|
presets = Path(os.environ["AI_RULES_PRESETS_ROOT"])
|
|
19
27
|
core_root = presets / "_shared" / "core"
|
|
20
28
|
|
|
21
|
-
EMBED = [
|
|
22
|
-
"quality/code-quality-and-refactoring.md",
|
|
23
|
-
"quality/anti-sycophancy-discipline.md",
|
|
24
|
-
"quality/design-guidance.md",
|
|
25
|
-
"quality/mcp-usage.md",
|
|
26
|
-
"meta/preset-layering.md",
|
|
27
|
-
"meta/preset-twin-sync.md",
|
|
28
|
-
"meta/preset-token-budget.md",
|
|
29
|
-
"meta/preset-pr-checklist.md",
|
|
30
|
-
"meta/preset-no-cross-stack-leakage.md",
|
|
31
|
-
"review/code-review-mr.md",
|
|
32
|
-
"review/technical-retro.md",
|
|
33
|
-
"review/mockup-review.md",
|
|
34
|
-
"review/ux-design.md",
|
|
35
|
-
"agent-team/agent-team-intake.md",
|
|
36
|
-
"architecture/product-specs.md",
|
|
37
|
-
"architecture/product-specs-authoring.md",
|
|
38
|
-
]
|
|
39
|
-
|
|
40
29
|
MARKER_LINE_RE = re.compile(r"^<!--\s*shared-core:\s*([^>]+?)\s*-->\s*$")
|
|
41
30
|
|
|
42
31
|
|
|
@@ -14,7 +14,7 @@ const hooks = [
|
|
|
14
14
|
...fs.readdirSync(path.join(presetsDirectory, 'claude')).map((stack) => path.join(presetsDirectory, 'claude', stack, 'hooks', 'chain-team-phases.sh')),
|
|
15
15
|
];
|
|
16
16
|
|
|
17
|
-
assert.equal(hooks.length,
|
|
17
|
+
assert.equal(hooks.length, 20, 'expected every packaged Cursor and Claude hook (10 stacks × 2 platforms)');
|
|
18
18
|
|
|
19
19
|
function readJson(filePath) {
|
|
20
20
|
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|