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.
- package/README.md +66 -27
- package/dist/index.js +158 -11
- package/package.json +9 -12
- package/templates/.add-coder-src-hash.json +256 -0
- package/templates/adapters/claude/hooks/doc-format-guard.sh +17 -0
- package/templates/adapters/claude/hooks/lib/notify.sh +34 -0
- package/templates/adapters/claude/hooks/pre-tool-use.sh +26 -7
- package/templates/adapters/claude/hooks/prompt-submit.sh +16 -0
- package/templates/adapters/codex/hooks/doc-format-guard.sh +17 -0
- package/templates/adapters/codex/hooks/lib/notify.sh +34 -0
- package/templates/adapters/codex/hooks/pre-tool-use.sh +48 -18
- package/templates/adapters/codex/hooks/prompt-submit.sh +16 -0
- package/templates/adapters/qoder/hooks/doc-format-guard.sh +17 -0
- package/templates/adapters/qoder/hooks/lib/notify.sh +34 -0
- package/templates/adapters/qoder/hooks/pre-tool-use.sh +28 -9
- package/templates/adapters/qoder/hooks/prompt-submit.sh +18 -1
- package/templates/adapters/trae/hooks/doc-format-guard.sh +17 -0
- package/templates/adapters/trae/hooks/lib/notify.sh +34 -0
- package/templates/adapters/trae/hooks/pre-tool-use.sh +48 -18
- package/templates/adapters/trae/hooks/prompt-submit.sh +16 -0
- package/templates/adapters/vscode/hooks/doc-format-guard.sh +16 -0
- package/templates/adapters/vscode/hooks/lib/notify.sh +34 -0
- package/templates/adapters/vscode/hooks/pre-tool-use.sh +26 -7
- package/templates/adapters/vscode/hooks/prompt-submit.sh +16 -0
- package/templates/core/hooks/doc-format-guard.sh +17 -0
- package/templates/core/hooks/lib/notify.sh +34 -0
- package/templates/core/hooks/pre-tool-use.sh +48 -18
- package/templates/core/hooks/prompt-submit.sh +16 -0
- package/templates/core/reviews/.gitkeep +0 -0
- package/templates/core/scripts/mcp-server/elicitation/confirm.ts +30 -0
- package/templates/core/scripts/mcp-server/elicitation/index.ts +1 -0
- package/templates/core/scripts/mcp-server/index.ts +15 -0
- package/templates/core/scripts/mcp-server/notifications/hitl.ts +49 -0
- package/templates/core/scripts/mcp-server/notifications/hook.ts +268 -0
- package/templates/core/scripts/mcp-server/notifications/index.ts +8 -0
- package/templates/core/scripts/mcp-server/resources/add-coder-version.ts +25 -0
- package/templates/core/scripts/mcp-server/resources/add-state.ts +44 -0
- package/templates/core/scripts/mcp-server/resources/hook-events-report.ts +104 -0
- package/templates/core/scripts/mcp-server/resources/index.ts +12 -0
- package/templates/core/scripts/mcp-server/resources/round-task.ts +22 -0
- package/templates/core/scripts/mcp-server/sampling/index.ts +1 -0
- package/templates/core/scripts/mcp-server/sampling/review.ts +47 -0
- package/templates/core/scripts/mcp-server/shared/env.ts +26 -0
- package/templates/core/scripts/mcp-server/shared/fs.ts +40 -0
- package/templates/core/scripts/mcp-server/shared/prisma.ts +35 -0
- package/templates/core/scripts/mcp-server/shared/response.ts +9 -0
- package/templates/core/scripts/mcp-server/tasks/index.ts +2 -0
- package/templates/core/scripts/mcp-server/tasks/runner.ts +20 -0
- package/templates/core/scripts/mcp-server/tasks/store.ts +20 -0
- package/templates/core/scripts/mcp-server/tools/audit.ts +73 -0
- package/templates/core/scripts/mcp-server/tools/context.ts +337 -0
- package/templates/core/scripts/mcp-server/tools/docs.ts +42 -0
- package/templates/core/scripts/mcp-server/tools/gateway.ts +135 -0
- package/templates/core/scripts/mcp-server/tools/hook-event-report.ts +92 -0
- package/templates/core/scripts/mcp-server/tools/index.ts +17 -0
- package/templates/core/scripts/mcp-server/tools/quality.ts +93 -0
- package/templates/core/scripts/mcp-server/types.ts +7 -0
- 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 '
|
|
32
|
-
echo "⛔ 禁止通过 mv
|
|
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|
|
|
37
|
-
echo "⛔
|
|
49
|
+
# python/node/ruby/perl/php 脚本解释器 — 可写任意文件
|
|
50
|
+
if echo "$cmd" | grep -qE '(^|;|\|\||&&|\|)\s*(python3?|node|ruby|perl|php)(\s|$)'; then
|
|
51
|
+
echo "⛔ 禁止通过脚本解释器直接写文件: $cmd。请使用 Write 或 SearchReplace 工具。" >&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 "
|
|
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
|
+
}
|