@bonesofspring/ai-rules 0.2.28 → 0.2.29

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.
Files changed (245) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +1 -1
  3. package/docs/MAVIS-COMPATIBILITY.md +10 -6
  4. package/docs/MAVIS.md +15 -6
  5. package/docs/OPENCODE-COMPATIBILITY.md +2 -2
  6. package/docs/OPENCODE.md +1 -1
  7. package/package.json +1 -1
  8. package/presets/_shared/core/meta/preset-pr-checklist.md +2 -2
  9. package/presets/claude/android-kotlin/CLAUDE.md +3 -1
  10. package/presets/claude/android-kotlin/REPO_AGENTS.md +1 -1
  11. package/presets/claude/android-kotlin/hooks/README.md +6 -5
  12. package/presets/claude/android-kotlin/hooks/chain-team-phases.sh +18 -0
  13. package/presets/claude/android-kotlin/hooks/examples/README.md +2 -0
  14. package/presets/claude/android-kotlin/hooks/guard-shell-command.sh +32 -9
  15. package/presets/claude/android-kotlin/rules/README.md +1 -1
  16. package/presets/claude/android-kotlin/rules/tooling-and-review/ai-local-overlay.md +0 -5
  17. package/presets/claude/android-kotlin/rules/tooling-and-review/preset-pr-checklist.md +2 -2
  18. package/presets/claude/android-kotlin/settings.json +23 -0
  19. package/presets/claude/go/CLAUDE.md +3 -1
  20. package/presets/claude/go/REPO_AGENTS.md +1 -1
  21. package/presets/claude/go/hooks/README.md +6 -5
  22. package/presets/claude/go/hooks/chain-team-phases.sh +18 -0
  23. package/presets/claude/go/hooks/examples/README.md +2 -0
  24. package/presets/claude/go/hooks/guard-shell-command.sh +32 -9
  25. package/presets/claude/go/rules/README.md +1 -1
  26. package/presets/claude/go/rules/tooling-and-review/ai-local-overlay.md +0 -5
  27. package/presets/claude/go/rules/tooling-and-review/preset-pr-checklist.md +2 -2
  28. package/presets/claude/go/settings.json +23 -0
  29. package/presets/claude/ios-swift/CLAUDE.md +3 -1
  30. package/presets/claude/ios-swift/REPO_AGENTS.md +1 -1
  31. package/presets/claude/ios-swift/hooks/README.md +6 -5
  32. package/presets/claude/ios-swift/hooks/chain-team-phases.sh +18 -0
  33. package/presets/claude/ios-swift/hooks/examples/README.md +2 -0
  34. package/presets/claude/ios-swift/hooks/guard-shell-command.sh +32 -9
  35. package/presets/claude/ios-swift/rules/README.md +1 -1
  36. package/presets/claude/ios-swift/rules/tooling-and-review/ai-local-overlay.md +0 -5
  37. package/presets/claude/ios-swift/rules/tooling-and-review/preset-pr-checklist.md +2 -2
  38. package/presets/claude/ios-swift/settings.json +23 -0
  39. package/presets/claude/java/CLAUDE.md +3 -1
  40. package/presets/claude/java/REPO_AGENTS.md +1 -1
  41. package/presets/claude/java/hooks/README.md +6 -5
  42. package/presets/claude/java/hooks/chain-team-phases.sh +18 -0
  43. package/presets/claude/java/hooks/examples/README.md +2 -0
  44. package/presets/claude/java/hooks/guard-shell-command.sh +32 -9
  45. package/presets/claude/java/rules/README.md +1 -1
  46. package/presets/claude/java/rules/tooling-and-review/ai-local-overlay.md +0 -5
  47. package/presets/claude/java/rules/tooling-and-review/preset-pr-checklist.md +2 -2
  48. package/presets/claude/java/settings.json +23 -0
  49. package/presets/claude/mcp-ts/CLAUDE.md +3 -1
  50. package/presets/claude/mcp-ts/REPO_AGENTS.md +1 -1
  51. package/presets/claude/mcp-ts/hooks/README.md +8 -3
  52. package/presets/claude/mcp-ts/hooks/chain-team-phases.sh +18 -0
  53. package/presets/claude/mcp-ts/hooks/examples/README.md +5 -0
  54. package/presets/claude/mcp-ts/hooks/guard-shell-command.sh +32 -9
  55. package/presets/claude/mcp-ts/rules/README.md +1 -1
  56. package/presets/claude/mcp-ts/rules/tooling-and-review/ai-local-overlay.md +0 -5
  57. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-pr-checklist.md +2 -2
  58. package/presets/claude/mcp-ts/settings.json +23 -0
  59. package/presets/claude/next/CLAUDE.md +3 -1
  60. package/presets/claude/next/REPO_AGENTS.md +1 -1
  61. package/presets/claude/next/hooks/README.md +10 -1
  62. package/presets/claude/next/hooks/chain-team-phases.sh +18 -0
  63. package/presets/claude/next/hooks/examples/README.md +2 -0
  64. package/presets/claude/next/hooks/guard-shell-command.sh +32 -9
  65. package/presets/claude/next/rules/README.md +1 -1
  66. package/presets/claude/next/rules/tooling-and-review/ai-local-overlay.md +0 -5
  67. package/presets/claude/next/rules/tooling-and-review/preset-pr-checklist.md +2 -2
  68. package/presets/claude/next/settings.json +23 -0
  69. package/presets/claude/nuxt/CLAUDE.md +3 -1
  70. package/presets/claude/nuxt/REPO_AGENTS.md +1 -1
  71. package/presets/claude/nuxt/hooks/README.md +7 -4
  72. package/presets/claude/nuxt/hooks/chain-team-phases.sh +18 -0
  73. package/presets/claude/nuxt/hooks/examples/README.md +2 -0
  74. package/presets/claude/nuxt/hooks/guard-shell-command.sh +32 -9
  75. package/presets/claude/nuxt/rules/README.md +1 -1
  76. package/presets/claude/nuxt/rules/tooling-and-review/ai-local-overlay.md +0 -5
  77. package/presets/claude/nuxt/rules/tooling-and-review/preset-pr-checklist.md +2 -2
  78. package/presets/claude/nuxt/settings.json +23 -0
  79. package/presets/claude/php-hexagonal/CLAUDE.md +3 -1
  80. package/presets/claude/php-hexagonal/REPO_AGENTS.md +1 -1
  81. package/presets/claude/php-hexagonal/hooks/README.md +6 -5
  82. package/presets/claude/php-hexagonal/hooks/chain-team-phases.sh +18 -0
  83. package/presets/claude/php-hexagonal/hooks/examples/README.md +3 -1
  84. package/presets/claude/php-hexagonal/hooks/guard-shell-command.sh +32 -9
  85. package/presets/claude/php-hexagonal/rules/README.md +1 -1
  86. package/presets/claude/php-hexagonal/rules/tooling-and-review/ai-local-overlay.md +0 -5
  87. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-pr-checklist.md +2 -2
  88. package/presets/claude/php-hexagonal/settings.json +23 -0
  89. package/presets/claude/php-laravel/CLAUDE.md +6 -0
  90. package/presets/claude/php-laravel/REPO_AGENTS.md +1 -1
  91. package/presets/claude/php-laravel/hooks/README.md +6 -5
  92. package/presets/claude/php-laravel/hooks/chain-team-phases.sh +18 -0
  93. package/presets/claude/php-laravel/hooks/examples/README.md +3 -1
  94. package/presets/claude/php-laravel/hooks/guard-shell-command.sh +32 -9
  95. package/presets/claude/php-laravel/rules/README.md +1 -1
  96. package/presets/claude/php-laravel/rules/tooling-and-review/ai-local-overlay.md +0 -5
  97. package/presets/claude/php-laravel/rules/tooling-and-review/preset-pr-checklist.md +2 -2
  98. package/presets/claude/php-laravel/settings.json +23 -0
  99. package/presets/claude/svelte/CLAUDE.md +3 -1
  100. package/presets/claude/svelte/REPO_AGENTS.md +1 -1
  101. package/presets/claude/svelte/hooks/README.md +7 -4
  102. package/presets/claude/svelte/hooks/chain-team-phases.sh +18 -0
  103. package/presets/claude/svelte/hooks/examples/README.md +2 -0
  104. package/presets/claude/svelte/hooks/guard-shell-command.sh +32 -9
  105. package/presets/claude/svelte/rules/README.md +1 -1
  106. package/presets/claude/svelte/rules/tooling-and-review/ai-local-overlay.md +0 -5
  107. package/presets/claude/svelte/rules/tooling-and-review/preset-pr-checklist.md +2 -2
  108. package/presets/claude/svelte/settings.json +23 -0
  109. package/presets/cursor/android-kotlin/REPO_AGENTS.md +1 -1
  110. package/presets/cursor/android-kotlin/rules/preset-pr-checklist.mdc +2 -2
  111. package/presets/cursor/go/REPO_AGENTS.md +1 -1
  112. package/presets/cursor/go/rules/preset-pr-checklist.mdc +2 -2
  113. package/presets/cursor/ios-swift/REPO_AGENTS.md +1 -1
  114. package/presets/cursor/ios-swift/rules/preset-pr-checklist.mdc +2 -2
  115. package/presets/cursor/java/REPO_AGENTS.md +1 -1
  116. package/presets/cursor/java/rules/preset-pr-checklist.mdc +2 -2
  117. package/presets/cursor/mcp-ts/REPO_AGENTS.md +1 -1
  118. package/presets/cursor/mcp-ts/rules/preset-pr-checklist.mdc +2 -2
  119. package/presets/cursor/next/REPO_AGENTS.md +1 -1
  120. package/presets/cursor/next/rules/preset-pr-checklist.mdc +2 -2
  121. package/presets/cursor/nuxt/REPO_AGENTS.md +1 -1
  122. package/presets/cursor/nuxt/rules/preset-pr-checklist.mdc +2 -2
  123. package/presets/cursor/php-hexagonal/REPO_AGENTS.md +1 -1
  124. package/presets/cursor/php-hexagonal/rules/preset-pr-checklist.mdc +2 -2
  125. package/presets/cursor/php-laravel/REPO_AGENTS.md +1 -1
  126. package/presets/cursor/php-laravel/rules/preset-pr-checklist.mdc +2 -2
  127. package/presets/cursor/svelte/REPO_AGENTS.md +1 -1
  128. package/presets/cursor/svelte/rules/preset-pr-checklist.mdc +2 -2
  129. package/presets/mavis/README.md +2 -0
  130. package/presets/mavis/android-kotlin/MAVIS.md +10 -1
  131. package/presets/mavis/android-kotlin/REPO_AGENTS.md +1 -1
  132. package/presets/mavis/android-kotlin/adapter-map.json +1 -1
  133. package/presets/mavis/android-kotlin/rules/preset-pr-checklist.md +2 -2
  134. package/presets/mavis/go/MAVIS.md +10 -1
  135. package/presets/mavis/go/REPO_AGENTS.md +1 -1
  136. package/presets/mavis/go/adapter-map.json +1 -1
  137. package/presets/mavis/go/rules/preset-pr-checklist.md +2 -2
  138. package/presets/mavis/ios-swift/MAVIS.md +10 -1
  139. package/presets/mavis/ios-swift/REPO_AGENTS.md +1 -1
  140. package/presets/mavis/ios-swift/adapter-map.json +1 -1
  141. package/presets/mavis/ios-swift/rules/preset-pr-checklist.md +2 -2
  142. package/presets/mavis/java/MAVIS.md +10 -1
  143. package/presets/mavis/java/REPO_AGENTS.md +1 -1
  144. package/presets/mavis/java/adapter-map.json +1 -1
  145. package/presets/mavis/java/rules/preset-pr-checklist.md +2 -2
  146. package/presets/mavis/mcp-ts/MAVIS.md +10 -1
  147. package/presets/mavis/mcp-ts/REPO_AGENTS.md +1 -1
  148. package/presets/mavis/mcp-ts/adapter-map.json +1 -1
  149. package/presets/mavis/mcp-ts/rules/preset-pr-checklist.md +2 -2
  150. package/presets/mavis/next/MAVIS.md +10 -1
  151. package/presets/mavis/next/REPO_AGENTS.md +1 -1
  152. package/presets/mavis/next/adapter-map.json +1 -1
  153. package/presets/mavis/next/rules/preset-pr-checklist.md +2 -2
  154. package/presets/mavis/nuxt/MAVIS.md +10 -1
  155. package/presets/mavis/nuxt/REPO_AGENTS.md +1 -1
  156. package/presets/mavis/nuxt/adapter-map.json +1 -1
  157. package/presets/mavis/nuxt/rules/preset-pr-checklist.md +2 -2
  158. package/presets/mavis/php-hexagonal/MAVIS.md +10 -1
  159. package/presets/mavis/php-hexagonal/REPO_AGENTS.md +1 -1
  160. package/presets/mavis/php-hexagonal/adapter-map.json +1 -1
  161. package/presets/mavis/php-hexagonal/rules/preset-pr-checklist.md +2 -2
  162. package/presets/mavis/php-laravel/MAVIS.md +10 -1
  163. package/presets/mavis/php-laravel/REPO_AGENTS.md +1 -1
  164. package/presets/mavis/php-laravel/adapter-map.json +1 -1
  165. package/presets/mavis/php-laravel/rules/preset-pr-checklist.md +2 -2
  166. package/presets/mavis/platform-contract.json +4 -4
  167. package/presets/mavis/svelte/MAVIS.md +10 -1
  168. package/presets/mavis/svelte/REPO_AGENTS.md +1 -1
  169. package/presets/mavis/svelte/adapter-map.json +1 -1
  170. package/presets/mavis/svelte/rules/preset-pr-checklist.md +2 -2
  171. package/presets/opencode/README.md +1 -1
  172. package/presets/opencode/android-kotlin/OPENCODE.md +8 -1
  173. package/presets/opencode/android-kotlin/REPO_AGENTS.md +1 -1
  174. package/presets/opencode/android-kotlin/adapter-map.json +1 -1
  175. package/presets/opencode/android-kotlin/rules/preset-pr-checklist.md +2 -2
  176. package/presets/opencode/go/OPENCODE.md +8 -1
  177. package/presets/opencode/go/REPO_AGENTS.md +1 -1
  178. package/presets/opencode/go/adapter-map.json +1 -1
  179. package/presets/opencode/go/rules/preset-pr-checklist.md +2 -2
  180. package/presets/opencode/ios-swift/OPENCODE.md +8 -1
  181. package/presets/opencode/ios-swift/REPO_AGENTS.md +1 -1
  182. package/presets/opencode/ios-swift/adapter-map.json +1 -1
  183. package/presets/opencode/ios-swift/rules/preset-pr-checklist.md +2 -2
  184. package/presets/opencode/java/OPENCODE.md +8 -1
  185. package/presets/opencode/java/REPO_AGENTS.md +1 -1
  186. package/presets/opencode/java/adapter-map.json +1 -1
  187. package/presets/opencode/java/rules/preset-pr-checklist.md +2 -2
  188. package/presets/opencode/mcp-ts/OPENCODE.md +8 -1
  189. package/presets/opencode/mcp-ts/REPO_AGENTS.md +1 -1
  190. package/presets/opencode/mcp-ts/adapter-map.json +1 -1
  191. package/presets/opencode/mcp-ts/rules/preset-pr-checklist.md +2 -2
  192. package/presets/opencode/next/OPENCODE.md +8 -1
  193. package/presets/opencode/next/REPO_AGENTS.md +1 -1
  194. package/presets/opencode/next/adapter-map.json +1 -1
  195. package/presets/opencode/next/rules/preset-pr-checklist.md +2 -2
  196. package/presets/opencode/nuxt/OPENCODE.md +8 -1
  197. package/presets/opencode/nuxt/REPO_AGENTS.md +1 -1
  198. package/presets/opencode/nuxt/adapter-map.json +1 -1
  199. package/presets/opencode/nuxt/rules/preset-pr-checklist.md +2 -2
  200. package/presets/opencode/php-hexagonal/OPENCODE.md +8 -1
  201. package/presets/opencode/php-hexagonal/REPO_AGENTS.md +1 -1
  202. package/presets/opencode/php-hexagonal/adapter-map.json +1 -1
  203. package/presets/opencode/php-hexagonal/rules/preset-pr-checklist.md +2 -2
  204. package/presets/opencode/php-laravel/OPENCODE.md +8 -1
  205. package/presets/opencode/php-laravel/REPO_AGENTS.md +1 -1
  206. package/presets/opencode/php-laravel/adapter-map.json +1 -1
  207. package/presets/opencode/php-laravel/rules/preset-pr-checklist.md +2 -2
  208. package/presets/opencode/platform-contract.json +1 -1
  209. package/presets/opencode/svelte/OPENCODE.md +8 -1
  210. package/presets/opencode/svelte/REPO_AGENTS.md +1 -1
  211. package/presets/opencode/svelte/adapter-map.json +1 -1
  212. package/presets/opencode/svelte/rules/preset-pr-checklist.md +2 -2
  213. package/scripts/check-local-overlay.sh +40 -4
  214. package/scripts/check-mavis-local-overlay.mjs +23 -0
  215. package/scripts/check-mavis-platform-contract.mjs +5 -2
  216. package/scripts/check-opencode-local-overlay.mjs +19 -0
  217. package/scripts/check-opencode-platform-contract.mjs +5 -2
  218. package/scripts/check-preset-token-budget.sh +7 -0
  219. package/scripts/fixtures/cli-golden/claude/next.json +10 -10
  220. package/scripts/fixtures/cli-golden/cursor/next.json +2 -2
  221. package/scripts/fixtures/cli-golden/mavis/android-kotlin.json +3 -3
  222. package/scripts/fixtures/cli-golden/mavis/go.json +3 -3
  223. package/scripts/fixtures/cli-golden/mavis/ios-swift.json +3 -3
  224. package/scripts/fixtures/cli-golden/mavis/java.json +3 -3
  225. package/scripts/fixtures/cli-golden/mavis/mcp-ts.json +3 -3
  226. package/scripts/fixtures/cli-golden/mavis/next.json +3 -3
  227. package/scripts/fixtures/cli-golden/mavis/nuxt.json +3 -3
  228. package/scripts/fixtures/cli-golden/mavis/php-hexagonal.json +3 -3
  229. package/scripts/fixtures/cli-golden/mavis/php-laravel.json +3 -3
  230. package/scripts/fixtures/cli-golden/mavis/svelte.json +3 -3
  231. package/scripts/fixtures/cli-golden/opencode/android-kotlin.json +3 -3
  232. package/scripts/fixtures/cli-golden/opencode/go.json +3 -3
  233. package/scripts/fixtures/cli-golden/opencode/ios-swift.json +3 -3
  234. package/scripts/fixtures/cli-golden/opencode/java.json +3 -3
  235. package/scripts/fixtures/cli-golden/opencode/mcp-ts.json +3 -3
  236. package/scripts/fixtures/cli-golden/opencode/next.json +3 -3
  237. package/scripts/fixtures/cli-golden/opencode/nuxt.json +3 -3
  238. package/scripts/fixtures/cli-golden/opencode/php-hexagonal.json +3 -3
  239. package/scripts/fixtures/cli-golden/opencode/php-laravel.json +3 -3
  240. package/scripts/fixtures/cli-golden/opencode/svelte.json +3 -3
  241. package/scripts/lib/generate-mavis-adapter.mjs +10 -1
  242. package/scripts/lib/generate-opencode-adapter.mjs +8 -1
  243. package/scripts/sync-claude-settings.mjs +25 -0
  244. package/scripts/sync-dogfood-claude.sh +62 -0
  245. package/scripts/test-mavis-orchestration.mjs +3 -2
@@ -69,4 +69,4 @@ A `.ai.local/` directory MAY exist at the repo root or at any nesting depth in m
69
69
 
70
70
  Plain markdown rules under `.ai.local/rules/*.md` are read by the agent with higher priority than preset rules. Living gotchas live in `.ai.local/conventions.md`.
71
71
 
72
- Authoring guide: `docs/LOCAL-OVERLAY.md` in the `@bonesofspring/ai-rules` package. The `ai-local-overlay` rule (always-on for Cursor, on-demand for Claude) is the mechanism; this `MANDATORY` section is the reinforcement.
72
+ On every turn, probe `ls -la .ai.local`, apply `.ai.local/rules/*.md` and `.ai.local/conventions.md`, and acknowledge `Using .ai.local: <rule-name>`. Authoring guide: `docs/LOCAL-OVERLAY.md` in the `@bonesofspring/ai-rules` package. The `ai-local-overlay` rule is always-on on Cursor and session-start on Claude (no `paths:`). Mavis and OpenCode have no native `alwaysApply`; this section plus the platform entry's essential-rules list is the reinforcement.
@@ -5,12 +5,13 @@
5
5
  | `chain-team-phases.sh` | Pipeline chaining after subagent stop (`TEAM_ROOT=.ai.local/team`) |
6
6
  | `guard-shell-command.sh` | Destructive git / package-manager guard; **allows** `xcodebuild` / `simctl` / `xcrun` |
7
7
 
8
- Claude Code may not use Cursor `hooks.json`. Wire scripts per project docs when enabling agent-team auto-chain.
8
+ No `hooks.json`. Default chain and shell guard are registered in `.claude/settings.json` (see **Shipped wiring**). Cookbook scripts in `hooks/examples/` stay unwired; keep stack-safe recipes (this preset: **ios-swift**).
9
9
 
10
- **No `hooks.json` in Claude preset** (platform limit — same as next Claude).
10
+ ## Shipped wiring (Claude Code settings)
11
11
 
12
- ## Optional cookbook
12
+ `.claude/settings.json` `hooks` (https://code.claude.com/docs/en/hooks) registers:
13
13
 
14
- Example scripts live in `hooks/examples/` (secret-guard, format-edited, test-on-save). They are **not** auto-enabled.
14
+ - `PreToolUse` matcher `Bash` → `guard-shell-command.sh` (reads `tool_input.command`; emits `permissionDecision` `ask` or `allow`)
15
+ - `SubagentStop` → `chain-team-phases.sh` (kebab-case `agent_type` maps to `status: completed`; empty or non-kebab types are ignored; `stop_hook_active` does not recurse)
15
16
 
16
- To wire in Claude Code: copy an `.example.sh` into `hooks/`, make executable, and register per [Claude Code hooks](https://code.claude.com/docs/en/hooks) for your project. Keep stack-safe recipes (this preset: **ios-swift**). Cursor twin examples under `presets/cursor/ios-swift/hooks/examples/` are the same allowlist forks.
17
+ There is no `hooks.json`. Cookbook scripts under `hooks/examples/` stay unwired. A hook crash is not a deny (Cursor `failClosed` has no Claude field); `ask` is the supported review decision.
@@ -21,6 +21,24 @@ try {
21
21
  process.exit(0);
22
22
  }
23
23
 
24
+ // Claude Code SubagentStop has hook_event_name / agent_type / stop_hook_active, not status.
25
+ // Kebab-case agent_type (preset roles) is the completed signal. Empty or non-kebab
26
+ // types (Claude internal agents) do not advance the pipeline. stop_hook_active
27
+ // means this hook already continued the turn — do not recurse.
28
+ // Manual pipes of {"status":"completed"} skip this block.
29
+ if (hookInput.hook_event_name === 'SubagentStop') {
30
+ if (hookInput.stop_hook_active === true) {
31
+ process.stdout.write('{}');
32
+ process.exit(0);
33
+ }
34
+ const agentType = typeof hookInput.agent_type === 'string' ? hookInput.agent_type : '';
35
+ if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(agentType)) {
36
+ process.stdout.write('{}');
37
+ process.exit(0);
38
+ }
39
+ if (hookInput.status == null) hookInput.status = 'completed';
40
+ }
41
+
24
42
  if (hookInput.status !== 'completed') {
25
43
  process.stdout.write('{}');
26
44
  process.exit(0);
@@ -10,6 +10,8 @@ Optional scripts under `hooks/examples/`. **Not** referenced from default `hooks
10
10
 
11
11
  ## Wiring (Claude Code)
12
12
 
13
+ Default `.claude/settings.json` already registers `guard-shell-command.sh` on `PreToolUse` (matcher `Bash`) and `chain-team-phases.sh` on `SubagentStop`. Cookbook scripts are not in that default set.
14
+
13
15
  Claude Code has no preset `hooks.json`; hooks are registered in `.claude/settings.json` and fire on events such as `PreToolUse`, `PostToolUse`, and `Stop`.
14
16
 
15
17
  1. Copy an example into `hooks/` (drop `.example` suffix), e.g. `cp hooks/examples/secret-guard.example.sh hooks/secret-guard.sh`.
@@ -19,20 +19,43 @@ try {
19
19
  process.exit(0);
20
20
  }
21
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
- }
22
+ const claudePreTool = event.hook_event_name === 'PreToolUse';
23
+ const command = String(
24
+ event.command
25
+ || (event.input && event.input.command)
26
+ || (event.tool_input && event.tool_input.command)
27
+ || '',
28
+ );
27
29
 
28
- function out(permission, userMessage, agentMessage) {
30
+ function out(permission, userMessage) {
31
+ if (claudePreTool) {
32
+ const decision = permission === 'ask' || permission === 'deny' ? permission : 'allow';
33
+ const hookSpecificOutput = {
34
+ hookEventName: 'PreToolUse',
35
+ permissionDecision: decision,
36
+ };
37
+ if (userMessage && decision !== 'allow') {
38
+ hookSpecificOutput.permissionDecisionReason = userMessage;
39
+ }
40
+ process.stdout.write(JSON.stringify({ hookSpecificOutput }));
41
+ return;
42
+ }
43
+ if (!userMessage) {
44
+ process.stdout.write('{ "permission": "allow" }');
45
+ return;
46
+ }
29
47
  process.stdout.write(JSON.stringify({
30
48
  permission,
31
49
  user_message: userMessage,
32
- agent_message: agentMessage || userMessage,
50
+ agent_message: userMessage,
33
51
  }));
34
52
  }
35
53
 
54
+ if (!command.trim()) {
55
+ out('allow');
56
+ process.exit(0);
57
+ }
58
+
36
59
  const dangerousGit = /\bgit\s+(reset\s+--hard|clean\s+-[^\n]*f|push\s+--force|push\s+-f|checkout\s+--\s+)/;
37
60
  if (dangerousGit.test(command)) {
38
61
  out(
@@ -61,7 +84,7 @@ if (!expected && fs.existsSync('package.json')) {
61
84
  }
62
85
 
63
86
  if (!expected) {
64
- process.stdout.write('{ "permission": "allow" }');
87
+ out('allow');
65
88
  process.exit(0);
66
89
  }
67
90
 
@@ -75,5 +98,5 @@ if (used && used !== expected) {
75
98
  process.exit(0);
76
99
  }
77
100
 
78
- process.stdout.write('{ "permission": "allow" }');
101
+ out('allow');
79
102
  NODE
@@ -13,7 +13,7 @@ In Claude Code all `.md` files under `rules/` are **discovered recursively**. Bo
13
13
 
14
14
  ## Loading budget
15
15
 
16
- - **Session-start (no `paths:`):** 3–5 — `ios-app-core`, `boundaries`, `code-quality` (≤200 body lines total)
16
+ - **Session-start (no `paths:`):** 3–5 — `ios-app-core`, `boundaries`, `code-quality` (≤200 body lines total), `ai-local-overlay`
17
17
  - **Everything else** — with `paths:` (commands/team/agents and/or Feature/Swift globs)
18
18
  - **Soft twin depth:** domain rules ≥15 body lines; thin aliases (`agent-team-intake`, `technical-retro`) may be shorter (as in next)
19
19
 
@@ -1,10 +1,5 @@
1
1
  ---
2
2
  description: Local overlay from .ai.local/ (consumer-owned rules with priority over preset rules) — MANDATORY
3
- paths:
4
- - "**/.ai.local/**"
5
- - "**/AGENTS.md"
6
- - "**/CLAUDE.md"
7
- alwaysApply: false
8
3
  impact: CRITICAL
9
4
  ---
10
5
 
@@ -30,7 +30,7 @@ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.curso
30
30
  - [ ] **README:** stack `rules/README.md` core→stack mapping / catalog updated if stems added
31
31
  - [ ] **CHANGELOG / package README:** note when public preset paths or install surface change
32
32
  - [ ] **i18n anchors:** kept-marked Cyrillic fragments in `tests-unit.md(c)` stay consistent with their English counterparts. Run `packages/ai-rules/scripts/check-preset-i18n.sh`.
33
- - [ ] **Dogfood:** run `packages/ai-rules/scripts/sync-dogfood-cursor.sh` (and `sync-dogfood-mavis.sh` / `sync-dogfood-opencode.sh` when those platforms changed), or document an intentional skip, when maintaining this monorepo
33
+ - [ ] **Dogfood:** run `packages/ai-rules/scripts/sync-dogfood-cursor.sh`, `sync-dogfood-claude.sh`, `sync-dogfood-mavis.sh`, and `sync-dogfood-opencode.sh` when those platforms changed, or document an intentional skip, when maintaining this monorepo
34
34
  - [ ] **shared-core drift:** for embed-mode stems, run `packages/ai-rules/scripts/check-shared-core-drift.sh` (or document intentional fork)
35
35
 
36
36
  ## Pointers
@@ -40,6 +40,6 @@ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.curso
40
40
  - Budget: `preset-token-budget`
41
41
  - Leakage: `preset-no-cross-stack-leakage`
42
42
  - Validation: stack `agents/build-verifier.md` → preset-structure section
43
- - Dogfood scripts: `packages/ai-rules/scripts/sync-dogfood-cursor.sh`, `sync-dogfood-mavis.sh`, `sync-dogfood-opencode.sh`
43
+ - Dogfood scripts: `packages/ai-rules/scripts/sync-dogfood-cursor.sh`, `sync-dogfood-claude.sh`, `sync-dogfood-mavis.sh`, `sync-dogfood-opencode.sh`
44
44
  - Drift script: `packages/ai-rules/scripts/check-shared-core-drift.sh`
45
45
  - Orchestrator: when editing presets, load this checklist + twin-sync
@@ -6,5 +6,28 @@
6
6
  "Bash(git push *)"
7
7
  ],
8
8
  "ask": []
9
+ },
10
+ "hooks": {
11
+ "PreToolUse": [
12
+ {
13
+ "matcher": "Bash",
14
+ "hooks": [
15
+ {
16
+ "type": "command",
17
+ "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard-shell-command.sh"
18
+ }
19
+ ]
20
+ }
21
+ ],
22
+ "SubagentStop": [
23
+ {
24
+ "hooks": [
25
+ {
26
+ "type": "command",
27
+ "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/chain-team-phases.sh"
28
+ }
29
+ ]
30
+ }
31
+ ]
9
32
  }
10
33
  }
@@ -4,7 +4,8 @@ Preset for Java backends using ports & adapters (Spring Boot default).
4
4
 
5
5
  **Repo-root agents:** see [`AGENTS.md`](../../AGENTS.md) at the project root.
6
6
 
7
- - Session-start: `java-app-core`, `architecture/boundaries`, `code-quality` (3–5).
7
+ - Session-start: `java-app-core`, `architecture/boundaries`, `code-quality`, `ai-local-overlay` (3–5).
8
+ - **Local overlay (session-start):** `ai-local-overlay` has no `paths:` and counts in the 3–5 budget. On every turn, probe `ls -la .ai.local`, apply `.ai.local/rules/*.md` and `.ai.local/conventions.md`, and acknowledge `Using .ai.local: <rule-name>`. Guide: `docs/LOCAL-OVERLAY.md`.
8
9
  - Delivery: `architecture/feature-delivery.md` + skill `feature-delivery`.
9
10
  - After Java edits: `tooling-and-review/post-change-test.md` (+ `java-tooling`).
10
11
  - Integration tests: agents `integration-test-*` + skill `integration-testing` (never Playwright/XCUITest).
@@ -39,3 +40,4 @@ Init: `npx @bonesofspring/ai-rules init claude --preset java` (also copies `REPO
39
40
  `git commit/push deny`; JS stacks also `npx jest* deny` and `npm/npx/pnpm/bun`
40
41
  ask). Re-init overwrites the file (consumer can edit afterwards); mirror
41
42
  with root `AGENTS.md` if you change the harness.
43
+ - **Pipeline hooks:** `.claude/settings.json` `hooks` wires `guard-shell-command.sh` (`PreToolUse` / `Bash`, `permissionDecision` `ask` or `allow`) and `chain-team-phases.sh` (`SubagentStop` for kebab-case `agent_type`). See `hooks/README.md`. No `hooks.json`.
@@ -69,4 +69,4 @@ A `.ai.local/` directory MAY exist at the repo root or at any nesting depth in m
69
69
 
70
70
  Plain markdown rules under `.ai.local/rules/*.md` are read by the agent with higher priority than preset rules. Living gotchas live in `.ai.local/conventions.md`.
71
71
 
72
- Authoring guide: `docs/LOCAL-OVERLAY.md` in the `@bonesofspring/ai-rules` package. The `ai-local-overlay` rule (always-on for Cursor, on-demand for Claude) is the mechanism; this `MANDATORY` section is the reinforcement.
72
+ On every turn, probe `ls -la .ai.local`, apply `.ai.local/rules/*.md` and `.ai.local/conventions.md`, and acknowledge `Using .ai.local: <rule-name>`. Authoring guide: `docs/LOCAL-OVERLAY.md` in the `@bonesofspring/ai-rules` package. The `ai-local-overlay` rule is always-on on Cursor and session-start on Claude (no `paths:`). Mavis and OpenCode have no native `alwaysApply`; this section plus the platform entry's essential-rules list is the reinforcement.
@@ -5,12 +5,13 @@
5
5
  | `chain-team-phases.sh` | Pipeline chaining after subagent stop (`TEAM_ROOT=.ai.local/team`) |
6
6
  | `guard-shell-command.sh` | Destructive git / JS package-manager guard; **allows** `mvn test / ./gradlew test` / `compiler/IDE inspections` / `configured static analysis` / `repo static analysis` |
7
7
 
8
- Claude Code may not use Cursor `hooks.json`. Wire scripts per project docs when enabling agent-team auto-chain.
8
+ No `hooks.json`. Default chain and shell guard are registered in `.claude/settings.json` (see **Shipped wiring**). Cookbook scripts in `hooks/examples/` stay unwired; keep stack-safe recipes (this preset: **java**).
9
9
 
10
- **No `hooks.json` in Claude preset** (platform limit — same as next Claude).
10
+ ## Shipped wiring (Claude Code settings)
11
11
 
12
- ## Optional cookbook
12
+ `.claude/settings.json` `hooks` (https://code.claude.com/docs/en/hooks) registers:
13
13
 
14
- Example scripts live in `hooks/examples/` (secret-guard, format-edited, test-on-save). They are **not** auto-enabled.
14
+ - `PreToolUse` matcher `Bash` → `guard-shell-command.sh` (reads `tool_input.command`; emits `permissionDecision` `ask` or `allow`)
15
+ - `SubagentStop` → `chain-team-phases.sh` (kebab-case `agent_type` maps to `status: completed`; empty or non-kebab types are ignored; `stop_hook_active` does not recurse)
15
16
 
16
- To wire in Claude Code: copy an `.example.sh` into `hooks/`, make executable, and register per [Claude Code hooks](https://code.claude.com/docs/en/hooks) for your project. Keep stack-safe recipes (this preset: **java**). Cursor twin examples under `presets/cursor/java/hooks/examples/` are the same allowlist forks.
17
+ There is no `hooks.json`. Cookbook scripts under `hooks/examples/` stay unwired. A hook crash is not a deny (Cursor `failClosed` has no Claude field); `ask` is the supported review decision.
@@ -22,6 +22,24 @@ try {
22
22
  process.exit(0);
23
23
  }
24
24
 
25
+ // Claude Code SubagentStop has hook_event_name / agent_type / stop_hook_active, not status.
26
+ // Kebab-case agent_type (preset roles) is the completed signal. Empty or non-kebab
27
+ // types (Claude internal agents) do not advance the pipeline. stop_hook_active
28
+ // means this hook already continued the turn — do not recurse.
29
+ // Manual pipes of {"status":"completed"} skip this block.
30
+ if (hookInput.hook_event_name === 'SubagentStop') {
31
+ if (hookInput.stop_hook_active === true) {
32
+ process.stdout.write('{}');
33
+ process.exit(0);
34
+ }
35
+ const agentType = typeof hookInput.agent_type === 'string' ? hookInput.agent_type : '';
36
+ if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(agentType)) {
37
+ process.stdout.write('{}');
38
+ process.exit(0);
39
+ }
40
+ if (hookInput.status == null) hookInput.status = 'completed';
41
+ }
42
+
25
43
  if (hookInput.status !== 'completed') {
26
44
  process.stdout.write('{}');
27
45
  process.exit(0);
@@ -10,6 +10,8 @@ Optional scripts under `hooks/examples/`. **Not** referenced from default `hooks
10
10
 
11
11
  ## Wiring (Claude Code)
12
12
 
13
+ Default `.claude/settings.json` already registers `guard-shell-command.sh` on `PreToolUse` (matcher `Bash`) and `chain-team-phases.sh` on `SubagentStop`. Cookbook scripts are not in that default set.
14
+
13
15
  Claude Code has no preset `hooks.json`; hooks are registered in `.claude/settings.json` and fire on events such as `PreToolUse`, `PostToolUse`, and `Stop`.
14
16
 
15
17
  1. Copy an example into `hooks/` (drop `.example` suffix), e.g. `cp hooks/examples/secret-guard.example.sh hooks/secret-guard.sh`.
@@ -20,20 +20,43 @@ try {
20
20
  process.exit(0);
21
21
  }
22
22
 
23
- const command = String(event.command || event.input?.command || '');
24
- if (!command.trim()) {
25
- process.stdout.write('{ "permission": "allow" }');
26
- process.exit(0);
27
- }
23
+ const claudePreTool = event.hook_event_name === 'PreToolUse';
24
+ const command = String(
25
+ event.command
26
+ || (event.input && event.input.command)
27
+ || (event.tool_input && event.tool_input.command)
28
+ || '',
29
+ );
28
30
 
29
- function out(permission, userMessage, agentMessage) {
31
+ function out(permission, userMessage) {
32
+ if (claudePreTool) {
33
+ const decision = permission === 'ask' || permission === 'deny' ? permission : 'allow';
34
+ const hookSpecificOutput = {
35
+ hookEventName: 'PreToolUse',
36
+ permissionDecision: decision,
37
+ };
38
+ if (userMessage && decision !== 'allow') {
39
+ hookSpecificOutput.permissionDecisionReason = userMessage;
40
+ }
41
+ process.stdout.write(JSON.stringify({ hookSpecificOutput }));
42
+ return;
43
+ }
44
+ if (!userMessage) {
45
+ process.stdout.write('{ "permission": "allow" }');
46
+ return;
47
+ }
30
48
  process.stdout.write(JSON.stringify({
31
49
  permission,
32
50
  user_message: userMessage,
33
- agent_message: agentMessage || userMessage,
51
+ agent_message: userMessage,
34
52
  }));
35
53
  }
36
54
 
55
+ if (!command.trim()) {
56
+ out('allow');
57
+ process.exit(0);
58
+ }
59
+
37
60
  const dangerousGit = /\bgit\s+(reset\s+--hard|clean\s+-[^\n]*f|push\s+--force|push\s+-f|checkout\s+--\s+)/;
38
61
  if (dangerousGit.test(command)) {
39
62
  out(
@@ -62,7 +85,7 @@ if (!expected && fs.existsSync('package.json')) {
62
85
  }
63
86
 
64
87
  if (!expected) {
65
- process.stdout.write('{ "permission": "allow" }');
88
+ out('allow');
66
89
  process.exit(0);
67
90
  }
68
91
 
@@ -76,5 +99,5 @@ if (used && used !== expected) {
76
99
  process.exit(0);
77
100
  }
78
101
 
79
- process.stdout.write('{ "permission": "allow" }');
102
+ out('allow');
80
103
  NODE
@@ -12,7 +12,7 @@ Claude topic `.md` files are **derived** from Cursor SoT `presets/cursor/java/ru
12
12
 
13
13
  ## Loading budget
14
14
 
15
- - **Session-start (no `paths:`):** 3–5 — `java-app-core`, `boundaries`, `code-quality`
15
+ - **Session-start (no `paths:`):** 3–5 — `java-app-core`, `boundaries`, `code-quality`, `ai-local-overlay`
16
16
  - All others — with `paths:`
17
17
  - **Twin depth:** domain rules target ≥15 body lines; thin aliases: `agent-team-intake`, `technical-retro`; **documented stub** (v1): `api-grpc`; `messaging-adapters` is **full** — see Cursor `presets/cursor/java/rules/README.md` Catalog (Depth column)
18
18
 
@@ -1,10 +1,5 @@
1
1
  ---
2
2
  description: Local overlay from .ai.local/ (consumer-owned rules with priority over preset rules) — MANDATORY
3
- paths:
4
- - "**/.ai.local/**"
5
- - "**/AGENTS.md"
6
- - "**/CLAUDE.md"
7
- alwaysApply: false
8
3
  impact: CRITICAL
9
4
  ---
10
5
 
@@ -30,7 +30,7 @@ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.curso
30
30
  - [ ] **README:** stack `rules/README.md` core→stack mapping / catalog updated if stems added
31
31
  - [ ] **CHANGELOG / package README:** note when public preset paths or install surface change
32
32
  - [ ] **i18n anchors:** kept-marked Cyrillic fragments in `tests-unit.md(c)` stay consistent with their English counterparts. Run `packages/ai-rules/scripts/check-preset-i18n.sh`.
33
- - [ ] **Dogfood:** run `packages/ai-rules/scripts/sync-dogfood-cursor.sh` (and `sync-dogfood-mavis.sh` / `sync-dogfood-opencode.sh` when those platforms changed), or document an intentional skip, when maintaining this monorepo
33
+ - [ ] **Dogfood:** run `packages/ai-rules/scripts/sync-dogfood-cursor.sh`, `sync-dogfood-claude.sh`, `sync-dogfood-mavis.sh`, and `sync-dogfood-opencode.sh` when those platforms changed, or document an intentional skip, when maintaining this monorepo
34
34
  - [ ] **shared-core drift:** for embed-mode stems, run `packages/ai-rules/scripts/check-shared-core-drift.sh` (or document intentional fork)
35
35
 
36
36
  ## Pointers
@@ -40,6 +40,6 @@ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.curso
40
40
  - Budget: `preset-token-budget`
41
41
  - Leakage: `preset-no-cross-stack-leakage`
42
42
  - Validation: stack `agents/build-verifier.md` → preset-structure section
43
- - Dogfood scripts: `packages/ai-rules/scripts/sync-dogfood-cursor.sh`, `sync-dogfood-mavis.sh`, `sync-dogfood-opencode.sh`
43
+ - Dogfood scripts: `packages/ai-rules/scripts/sync-dogfood-cursor.sh`, `sync-dogfood-claude.sh`, `sync-dogfood-mavis.sh`, `sync-dogfood-opencode.sh`
44
44
  - Drift script: `packages/ai-rules/scripts/check-shared-core-drift.sh`
45
45
  - Orchestrator: when editing presets, load this checklist + twin-sync
@@ -6,5 +6,28 @@
6
6
  "Bash(git push *)"
7
7
  ],
8
8
  "ask": []
9
+ },
10
+ "hooks": {
11
+ "PreToolUse": [
12
+ {
13
+ "matcher": "Bash",
14
+ "hooks": [
15
+ {
16
+ "type": "command",
17
+ "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard-shell-command.sh"
18
+ }
19
+ ]
20
+ }
21
+ ],
22
+ "SubagentStop": [
23
+ {
24
+ "hooks": [
25
+ {
26
+ "type": "command",
27
+ "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/chain-team-phases.sh"
28
+ }
29
+ ]
30
+ }
31
+ ]
9
32
  }
10
33
  }
@@ -4,7 +4,8 @@ Preset for authoring TypeScript MCP servers with `@modelcontextprotocol/sdk`.
4
4
 
5
5
  **Repo-root agents:** see [`AGENTS.md`](../../AGENTS.md) at the project root.
6
6
 
7
- - Session-start: `mcp-ts-app-core`, `architecture/mcp-server-boundaries`, `code-quality` (3–5).
7
+ - Session-start: `mcp-ts-app-core`, `architecture/mcp-server-boundaries`, `code-quality`, `ai-local-overlay` (3–5).
8
+ - **Local overlay (session-start):** `ai-local-overlay` has no `paths:` and counts in the 3–5 budget. On every turn, probe `ls -la .ai.local`, apply `.ai.local/rules/*.md` and `.ai.local/conventions.md`, and acknowledge `Using .ai.local: <rule-name>`. Guide: `docs/LOCAL-OVERLAY.md`.
8
9
  - Delivery: `architecture/feature-delivery.md` + skill `feature-delivery`.
9
10
  - After TS edits: `tooling-and-review/post-change-test.md`.
10
11
  - Contract checks: `mcp-contract-testing` rule (Phase 1: feature-developer owns verification).
@@ -23,3 +24,4 @@ Init: `npx @bonesofspring/ai-rules init claude --preset mcp-ts` (also copies `RE
23
24
  `git commit/push deny`; JS stacks also `npx jest* deny` and `npm/npx/pnpm/bun`
24
25
  ask). Re-init overwrites the file (consumer can edit afterwards); mirror
25
26
  with root `AGENTS.md` if you change the harness.
27
+ - **Pipeline hooks:** `.claude/settings.json` `hooks` wires `guard-shell-command.sh` (`PreToolUse` / `Bash`, `permissionDecision` `ask` or `allow`) and `chain-team-phases.sh` (`SubagentStop` for kebab-case `agent_type`). See `hooks/README.md`. No `hooks.json`.
@@ -72,4 +72,4 @@ A `.ai.local/` directory MAY exist at the repo root or at any nesting depth in m
72
72
 
73
73
  Plain markdown rules under `.ai.local/rules/*.md` are read by the agent with higher priority than preset rules. Living gotchas live in `.ai.local/conventions.md`.
74
74
 
75
- Authoring guide: `docs/LOCAL-OVERLAY.md` in the `@bonesofspring/ai-rules` package. The `ai-local-overlay` rule (always-on for Cursor, on-demand for Claude) is the mechanism; this `MANDATORY` section is the reinforcement.
75
+ On every turn, probe `ls -la .ai.local`, apply `.ai.local/rules/*.md` and `.ai.local/conventions.md`, and acknowledge `Using .ai.local: <rule-name>`. Authoring guide: `docs/LOCAL-OVERLAY.md` in the `@bonesofspring/ai-rules` package. The `ai-local-overlay` rule is always-on on Cursor and session-start on Claude (no `paths:`). Mavis and OpenCode have no native `alwaysApply`; this section plus the platform entry's essential-rules list is the reinforcement.
@@ -5,8 +5,13 @@
5
5
  | `guard-shell-command.sh` | Destructive git / JS package-manager mismatch; allows npm/npx/node/tsc |
6
6
  | `chain-team-phases.sh` | Auto-chain pipeline steps on `subagentStop` (Phase 1: build-verifier, security-reviewer; **no** `contract-test-*`) |
7
7
 
8
- Claude: register hooks per Claude Code project conventions.
8
+ No `hooks.json`. Default chain and shell guard are registered in `.claude/settings.json` (see **Shipped wiring**). Cookbook scripts in `hooks/examples/` stay unwired.
9
9
 
10
- ## Optional cookbook
10
+ ## Shipped wiring (Claude Code settings)
11
11
 
12
- See `hooks/examples/README.md` — secret-guard / format-edited / test-on-save. **Not** in default `hooks.json`.
12
+ `.claude/settings.json` `hooks` (https://code.claude.com/docs/en/hooks) registers:
13
+
14
+ - `PreToolUse` matcher `Bash` → `guard-shell-command.sh` (reads `tool_input.command`; emits `permissionDecision` `ask` or `allow`)
15
+ - `SubagentStop` → `chain-team-phases.sh` (kebab-case `agent_type` maps to `status: completed`; empty or non-kebab types are ignored; `stop_hook_active` does not recurse)
16
+
17
+ There is no `hooks.json`. Cookbook scripts under `hooks/examples/` stay unwired. A hook crash is not a deny (Cursor `failClosed` has no Claude field); `ask` is the supported review decision.
@@ -23,6 +23,24 @@ try {
23
23
  process.exit(0);
24
24
  }
25
25
 
26
+ // Claude Code SubagentStop has hook_event_name / agent_type / stop_hook_active, not status.
27
+ // Kebab-case agent_type (preset roles) is the completed signal. Empty or non-kebab
28
+ // types (Claude internal agents) do not advance the pipeline. stop_hook_active
29
+ // means this hook already continued the turn — do not recurse.
30
+ // Manual pipes of {"status":"completed"} skip this block.
31
+ if (hookInput.hook_event_name === 'SubagentStop') {
32
+ if (hookInput.stop_hook_active === true) {
33
+ process.stdout.write('{}');
34
+ process.exit(0);
35
+ }
36
+ const agentType = typeof hookInput.agent_type === 'string' ? hookInput.agent_type : '';
37
+ if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(agentType)) {
38
+ process.stdout.write('{}');
39
+ process.exit(0);
40
+ }
41
+ if (hookInput.status == null) hookInput.status = 'completed';
42
+ }
43
+
26
44
  if (hookInput.status !== 'completed') {
27
45
  process.stdout.write('{}');
28
46
  process.exit(0);
@@ -9,3 +9,8 @@ Optional cookbook scripts — **not** wired into default `hooks.json`.
9
9
  | `test-on-save.example.sh` | Run scoped tests after edits |
10
10
 
11
11
  Adapt commands to the repository package manager (`mcp-ts-tooling`).
12
+
13
+
14
+ ## Wiring (Claude Code)
15
+
16
+ Default `.claude/settings.json` already registers `guard-shell-command.sh` on `PreToolUse` (matcher `Bash`) and `chain-team-phases.sh` on `SubagentStop`. The cookbook scripts above are not in that default set. There is no `hooks.json`.
@@ -19,20 +19,43 @@ try {
19
19
  process.exit(0);
20
20
  }
21
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
- }
22
+ const claudePreTool = event.hook_event_name === 'PreToolUse';
23
+ const command = String(
24
+ event.command
25
+ || (event.input && event.input.command)
26
+ || (event.tool_input && event.tool_input.command)
27
+ || '',
28
+ );
27
29
 
28
- function out(permission, userMessage, agentMessage) {
30
+ function out(permission, userMessage) {
31
+ if (claudePreTool) {
32
+ const decision = permission === 'ask' || permission === 'deny' ? permission : 'allow';
33
+ const hookSpecificOutput = {
34
+ hookEventName: 'PreToolUse',
35
+ permissionDecision: decision,
36
+ };
37
+ if (userMessage && decision !== 'allow') {
38
+ hookSpecificOutput.permissionDecisionReason = userMessage;
39
+ }
40
+ process.stdout.write(JSON.stringify({ hookSpecificOutput }));
41
+ return;
42
+ }
43
+ if (!userMessage) {
44
+ process.stdout.write('{ "permission": "allow" }');
45
+ return;
46
+ }
29
47
  process.stdout.write(JSON.stringify({
30
48
  permission,
31
49
  user_message: userMessage,
32
- agent_message: agentMessage || userMessage,
50
+ agent_message: userMessage,
33
51
  }));
34
52
  }
35
53
 
54
+ if (!command.trim()) {
55
+ out('allow');
56
+ process.exit(0);
57
+ }
58
+
36
59
  const dangerousGit = /\bgit\s+(reset\s+--hard|clean\s+-[^\n]*f|push\s+--force|push\s+-f|checkout\s+--\s+)/;
37
60
  if (dangerousGit.test(command)) {
38
61
  out(
@@ -61,7 +84,7 @@ if (!expected && fs.existsSync('package.json')) {
61
84
  }
62
85
 
63
86
  if (!expected) {
64
- process.stdout.write('{ "permission": "allow" }');
87
+ out('allow');
65
88
  process.exit(0);
66
89
  }
67
90
 
@@ -75,5 +98,5 @@ if (used && used !== expected) {
75
98
  process.exit(0);
76
99
  }
77
100
 
78
- process.stdout.write('{ "permission": "allow" }');
101
+ out('allow');
79
102
  NODE
@@ -12,7 +12,7 @@ Claude topic `.md` files are **derived** from Cursor SoT `presets/cursor/mcp-ts/
12
12
 
13
13
  ## Loading budget
14
14
 
15
- - **Session-start (no `paths:`):** 3–5 — `mcp-ts-app-core`, `mcp-server-boundaries`, `code-quality`
15
+ - **Session-start (no `paths:`):** 3–5 — `mcp-ts-app-core`, `mcp-server-boundaries`, `code-quality`, `ai-local-overlay`
16
16
  - All others — with `paths:`
17
17
  - **Twin depth:** domain rules target ≥15 body lines; thin aliases: `agent-team-intake`, `technical-retro`
18
18
 
@@ -1,10 +1,5 @@
1
1
  ---
2
2
  description: Local overlay from .ai.local/ (consumer-owned rules with priority over preset rules) — MANDATORY
3
- paths:
4
- - "**/.ai.local/**"
5
- - "**/AGENTS.md"
6
- - "**/CLAUDE.md"
7
- alwaysApply: false
8
3
  impact: CRITICAL
9
4
  ---
10
5
 
@@ -30,7 +30,7 @@ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.curso
30
30
  - [ ] **README:** stack `rules/README.md` core→stack mapping / catalog updated if stems added
31
31
  - [ ] **CHANGELOG / package README:** note when public preset paths or install surface change
32
32
  - [ ] **i18n anchors:** kept-marked Cyrillic fragments in `tests-unit.md(c)` stay consistent with their English counterparts. Run `packages/ai-rules/scripts/check-preset-i18n.sh`.
33
- - [ ] **Dogfood:** run `packages/ai-rules/scripts/sync-dogfood-cursor.sh` (and `sync-dogfood-mavis.sh` / `sync-dogfood-opencode.sh` when those platforms changed), or document an intentional skip, when maintaining this monorepo
33
+ - [ ] **Dogfood:** run `packages/ai-rules/scripts/sync-dogfood-cursor.sh`, `sync-dogfood-claude.sh`, `sync-dogfood-mavis.sh`, and `sync-dogfood-opencode.sh` when those platforms changed, or document an intentional skip, when maintaining this monorepo
34
34
  - [ ] **shared-core drift:** for embed-mode stems, run `packages/ai-rules/scripts/check-shared-core-drift.sh` (or document intentional fork)
35
35
 
36
36
  ## Pointers
@@ -40,6 +40,6 @@ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.curso
40
40
  - Budget: `preset-token-budget`
41
41
  - Leakage: `preset-no-cross-stack-leakage`
42
42
  - Validation: stack `agents/build-verifier.md` → preset-structure section
43
- - Dogfood scripts: `packages/ai-rules/scripts/sync-dogfood-cursor.sh`, `sync-dogfood-mavis.sh`, `sync-dogfood-opencode.sh`
43
+ - Dogfood scripts: `packages/ai-rules/scripts/sync-dogfood-cursor.sh`, `sync-dogfood-claude.sh`, `sync-dogfood-mavis.sh`, `sync-dogfood-opencode.sh`
44
44
  - Drift script: `packages/ai-rules/scripts/check-shared-core-drift.sh`
45
45
  - Orchestrator: when editing presets, load this checklist + twin-sync