add-coder 0.3.26 → 0.3.28

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 (323) hide show
  1. package/README.md +282 -155
  2. package/dist/index.js +481 -209
  3. package/package.json +15 -4
  4. package/templates/.add-coder-src-hash.json +186 -185
  5. package/templates/adapters/claude/hooks/doc-format-guard.ts +32 -0
  6. package/templates/adapters/claude/hooks/lib/claude-env.ts +7 -0
  7. package/templates/adapters/claude/hooks/notification.ts +24 -0
  8. package/templates/adapters/claude/hooks/permission-denied.ts +33 -0
  9. package/templates/adapters/claude/hooks/permission-gate.ts +12 -0
  10. package/templates/adapters/claude/hooks/post-tool-failure.ts +4 -0
  11. package/templates/adapters/claude/hooks/post-tool-use.ts +17 -0
  12. package/templates/adapters/claude/hooks/pre-compact.ts +10 -0
  13. package/templates/adapters/claude/hooks/pre-tool-use.ts +81 -0
  14. package/templates/adapters/claude/hooks/prompt-submit.ts +82 -0
  15. package/templates/adapters/claude/hooks/review-checklist.ts +4 -0
  16. package/templates/adapters/claude/hooks/session-end.ts +10 -0
  17. package/templates/adapters/claude/hooks/session-start.ts +24 -0
  18. package/templates/adapters/claude/hooks/stop-check.ts +15 -0
  19. package/templates/adapters/claude/hooks/stop-failure.ts +34 -0
  20. package/templates/adapters/claude/hooks/subagent-guard.ts +25 -0
  21. package/templates/adapters/claude/hooks/subagent-stop.ts +12 -0
  22. package/templates/adapters/claude/settings.json +13 -13
  23. package/templates/adapters/codex/config.toml.example +12 -0
  24. package/templates/adapters/codex/hooks/doc-format-guard.ts +30 -0
  25. package/templates/adapters/codex/hooks/notification.ts +26 -0
  26. package/templates/adapters/codex/hooks/permission-gate.ts +15 -0
  27. package/templates/adapters/codex/hooks/post-tool-failure.ts +14 -0
  28. package/templates/adapters/codex/hooks/post-tool-use.ts +85 -0
  29. package/templates/adapters/codex/hooks/pre-compact.ts +20 -0
  30. package/templates/adapters/codex/hooks/pre-tool-use.ts +141 -0
  31. package/templates/adapters/codex/hooks/prompt-submit.ts +38 -0
  32. package/templates/adapters/codex/hooks/review-checklist.ts +5 -0
  33. package/templates/adapters/codex/hooks/session-end.ts +19 -0
  34. package/templates/adapters/codex/hooks/session-start.ts +45 -0
  35. package/templates/adapters/codex/hooks/stop-check.ts +59 -0
  36. package/templates/adapters/codex/hooks/subagent-guard.ts +22 -0
  37. package/templates/adapters/codex/hooks/subagent-stop.ts +20 -0
  38. package/templates/adapters/codex/hooks.json +67 -1
  39. package/templates/adapters/qoder/hooks/doc-format-guard.ts +34 -0
  40. package/templates/adapters/qoder/hooks/lib/context-inject.ts +61 -0
  41. package/templates/adapters/qoder/hooks/lib/qoder-env.ts +23 -0
  42. package/templates/adapters/qoder/hooks/lib/review-checklist.ts +5 -0
  43. package/templates/adapters/qoder/hooks/notification.ts +34 -0
  44. package/templates/adapters/qoder/hooks/permission-gate.ts +26 -0
  45. package/templates/adapters/qoder/hooks/post-tool-failure.ts +30 -0
  46. package/templates/adapters/qoder/hooks/post-tool-use.ts +32 -0
  47. package/templates/adapters/qoder/hooks/pre-compact.ts +16 -0
  48. package/templates/adapters/qoder/hooks/pre-tool-use.ts +112 -0
  49. package/templates/adapters/qoder/hooks/prompt-submit.ts +66 -0
  50. package/templates/adapters/qoder/hooks/review-checklist.ts +24 -0
  51. package/templates/adapters/qoder/hooks/session-end.ts +27 -0
  52. package/templates/adapters/qoder/hooks/session-start.ts +83 -0
  53. package/templates/adapters/qoder/hooks/stop-check.ts +69 -0
  54. package/templates/adapters/qoder/hooks/subagent-guard.ts +16 -0
  55. package/templates/adapters/qoder/hooks/subagent-stop.ts +33 -0
  56. package/templates/adapters/qoder/settings.json +13 -13
  57. package/templates/adapters/trae/hooks/doc-format-guard.ts +30 -0
  58. package/templates/adapters/trae/hooks/notification.ts +22 -0
  59. package/templates/adapters/trae/hooks/permission-gate.ts +15 -0
  60. package/templates/adapters/trae/hooks/post-tool-failure.ts +14 -0
  61. package/templates/adapters/trae/hooks/post-tool-use.ts +24 -0
  62. package/templates/adapters/trae/hooks/pre-compact.ts +15 -0
  63. package/templates/adapters/trae/hooks/pre-tool-use.ts +40 -0
  64. package/templates/adapters/trae/hooks/prompt-submit.ts +29 -0
  65. package/templates/adapters/trae/hooks/review-checklist.ts +5 -0
  66. package/templates/adapters/trae/hooks/session-end.ts +16 -0
  67. package/templates/adapters/trae/hooks/session-start.ts +15 -0
  68. package/templates/adapters/trae/hooks/stop-check.ts +20 -0
  69. package/templates/adapters/trae/hooks/subagent-guard.ts +22 -0
  70. package/templates/adapters/trae/hooks/subagent-stop.ts +15 -0
  71. package/templates/adapters/trae/hooks.json +1 -1
  72. package/templates/adapters/vscode/hooks/doc-format-guard.ts +27 -0
  73. package/templates/adapters/vscode/hooks/notification.ts +22 -0
  74. package/templates/adapters/vscode/hooks/permission-gate.ts +15 -0
  75. package/templates/adapters/vscode/hooks/post-tool-failure.ts +32 -0
  76. package/templates/adapters/vscode/hooks/post-tool-use.ts +25 -0
  77. package/templates/adapters/vscode/hooks/pre-compact.ts +15 -0
  78. package/templates/adapters/vscode/hooks/pre-tool-use.ts +78 -0
  79. package/templates/adapters/vscode/hooks/prompt-submit.ts +74 -0
  80. package/templates/adapters/vscode/hooks/review-checklist.ts +5 -0
  81. package/templates/adapters/vscode/hooks/session-end.ts +16 -0
  82. package/templates/adapters/vscode/hooks/session-start.ts +24 -0
  83. package/templates/adapters/vscode/hooks/stop-check.ts +21 -0
  84. package/templates/adapters/vscode/hooks/subagent-guard.ts +21 -0
  85. package/templates/adapters/vscode/hooks/subagent-stop.ts +15 -0
  86. package/templates/core/docs/ADD-governance-claude-code.md +4 -4
  87. package/templates/core/docs/ADD-governance-codex.md +6 -6
  88. package/templates/core/docs/ADD-governance-qoder-cn.md +5 -5
  89. package/templates/core/docs/ADD-governance-trae.md +3 -3
  90. package/templates/core/docs/ADD-governance-vscode-copilot.md +22 -23
  91. package/templates/core/governance/audit-bridge.ts +47 -0
  92. package/templates/core/governance/common.ts +299 -0
  93. package/templates/core/governance/context-inject.ts +53 -0
  94. package/templates/core/governance/doc-format-guard.ts +440 -0
  95. package/templates/core/governance/notification-router.ts +62 -0
  96. package/templates/core/governance/notify.ts +66 -0
  97. package/templates/core/governance/permission-gate-router.ts +42 -0
  98. package/templates/core/governance/post-tool-failure-router.ts +56 -0
  99. package/templates/core/governance/post-tool-router.ts +212 -0
  100. package/templates/core/governance/pre-compact-guard.ts +41 -0
  101. package/templates/core/governance/pre-tool-guard.ts +309 -0
  102. package/templates/core/governance/preload-templates.ts +241 -0
  103. package/templates/core/governance/prompt-router.ts +222 -0
  104. package/templates/core/governance/review-checklist-guard.ts +186 -0
  105. package/templates/core/governance/rules.ts +720 -0
  106. package/templates/core/governance/session-end.ts +88 -0
  107. package/templates/core/governance/session-start-guard.ts +99 -0
  108. package/templates/core/governance/state-detect.ts +6 -0
  109. package/templates/core/governance/stop-router.ts +140 -0
  110. package/templates/core/governance/subagent-guard-router.ts +35 -0
  111. package/templates/core/governance/subagent-stop-router.ts +93 -0
  112. package/templates/core/governance/subagent-stop.ts +75 -0
  113. package/templates/core/governance/vocabulary.ts +109 -0
  114. package/templates/core/hooks/doc-format-guard.ts +21 -0
  115. package/templates/core/hooks/notification.ts +11 -0
  116. package/templates/core/hooks/permission-gate.ts +7 -0
  117. package/templates/core/hooks/post-tool-failure.ts +7 -0
  118. package/templates/core/hooks/post-tool-use.ts +23 -0
  119. package/templates/core/hooks/pre-compact.ts +9 -0
  120. package/templates/core/hooks/pre-tool-use.ts +30 -0
  121. package/templates/core/hooks/prompt-submit.ts +11 -0
  122. package/templates/core/hooks/review-checklist.ts +4 -0
  123. package/templates/core/hooks/session-end.ts +10 -0
  124. package/templates/core/hooks/session-start.ts +9 -0
  125. package/templates/core/hooks/stop-check.ts +14 -0
  126. package/templates/core/hooks/subagent-guard.ts +8 -0
  127. package/templates/core/hooks/subagent-stop.ts +9 -0
  128. package/templates/core/prisma/add.prisma +140 -82
  129. package/templates/core/rules/project_rules.md +27 -24
  130. package/templates/core/scripts/db-ensure.sh +8 -0
  131. package/templates/core/scripts/gen-plan-index.sh +4 -15
  132. package/templates/core/scripts/mcp-server/notifications/hitl.ts +9 -1
  133. package/templates/core/scripts/mcp-server/notifications/hook.ts +25 -9
  134. package/templates/core/scripts/mcp-server/resources/hitl-approval-widget.ts +34 -0
  135. package/templates/core/scripts/mcp-server/resources/hook-events-report.ts +14 -2
  136. package/templates/core/scripts/mcp-server/resources/index.ts +2 -0
  137. package/templates/core/scripts/mcp-server/sampling/review.ts +25 -10
  138. package/templates/core/scripts/mcp-server/shared/db-types.ts +33 -8
  139. package/templates/core/scripts/mcp-server/shared/dps-scoring.strategy.ts +1 -1
  140. package/templates/core/scripts/mcp-server/shared/env.ts +28 -8
  141. package/templates/core/scripts/mcp-server/shared/fs.ts +3 -0
  142. package/templates/core/scripts/mcp-server/shared/hitl-interaction.strategy.ts +2 -3
  143. package/templates/core/scripts/mcp-server/shared/hitl-lifecycle-mutation.ts +129 -0
  144. package/templates/core/scripts/mcp-server/shared/hitl-proposal-mutation.ts +98 -0
  145. package/templates/core/scripts/mcp-server/shared/hitl-ui.ts +3 -0
  146. package/templates/core/scripts/mcp-server/shared/plan-lifecycle-events.ts +62 -0
  147. package/templates/core/scripts/mcp-server/shared/plan-lifecycle-mutation.ts +78 -0
  148. package/templates/core/scripts/mcp-server/shared/plan-lifecycle-subscriber.ts +145 -0
  149. package/templates/core/scripts/mcp-server/shared/plan-lifecycle.ts +153 -0
  150. package/templates/core/scripts/mcp-server/shared/plan-round-events.ts +56 -0
  151. package/templates/core/scripts/mcp-server/shared/plan-round-mutation.ts +143 -0
  152. package/templates/core/scripts/mcp-server/shared/plan-round-store.ts +47 -0
  153. package/templates/core/scripts/mcp-server/shared/plan-round-subscriber.ts +99 -0
  154. package/templates/core/scripts/mcp-server/shared/plan-status-store.ts +37 -0
  155. package/templates/core/scripts/mcp-server/shared/plan-tracking-mutation.ts +71 -0
  156. package/templates/core/scripts/mcp-server/shared/prisma.ts +12 -6
  157. package/templates/core/scripts/mcp-server/shared/project-root-strategy.ts +1 -2
  158. package/templates/core/scripts/mcp-server/shared/quant-recheck.strategy.ts +16 -0
  159. package/templates/core/scripts/mcp-server/shared/redact.ts +28 -0
  160. package/templates/core/scripts/mcp-server/shared/response.ts +3 -2
  161. package/templates/core/scripts/mcp-server/shared/runtime-context.ts +77 -0
  162. package/templates/core/scripts/mcp-server/shared/schema-topology.ts +159 -0
  163. package/templates/core/scripts/mcp-server/tools/audit.ts +49 -7
  164. package/templates/core/scripts/mcp-server/tools/context.ts +117 -121
  165. package/templates/core/scripts/mcp-server/tools/contract.ts +34 -9
  166. package/templates/core/scripts/mcp-server/tools/gateway/check_add_route_status.ts +50 -3
  167. package/templates/core/scripts/mcp-server/tools/gateway/check_doc_similarity.ts +218 -0
  168. package/templates/core/scripts/mcp-server/tools/gateway/check_dps.ts +22 -7
  169. package/templates/core/scripts/mcp-server/tools/gateway/check_rahs.ts +86 -4
  170. package/templates/core/scripts/mcp-server/tools/gateway/check_spec_sync.ts +19 -6
  171. package/templates/core/scripts/mcp-server/tools/gateway/index.ts +2 -0
  172. package/templates/core/scripts/mcp-server/tools/hitl.ts +160 -75
  173. package/templates/core/scripts/mcp-server/tools/hook-event-report.ts +9 -2
  174. package/templates/core/scripts/mcp-server/tools/index.ts +69 -3
  175. package/templates/core/scripts/mcp-server/tools/plan.ts +152 -17
  176. package/templates/core/scripts/mcp-server/tools/review.ts +44 -15
  177. package/templates/core/scripts/mcp-server.ts +60 -1
  178. package/templates/core/scripts/plan-status-bridge.ts +26 -0
  179. package/templates/core/skills/add-paradigm/SKILL.md +2 -2
  180. package/templates/core/templates/add-route-template.schema.json +24 -56
  181. package/templates/core/templates/collab-contract-template.md +1 -1
  182. package/templates/core/templates/handoff-multi-round-template.schema.json +48 -0
  183. package/templates/core/templates/handoff-single-round-template.schema.json +92 -0
  184. package/templates/core/templates/handoff-single-round.schema.json +1 -1
  185. package/templates/core/templates/hitl-approval-widget.html +222 -37
  186. package/templates/core/templates/spec-template.schema.json +9 -46
  187. package/templates/core/templates/standard-plan-template.schema.json +1 -1
  188. package/templates/core/templates/tasks-template.schema.json +13 -54
  189. package/templates/adapters/claude/hooks/doc-format-guard.sh +0 -202
  190. package/templates/adapters/claude/hooks/lib/common.sh +0 -261
  191. package/templates/adapters/claude/hooks/lib/context-inject.sh +0 -96
  192. package/templates/adapters/claude/hooks/lib/notify.sh +0 -34
  193. package/templates/adapters/claude/hooks/lib/preload-templates.sh +0 -187
  194. package/templates/adapters/claude/hooks/lib/session-end.sh +0 -76
  195. package/templates/adapters/claude/hooks/lib/state-detect.sh +0 -117
  196. package/templates/adapters/claude/hooks/lib/subagent-stop.sh +0 -90
  197. package/templates/adapters/claude/hooks/lib/vocabulary.sh +0 -56
  198. package/templates/adapters/claude/hooks/notification.sh +0 -45
  199. package/templates/adapters/claude/hooks/permission-denied.sh +0 -42
  200. package/templates/adapters/claude/hooks/permission-gate.sh +0 -18
  201. package/templates/adapters/claude/hooks/post-tool-failure.sh +0 -10
  202. package/templates/adapters/claude/hooks/post-tool-use.sh +0 -35
  203. package/templates/adapters/claude/hooks/pre-compact.sh +0 -37
  204. package/templates/adapters/claude/hooks/pre-tool-use.sh +0 -153
  205. package/templates/adapters/claude/hooks/prompt-submit.sh +0 -99
  206. package/templates/adapters/claude/hooks/review-checklist.sh +0 -10
  207. package/templates/adapters/claude/hooks/session-end.sh +0 -21
  208. package/templates/adapters/claude/hooks/session-start.sh +0 -36
  209. package/templates/adapters/claude/hooks/stop-check.sh +0 -45
  210. package/templates/adapters/claude/hooks/stop-failure.sh +0 -44
  211. package/templates/adapters/claude/hooks/subagent-guard.sh +0 -36
  212. package/templates/adapters/claude/hooks/subagent-stop.sh +0 -20
  213. package/templates/adapters/codex/hooks/doc-format-guard.sh +0 -261
  214. package/templates/adapters/codex/hooks/lib/common.sh +0 -261
  215. package/templates/adapters/codex/hooks/lib/context-inject.sh +0 -96
  216. package/templates/adapters/codex/hooks/lib/notify.sh +0 -34
  217. package/templates/adapters/codex/hooks/lib/preload-templates.sh +0 -187
  218. package/templates/adapters/codex/hooks/lib/session-end.sh +0 -76
  219. package/templates/adapters/codex/hooks/lib/state-detect.sh +0 -117
  220. package/templates/adapters/codex/hooks/lib/subagent-stop.sh +0 -90
  221. package/templates/adapters/codex/hooks/lib/vocabulary.sh +0 -56
  222. package/templates/adapters/codex/hooks/notification.sh +0 -45
  223. package/templates/adapters/codex/hooks/permission-gate.sh +0 -18
  224. package/templates/adapters/codex/hooks/post-tool-failure.sh +0 -10
  225. package/templates/adapters/codex/hooks/post-tool-use.sh +0 -138
  226. package/templates/adapters/codex/hooks/pre-compact.sh +0 -37
  227. package/templates/adapters/codex/hooks/pre-tool-use.sh +0 -217
  228. package/templates/adapters/codex/hooks/prompt-submit.sh +0 -87
  229. package/templates/adapters/codex/hooks/review-checklist.sh +0 -10
  230. package/templates/adapters/codex/hooks/session-end.sh +0 -38
  231. package/templates/adapters/codex/hooks/session-start.sh +0 -53
  232. package/templates/adapters/codex/hooks/stop-check.sh +0 -45
  233. package/templates/adapters/codex/hooks/subagent-guard.sh +0 -15
  234. package/templates/adapters/codex/hooks/subagent-stop.sh +0 -47
  235. package/templates/adapters/qoder/hooks/doc-format-guard.sh +0 -260
  236. package/templates/adapters/qoder/hooks/lib/common.sh +0 -261
  237. package/templates/adapters/qoder/hooks/lib/context-inject.sh +0 -96
  238. package/templates/adapters/qoder/hooks/lib/notify.sh +0 -34
  239. package/templates/adapters/qoder/hooks/lib/preload-templates.sh +0 -187
  240. package/templates/adapters/qoder/hooks/lib/session-end.sh +0 -76
  241. package/templates/adapters/qoder/hooks/lib/state-detect.sh +0 -117
  242. package/templates/adapters/qoder/hooks/lib/subagent-stop.sh +0 -90
  243. package/templates/adapters/qoder/hooks/lib/vocabulary.sh +0 -56
  244. package/templates/adapters/qoder/hooks/notification.sh +0 -25
  245. package/templates/adapters/qoder/hooks/permission-gate.sh +0 -8
  246. package/templates/adapters/qoder/hooks/post-tool-failure.sh +0 -8
  247. package/templates/adapters/qoder/hooks/post-tool-use.sh +0 -121
  248. package/templates/adapters/qoder/hooks/pre-compact.sh +0 -37
  249. package/templates/adapters/qoder/hooks/pre-tool-use.sh +0 -154
  250. package/templates/adapters/qoder/hooks/prompt-submit.sh +0 -96
  251. package/templates/adapters/qoder/hooks/review-checklist.sh +0 -157
  252. package/templates/adapters/qoder/hooks/session-end.sh +0 -24
  253. package/templates/adapters/qoder/hooks/session-start.sh +0 -45
  254. package/templates/adapters/qoder/hooks/stop-check.sh +0 -48
  255. package/templates/adapters/qoder/hooks/subagent-guard.sh +0 -27
  256. package/templates/adapters/qoder/hooks/subagent-stop.sh +0 -26
  257. package/templates/adapters/trae/hooks/doc-format-guard.sh +0 -261
  258. package/templates/adapters/trae/hooks/lib/common.sh +0 -261
  259. package/templates/adapters/trae/hooks/lib/context-inject.sh +0 -96
  260. package/templates/adapters/trae/hooks/lib/notify.sh +0 -34
  261. package/templates/adapters/trae/hooks/lib/preload-templates.sh +0 -187
  262. package/templates/adapters/trae/hooks/lib/session-end.sh +0 -76
  263. package/templates/adapters/trae/hooks/lib/state-detect.sh +0 -117
  264. package/templates/adapters/trae/hooks/lib/subagent-stop.sh +0 -90
  265. package/templates/adapters/trae/hooks/lib/vocabulary.sh +0 -56
  266. package/templates/adapters/trae/hooks/notification.sh +0 -45
  267. package/templates/adapters/trae/hooks/permission-gate.sh +0 -18
  268. package/templates/adapters/trae/hooks/post-tool-failure.sh +0 -10
  269. package/templates/adapters/trae/hooks/post-tool-use.sh +0 -138
  270. package/templates/adapters/trae/hooks/pre-compact.sh +0 -37
  271. package/templates/adapters/trae/hooks/pre-tool-use.sh +0 -217
  272. package/templates/adapters/trae/hooks/prompt-submit.sh +0 -87
  273. package/templates/adapters/trae/hooks/review-checklist.sh +0 -10
  274. package/templates/adapters/trae/hooks/session-end.sh +0 -38
  275. package/templates/adapters/trae/hooks/session-start.sh +0 -53
  276. package/templates/adapters/trae/hooks/stop-check.sh +0 -45
  277. package/templates/adapters/trae/hooks/subagent-guard.sh +0 -15
  278. package/templates/adapters/trae/hooks/subagent-stop.sh +0 -47
  279. package/templates/adapters/vscode/hooks/doc-format-guard.sh +0 -201
  280. package/templates/adapters/vscode/hooks/lib/common.sh +0 -261
  281. package/templates/adapters/vscode/hooks/lib/context-inject.sh +0 -96
  282. package/templates/adapters/vscode/hooks/lib/notify.sh +0 -34
  283. package/templates/adapters/vscode/hooks/lib/preload-templates.sh +0 -187
  284. package/templates/adapters/vscode/hooks/lib/session-end.sh +0 -76
  285. package/templates/adapters/vscode/hooks/lib/state-detect.sh +0 -117
  286. package/templates/adapters/vscode/hooks/lib/subagent-stop.sh +0 -90
  287. package/templates/adapters/vscode/hooks/lib/vocabulary.sh +0 -56
  288. package/templates/adapters/vscode/hooks/notification.sh +0 -45
  289. package/templates/adapters/vscode/hooks/permission-gate.sh +0 -18
  290. package/templates/adapters/vscode/hooks/post-tool-failure.sh +0 -28
  291. package/templates/adapters/vscode/hooks/post-tool-use.sh +0 -35
  292. package/templates/adapters/vscode/hooks/pre-compact.sh +0 -37
  293. package/templates/adapters/vscode/hooks/pre-tool-use.sh +0 -153
  294. package/templates/adapters/vscode/hooks/prompt-submit.sh +0 -99
  295. package/templates/adapters/vscode/hooks/review-checklist.sh +0 -10
  296. package/templates/adapters/vscode/hooks/session-end.sh +0 -13
  297. package/templates/adapters/vscode/hooks/session-start.sh +0 -35
  298. package/templates/adapters/vscode/hooks/stop-check.sh +0 -53
  299. package/templates/adapters/vscode/hooks/subagent-guard.sh +0 -37
  300. package/templates/adapters/vscode/hooks/subagent-stop.sh +0 -12
  301. package/templates/core/hooks/doc-format-guard.sh +0 -261
  302. package/templates/core/hooks/lib/common.sh +0 -261
  303. package/templates/core/hooks/lib/context-inject.sh +0 -96
  304. package/templates/core/hooks/lib/notify.sh +0 -34
  305. package/templates/core/hooks/lib/preload-templates.sh +0 -187
  306. package/templates/core/hooks/lib/session-end.sh +0 -76
  307. package/templates/core/hooks/lib/state-detect.sh +0 -117
  308. package/templates/core/hooks/lib/subagent-stop.sh +0 -90
  309. package/templates/core/hooks/lib/vocabulary.sh +0 -56
  310. package/templates/core/hooks/notification.sh +0 -45
  311. package/templates/core/hooks/permission-gate.sh +0 -18
  312. package/templates/core/hooks/post-tool-failure.sh +0 -10
  313. package/templates/core/hooks/post-tool-use.sh +0 -138
  314. package/templates/core/hooks/pre-compact.sh +0 -37
  315. package/templates/core/hooks/pre-tool-use.sh +0 -217
  316. package/templates/core/hooks/prompt-submit.sh +0 -87
  317. package/templates/core/hooks/review-checklist.sh +0 -10
  318. package/templates/core/hooks/session-end.sh +0 -38
  319. package/templates/core/hooks/session-start.sh +0 -53
  320. package/templates/core/hooks/stop-check.sh +0 -45
  321. package/templates/core/hooks/subagent-guard.sh +0 -15
  322. package/templates/core/hooks/subagent-stop.sh +0 -47
  323. package/templates/shared/hooks-lib/common.sh +0 -22
@@ -1,121 +0,0 @@
1
- #!/bin/bash
2
- # post-tool-use.sh — Qoder CN PostToolUse:格式化 + 文档守卫 + 审计提醒 + DPS 自动化
3
- # 治理卡位 #5: 格式化 + ADD文档守卫 + 审计落库 + 结果增强 + 哨兵自动化
4
- set -euo pipefail
5
-
6
- input=$(cat)
7
- HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
8
- export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
9
- export PROJECT_DIR="${QODER_PROJECT_DIR:-${QODERCN_PROJECT_DIR:-$PWD}}"
10
- source "$HOOK_DIR/lib/common.sh" 2>/dev/null || true
11
- MAGIC_DIR="$CURRENT_MAGIC"
12
-
13
- tool_name=$(json_get "$input" "tool_name")
14
- [ -z "$tool_name" ] && tool_name=$(echo "$input" | grep -o '"tool_name"[[:space:]]*:[[:space:]]*"[^"]*"' 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "")
15
-
16
- # ═══════════════ §1: HITL DPS 自动化 — check_dps ≥ 80 → 自动建哨兵 ═══════════════
17
- if echo "$input" | grep -q '"check_dps"'; then
18
- dps_score=$(echo "$input" | grep -oP 'DPS\s*=\s*\K\d+' 2>/dev/null || echo "")
19
- plan_keyword=$(echo "$input" | grep -oP '"planKeyword"\s*:\s*"\K[^"]+' 2>/dev/null || echo "")
20
-
21
- if [ -n "$dps_score" ] && [ -n "$plan_keyword" ]; then
22
- if [ "$dps_score" -ge 80 ] 2>/dev/null; then
23
- sentinel="${PROJECT_DIR}/${MAGIC_DIR}/hitl/.tongyi-${plan_keyword}"
24
- if [ ! -f "$sentinel" ]; then
25
- touch "$sentinel" 2>/dev/null || true
26
- echo "[ADD PostToolUse] ✅ DPS=${dps_score} ≥80, HITL 自动通过 → ${sentinel}" >&2
27
- fi
28
- else
29
- echo "[ADD PostToolUse] ⚠️ DPS=${dps_score} <80, 需 Review 后手动建哨兵 .tongyi-${plan_keyword}" >&2
30
- fi
31
- fi
32
- fi
33
-
34
- # ═══════════════ §2: Edit/Write matcher ═══════════════
35
- if [ "$tool_name" = "Edit" ] || [ "$tool_name" = "Write" ]; then
36
- file_path=$(echo "$input" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "")
37
- [ -z "$file_path" ] && exit 0
38
-
39
- # §2a: ADD 文档结构守卫
40
- if echo "$file_path" | grep -qE '\.(qoder|claude|add)/(plans|specs|reviews)/'; then
41
- echo "[ADD PostToolUse] ADD 文档已写入: ${file_path}。请确保章节完整、双向链接齐全。" >&2
42
- fi
43
-
44
- # §2b: plan_track 自动触发 — specs/ 或 add-route 写入后提醒
45
- if echo "$file_path" | grep -qE '/(specs|plans)/.*add-route'; then
46
- plan_name=""
47
- if echo "$file_path" | grep -qE 'add-route'; then
48
- plan_prefix=$(basename "$file_path" | sed 's/-add-route-v[0-9]*\.md$//')
49
- plan_dir=$(dirname "$file_path")
50
- if [ -d "$plan_dir" ]; then
51
- plan_file=$(ls "$plan_dir"/*-plan-v*.md 2>/dev/null | head -1 || echo "")
52
- if [ -n "$plan_file" ]; then
53
- plan_name=$(basename "$plan_file" .md)
54
- fi
55
- fi
56
- fi
57
- if [ -n "$plan_name" ]; then
58
- echo "[ADD PostToolUse] 📊 请执行 plan_track({ planName: \"${plan_name}\" }) 落库同步" >&2
59
- fi
60
- fi
61
-
62
- # §2c: devlog 自动提醒 — add-route Step 8 全 [x] 时提醒
63
- if echo "$file_path" | grep -qE 'add-route.*\.md$'; then
64
- if [ -f "$file_path" ]; then
65
- step8_unchecked=$(sed -n '/## Step 8/,/^## /p' "$file_path" 2>/dev/null | grep -c '^\- \[ \]' 2>/dev/null || echo "0")
66
- step8_checked=$(sed -n '/## Step 8/,/^## /p' "$file_path" 2>/dev/null | grep -c '^\- \[x\]' 2>/dev/null || echo "0")
67
- if [ "$step8_unchecked" = "0" ] && [ "$step8_checked" -gt 0 ]; then
68
- echo "[ADD PostToolUse] ⚠️ Step 8 全部收敛完成!请写 devlog日志(走mcp) → 更新 handoff" >&2
69
- fi
70
- fi
71
- fi
72
-
73
- # §2d: schema.json 自动 regen 提醒
74
- if echo "$file_path" | grep -qE 'templates/.*\.md$'; then
75
- schema_file="${file_path%.md}.schema.json"
76
- if [ -f "$schema_file" ]; then
77
- echo "[ADD PostToolUse] 🔄 模板已修改,请检查 ${schema_file} 是否需更新" >&2
78
- fi
79
- fi
80
-
81
- echo "[ADD PostToolUse] 文件已写入: ${file_path}。请执行 record_dev_operation 落库审计(ADD-7)。" >&2
82
- exit 0
83
- fi
84
-
85
- # ═══════════════ §3: Bash matcher ═══════════════
86
- if [ "$tool_name" = "Bash" ]; then
87
- echo "[ADD PostToolUse] 命令执行完成。如有 lint/tsc 错误请修复。" >&2
88
- exit 0
89
- fi
90
-
91
- exit 0
92
- #!/bin/bash
93
- # post-tool-use.sh — Qoder CN PostToolUse:格式化 + 文档守卫 + 审计提醒
94
- # 治理卡位 #5: 格式化 + ADD文档守卫 + 审计落库 + 结果增强
95
- set -euo pipefail
96
-
97
- input=$(cat)
98
- HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
99
- source "$HOOK_DIR/lib/common.sh" 2>/dev/null || true
100
-
101
- tool_name=$(json_get "$input" "tool_name")
102
- [ -z "$tool_name" ] && tool_name=$(echo "$input" | grep -o '"tool_name"[[:space:]]*:[[:space:]]*"[^"]*"' 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "")
103
-
104
- if [ "$tool_name" = "Edit" ] || [ "$tool_name" = "Write" ]; then
105
- file_path=$(echo "$input" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "")
106
- [ -z "$file_path" ] && exit 0
107
-
108
- if echo "$file_path" | grep -qE '\.(qoder|claude|add)/(plans|specs|reviews)/'; then
109
- echo "[ADD PostToolUse] ADD 文档已写入: ${file_path}。请确保章节完整、双向链接齐全、增量修订格式正确。" >&2
110
- fi
111
-
112
- echo "[ADD PostToolUse] 文件已写入: ${file_path}。请执行 record_dev_operation 落库审计(ADD-7)。" >&2
113
- exit 0
114
- fi
115
-
116
- if [ "$tool_name" = "Bash" ]; then
117
- echo "[ADD PostToolUse] 命令执行完成。如有 lint/tsc 错误请修复。" >&2
118
- exit 0
119
- fi
120
-
121
- exit 0
@@ -1,37 +0,0 @@
1
- #!/bin/bash
2
- # pre-compact.sh — 上下文压缩前 ADD 状态保存(Claude Code 适配)
3
- # 治理卡位 #9: ADD状态保存 + 恢复清单导出 + tpl标记清理
4
- set -euo pipefail
5
-
6
- HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
7
- export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
8
- COMMON_LIB="$HOOK_DIR/lib/common.sh"
9
- [ -f "$COMMON_LIB" ] && source "$COMMON_LIB"
10
-
11
- export PROJECT_DIR="${QODER_PROJECT_DIR:-${QODERCN_PROJECT_DIR:-$PWD}}"
12
-
13
- # ── ① 获取 ADD 状态并保存到标记文件 ──
14
- if type detect_active_add >/dev/null 2>&1; then
15
- state=$(detect_active_add 2>/dev/null || true)
16
- if [ -n "$state" ]; then
17
- IFS='::' read -r plan step rounds handoff add_route <<< "$state"
18
-
19
- # 写入恢复标记文件(SessionStart 恢复时读取)
20
- RECOVERY_FILE="/tmp/add_recovery_$(echo "${PROJECT_DIR}" | md5sum 2>/dev/null | cut -c1-8 || echo "default")"
21
- cat > "$RECOVERY_FILE" <<EOF
22
- plan=${plan}
23
- step=${step}
24
- rounds=${rounds}
25
- handoff=${handoff}
26
- add_route=${add_route}
27
- EOF
28
-
29
- echo "[ADD PreCompact] ADD 状态已保存: Plan=${plan}, Step=${step}" >&2
30
- fi
31
- fi
32
-
33
- # ── ② 清理 tpl-injected 标记(compact 后上下文丢失,下次需重注) ──
34
- TPL_FLAG="/tmp/add_tpl_$(echo "${PROJECT_DIR}" | md5sum 2>/dev/null | cut -c1-8 || echo "default")"
35
- rm -f "$TPL_FLAG" 2>/dev/null || true
36
-
37
- exit 0
@@ -1,154 +0,0 @@
1
- #!/bin/bash
2
- # pre-tool-use.sh — Qoder CN PreToolUse:四路守卫
3
- # 治理卡位 #4: 危险命令拦截 / 模板路径兜底 / 写入前置守卫 / 敏感文件保护
4
- set -euo pipefail
5
-
6
- input=$(cat)
7
- HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
8
- export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
9
- export PROJECT_DIR="${QODER_PROJECT_DIR:-${QODERCN_PROJECT_DIR:-$PWD}}"
10
- source "$HOOK_DIR/lib/common.sh" 2>/dev/null || true
11
- source "$HOOK_DIR/lib/notify.sh" 2>/dev/null || true
12
- MAGIC_DIR="$CURRENT_MAGIC"
13
-
14
- # ── Hook 通知: 提前计算 Plan 关联信息 ──
15
- ACTIVE_PLAN=$(detect_active_add 2>/dev/null || true)
16
- if [ -n "$ACTIVE_PLAN" ]; then
17
- PLAN_KEYWORD="${ACTIVE_PLAN%%::*}"
18
- PLAN_STATUS="active"
19
- else
20
- PLAN_KEYWORD="no-active-plan"
21
- PLAN_STATUS="none"
22
- fi
23
-
24
- tool_name=$(json_get "$input" "tool_name")
25
- [ -z "$tool_name" ] && tool_name=$(echo "$input" | grep -o '"tool_name"[[:space:]]*:[[:space:]]*"[^"]*"' 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "")
26
-
27
- # ── ① Bash matcher: 危险命令拦截 + 终端写文件拦截 ──
28
- if [ "$tool_name" = "Bash" ]; then
29
- cmd=$(echo "$input" | grep -o '"command"[[:space:]]*:[[:space:]]*"[^"]*"' 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "")
30
- # 危险命令
31
- if echo "$cmd" | grep -qiE 'rm[[:space:]]+-rf[[:space:]]+/|DROP[[:space:]]+TABLE|git[[:space:]]+push[[:space:]]+--force|mkfs\.|dd[[:space:]]+if='; then
32
- echo "⛔ 危险命令已被阻止: $cmd" >&2
33
- echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"危险命令已被阻止\"}}"
34
- write_hook_event "pre-tool-use" "deny" "$cmd" "危险命令已被阻止" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
35
- exit 2
36
- fi
37
- # 终端写文件拦截(含 > / >> / << heredoc / mv / touch / python -c > file)
38
- if echo "$cmd" | grep -qE '(cat|echo|tee|sed[[:space:]]+-i|awk|printf|cp|mv|dd|touch)[[:space:]]*.*([>]{1,2}|[|][[:space:]]*tee|<<)'; then
39
- echo "⛔ 禁止通过终端命令直接写文件: $cmd。请使用 Write/Edit/SearchReplace 工具。" >&2
40
- echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"禁止通过终端直接写文件,请使用 IDE 工具\"}}"
41
- write_hook_event "pre-tool-use" "deny" "$cmd" "禁止通过终端直接写文件" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
42
- exit 2
43
- fi
44
- # cp / mv / touch — 可创建或覆盖文件,无重定向也拦(对齐 core §A 检测5)
45
- if echo "$cmd" | grep -qE '(^|;|\|\||&&|\|)\s*(cp|mv|touch)\b'; then
46
- echo "⛔ 禁止通过 cp/mv/touch 操作文件: $cmd。请使用 Write 或 SearchReplace 工具。" >&2
47
- echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"禁止通过 cp/mv/touch 操作文件,请使用 IDE 工具\"}}"
48
- write_hook_event "pre-tool-use" "deny" "$cmd" "禁止通过 cp/mv/touch 操作文件" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
49
- exit 2
50
- fi
51
- # python/node/ruby/perl/php 脚本解释器 — 可写任意文件
52
- if echo "$cmd" | grep -qE '(^|;|\|\||&&|\|)\s*(python3?|node|ruby|perl|php)(\s|$)'; then
53
- echo "⛔ 禁止通过脚本解释器直接写文件: $cmd。请使用 Write 或 SearchReplace 工具。" >&2
54
- echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"禁止通过脚本解释器直接写文件,请使用 IDE 工具\"}}"
55
- write_hook_event "pre-tool-use" "deny" "$cmd" "禁止通过脚本解释器直接修改文件" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
56
- exit 2
57
- fi
58
- mark_dev_action 2>/dev/null || true
59
- exit 0
60
- fi
61
-
62
- # ── ② Write/Edit matcher: 文件写入前置守卫 ──
63
- if [ "$tool_name" = "Write" ] || [ "$tool_name" = "Edit" ] || [ "$tool_name" = "SearchReplace" ]; then
64
- file_path=$(echo "$input" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "")
65
- [ -z "$file_path" ] && exit 0
66
-
67
- if echo "$file_path" | grep -qE '\.(qoder|claude|add)/(plans|specs|reviews)/'; then
68
- if type detect_active_add >/dev/null 2>&1; then
69
- state=$(detect_active_add 2>/dev/null || true)
70
- if [ -z "$state" ]; then
71
- echo "[ADD 提示] 正在写入 Plan/Spec/Review 文档但无活跃 ADD Plan——首次创建场景放行,建议先执行 add-paradigm 生成 Plan+add-route" >&2
72
- echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"allow\",\"permissionDecisionReason\":\"无活跃 ADD Plan 但为 Plan/Spec/Review 写入(首次创建场景),提示而非拦截\"}}"
73
- write_hook_event "pre-tool-use" "info" "$file_path" "无活跃 ADD Plan 下写入 Plan/Spec/Review(首次创建放行)" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
74
- exit 0
75
- fi
76
- fi
77
- fi
78
-
79
- if echo "$file_path" | grep -qE '\.env$|\.env\.production$|\.env\.local$|credentials|secrets'; then
80
- echo "⛔ 敏感文件受保护,禁止写入: $file_path" >&2
81
- echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"敏感文件受保护\"}}"
82
- write_hook_event "pre-tool-use" "deny" "$file_path" "敏感文件受保护" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
83
- exit 2
84
- fi
85
-
86
- # §B: 模板类型前置注入 — plans/ 写入前提示应选模板
87
- if echo "$file_path" | grep -qE '\.(qoder|claude|add|vscode|trae)/(plans)/'; then
88
- fname=$(basename "$file_path")
89
- if echo "$fname" | grep -qE 'plan-v[0-9]'; then
90
- echo "💡 [ADD PreToolUse] 写入 Plan → 模板: standard-plan-template.md(标准)或 simple-plan-template.md(≤3文件)" >&2
91
- elif echo "$fname" | grep -qE 'add-route'; then
92
- echo "💡 [ADD PreToolUse] 写入 ADD Route → 模板: add-route-template.md" >&2
93
- elif echo "$fname" | grep -qE 'handoff'; then
94
- echo "💡 [ADD PreToolUse] 写入 Handoff → 模板: handoff-single-round-template.md(单轮)或 handoff-multi-round-template.md(多轮)" >&2
95
- fi
96
- # Qoder Write 大文件适配 — 已存在大文件建议用 SearchReplace 分块
97
- if echo "$tool_name" | grep -qE 'Write' && [ -f "$file_path" ]; then
98
- fsize=$(wc -c < "$file_path" 2>/dev/null || echo "0")
99
- if [ "$fsize" -gt 2000 ] 2>/dev/null; then
100
- echo "⚠️ [ADD PreToolUse] 文件已有 ${fsize} 字节,Write 全量覆盖可能触发 Qoder 40500。建议用 SearchReplace 分块追加。" >&2
101
- fi
102
- fi
103
- fi
104
-
105
- # §C: HITL tongyi 检查 — plans/ + PLAN_REVIEW reviews/ 写入前必须有 .hitl-tongyi-{planName} 哨兵
106
- # implementation/runtime review 不需要 HITL,走 §B 活跃 Plan 检查
107
- # handoff 是 Step 8 收敛产物(多轮交接手册),不经 HITL 审批,同样豁免
108
- if echo "$file_path" | grep -qE '\.(qoder|claude|add|vscode|trae)/(plans)/'; then
109
- if echo "$file_path" | grep -qE '\-handoff'; then
110
- _do_hitl=false # handoff 不被 HITL 拦截(Step 8 产物,无独立审批)
111
- else
112
- _do_hitl=true
113
- fi
114
- elif echo "$file_path" | grep -qE '\.(qoder|claude|add|vscode|trae)/(reviews)/'; then
115
- if echo "$file_path" | grep -qE '-(implementation|runtime)'; then
116
- _do_hitl=false # implementation/runtime review 不被 HITL 拦截
117
- else
118
- _do_hitl=true # PLAN_REVIEW 需要 HITL
119
- fi
120
- else
121
- _do_hitl=false
122
- fi
123
-
124
- if [ "$_do_hitl" = true ]; then
125
- _relative=$(echo "$file_path" | sed 's|.*/\.\(qoder\|claude\|add\|vscode\|trae\)/\(plans\|reviews\)/||')
126
- _planName=$(basename "$_relative" .md | sed 's/\.hitl$//;s/-plan-v[0-9]*$//;s/-add-route-v[0-9]*$//;s/-review-v[0-9]*$//;s/-review-implementation$//;s/-review-runtime$//')
127
- if [ -n "$_planName" ]; then
128
- _tongyi_marker="${PROJECT_DIR}/${MAGIC_DIR}/hitl/.tongyi-${_planName}"
129
- if [ ! -f "$_tongyi_marker" ]; then
130
- echo "⛔ [ADD PreToolUse §C] HITL 未 tongyi: $file_path" >&2
131
- echo " 原因: 哨兵文件 $_tongyi_marker 不存在" >&2
132
- echo " 操作: 请先调用 create_hitl 创建审批,再 update_hitl({ status: \"TONGYI\" })" >&2
133
- _msg="⛔ HITL 未 tongyi: 哨兵 ${_tongyi_marker} 不存在。请先 create_hitl → 人工 tongyi → update_hitl 后再写入"
134
- echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"${_msg}\",\"additionalContext\":\"${_msg}\"}}"
135
- write_hook_event "pre-tool-use" "ask" "$file_path" "HITL 未 tongyi: $_tongyi_marker" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
136
- exit 2
137
- fi
138
- fi
139
- fi
140
-
141
- mark_dev_action 2>/dev/null || true
142
- exit 0
143
- fi
144
-
145
- # ── ③ Read matcher: 模板路径兜底 ──
146
- if [ "$tool_name" = "Read" ]; then
147
- file_path=$(echo "$input" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "")
148
- if echo "$file_path" | grep -q 'templates/'; then
149
- echo "[ADD PreToolUse] 提示: 模板文件已通过 hook 预读到上下文,可跳过重复读取" >&2
150
- fi
151
- exit 0
152
- fi
153
-
154
- exit 0
@@ -1,96 +0,0 @@
1
- #!/bin/bash
2
- # prompt-submit.sh — UserPromptSubmit 触发词智能路由(★入口)
3
- # 治理卡位 #3: 触发词路由 + 模板全文注入(增量插入,保留 Layer 1/2/3)
4
- input=$(cat)
5
- prompt=$(echo "$input" | jq -r '.prompt // empty')
6
- [ -z "$prompt" ] && exit 0
7
-
8
- HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
9
- export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
10
- export PROJECT_DIR="${QODER_PROJECT_DIR:-${QODERCN_PROJECT_DIR:-$PWD}}"
11
- source "$HOOK_DIR/lib/common.sh" 2>/dev/null || true
12
- source "$HOOK_DIR/lib/vocabulary.sh"
13
- source "$HOOK_DIR/lib/state-detect.sh"
14
- source "$HOOK_DIR/lib/notify.sh" 2>/dev/null || true
15
-
16
- # ─── additionalContext 注入(Qoder CN IDE 通过 stdout JSON 注入模型上下文)───
17
- echo '{"hookSpecificOutput":{"hookEventName":"UserPromptSubmit","additionalContext":"ADD workflow active. Templates preloaded. Use add-paradigm SKILL."}}'
18
-
19
- # ─── Layer 1: 精准 P0 触发词 ───
20
- matched=$(match_trigger "$prompt")
21
- if [ -n "$matched" ]; then
22
- # 验收幂等保护: 如果已验收,提示不重复
23
- if echo "$prompt" | grep -qiE '验收|收敛' 2>/dev/null; then
24
- add_state=$(detect_active_add 2>/dev/null || true)
25
- if [ -n "$add_state" ]; then
26
- _handoff=$(echo "$add_state" | awk -F'::' '{print $4}')
27
- _add_route=$(echo "$add_state" | awk -F'::' '{print $5}')
28
- if is_already_accepted "$_add_route" "$_handoff" 2>/dev/null; then
29
- printf '%s\n' \
30
- "[ADD 验收] ⚠️ 已验收。进入 Review 模式:" \
31
- " ① 重新检查 checklist [T]/[R] 项" \
32
- " ② 审查 audit 记录完整性" \
33
- " ③ 如有差异 → Review 回流至 handoff(增量更新,不覆盖已有结论)" \
34
- " ④ 无差异 → 记录 'Review 已确认,无新发现'" \
35
- " ★ 同步检查: 如 checklist 有新 cuid 但 handoff 审计表缺失 → 更新 handoff ADD-7 表 + query_audit_logs 命令"
36
- # 执行 checklist 质量检查
37
- HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
38
- export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
39
- "$HOOK_DIR/review-checklist.sh" "$_handoff" "$_add_route" 2>/dev/null
40
- exit 0
41
- fi
42
- fi
43
- fi
44
- echo "$matched"
45
- exit 0
46
- fi
47
-
48
- # ─── 开发关键词检测 ───
49
- dev_kw=$(load_dev_keywords 2>/dev/null || true)
50
- if [ -z "$dev_kw" ]; then
51
- exit 0
52
- fi
53
-
54
- if ! echo "$prompt" | grep -qiE "$dev_kw"; then
55
- exit 0
56
- fi
57
-
58
- # ─── Layer 2/3: 按活跃 ADD 分流 ───
59
- state=$(detect_active_add 2>/dev/null || true)
60
- if [ -z "$state" ]; then
61
- # Layer 2: 无活跃 ADD → 提示启动(不阻断)
62
- cat >&2 <<'EOF'
63
- [ADD 提示] 检测到开发任务,但无活跃 ADD Plan。建议先执行 add-paradigm SKILL:
64
- Step 0: 文档先行 (Plan → Review → Specs)
65
- Step 3: 代码实现 + 审计植入
66
- Step 8: 收敛判断
67
- EOF
68
- write_hook_event "prompt-submit" "info" "$prompt" "无活跃 ADD Plan 下检测到开发任务" "no-active-plan" "none" 2>/dev/null || true
69
- exit 0
70
- fi
71
-
72
- # Layer 3: 有活跃 ADD → 注入状态
73
- plan=$(echo "$state" | awk -F'::' '{print $1}')
74
- step=$(echo "$state" | awk -F'::' '{print $2}')
75
- rounds=$(echo "$state" | awk -F'::' '{print $3}')
76
- handoff=$(echo "$state" | awk -F'::' '{print $4}')
77
- add_route=$(echo "$state" | awk -F'::' '{print $5}')
78
- add_ctx="[ADD 状态] Plan: ${plan}, 轮次: ${rounds}, Step: ${step}, handoff: ${handoff}"
79
-
80
- # ─── Hook 治理日报 ───
81
- HOOK_JSONL="${MAGIC_DIR:-.qoder}/reports/hook-events.jsonl"
82
- if [ -f "$HOOK_JSONL" ]; then
83
- TODAY="$(date +%Y-%m-%d)"
84
- TOTAL=$(grep -c "\"ts\":\"${TODAY}" "$HOOK_JSONL" 2>/dev/null || echo 0)
85
- NO_PLAN=$(grep "\"ts\":\"${TODAY}" "$HOOK_JSONL" 2>/dev/null | grep -c '"planKeyword":"no-active-plan"' || echo 0)
86
- if [ "$TOTAL" -gt 0 ] 2>/dev/null; then
87
- add_ctx="${add_ctx}\n[Hook 治理] 今日提示: ${TOTAL} 次 | 无 Plan 提示: ${NO_PLAN} 次"
88
- if [ "$NO_PLAN" -ge 10 ] 2>/dev/null; then
89
- add_ctx="${add_ctx}\n[Hook ⚠️] 无 Plan 提示已达 ${NO_PLAN} 次(≥10),建议创建 Plan"
90
- fi
91
- fi
92
- fi
93
-
94
- echo "{\"hookSpecificOutput\":{\"hookEventName\":\"UserPromptSubmit\",\"additionalContext\":\"${add_ctx}\"}}"
95
- exit 0
96
-
@@ -1,157 +0,0 @@
1
- #!/bin/bash
2
- # review-checklist.sh — 验收 Review 模式:检查 checklist 质量
3
- # 被 prompt-submit.sh 的"验收"幂等检查后调用
4
- #
5
- # 输入: handoff_path add_route_path
6
- # 输出: checklist 质量问题清单
7
-
8
- handoff="$1"
9
- add_route="$2"
10
- [ -z "$handoff" ] && exit 0
11
-
12
- # 从 handoff 关联找到 spec 目录
13
- plan_dir=$(dirname "$handoff")
14
- plan_kw=$(basename "$handoff" | sed 's/-handoff.*//')
15
-
16
- # 找 checklist
17
- spec_dir=".qoder/specs/${plan_kw}"
18
- checklist=""
19
- [ -d "$spec_dir" ] && checklist="$spec_dir/checklist.md"
20
- # fallback: 搜索
21
- [ ! -f "$checklist" ] && checklist=$(find .qoder/specs -name "checklist.md" -path "*${plan_kw}*" 2>/dev/null | head -1)
22
-
23
- tasks_file=""
24
- [ -d "$spec_dir" ] && tasks_file="$spec_dir/tasks.md"
25
- [ ! -f "$tasks_file" ] && tasks_file=$(find .qoder/specs -name "tasks.md" -path "*${plan_kw}*" 2>/dev/null | head -1)
26
-
27
- issues=""
28
-
29
- # ══════════════════════════════════════════════════════════════════════
30
- # 0. Step 0 准入: ADD 核心文档存在性(BLOCKING)
31
- # ══════════════════════════════════════════════════════════════════════
32
- _missing_docs=""
33
- if [ ! -f "$handoff" ]; then
34
- _missing_docs="${_missing_docs} Handoff"
35
- else
36
- # 章节完整性: 至少要有 spec 文件/你要改的文件/验证标准/完成后记录 四个关键小节
37
- _h_sections=0
38
- grep -q "spec 文件" "$handoff" 2>/dev/null && _h_sections=$((_h_sections + 1))
39
- grep -q "你要改的文件" "$handoff" 2>/dev/null && _h_sections=$((_h_sections + 1))
40
- grep -q "验证标准" "$handoff" 2>/dev/null && _h_sections=$((_h_sections + 1))
41
- grep -q "完成后记录 ADD-7 审计" "$handoff" 2>/dev/null && _h_sections=$((_h_sections + 1))
42
- if [ "$_h_sections" -lt 4 ]; then
43
- _missing_docs="${_missing_docs} Handoff(缺章节:${_h_sections}/4)"
44
- fi
45
- fi
46
- if [ ! -f "$add_route" ]; then
47
- _missing_docs="${_missing_docs} add-route"
48
- else
49
- # add-route 至少要有 Task 映射表 + 文件清单
50
- if ! grep -q "Task 映射表" "$add_route" 2>/dev/null && ! grep -q "文件清单" "$add_route" 2>/dev/null; then
51
- _missing_docs="${_missing_docs} add-route(缺Task映射/文件清单)"
52
- fi
53
- fi
54
- if [ ! -f "$checklist" ]; then
55
- _missing_docs="${_missing_docs} checklist"
56
- else
57
- # checklist 至少要有 [T] 项
58
- if ! grep -q '\[T\]' "$checklist" 2>/dev/null; then
59
- _missing_docs="${_missing_docs} checklist(无[T]项)"
60
- fi
61
- fi
62
- if [ ! -f "$tasks_file" ]; then
63
- _missing_docs="${_missing_docs} tasks"
64
- else
65
- # tasks 至少要有 Task 列表 + 验证
66
- if ! grep -q 'Task\|\- \[ \]' "$tasks_file" 2>/dev/null; then
67
- _missing_docs="${_missing_docs} tasks(无Task项)"
68
- fi
69
- fi
70
- if [ -n "$_missing_docs" ]; then
71
- echo " ❌ Step 0 未完成:$(echo $_missing_docs | sed 's/ /, /g') 文件缺失。回退 Step 0.5/Step 1 补建后再进入代码实现。"
72
- exit 1
73
- fi
74
-
75
- # 1. checklist [x] 数 vs tasks.md [x] 数 是否一致
76
- if [ -f "$checklist" ] && [ -f "$tasks_file" ]; then
77
- cl_ck=$(grep -c '\[x\]' "$checklist" 2>/dev/null || true); cl_ck=${cl_ck:-0}
78
- cl_open=$(grep -c '\[ \]' "$checklist" 2>/dev/null || true); cl_open=${cl_open:-0}
79
- tk_ck=$(grep -c '\[x\]' "$tasks_file" 2>/dev/null || echo "0")
80
-
81
- if [ "$cl_open" -gt 0 ]; then
82
- issues="${issues} ⚠️ checklist 有 ${cl_open} 项未勾选\n"
83
- fi
84
-
85
- # 2. [T] 项是否都有 [x](编译期验证项)
86
- t_items=$(grep -c '\[T\]' "$checklist" 2>/dev/null || true); t_items=${t_items:-0}
87
- t_checked=$(grep '\[T\]' "$checklist" 2>/dev/null | grep -c '\[x\]' || true); t_checked=${t_checked:-0}
88
- if [ "$t_items" -gt "$t_checked" ]; then
89
- issues="${issues} ⚠️ [T] 编译期验证: ${t_checked}/${t_items} 通过\n"
90
- fi
91
-
92
- # 3. 证据缺失检测:[x] 但缺 — 证据: 标记
93
- _no_evidence=0
94
- while IFS= read -r line; do
95
- [ -z "$line" ] && continue
96
- # 有证据: — 证据: 字段 + 具体内容(tsc/vitest/grep/审计ID 等)
97
- if echo "$line" | grep -qE '—\s*证据:\s*\S' 2>/dev/null; then
98
- continue
99
- fi
100
- # 有验证结果描述也行
101
- if echo "$line" | grep -qE 'npx|tsc|vitest|grep|✅|cmq[0-9a-z]{10}|18/18|exit.*0' 2>/dev/null; then
102
- continue
103
- fi
104
- _no_evidence=$((_no_evidence + 1))
105
- done < <(grep '\[x\]' "$checklist" 2>/dev/null)
106
-
107
- if [ "$_no_evidence" -gt 0 ]; then
108
- issues="${issues} ❌ ${_no_evidence} 项 [x] 缺少验收证据(需附 — 证据: tsc/vitest/grep/审计ID 等)\n"
109
- fi
110
-
111
- # 4. 审计链:[x] 项引用 audit ID 的比例
112
- # 初验: 有证据即可,审计ID是证据产出物
113
- # 复验: 有审计ID + 证据仍有效 → 不重复落库;证据失效 → 追写新审计
114
- _with_audit=$(grep '\[x\]' "$checklist" 2>/dev/null | grep -cE 'cmq[a-z0-9]{10,}' || true); _with_audit=${_with_audit:-0}
115
- _fake_audit=$(grep '\[x\]' "$checklist" 2>/dev/null | grep -cE 'cmq\.\.\.|cmqxxx|审计.*cmq\.\.' || true); _fake_audit=${_fake_audit:-0}
116
- if [ "$_fake_audit" -gt 0 ]; then
117
- issues="${issues} ❌ ${_fake_audit} 项 [x] 使用了占位符审计ID(cmq.../cmqxxx),必须调 record_dev_operation 获取真实 cuid 后替换\n"
118
- fi
119
- _with_evidence=$(grep '\[x\]' "$checklist" 2>/dev/null | grep -cE 'tsc|vitest|npx|grep|✅|验证|确认|compgen|审计.*cmq[a-z0-9]{10}' || true); _with_evidence=${_with_evidence:-0}
120
- if [ "$_with_evidence" -gt 0 ] && [ "$_with_audit" -eq 0 ]; then
121
- issues="${issues} 📎 初验: ${_with_evidence}/${cl_ck} 项有证据但未写审计 ID(需调 record_dev_operation 落库)\n"
122
- elif [ "$_with_audit" -gt 0 ] && [ "$_with_audit" -lt "$cl_ck" ]; then
123
- issues="${issues} 📎 复验: ${_with_audit}/${cl_ck} 项引用审计 ID。${_with_evidence}/${cl_ck} 项有证据。证据一致则不需追写 devlog日志(走mcp)\n"
124
- fi
125
- fi
126
-
127
- # 5. add-route Step 闭环
128
- if [ -f "$add_route" ]; then
129
- ar_ck=$(grep -c '\[x\]' "$add_route" 2>/dev/null || true); ar_ck=${ar_ck:-0}
130
- ar_open=$(grep -c '\[ \]' "$add_route" 2>/dev/null || true); ar_open=${ar_open:-0}
131
- if [ "$ar_open" -gt 0 ]; then
132
- issues="${issues} ⚠️ add-route ${ar_open} Step 未闭环\n"
133
- fi
134
- fi
135
-
136
- # 6. handoff 审计表同步:checklist 中的 cuid 是否在 handoff 中有记录
137
- if [ -f "$handoff" ] && [ -f "$checklist" ]; then
138
- _new_cuids=""
139
- while IFS= read -r cuid; do
140
- [ -z "$cuid" ] && continue
141
- if ! grep -q "$cuid" "$handoff" 2>/dev/null; then
142
- [ -n "$_new_cuids" ] && _new_cuids="${_new_cuids}, "
143
- _new_cuids="${_new_cuids}${cuid}"
144
- fi
145
- done < <(grep -oE 'cmq[a-z0-9]{10,}' "$checklist" 2>/dev/null | sort -u)
146
- if [ -n "$_new_cuids" ]; then
147
- _new_count=$(echo "$_new_cuids" | tr ',' '\n' | wc -l)
148
- issues="${issues} ❌ handoff 审计表未同步: ${_new_count} 个 cuid 在 checklist 中存在但 handoff 中缺失(需更新 handoff ADD-7 表 + query_audit_logs 命令)\n"
149
- fi
150
- fi
151
-
152
- if [ -z "$issues" ]; then
153
- echo " ✅ Review: checklist 质量检查通过"
154
- else
155
- echo " 📋 Review 发现问题:"
156
- echo -e "$issues"
157
- fi
@@ -1,24 +0,0 @@
1
- #!/bin/bash
2
- # SessionEnd — Qoder CN 专用(独立实现,stdout JSON additionalContext 注入)
3
- # 治理卡位 #2: 标记清理 + 会话审计结算 + Stop未触发兜底
4
- set -euo pipefail
5
-
6
- HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
7
- export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
8
- export PROJECT_DIR="${QODER_PROJECT_DIR:-${QODERCN_PROJECT_DIR:-$PWD}}"
9
- source "$HOOK_DIR/lib/common.sh" 2>/dev/null || true
10
-
11
- # ── ① 清理标记文件 ──
12
- project_hash=$(echo "${PROJECT_DIR:-$PWD}" | md5sum 2>/dev/null | cut -c1-8 || echo "default")
13
- rm -f "/tmp/add_tpl_${project_hash}" 2>/dev/null || true
14
- rm -f "/tmp/add_dev_${project_hash}" 2>/dev/null || true
15
-
16
- # ── ② Stop 未触发兜底 ──
17
- fallback_msg=""
18
- if has_dev_action 2>/dev/null; then
19
- fallback_msg="⚠️ 检测到 dev action 标记未清除——Stop 可能未触发验收检查"
20
- fi
21
-
22
- # ── ③ stdout JSON additionalContext ──
23
- echo "{\"hookSpecificOutput\":{\"hookEventName\":\"SessionEnd\",\"additionalContext\":\"[ADD SessionEnd] 会话结束 — $(date -Iseconds)。标记已清理。${fallback_msg}\"}}"
24
- exit 0
@@ -1,45 +0,0 @@
1
- #!/bin/bash
2
- # SessionStart — ADD 上下文恢复 + 模板索引注入(Qoder CN 适配,stdout additionalContext 注入)
3
- # 治理卡位 #1: ADD状态恢复 + 模板索引注入
4
- set -euo pipefail
5
-
6
- HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
7
- export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
8
- export PROJECT_DIR="${QODER_PROJECT_DIR:-${QODERCN_PROJECT_DIR:-$PWD}}"
9
- source "$HOOK_DIR/lib/common.sh"
10
- source "$HOOK_DIR/lib/state-detect.sh" 2>/dev/null || true
11
- source "$HOOK_DIR/lib/context-inject.sh" 2>/dev/null || true
12
-
13
- # ── ① ADD 状态恢复 ──
14
- state=$(detect_active_add 2>/dev/null || true)
15
- if [ -n "$state" ]; then
16
- IFS='::' read -r plan step rounds handoff add_route <<< "$state"
17
- add_ctx="ADD: ${plan} Step${step} Round${rounds}"
18
- # §代办刷新:提醒加载 IDE 代办清单
19
- add_ctx="${add_ctx}\n[代办] 如有未加载的 IDE 代办清单,请从 tasks.md §IDE JSON 刷新 TodoWrite"
20
- cat <<EOJSON
21
- {"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"${add_ctx}"}}
22
- EOJSON
23
- fi
24
-
25
- # ── ② 模板索引注入 ──
26
- TPL_SCRIPT="$HOOK_DIR/lib/preload-templates.sh"
27
- if [ -f "$TPL_SCRIPT" ]; then
28
- lines=$(bash "$TPL_SCRIPT" --index 2>/dev/null | wc -l)
29
- cat <<EOJSON
30
- {"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"${lines} ADD templates available. Use preload-templates.sh --index for list."}}
31
- EOJSON
32
- fi
33
-
34
- # ── ③ §HITL 待审批检测 ──
35
- PLANS_DIR="${PROJECT_DIR}/${MAGIC_DIR:-.qoder}/plans"
36
- if [ -d "$PLANS_DIR" ]; then
37
- hitl_count=$(find "$PLANS_DIR" -name "*.hitl.md" -mtime -7 -type f 2>/dev/null | wc -l)
38
- if [ "$hitl_count" -gt 0 ] 2>/dev/null; then
39
- cat <<EOJSON
40
- {"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"[HITL 待审批] 检测到 ${hitl_count} 个待审批 HITL 提案,请检查并处理"}}
41
- EOJSON
42
- fi
43
- fi
44
-
45
- exit 0