add-coder 0.2.8 → 0.3.0

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 (58) hide show
  1. package/README.md +66 -27
  2. package/dist/index.js +158 -11
  3. package/package.json +9 -12
  4. package/templates/.add-coder-src-hash.json +256 -0
  5. package/templates/adapters/claude/hooks/doc-format-guard.sh +17 -0
  6. package/templates/adapters/claude/hooks/lib/notify.sh +34 -0
  7. package/templates/adapters/claude/hooks/pre-tool-use.sh +26 -7
  8. package/templates/adapters/claude/hooks/prompt-submit.sh +16 -0
  9. package/templates/adapters/codex/hooks/doc-format-guard.sh +17 -0
  10. package/templates/adapters/codex/hooks/lib/notify.sh +34 -0
  11. package/templates/adapters/codex/hooks/pre-tool-use.sh +48 -18
  12. package/templates/adapters/codex/hooks/prompt-submit.sh +16 -0
  13. package/templates/adapters/qoder/hooks/doc-format-guard.sh +17 -0
  14. package/templates/adapters/qoder/hooks/lib/notify.sh +34 -0
  15. package/templates/adapters/qoder/hooks/pre-tool-use.sh +28 -9
  16. package/templates/adapters/qoder/hooks/prompt-submit.sh +18 -1
  17. package/templates/adapters/trae/hooks/doc-format-guard.sh +17 -0
  18. package/templates/adapters/trae/hooks/lib/notify.sh +34 -0
  19. package/templates/adapters/trae/hooks/pre-tool-use.sh +48 -18
  20. package/templates/adapters/trae/hooks/prompt-submit.sh +16 -0
  21. package/templates/adapters/vscode/hooks/doc-format-guard.sh +16 -0
  22. package/templates/adapters/vscode/hooks/lib/notify.sh +34 -0
  23. package/templates/adapters/vscode/hooks/pre-tool-use.sh +26 -7
  24. package/templates/adapters/vscode/hooks/prompt-submit.sh +16 -0
  25. package/templates/core/hooks/doc-format-guard.sh +17 -0
  26. package/templates/core/hooks/lib/notify.sh +34 -0
  27. package/templates/core/hooks/pre-tool-use.sh +48 -18
  28. package/templates/core/hooks/prompt-submit.sh +16 -0
  29. package/templates/core/reviews/.gitkeep +0 -0
  30. package/templates/core/scripts/mcp-server/elicitation/confirm.ts +30 -0
  31. package/templates/core/scripts/mcp-server/elicitation/index.ts +1 -0
  32. package/templates/core/scripts/mcp-server/index.ts +15 -0
  33. package/templates/core/scripts/mcp-server/notifications/hitl.ts +49 -0
  34. package/templates/core/scripts/mcp-server/notifications/hook.ts +268 -0
  35. package/templates/core/scripts/mcp-server/notifications/index.ts +8 -0
  36. package/templates/core/scripts/mcp-server/resources/add-coder-version.ts +25 -0
  37. package/templates/core/scripts/mcp-server/resources/add-state.ts +44 -0
  38. package/templates/core/scripts/mcp-server/resources/hook-events-report.ts +104 -0
  39. package/templates/core/scripts/mcp-server/resources/index.ts +12 -0
  40. package/templates/core/scripts/mcp-server/resources/round-task.ts +22 -0
  41. package/templates/core/scripts/mcp-server/sampling/index.ts +1 -0
  42. package/templates/core/scripts/mcp-server/sampling/review.ts +47 -0
  43. package/templates/core/scripts/mcp-server/shared/env.ts +26 -0
  44. package/templates/core/scripts/mcp-server/shared/fs.ts +40 -0
  45. package/templates/core/scripts/mcp-server/shared/prisma.ts +35 -0
  46. package/templates/core/scripts/mcp-server/shared/response.ts +9 -0
  47. package/templates/core/scripts/mcp-server/tasks/index.ts +2 -0
  48. package/templates/core/scripts/mcp-server/tasks/runner.ts +20 -0
  49. package/templates/core/scripts/mcp-server/tasks/store.ts +20 -0
  50. package/templates/core/scripts/mcp-server/tools/audit.ts +73 -0
  51. package/templates/core/scripts/mcp-server/tools/context.ts +337 -0
  52. package/templates/core/scripts/mcp-server/tools/docs.ts +42 -0
  53. package/templates/core/scripts/mcp-server/tools/gateway.ts +135 -0
  54. package/templates/core/scripts/mcp-server/tools/hook-event-report.ts +92 -0
  55. package/templates/core/scripts/mcp-server/tools/index.ts +17 -0
  56. package/templates/core/scripts/mcp-server/tools/quality.ts +93 -0
  57. package/templates/core/scripts/mcp-server/types.ts +7 -0
  58. package/templates/core/scripts/mcp-server.ts +8 -3455
@@ -0,0 +1,256 @@
1
+ {
2
+ "_version": "0.3.0",
3
+ "adapters/claude/hooks/doc-format-guard.sh": "ec59ad3f",
4
+ "adapters/claude/hooks/lib/common.sh": "db321ef6",
5
+ "adapters/claude/hooks/lib/context-inject.sh": "4132f203",
6
+ "adapters/claude/hooks/lib/notify.sh": "e0033e53",
7
+ "adapters/claude/hooks/lib/preload-templates.sh": "96dd67fe",
8
+ "adapters/claude/hooks/lib/session-end.sh": "29813cbc",
9
+ "adapters/claude/hooks/lib/state-detect.sh": "b87dd85a",
10
+ "adapters/claude/hooks/lib/subagent-stop.sh": "4cc1d446",
11
+ "adapters/claude/hooks/lib/vocabulary.sh": "d5a92ac3",
12
+ "adapters/claude/hooks/notification.sh": "60bf9b01",
13
+ "adapters/claude/hooks/permission-denied.sh": "0a0605df",
14
+ "adapters/claude/hooks/permission-gate.sh": "bcca7732",
15
+ "adapters/claude/hooks/post-tool-failure.sh": "669b1b65",
16
+ "adapters/claude/hooks/post-tool-use.sh": "f54dd009",
17
+ "adapters/claude/hooks/pre-compact.sh": "4248f84f",
18
+ "adapters/claude/hooks/pre-tool-use.sh": "34e7e4de",
19
+ "adapters/claude/hooks/prompt-submit.sh": "680b41f4",
20
+ "adapters/claude/hooks/review-checklist.sh": "b383a983",
21
+ "adapters/claude/hooks/session-end.sh": "777ae808",
22
+ "adapters/claude/hooks/session-start.sh": "fd1d5e4f",
23
+ "adapters/claude/hooks/stop-check.sh": "41bc519a",
24
+ "adapters/claude/hooks/stop-failure.sh": "e3d6c335",
25
+ "adapters/claude/hooks/subagent-guard.sh": "5922efba",
26
+ "adapters/claude/hooks/subagent-stop.sh": "0f89e28c",
27
+ "adapters/claude/mcp.json": "e8c54cbd",
28
+ "adapters/claude/settings.json": "067ccc45",
29
+ "adapters/codex/hooks/doc-format-guard.sh": "94ebd860",
30
+ "adapters/codex/hooks/lib/common.sh": "db321ef6",
31
+ "adapters/codex/hooks/lib/context-inject.sh": "4132f203",
32
+ "adapters/codex/hooks/lib/notify.sh": "e0033e53",
33
+ "adapters/codex/hooks/lib/preload-templates.sh": "96dd67fe",
34
+ "adapters/codex/hooks/lib/session-end.sh": "29813cbc",
35
+ "adapters/codex/hooks/lib/state-detect.sh": "64c23045",
36
+ "adapters/codex/hooks/lib/subagent-stop.sh": "4cc1d446",
37
+ "adapters/codex/hooks/lib/vocabulary.sh": "d5a92ac3",
38
+ "adapters/codex/hooks/notification.sh": "f7aed25d",
39
+ "adapters/codex/hooks/permission-gate.sh": "bcca7732",
40
+ "adapters/codex/hooks/post-tool-failure.sh": "669b1b65",
41
+ "adapters/codex/hooks/post-tool-use.sh": "f54dd009",
42
+ "adapters/codex/hooks/pre-compact.sh": "6164c007",
43
+ "adapters/codex/hooks/pre-tool-use.sh": "a7072670",
44
+ "adapters/codex/hooks/prompt-submit.sh": "bea6f381",
45
+ "adapters/codex/hooks/review-checklist.sh": "b383a983",
46
+ "adapters/codex/hooks/session-end.sh": "3cc8c346",
47
+ "adapters/codex/hooks/session-start.sh": "8a5a2c62",
48
+ "adapters/codex/hooks/stop-check.sh": "dc4829be",
49
+ "adapters/codex/hooks/subagent-guard.sh": "47d04662",
50
+ "adapters/codex/hooks/subagent-stop.sh": "0a34648b",
51
+ "adapters/codex/hooks.json": "d9c99f6b",
52
+ "adapters/codex/settings.json": "44136fa3",
53
+ "adapters/qoder/hooks/doc-format-guard.sh": "bd4ffffb",
54
+ "adapters/qoder/hooks/lib/common.sh": "db321ef6",
55
+ "adapters/qoder/hooks/lib/context-inject.sh": "4132f203",
56
+ "adapters/qoder/hooks/lib/notify.sh": "e0033e53",
57
+ "adapters/qoder/hooks/lib/preload-templates.sh": "96dd67fe",
58
+ "adapters/qoder/hooks/lib/session-end.sh": "29813cbc",
59
+ "adapters/qoder/hooks/lib/state-detect.sh": "b87dd85a",
60
+ "adapters/qoder/hooks/lib/subagent-stop.sh": "4cc1d446",
61
+ "adapters/qoder/hooks/lib/vocabulary.sh": "d5a92ac3",
62
+ "adapters/qoder/hooks/notification.sh": "7d4efea6",
63
+ "adapters/qoder/hooks/permission-gate.sh": "3bf27b1a",
64
+ "adapters/qoder/hooks/post-tool-failure.sh": "8bc7a0e4",
65
+ "adapters/qoder/hooks/post-tool-use.sh": "47dd691c",
66
+ "adapters/qoder/hooks/pre-compact.sh": "092fa6cf",
67
+ "adapters/qoder/hooks/pre-tool-use.sh": "51d31986",
68
+ "adapters/qoder/hooks/prompt-submit.sh": "ac37b64c",
69
+ "adapters/qoder/hooks/review-checklist.sh": "666831c8",
70
+ "adapters/qoder/hooks/session-end.sh": "c50339df",
71
+ "adapters/qoder/hooks/session-start.sh": "7cf070d6",
72
+ "adapters/qoder/hooks/stop-check.sh": "974db988",
73
+ "adapters/qoder/hooks/subagent-guard.sh": "ce60eaac",
74
+ "adapters/qoder/hooks/subagent-stop.sh": "5a2c78c6",
75
+ "adapters/qoder/mcp.json": "209444d5",
76
+ "adapters/qoder/settings.json": "4bae3c9a",
77
+ "adapters/qoder/sync-policy.json": "a4bcbbaf",
78
+ "adapters/trae/hooks/doc-format-guard.sh": "a563db0f",
79
+ "adapters/trae/hooks/lib/common.sh": "db321ef6",
80
+ "adapters/trae/hooks/lib/context-inject.sh": "4132f203",
81
+ "adapters/trae/hooks/lib/notify.sh": "e0033e53",
82
+ "adapters/trae/hooks/lib/preload-templates.sh": "96dd67fe",
83
+ "adapters/trae/hooks/lib/session-end.sh": "29813cbc",
84
+ "adapters/trae/hooks/lib/state-detect.sh": "64c23045",
85
+ "adapters/trae/hooks/lib/subagent-stop.sh": "4cc1d446",
86
+ "adapters/trae/hooks/lib/vocabulary.sh": "d5a92ac3",
87
+ "adapters/trae/hooks/notification.sh": "f7aed25d",
88
+ "adapters/trae/hooks/permission-gate.sh": "bcca7732",
89
+ "adapters/trae/hooks/post-tool-failure.sh": "669b1b65",
90
+ "adapters/trae/hooks/post-tool-use.sh": "f54dd009",
91
+ "adapters/trae/hooks/pre-compact.sh": "6164c007",
92
+ "adapters/trae/hooks/pre-tool-use.sh": "a7072670",
93
+ "adapters/trae/hooks/prompt-submit.sh": "bea6f381",
94
+ "adapters/trae/hooks/review-checklist.sh": "b383a983",
95
+ "adapters/trae/hooks/session-end.sh": "3cc8c346",
96
+ "adapters/trae/hooks/session-start.sh": "8a5a2c62",
97
+ "adapters/trae/hooks/stop-check.sh": "dc4829be",
98
+ "adapters/trae/hooks/subagent-guard.sh": "47d04662",
99
+ "adapters/trae/hooks/subagent-stop.sh": "0a34648b",
100
+ "adapters/trae/hooks.json": "e5045c2c",
101
+ "adapters/trae/settings.json": "ca3d163b",
102
+ "adapters/vscode/.github/hooks/error-occurred.json": "9caa13dc",
103
+ "adapters/vscode/.github/hooks/post-tool-use.json": "bff9d4d8",
104
+ "adapters/vscode/.github/hooks/pre-compact.json": "fade404e",
105
+ "adapters/vscode/.github/hooks/pre-tool-use.json": "19c59396",
106
+ "adapters/vscode/.github/hooks/session-end.json": "3089c017",
107
+ "adapters/vscode/.github/hooks/session-start.json": "fa0b3d63",
108
+ "adapters/vscode/.github/hooks/stop-check.json": "e5a16e33",
109
+ "adapters/vscode/.github/hooks/subagent-start.json": "169857ad",
110
+ "adapters/vscode/.github/hooks/subagent-stop.json": "47dbdd8d",
111
+ "adapters/vscode/.github/hooks/user-prompt-submit.json": "3a608d62",
112
+ "adapters/vscode/extensions.json": "0f4024c1",
113
+ "adapters/vscode/hooks/doc-format-guard.sh": "0db27261",
114
+ "adapters/vscode/hooks/lib/common.sh": "db321ef6",
115
+ "adapters/vscode/hooks/lib/context-inject.sh": "4132f203",
116
+ "adapters/vscode/hooks/lib/notify.sh": "e0033e53",
117
+ "adapters/vscode/hooks/lib/preload-templates.sh": "96dd67fe",
118
+ "adapters/vscode/hooks/lib/session-end.sh": "29813cbc",
119
+ "adapters/vscode/hooks/lib/state-detect.sh": "b87dd85a",
120
+ "adapters/vscode/hooks/lib/subagent-stop.sh": "4cc1d446",
121
+ "adapters/vscode/hooks/lib/vocabulary.sh": "d5a92ac3",
122
+ "adapters/vscode/hooks/notification.sh": "f7aed25d",
123
+ "adapters/vscode/hooks/permission-gate.sh": "bcca7732",
124
+ "adapters/vscode/hooks/post-tool-failure.sh": "355cfab1",
125
+ "adapters/vscode/hooks/post-tool-use.sh": "5f188718",
126
+ "adapters/vscode/hooks/pre-compact.sh": "a0908f0e",
127
+ "adapters/vscode/hooks/pre-tool-use.sh": "0da68eed",
128
+ "adapters/vscode/hooks/prompt-submit.sh": "4529a394",
129
+ "adapters/vscode/hooks/review-checklist.sh": "b383a983",
130
+ "adapters/vscode/hooks/session-end.sh": "7b407b9f",
131
+ "adapters/vscode/hooks/session-start.sh": "ad724a3e",
132
+ "adapters/vscode/hooks/stop-check.sh": "df1ad9dd",
133
+ "adapters/vscode/hooks/subagent-guard.sh": "5d0ea685",
134
+ "adapters/vscode/hooks/subagent-stop.sh": "dd19f712",
135
+ "adapters/vscode/launch.json": "f2b79855",
136
+ "adapters/vscode/settings.json": "f2a30bf7",
137
+ "adapters/vscode/tasks.json": "654d7fbd",
138
+ "core/agents/add-flow-guardian.md": "697d422f",
139
+ "core/agents/add-orchestrator.md": "0d555e99",
140
+ "core/docs/ADD-governance-claude-code.md": "0f582a7e",
141
+ "core/docs/ADD-governance-codex.md": "289e8b71",
142
+ "core/docs/ADD-governance-qoder-cn.md": "332a7253",
143
+ "core/docs/ADD-governance-trae.md": "ffb29a0e",
144
+ "core/docs/ADD-governance-vscode-copilot.md": "74062e88",
145
+ "core/hooks/doc-format-guard.sh": "6f14934b",
146
+ "core/hooks/lib/common.sh": "db321ef6",
147
+ "core/hooks/lib/context-inject.sh": "4132f203",
148
+ "core/hooks/lib/notify.sh": "e0033e53",
149
+ "core/hooks/lib/preload-templates.sh": "96dd67fe",
150
+ "core/hooks/lib/session-end.sh": "29813cbc",
151
+ "core/hooks/lib/state-detect.sh": "135bde23",
152
+ "core/hooks/lib/subagent-stop.sh": "4cc1d446",
153
+ "core/hooks/lib/vocabulary.sh": "d5a92ac3",
154
+ "core/hooks/notification.sh": "f7aed25d",
155
+ "core/hooks/permission-gate.sh": "bcca7732",
156
+ "core/hooks/post-tool-failure.sh": "669b1b65",
157
+ "core/hooks/post-tool-use.sh": "f54dd009",
158
+ "core/hooks/pre-compact.sh": "6164c007",
159
+ "core/hooks/pre-tool-use.sh": "a7072670",
160
+ "core/hooks/prompt-submit.sh": "bea6f381",
161
+ "core/hooks/review-checklist.sh": "b383a983",
162
+ "core/hooks/session-end.sh": "3cc8c346",
163
+ "core/hooks/session-start.sh": "8a5a2c62",
164
+ "core/hooks/stop-check.sh": "dc4829be",
165
+ "core/hooks/subagent-guard.sh": "47d04662",
166
+ "core/hooks/subagent-stop.sh": "0a34648b",
167
+ "core/plans/2026-07/08/add-coder-npm-package-add-route-v1.md": "b05fce99",
168
+ "core/plans/2026-07/08/add-coder-npm-package-handoff-v1.md": "1bd40a4a",
169
+ "core/plans/2026-07/08/add-coder-npm-package-plan-v1.md": "323cbc7c",
170
+ "core/prisma/add.prisma": "83700ec2",
171
+ "core/reports/REPORT-WORKFLOW.md": "03d39b21",
172
+ "core/reports/boundary-runtime-report.md": "6fd8053f",
173
+ "core/reports/code-review-combined-report.md": "195d52aa",
174
+ "core/reports/code-review-fix-verification-report.md": "478e38e2",
175
+ "core/reports/code-review-suggestions.md": "1b8f6a16",
176
+ "core/reports/index.md": "6348c374",
177
+ "core/reports/runtime-report/gateway.md": "a5751665",
178
+ "core/reviews/.gitkeep": "e3b0c442",
179
+ "core/rules/project_rules.md": "5bf3dc94",
180
+ "core/rules/theory-practice-map.toml": "876192f5",
181
+ "core/scripts/db-ensure.sh": "fb81c10a",
182
+ "core/scripts/gen-plan-index.sh": "bfc6ad3e",
183
+ "core/scripts/mcp-server/elicitation/confirm.ts": "924857b8",
184
+ "core/scripts/mcp-server/elicitation/index.ts": "44c5dc3f",
185
+ "core/scripts/mcp-server/index.ts": "3483ec45",
186
+ "core/scripts/mcp-server/notifications/hitl.ts": "96eb7c5d",
187
+ "core/scripts/mcp-server/notifications/hook.ts": "a6cb861f",
188
+ "core/scripts/mcp-server/notifications/index.ts": "b6615afa",
189
+ "core/scripts/mcp-server/resources/add-coder-version.ts": "299fa071",
190
+ "core/scripts/mcp-server/resources/add-state.ts": "1c1cc3a2",
191
+ "core/scripts/mcp-server/resources/hook-events-report.ts": "1d4b5996",
192
+ "core/scripts/mcp-server/resources/index.ts": "50e19629",
193
+ "core/scripts/mcp-server/resources/round-task.ts": "104a0d74",
194
+ "core/scripts/mcp-server/sampling/index.ts": "7ee26d92",
195
+ "core/scripts/mcp-server/sampling/review.ts": "5db7a8df",
196
+ "core/scripts/mcp-server/shared/env.ts": "4b295e42",
197
+ "core/scripts/mcp-server/shared/fs.ts": "97257db9",
198
+ "core/scripts/mcp-server/shared/prisma.ts": "5133f329",
199
+ "core/scripts/mcp-server/shared/response.ts": "f7806b67",
200
+ "core/scripts/mcp-server/tasks/index.ts": "c040eb75",
201
+ "core/scripts/mcp-server/tasks/runner.ts": "d84bd35d",
202
+ "core/scripts/mcp-server/tasks/store.ts": "2fce1a92",
203
+ "core/scripts/mcp-server/tools/audit.ts": "47ea912f",
204
+ "core/scripts/mcp-server/tools/context.ts": "463df4f4",
205
+ "core/scripts/mcp-server/tools/docs.ts": "a3937aec",
206
+ "core/scripts/mcp-server/tools/gateway.ts": "388ff183",
207
+ "core/scripts/mcp-server/tools/hook-event-report.ts": "3926005b",
208
+ "core/scripts/mcp-server/tools/index.ts": "d5b3bc68",
209
+ "core/scripts/mcp-server/tools/quality.ts": "26ddf75d",
210
+ "core/scripts/mcp-server/types.ts": "6c5e60bc",
211
+ "core/scripts/mcp-server.ts": "99cc6833",
212
+ "core/skills/add-paradigm/SKILL.md": "082b1fb2",
213
+ "core/skills/session-init/SKILL.md": "0fbdc5cd",
214
+ "core/specs/add-coder-npm-package/checklist.md": "ed92032c",
215
+ "core/specs/add-coder-npm-package/spec.md": "c7d0f235",
216
+ "core/specs/add-coder-npm-package/tasks.md": "c34301e5",
217
+ "core/templates/01-架构/《ADD开发工作路径与文档协同规范》.md": "811716d8",
218
+ "core/templates/TERMINOLOGY.md": "e9f4f781",
219
+ "core/templates/add-route-template-heavyweight.md": "8b1eb7c2",
220
+ "core/templates/add-route-template.md": "670f9ebe",
221
+ "core/templates/add-route-template.schema.json": "c29a8f65",
222
+ "core/templates/checklist-template.md": "f904e049",
223
+ "core/templates/checklist-template.schema.json": "fb3a73e8",
224
+ "core/templates/fix-verification-template.md": "9c9ed175",
225
+ "core/templates/fix-verification-template.schema.json": "a18bc6a5",
226
+ "core/templates/handoff-multi-round-template.md": "d3a2375d",
227
+ "core/templates/handoff-multi-round.schema.json": "abed4220",
228
+ "core/templates/handoff-single-round-template.md": "dceb7c86",
229
+ "core/templates/handoff-single-round.schema.json": "0627cda2",
230
+ "core/templates/index.md": "7ffab71a",
231
+ "core/templates/prd-incremental-template.md": "bf8a4a1a",
232
+ "core/templates/prd-incremental-template.schema.json": "7d0d6a39",
233
+ "core/templates/prd-standard-template.md": "f9c53727",
234
+ "core/templates/prd-standard-template.schema.json": "79e7fae0",
235
+ "core/templates/report-template.md": "bc4602ac",
236
+ "core/templates/report-template.schema.json": "44dd2bd0",
237
+ "core/templates/review-implementation-template.md": "a8f8c748",
238
+ "core/templates/review-implementation-template.schema.json": "d97b9eb6",
239
+ "core/templates/review-runtime-template.md": "c5960af1",
240
+ "core/templates/review-runtime-template.schema.json": "c346ea7d",
241
+ "core/templates/review-template.md": "d5fd3323",
242
+ "core/templates/review-template.schema.json": "abc2ece6",
243
+ "core/templates/runtime-report-template.md": "7b35208a",
244
+ "core/templates/runtime-report-template.schema.json": "6c1143e6",
245
+ "core/templates/simple-plan-template.md": "0bb1ebbe",
246
+ "core/templates/simple-plan-template.schema.json": "99d53cc1",
247
+ "core/templates/spec-template.md": "3fe8f818",
248
+ "core/templates/spec-template.schema.json": "b13b3de8",
249
+ "core/templates/standard-plan-template.md": "44d30a4e",
250
+ "core/templates/standard-plan-template.schema.json": "2b767928",
251
+ "core/templates/tasks-template.md": "3a0f318d",
252
+ "core/templates/tasks-template.schema.json": "c046de41",
253
+ "core/tools/README.md": "26a63460",
254
+ "core/vocabulary/add-governance-vocabulary.md": "e2227fae",
255
+ "shared/hooks-lib/common.sh": "441eee52"
256
+ }
@@ -8,6 +8,18 @@ input=$(cat)
8
8
  HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
9
9
  PARENT_DIR="$(dirname "$HOOK_DIR")"
10
10
  MAGIC_DIR="$(basename "$PARENT_DIR")"
11
+ PROJECT_DIR="$PWD"
12
+
13
+ # ── Hook 通知: 拦截事件写入 jsonl(旁路,失败不阻断 exit 2)──
14
+ source "${HOOK_DIR}/lib/notify.sh" 2>/dev/null || true
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
11
23
 
12
24
  # DEBUG: dump stdin for investigation
13
25
  mkdir -p "$MAGIC_DIR/debug-dump"
@@ -44,6 +56,7 @@ CONTENT=$(echo "$input" | jq -r '
44
56
  if [ -z "$CONTENT" ]; then
45
57
  echo "⛔ 拒绝:Write 工具未传 file_content,无法校验手写文档格式" >&2
46
58
  echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"ask","permissionDecisionReason":"Write 工具未传 file_content,无法校验手写文档。请用 SearchReplace 改写已有文件,或用 Write 工具重试。"}}'
59
+ write_hook_event "doc-format-guard" "deny" "Write" "Write 工具未传 file_content" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
47
60
  exit 2
48
61
  fi
49
62
 
@@ -91,6 +104,7 @@ if [ -z "$TEMPLATE_NAME" ]; then
91
104
  else
92
105
  echo "⛔ handoff 文件内容无法识别模板类型(缺 '## 全局元信息' 或 '## 1. 交接前状态'),拒绝写入" >&2
93
106
  echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"ask","permissionDecisionReason":"handoff 内容不符合 single/multi 模板规范"}}'
107
+ write_hook_event "doc-format-guard" "deny" "$file_path" "handoff 模板类型无法识别" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
94
108
  exit 2
95
109
  fi
96
110
  ;;
@@ -111,6 +125,7 @@ if [ -z "$TEMPLATE_NAME" ]; then
111
125
  fi
112
126
  echo "⛔ 拒绝:无法识别文档类型 (file_path: $file_path),缺少模板匹配规则" >&2
113
127
  echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"ask","permissionDecisionReason":"无法识别 ADD 文档类型,请联系管理员更新 doc-format-guard.sh"}}'
128
+ write_hook_event "doc-format-guard" "deny" "$file_path" "无法识别文档类型" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
114
129
  exit 2
115
130
  ;;
116
131
  esac
@@ -122,6 +137,7 @@ SCHEMA_FILE="$TEMPLATES_DIR/${TEMPLATE_NAME%.md}.schema.json"
122
137
  if [ ! -f "$SCHEMA_FILE" ]; then
123
138
  echo "⛔ 阻断:模板 ${TEMPLATE_NAME} 缺少对应的 .schema.json 校验规则" >&2
124
139
  echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"ask","permissionDecisionReason":"缺少 .schema.json 校验规则文件,禁止无规则放行"}}'
140
+ write_hook_event "doc-format-guard" "deny" "$file_path" "缺少 .schema.json 校验规则" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
125
141
  exit 2
126
142
  fi
127
143
 
@@ -172,6 +188,7 @@ if [ -n "$ISSUES" ]; then
172
188
  echo "⛔ $TEMPLATE_NAME 校验不通过:
173
189
  $ISSUES" >&2
174
190
  echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"ask\",\"permissionDecisionReason\":\"文档格式校验不通过,请对照模板修正\"}}"
191
+ write_hook_event "doc-format-guard" "deny" "$file_path" "文档格式校验不通过" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
175
192
  exit 2
176
193
  fi
177
194
 
@@ -0,0 +1,34 @@
1
+ #!/bin/bash
2
+ # notify.sh — Hook 拦截事件写入 jsonl(零外部依赖,bash 原生)
3
+ # 用法: source 后在 exit 2 前调用 write_hook_event
4
+ #
5
+ # 写入格式(7 字段 jsonl):
6
+ # {"ts":"ISO8601","hook":"...","decision":"deny","cmd":"...","reason":"...","planKeyword":"...","planStatus":"..."}
7
+ #
8
+ # 磁盘管理:
9
+ # - 单文件 ≤256KB,超限轮转为 .old(覆盖,不累积多份)
10
+ # - 总量 ≤512KB(当前 + 一个 .old)
11
+ # - MCP Server 宕机不丢事件,重启后从文件恢复消费
12
+
13
+ write_hook_event() {
14
+ local hook="$1" decision="$2" cmd="$3" reason="$4" plan="${5:-unknown}" status="${6:-none}"
15
+ local dir="${MAGIC_DIR:-.qoder}/reports"
16
+ mkdir -p "$dir" 2>/dev/null || true
17
+ local file="$dir/hook-events.jsonl"
18
+
19
+ # 超过 256KB 自动轮转(262144 bytes)
20
+ if [ -f "$file" ]; then
21
+ local sz
22
+ sz=$(stat -c%s "$file" 2>/dev/null || echo 0)
23
+ [ "$sz" -gt 262144 ] && mv "$file" "${file}.old" 2>/dev/null || true
24
+ fi
25
+
26
+ printf '{"ts":"%s","hook":"%s","decision":"%s","cmd":"%s","reason":"%s","planKeyword":"%s","planStatus":"%s"}\n' \
27
+ "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
28
+ "$hook" \
29
+ "$decision" \
30
+ "$cmd" \
31
+ "$reason" \
32
+ "$plan" \
33
+ "$status" >> "$file"
34
+ }
@@ -7,6 +7,17 @@ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
7
7
  export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
8
8
  COMMON_LIB="$HOOK_DIR/lib/common.sh"
9
9
  [ -f "$COMMON_LIB" ] && source "$COMMON_LIB"
10
+ [ -f "$HOOK_DIR/lib/notify.sh" ] && source "$HOOK_DIR/lib/notify.sh" 2>/dev/null || true
11
+
12
+ # ── Hook 通知: 提前计算 Plan 关联信息 ──
13
+ ACTIVE_PLAN=$(detect_active_add 2>/dev/null || true)
14
+ if [ -n "$ACTIVE_PLAN" ]; then
15
+ PLAN_KEYWORD="${ACTIVE_PLAN%%::*}"
16
+ PLAN_STATUS="active"
17
+ else
18
+ PLAN_KEYWORD="no-active-plan"
19
+ PLAN_STATUS="none"
20
+ fi
10
21
 
11
22
  input=$(parse_input)
12
23
  tool_name=$(json_get "$input" "tool_name")
@@ -20,21 +31,25 @@ if [ "$tool_name" = "Bash" ]; then
20
31
  # 危险命令
21
32
  if echo "$cmd" | grep -qiE 'rm[[:space:]]+-rf[[:space:]]+/|DROP[[:space:]]+TABLE|git[[:space:]]+push[[:space:]]+--force|mkfs\.|dd[[:space:]]+if='; then
22
33
  echo "⛔ 危险命令已被阻止: $cmd" >&2
34
+ write_hook_event "pre-tool-use" "deny" "$cmd" "危险命令已被阻止" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
23
35
  exit $EXIT_BLOCK
24
36
  fi
25
37
  # 终端写文件拦截(含 > / >> / << heredoc / mv / touch / python -c > file)
26
38
  if echo "$cmd" | grep -qE '(cat|echo|tee|sed[[:space:]]+-i|awk|printf|cp|mv|dd|touch)[[:space:]]*.*([>]{1,2}|[|][[:space:]]*tee|<<)'; then
27
39
  echo "⛔ 禁止通过终端命令直接写文件: $cmd。请使用 Write/Edit/SearchReplace 工具。" >&2
40
+ write_hook_event "pre-tool-use" "deny" "$cmd" "禁止通过终端直接写文件" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
28
41
  exit $EXIT_BLOCK
29
42
  fi
30
- # mv 无重定向但仍操作文件
31
- if echo "$cmd" | grep -qE '^[[:space:]]*mv[[:space:]]+/tmp/'; then
32
- echo "⛔ 禁止通过 mv /tmp/ 绕过 IDE 工具: $cmd" >&2
43
+ # cp / mv / touch — 可创建或覆盖文件,无重定向也拦(对齐 core §A 检测5)
44
+ if echo "$cmd" | grep -qE '(^|;|\|\||&&|\|)\s*(cp|mv|touch)\b'; then
45
+ echo "⛔ 禁止通过 cp/mv/touch 操作文件: $cmd。请使用 Write 或 SearchReplace 工具。" >&2
46
+ write_hook_event "pre-tool-use" "deny" "$cmd" "禁止通过 cp/mv/touch 操作文件" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
33
47
  exit $EXIT_BLOCK
34
48
  fi
35
- # python/node 脚本写文件
36
- if echo "$cmd" | grep -qE '(python3|python|node)[[:space:]].*[>]{1,2}'; then
37
- echo "⛔ 禁止通过脚本语言直接写文件: $cmd。请使用 Write/Edit/SearchReplace 工具。" >&2
49
+ # python/node/ruby/perl/php 脚本解释器 — 可写任意文件
50
+ if echo "$cmd" | grep -qE '(^|;|\|\||&&|\|)\s*(python3?|node|ruby|perl|php)(\s|$)'; then
51
+ echo "⛔ 禁止通过脚本解释器直接写文件: $cmd。请使用 WriteSearchReplace 工具。" >&2
52
+ write_hook_event "pre-tool-use" "deny" "$cmd" "禁止通过脚本解释器直接修改文件" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
38
53
  exit $EXIT_BLOCK
39
54
  fi
40
55
  mark_dev_action
@@ -51,7 +66,10 @@ if [ "$tool_name" = "Write" ] || [ "$tool_name" = "Edit" ]; then
51
66
  if type detect_active_add >/dev/null 2>&1; then
52
67
  state=$(detect_active_add 2>/dev/null || true)
53
68
  if [ -z "$state" ]; then
54
- echo "[ADD PreToolUse] ⚠️ 正在写入 Plan/Spec/Review 文档但无活跃 ADD Plan——请先执行 add-paradigm" >&2
69
+ echo " 正在写入 Plan/Spec/Review 文档但无活跃 ADD Plan——请先执行 add-paradigm" >&2
70
+ echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"Plan/Spec/Review 写入需要活跃 ADD Plan,请先执行 add-paradigm\"}}"
71
+ write_hook_event "pre-tool-use" "deny" "$file_path" "Plan/Spec/Review 写入需活跃 ADD Plan" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
72
+ exit $EXIT_BLOCK
55
73
  fi
56
74
  fi
57
75
  fi
@@ -59,6 +77,7 @@ if [ "$tool_name" = "Write" ] || [ "$tool_name" = "Edit" ]; then
59
77
  # 敏感文件保护
60
78
  if echo "$file_path" | grep -qE '\.env$|\.env\.production$|\.env\.local$|credentials|secrets'; then
61
79
  echo "⛔ 敏感文件受保护,禁止写入: $file_path" >&2
80
+ write_hook_event "pre-tool-use" "deny" "$file_path" "敏感文件受保护" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
62
81
  exit $EXIT_BLOCK
63
82
  fi
64
83
 
@@ -8,6 +8,7 @@ export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
8
8
 
9
9
  COMMON_LIB="$HOOK_DIR/lib/common.sh"
10
10
  [ -f "$COMMON_LIB" ] && source "$COMMON_LIB"
11
+ [ -f "$HOOK_DIR/lib/notify.sh" ] && source "$HOOK_DIR/lib/notify.sh" 2>/dev/null || true
11
12
 
12
13
  export PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$PWD}"
13
14
 
@@ -56,6 +57,7 @@ if [ -z "$state" ]; then
56
57
  Step 8: 收敛判断
57
58
  如果 add-paradigm SKILL 尚未激活,请先调用它。
58
59
  EOF
60
+ write_hook_event "prompt-submit" "deny" "$prompt" "无活跃 ADD Plan 下检测到开发任务" "no-active-plan" "none" 2>/dev/null || true
59
61
  exit 2
60
62
  fi
61
63
 
@@ -69,6 +71,20 @@ cat <<EOF
69
71
  handoff: ${handoff}
70
72
  EOF
71
73
 
74
+ # ─── Hook 治理日报(注入 AI 上下文)───
75
+ HOOK_JSONL="${MAGIC_DIR:-.qoder}/reports/hook-events.jsonl"
76
+ if [ -f "$HOOK_JSONL" ]; then
77
+ TODAY="$(date +%Y-%m-%d)"
78
+ TOTAL=$(grep -c "\"ts\":\"${TODAY}" "$HOOK_JSONL" 2>/dev/null || echo 0)
79
+ NO_PLAN=$(grep "\"ts\":\"${TODAY}" "$HOOK_JSONL" 2>/dev/null | grep -c '"planKeyword":"no-active-plan"' || echo 0)
80
+ if [ "$TOTAL" -gt 0 ] 2>/dev/null; then
81
+ echo "[Hook 治理] 今日拦截: ${TOTAL} 次 | 无 Plan 违规: ${NO_PLAN} 次"
82
+ if [ "$NO_PLAN" -ge 10 ] 2>/dev/null; then
83
+ echo "[Hook ⚠️] 无 Plan 违规已达 ${NO_PLAN} 次(≥10),建议创建 Plan"
84
+ fi
85
+ fi
86
+ fi
87
+
72
88
  # 模板全文注入(tpl-injected 去重)
73
89
  TPL_SCRIPT="$HOOK_DIR/lib/preload-templates.sh"
74
90
  if [ -f "$TPL_SCRIPT" ]; then
@@ -5,6 +5,18 @@ set -euo pipefail
5
5
  input=$(cat)
6
6
 
7
7
  MAGIC_DIR=".codex"
8
+ PROJECT_DIR="$PWD"
9
+
10
+ # ── Hook 通知: 拦截事件写入 jsonl(旁路,失败不阻断 exit 2)──
11
+ source "${HOOK_DIR}/lib/notify.sh" 2>/dev/null || true
12
+ ACTIVE_PLAN=$(detect_active_add 2>/dev/null || true)
13
+ if [ -n "$ACTIVE_PLAN" ]; then
14
+ PLAN_KEYWORD="${ACTIVE_PLAN%%::*}"
15
+ PLAN_STATUS="active"
16
+ else
17
+ PLAN_KEYWORD="no-active-plan"
18
+ PLAN_STATUS="none"
19
+ fi
8
20
 
9
21
  # DEBUG: dump stdin for investigation
10
22
  mkdir -p "$MAGIC_DIR/debug-dump"
@@ -41,6 +53,7 @@ CONTENT=$(echo "$input" | jq -r '
41
53
  if [ -z "$CONTENT" ]; then
42
54
  echo "⛔ 拒绝:Write 工具未传 file_content,无法校验手写文档格式" >&2
43
55
  echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"ask","permissionDecisionReason":"Write 工具未传 file_content,无法校验手写文档。请用 SearchReplace 改写已有文件,或用 Write 工具重试。"}}'
56
+ write_hook_event "doc-format-guard" "deny" "Write" "Write 工具未传 file_content" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
44
57
  exit 2
45
58
  fi
46
59
 
@@ -90,6 +103,7 @@ if [ -z "$TEMPLATE_NAME" ]; then
90
103
  else
91
104
  echo "⛔ handoff 文件内容无法识别模板类型(缺 '## 全局元信息' 或 '## 1. 交接前状态'),拒绝写入" >&2
92
105
  echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"ask","permissionDecisionReason":"handoff 内容不符合 single/multi 模板规范"}}'
106
+ write_hook_event "doc-format-guard" "deny" "$file_path" "handoff 模板类型无法识别" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
93
107
  exit 2
94
108
  fi
95
109
  ;;
@@ -110,6 +124,7 @@ if [ -z "$TEMPLATE_NAME" ]; then
110
124
  fi
111
125
  echo "⛔ 拒绝:无法识别文档类型 (file_path: $file_path),缺少模板匹配规则" >&2
112
126
  echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"ask","permissionDecisionReason":"无法识别 ADD 文档类型,请联系管理员更新 doc-format-guard.sh"}}'
127
+ write_hook_event "doc-format-guard" "deny" "$file_path" "无法识别文档类型" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
113
128
  exit 2
114
129
  ;;
115
130
  esac
@@ -121,6 +136,7 @@ SCHEMA_FILE="$TEMPLATES_DIR/${TEMPLATE_NAME%.md}.schema.json"
121
136
  if [ ! -f "$SCHEMA_FILE" ]; then
122
137
  echo "⛔ 阻断:模板 ${TEMPLATE_NAME} 缺少对应的 .schema.json 校验规则" >&2
123
138
  echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"ask","permissionDecisionReason":"缺少 .schema.json 校验规则文件,禁止无规则放行"}}'
139
+ write_hook_event "doc-format-guard" "deny" "$file_path" "缺少 .schema.json 校验规则" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
124
140
  exit 2
125
141
  fi
126
142
 
@@ -227,6 +243,7 @@ if [ -n "$ISSUES" ]; then
227
243
  echo "⛔ $TEMPLATE_NAME 校验不通过:
228
244
  $ISSUES" >&2
229
245
  echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"ask\",\"permissionDecisionReason\":\"文档格式校验不通过,请对照模板修正\"}}"
246
+ write_hook_event "doc-format-guard" "deny" "$file_path" "文档格式校验不通过" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
230
247
  exit 2
231
248
  fi
232
249
 
@@ -0,0 +1,34 @@
1
+ #!/bin/bash
2
+ # notify.sh — Hook 拦截事件写入 jsonl(零外部依赖,bash 原生)
3
+ # 用法: source 后在 exit 2 前调用 write_hook_event
4
+ #
5
+ # 写入格式(7 字段 jsonl):
6
+ # {"ts":"ISO8601","hook":"...","decision":"deny","cmd":"...","reason":"...","planKeyword":"...","planStatus":"..."}
7
+ #
8
+ # 磁盘管理:
9
+ # - 单文件 ≤256KB,超限轮转为 .old(覆盖,不累积多份)
10
+ # - 总量 ≤512KB(当前 + 一个 .old)
11
+ # - MCP Server 宕机不丢事件,重启后从文件恢复消费
12
+
13
+ write_hook_event() {
14
+ local hook="$1" decision="$2" cmd="$3" reason="$4" plan="${5:-unknown}" status="${6:-none}"
15
+ local dir="${MAGIC_DIR:-.qoder}/reports"
16
+ mkdir -p "$dir" 2>/dev/null || true
17
+ local file="$dir/hook-events.jsonl"
18
+
19
+ # 超过 256KB 自动轮转(262144 bytes)
20
+ if [ -f "$file" ]; then
21
+ local sz
22
+ sz=$(stat -c%s "$file" 2>/dev/null || echo 0)
23
+ [ "$sz" -gt 262144 ] && mv "$file" "${file}.old" 2>/dev/null || true
24
+ fi
25
+
26
+ printf '{"ts":"%s","hook":"%s","decision":"%s","cmd":"%s","reason":"%s","planKeyword":"%s","planStatus":"%s"}\n' \
27
+ "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
28
+ "$hook" \
29
+ "$decision" \
30
+ "$cmd" \
31
+ "$reason" \
32
+ "$plan" \
33
+ "$status" >> "$file"
34
+ }