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.
- package/README.md +282 -155
- package/dist/index.js +481 -209
- package/package.json +15 -4
- package/templates/.add-coder-src-hash.json +186 -185
- package/templates/adapters/claude/hooks/doc-format-guard.ts +32 -0
- package/templates/adapters/claude/hooks/lib/claude-env.ts +7 -0
- package/templates/adapters/claude/hooks/notification.ts +24 -0
- package/templates/adapters/claude/hooks/permission-denied.ts +33 -0
- package/templates/adapters/claude/hooks/permission-gate.ts +12 -0
- package/templates/adapters/claude/hooks/post-tool-failure.ts +4 -0
- package/templates/adapters/claude/hooks/post-tool-use.ts +17 -0
- package/templates/adapters/claude/hooks/pre-compact.ts +10 -0
- package/templates/adapters/claude/hooks/pre-tool-use.ts +81 -0
- package/templates/adapters/claude/hooks/prompt-submit.ts +82 -0
- package/templates/adapters/claude/hooks/review-checklist.ts +4 -0
- package/templates/adapters/claude/hooks/session-end.ts +10 -0
- package/templates/adapters/claude/hooks/session-start.ts +24 -0
- package/templates/adapters/claude/hooks/stop-check.ts +15 -0
- package/templates/adapters/claude/hooks/stop-failure.ts +34 -0
- package/templates/adapters/claude/hooks/subagent-guard.ts +25 -0
- package/templates/adapters/claude/hooks/subagent-stop.ts +12 -0
- package/templates/adapters/claude/settings.json +13 -13
- package/templates/adapters/codex/config.toml.example +12 -0
- package/templates/adapters/codex/hooks/doc-format-guard.ts +30 -0
- package/templates/adapters/codex/hooks/notification.ts +26 -0
- package/templates/adapters/codex/hooks/permission-gate.ts +15 -0
- package/templates/adapters/codex/hooks/post-tool-failure.ts +14 -0
- package/templates/adapters/codex/hooks/post-tool-use.ts +85 -0
- package/templates/adapters/codex/hooks/pre-compact.ts +20 -0
- package/templates/adapters/codex/hooks/pre-tool-use.ts +141 -0
- package/templates/adapters/codex/hooks/prompt-submit.ts +38 -0
- package/templates/adapters/codex/hooks/review-checklist.ts +5 -0
- package/templates/adapters/codex/hooks/session-end.ts +19 -0
- package/templates/adapters/codex/hooks/session-start.ts +45 -0
- package/templates/adapters/codex/hooks/stop-check.ts +59 -0
- package/templates/adapters/codex/hooks/subagent-guard.ts +22 -0
- package/templates/adapters/codex/hooks/subagent-stop.ts +20 -0
- package/templates/adapters/codex/hooks.json +67 -1
- package/templates/adapters/qoder/hooks/doc-format-guard.ts +34 -0
- package/templates/adapters/qoder/hooks/lib/context-inject.ts +61 -0
- package/templates/adapters/qoder/hooks/lib/qoder-env.ts +23 -0
- package/templates/adapters/qoder/hooks/lib/review-checklist.ts +5 -0
- package/templates/adapters/qoder/hooks/notification.ts +34 -0
- package/templates/adapters/qoder/hooks/permission-gate.ts +26 -0
- package/templates/adapters/qoder/hooks/post-tool-failure.ts +30 -0
- package/templates/adapters/qoder/hooks/post-tool-use.ts +32 -0
- package/templates/adapters/qoder/hooks/pre-compact.ts +16 -0
- package/templates/adapters/qoder/hooks/pre-tool-use.ts +112 -0
- package/templates/adapters/qoder/hooks/prompt-submit.ts +66 -0
- package/templates/adapters/qoder/hooks/review-checklist.ts +24 -0
- package/templates/adapters/qoder/hooks/session-end.ts +27 -0
- package/templates/adapters/qoder/hooks/session-start.ts +83 -0
- package/templates/adapters/qoder/hooks/stop-check.ts +69 -0
- package/templates/adapters/qoder/hooks/subagent-guard.ts +16 -0
- package/templates/adapters/qoder/hooks/subagent-stop.ts +33 -0
- package/templates/adapters/qoder/settings.json +13 -13
- package/templates/adapters/trae/hooks/doc-format-guard.ts +30 -0
- package/templates/adapters/trae/hooks/notification.ts +22 -0
- package/templates/adapters/trae/hooks/permission-gate.ts +15 -0
- package/templates/adapters/trae/hooks/post-tool-failure.ts +14 -0
- package/templates/adapters/trae/hooks/post-tool-use.ts +24 -0
- package/templates/adapters/trae/hooks/pre-compact.ts +15 -0
- package/templates/adapters/trae/hooks/pre-tool-use.ts +40 -0
- package/templates/adapters/trae/hooks/prompt-submit.ts +29 -0
- package/templates/adapters/trae/hooks/review-checklist.ts +5 -0
- package/templates/adapters/trae/hooks/session-end.ts +16 -0
- package/templates/adapters/trae/hooks/session-start.ts +15 -0
- package/templates/adapters/trae/hooks/stop-check.ts +20 -0
- package/templates/adapters/trae/hooks/subagent-guard.ts +22 -0
- package/templates/adapters/trae/hooks/subagent-stop.ts +15 -0
- package/templates/adapters/trae/hooks.json +1 -1
- package/templates/adapters/vscode/hooks/doc-format-guard.ts +27 -0
- package/templates/adapters/vscode/hooks/notification.ts +22 -0
- package/templates/adapters/vscode/hooks/permission-gate.ts +15 -0
- package/templates/adapters/vscode/hooks/post-tool-failure.ts +32 -0
- package/templates/adapters/vscode/hooks/post-tool-use.ts +25 -0
- package/templates/adapters/vscode/hooks/pre-compact.ts +15 -0
- package/templates/adapters/vscode/hooks/pre-tool-use.ts +78 -0
- package/templates/adapters/vscode/hooks/prompt-submit.ts +74 -0
- package/templates/adapters/vscode/hooks/review-checklist.ts +5 -0
- package/templates/adapters/vscode/hooks/session-end.ts +16 -0
- package/templates/adapters/vscode/hooks/session-start.ts +24 -0
- package/templates/adapters/vscode/hooks/stop-check.ts +21 -0
- package/templates/adapters/vscode/hooks/subagent-guard.ts +21 -0
- package/templates/adapters/vscode/hooks/subagent-stop.ts +15 -0
- package/templates/core/docs/ADD-governance-claude-code.md +4 -4
- package/templates/core/docs/ADD-governance-codex.md +6 -6
- package/templates/core/docs/ADD-governance-qoder-cn.md +5 -5
- package/templates/core/docs/ADD-governance-trae.md +3 -3
- package/templates/core/docs/ADD-governance-vscode-copilot.md +22 -23
- package/templates/core/governance/audit-bridge.ts +47 -0
- package/templates/core/governance/common.ts +299 -0
- package/templates/core/governance/context-inject.ts +53 -0
- package/templates/core/governance/doc-format-guard.ts +440 -0
- package/templates/core/governance/notification-router.ts +62 -0
- package/templates/core/governance/notify.ts +66 -0
- package/templates/core/governance/permission-gate-router.ts +42 -0
- package/templates/core/governance/post-tool-failure-router.ts +56 -0
- package/templates/core/governance/post-tool-router.ts +212 -0
- package/templates/core/governance/pre-compact-guard.ts +41 -0
- package/templates/core/governance/pre-tool-guard.ts +309 -0
- package/templates/core/governance/preload-templates.ts +241 -0
- package/templates/core/governance/prompt-router.ts +222 -0
- package/templates/core/governance/review-checklist-guard.ts +186 -0
- package/templates/core/governance/rules.ts +720 -0
- package/templates/core/governance/session-end.ts +88 -0
- package/templates/core/governance/session-start-guard.ts +99 -0
- package/templates/core/governance/state-detect.ts +6 -0
- package/templates/core/governance/stop-router.ts +140 -0
- package/templates/core/governance/subagent-guard-router.ts +35 -0
- package/templates/core/governance/subagent-stop-router.ts +93 -0
- package/templates/core/governance/subagent-stop.ts +75 -0
- package/templates/core/governance/vocabulary.ts +109 -0
- package/templates/core/hooks/doc-format-guard.ts +21 -0
- package/templates/core/hooks/notification.ts +11 -0
- package/templates/core/hooks/permission-gate.ts +7 -0
- package/templates/core/hooks/post-tool-failure.ts +7 -0
- package/templates/core/hooks/post-tool-use.ts +23 -0
- package/templates/core/hooks/pre-compact.ts +9 -0
- package/templates/core/hooks/pre-tool-use.ts +30 -0
- package/templates/core/hooks/prompt-submit.ts +11 -0
- package/templates/core/hooks/review-checklist.ts +4 -0
- package/templates/core/hooks/session-end.ts +10 -0
- package/templates/core/hooks/session-start.ts +9 -0
- package/templates/core/hooks/stop-check.ts +14 -0
- package/templates/core/hooks/subagent-guard.ts +8 -0
- package/templates/core/hooks/subagent-stop.ts +9 -0
- package/templates/core/prisma/add.prisma +140 -82
- package/templates/core/rules/project_rules.md +27 -24
- package/templates/core/scripts/db-ensure.sh +8 -0
- package/templates/core/scripts/gen-plan-index.sh +4 -15
- package/templates/core/scripts/mcp-server/notifications/hitl.ts +9 -1
- package/templates/core/scripts/mcp-server/notifications/hook.ts +25 -9
- package/templates/core/scripts/mcp-server/resources/hitl-approval-widget.ts +34 -0
- package/templates/core/scripts/mcp-server/resources/hook-events-report.ts +14 -2
- package/templates/core/scripts/mcp-server/resources/index.ts +2 -0
- package/templates/core/scripts/mcp-server/sampling/review.ts +25 -10
- package/templates/core/scripts/mcp-server/shared/db-types.ts +33 -8
- package/templates/core/scripts/mcp-server/shared/dps-scoring.strategy.ts +1 -1
- package/templates/core/scripts/mcp-server/shared/env.ts +28 -8
- package/templates/core/scripts/mcp-server/shared/fs.ts +3 -0
- package/templates/core/scripts/mcp-server/shared/hitl-interaction.strategy.ts +2 -3
- package/templates/core/scripts/mcp-server/shared/hitl-lifecycle-mutation.ts +129 -0
- package/templates/core/scripts/mcp-server/shared/hitl-proposal-mutation.ts +98 -0
- package/templates/core/scripts/mcp-server/shared/hitl-ui.ts +3 -0
- package/templates/core/scripts/mcp-server/shared/plan-lifecycle-events.ts +62 -0
- package/templates/core/scripts/mcp-server/shared/plan-lifecycle-mutation.ts +78 -0
- package/templates/core/scripts/mcp-server/shared/plan-lifecycle-subscriber.ts +145 -0
- package/templates/core/scripts/mcp-server/shared/plan-lifecycle.ts +153 -0
- package/templates/core/scripts/mcp-server/shared/plan-round-events.ts +56 -0
- package/templates/core/scripts/mcp-server/shared/plan-round-mutation.ts +143 -0
- package/templates/core/scripts/mcp-server/shared/plan-round-store.ts +47 -0
- package/templates/core/scripts/mcp-server/shared/plan-round-subscriber.ts +99 -0
- package/templates/core/scripts/mcp-server/shared/plan-status-store.ts +37 -0
- package/templates/core/scripts/mcp-server/shared/plan-tracking-mutation.ts +71 -0
- package/templates/core/scripts/mcp-server/shared/prisma.ts +12 -6
- package/templates/core/scripts/mcp-server/shared/project-root-strategy.ts +1 -2
- package/templates/core/scripts/mcp-server/shared/quant-recheck.strategy.ts +16 -0
- package/templates/core/scripts/mcp-server/shared/redact.ts +28 -0
- package/templates/core/scripts/mcp-server/shared/response.ts +3 -2
- package/templates/core/scripts/mcp-server/shared/runtime-context.ts +77 -0
- package/templates/core/scripts/mcp-server/shared/schema-topology.ts +159 -0
- package/templates/core/scripts/mcp-server/tools/audit.ts +49 -7
- package/templates/core/scripts/mcp-server/tools/context.ts +117 -121
- package/templates/core/scripts/mcp-server/tools/contract.ts +34 -9
- package/templates/core/scripts/mcp-server/tools/gateway/check_add_route_status.ts +50 -3
- package/templates/core/scripts/mcp-server/tools/gateway/check_doc_similarity.ts +218 -0
- package/templates/core/scripts/mcp-server/tools/gateway/check_dps.ts +22 -7
- package/templates/core/scripts/mcp-server/tools/gateway/check_rahs.ts +86 -4
- package/templates/core/scripts/mcp-server/tools/gateway/check_spec_sync.ts +19 -6
- package/templates/core/scripts/mcp-server/tools/gateway/index.ts +2 -0
- package/templates/core/scripts/mcp-server/tools/hitl.ts +160 -75
- package/templates/core/scripts/mcp-server/tools/hook-event-report.ts +9 -2
- package/templates/core/scripts/mcp-server/tools/index.ts +69 -3
- package/templates/core/scripts/mcp-server/tools/plan.ts +152 -17
- package/templates/core/scripts/mcp-server/tools/review.ts +44 -15
- package/templates/core/scripts/mcp-server.ts +60 -1
- package/templates/core/scripts/plan-status-bridge.ts +26 -0
- package/templates/core/skills/add-paradigm/SKILL.md +2 -2
- package/templates/core/templates/add-route-template.schema.json +24 -56
- package/templates/core/templates/collab-contract-template.md +1 -1
- package/templates/core/templates/handoff-multi-round-template.schema.json +48 -0
- package/templates/core/templates/handoff-single-round-template.schema.json +92 -0
- package/templates/core/templates/handoff-single-round.schema.json +1 -1
- package/templates/core/templates/hitl-approval-widget.html +222 -37
- package/templates/core/templates/spec-template.schema.json +9 -46
- package/templates/core/templates/standard-plan-template.schema.json +1 -1
- package/templates/core/templates/tasks-template.schema.json +13 -54
- package/templates/adapters/claude/hooks/doc-format-guard.sh +0 -202
- package/templates/adapters/claude/hooks/lib/common.sh +0 -261
- package/templates/adapters/claude/hooks/lib/context-inject.sh +0 -96
- package/templates/adapters/claude/hooks/lib/notify.sh +0 -34
- package/templates/adapters/claude/hooks/lib/preload-templates.sh +0 -187
- package/templates/adapters/claude/hooks/lib/session-end.sh +0 -76
- package/templates/adapters/claude/hooks/lib/state-detect.sh +0 -117
- package/templates/adapters/claude/hooks/lib/subagent-stop.sh +0 -90
- package/templates/adapters/claude/hooks/lib/vocabulary.sh +0 -56
- package/templates/adapters/claude/hooks/notification.sh +0 -45
- package/templates/adapters/claude/hooks/permission-denied.sh +0 -42
- package/templates/adapters/claude/hooks/permission-gate.sh +0 -18
- package/templates/adapters/claude/hooks/post-tool-failure.sh +0 -10
- package/templates/adapters/claude/hooks/post-tool-use.sh +0 -35
- package/templates/adapters/claude/hooks/pre-compact.sh +0 -37
- package/templates/adapters/claude/hooks/pre-tool-use.sh +0 -153
- package/templates/adapters/claude/hooks/prompt-submit.sh +0 -99
- package/templates/adapters/claude/hooks/review-checklist.sh +0 -10
- package/templates/adapters/claude/hooks/session-end.sh +0 -21
- package/templates/adapters/claude/hooks/session-start.sh +0 -36
- package/templates/adapters/claude/hooks/stop-check.sh +0 -45
- package/templates/adapters/claude/hooks/stop-failure.sh +0 -44
- package/templates/adapters/claude/hooks/subagent-guard.sh +0 -36
- package/templates/adapters/claude/hooks/subagent-stop.sh +0 -20
- package/templates/adapters/codex/hooks/doc-format-guard.sh +0 -261
- package/templates/adapters/codex/hooks/lib/common.sh +0 -261
- package/templates/adapters/codex/hooks/lib/context-inject.sh +0 -96
- package/templates/adapters/codex/hooks/lib/notify.sh +0 -34
- package/templates/adapters/codex/hooks/lib/preload-templates.sh +0 -187
- package/templates/adapters/codex/hooks/lib/session-end.sh +0 -76
- package/templates/adapters/codex/hooks/lib/state-detect.sh +0 -117
- package/templates/adapters/codex/hooks/lib/subagent-stop.sh +0 -90
- package/templates/adapters/codex/hooks/lib/vocabulary.sh +0 -56
- package/templates/adapters/codex/hooks/notification.sh +0 -45
- package/templates/adapters/codex/hooks/permission-gate.sh +0 -18
- package/templates/adapters/codex/hooks/post-tool-failure.sh +0 -10
- package/templates/adapters/codex/hooks/post-tool-use.sh +0 -138
- package/templates/adapters/codex/hooks/pre-compact.sh +0 -37
- package/templates/adapters/codex/hooks/pre-tool-use.sh +0 -217
- package/templates/adapters/codex/hooks/prompt-submit.sh +0 -87
- package/templates/adapters/codex/hooks/review-checklist.sh +0 -10
- package/templates/adapters/codex/hooks/session-end.sh +0 -38
- package/templates/adapters/codex/hooks/session-start.sh +0 -53
- package/templates/adapters/codex/hooks/stop-check.sh +0 -45
- package/templates/adapters/codex/hooks/subagent-guard.sh +0 -15
- package/templates/adapters/codex/hooks/subagent-stop.sh +0 -47
- package/templates/adapters/qoder/hooks/doc-format-guard.sh +0 -260
- package/templates/adapters/qoder/hooks/lib/common.sh +0 -261
- package/templates/adapters/qoder/hooks/lib/context-inject.sh +0 -96
- package/templates/adapters/qoder/hooks/lib/notify.sh +0 -34
- package/templates/adapters/qoder/hooks/lib/preload-templates.sh +0 -187
- package/templates/adapters/qoder/hooks/lib/session-end.sh +0 -76
- package/templates/adapters/qoder/hooks/lib/state-detect.sh +0 -117
- package/templates/adapters/qoder/hooks/lib/subagent-stop.sh +0 -90
- package/templates/adapters/qoder/hooks/lib/vocabulary.sh +0 -56
- package/templates/adapters/qoder/hooks/notification.sh +0 -25
- package/templates/adapters/qoder/hooks/permission-gate.sh +0 -8
- package/templates/adapters/qoder/hooks/post-tool-failure.sh +0 -8
- package/templates/adapters/qoder/hooks/post-tool-use.sh +0 -121
- package/templates/adapters/qoder/hooks/pre-compact.sh +0 -37
- package/templates/adapters/qoder/hooks/pre-tool-use.sh +0 -154
- package/templates/adapters/qoder/hooks/prompt-submit.sh +0 -96
- package/templates/adapters/qoder/hooks/review-checklist.sh +0 -157
- package/templates/adapters/qoder/hooks/session-end.sh +0 -24
- package/templates/adapters/qoder/hooks/session-start.sh +0 -45
- package/templates/adapters/qoder/hooks/stop-check.sh +0 -48
- package/templates/adapters/qoder/hooks/subagent-guard.sh +0 -27
- package/templates/adapters/qoder/hooks/subagent-stop.sh +0 -26
- package/templates/adapters/trae/hooks/doc-format-guard.sh +0 -261
- package/templates/adapters/trae/hooks/lib/common.sh +0 -261
- package/templates/adapters/trae/hooks/lib/context-inject.sh +0 -96
- package/templates/adapters/trae/hooks/lib/notify.sh +0 -34
- package/templates/adapters/trae/hooks/lib/preload-templates.sh +0 -187
- package/templates/adapters/trae/hooks/lib/session-end.sh +0 -76
- package/templates/adapters/trae/hooks/lib/state-detect.sh +0 -117
- package/templates/adapters/trae/hooks/lib/subagent-stop.sh +0 -90
- package/templates/adapters/trae/hooks/lib/vocabulary.sh +0 -56
- package/templates/adapters/trae/hooks/notification.sh +0 -45
- package/templates/adapters/trae/hooks/permission-gate.sh +0 -18
- package/templates/adapters/trae/hooks/post-tool-failure.sh +0 -10
- package/templates/adapters/trae/hooks/post-tool-use.sh +0 -138
- package/templates/adapters/trae/hooks/pre-compact.sh +0 -37
- package/templates/adapters/trae/hooks/pre-tool-use.sh +0 -217
- package/templates/adapters/trae/hooks/prompt-submit.sh +0 -87
- package/templates/adapters/trae/hooks/review-checklist.sh +0 -10
- package/templates/adapters/trae/hooks/session-end.sh +0 -38
- package/templates/adapters/trae/hooks/session-start.sh +0 -53
- package/templates/adapters/trae/hooks/stop-check.sh +0 -45
- package/templates/adapters/trae/hooks/subagent-guard.sh +0 -15
- package/templates/adapters/trae/hooks/subagent-stop.sh +0 -47
- package/templates/adapters/vscode/hooks/doc-format-guard.sh +0 -201
- package/templates/adapters/vscode/hooks/lib/common.sh +0 -261
- package/templates/adapters/vscode/hooks/lib/context-inject.sh +0 -96
- package/templates/adapters/vscode/hooks/lib/notify.sh +0 -34
- package/templates/adapters/vscode/hooks/lib/preload-templates.sh +0 -187
- package/templates/adapters/vscode/hooks/lib/session-end.sh +0 -76
- package/templates/adapters/vscode/hooks/lib/state-detect.sh +0 -117
- package/templates/adapters/vscode/hooks/lib/subagent-stop.sh +0 -90
- package/templates/adapters/vscode/hooks/lib/vocabulary.sh +0 -56
- package/templates/adapters/vscode/hooks/notification.sh +0 -45
- package/templates/adapters/vscode/hooks/permission-gate.sh +0 -18
- package/templates/adapters/vscode/hooks/post-tool-failure.sh +0 -28
- package/templates/adapters/vscode/hooks/post-tool-use.sh +0 -35
- package/templates/adapters/vscode/hooks/pre-compact.sh +0 -37
- package/templates/adapters/vscode/hooks/pre-tool-use.sh +0 -153
- package/templates/adapters/vscode/hooks/prompt-submit.sh +0 -99
- package/templates/adapters/vscode/hooks/review-checklist.sh +0 -10
- package/templates/adapters/vscode/hooks/session-end.sh +0 -13
- package/templates/adapters/vscode/hooks/session-start.sh +0 -35
- package/templates/adapters/vscode/hooks/stop-check.sh +0 -53
- package/templates/adapters/vscode/hooks/subagent-guard.sh +0 -37
- package/templates/adapters/vscode/hooks/subagent-stop.sh +0 -12
- package/templates/core/hooks/doc-format-guard.sh +0 -261
- package/templates/core/hooks/lib/common.sh +0 -261
- package/templates/core/hooks/lib/context-inject.sh +0 -96
- package/templates/core/hooks/lib/notify.sh +0 -34
- package/templates/core/hooks/lib/preload-templates.sh +0 -187
- package/templates/core/hooks/lib/session-end.sh +0 -76
- package/templates/core/hooks/lib/state-detect.sh +0 -117
- package/templates/core/hooks/lib/subagent-stop.sh +0 -90
- package/templates/core/hooks/lib/vocabulary.sh +0 -56
- package/templates/core/hooks/notification.sh +0 -45
- package/templates/core/hooks/permission-gate.sh +0 -18
- package/templates/core/hooks/post-tool-failure.sh +0 -10
- package/templates/core/hooks/post-tool-use.sh +0 -138
- package/templates/core/hooks/pre-compact.sh +0 -37
- package/templates/core/hooks/pre-tool-use.sh +0 -217
- package/templates/core/hooks/prompt-submit.sh +0 -87
- package/templates/core/hooks/review-checklist.sh +0 -10
- package/templates/core/hooks/session-end.sh +0 -38
- package/templates/core/hooks/session-start.sh +0 -53
- package/templates/core/hooks/stop-check.sh +0 -45
- package/templates/core/hooks/subagent-guard.sh +0 -15
- package/templates/core/hooks/subagent-stop.sh +0 -47
- package/templates/shared/hooks-lib/common.sh +0 -22
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# stop-check.sh — Claude Code Stop:四象限分流 + 验收检查(few-shot 上下文注入)
|
|
3
|
-
# 治理卡位 #7: 验收检查 + devlog + 阻断
|
|
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="$PWD"
|
|
12
|
-
|
|
13
|
-
state=$(detect_active_add 2>/dev/null || true)
|
|
14
|
-
has_dev=$(has_dev_action 2>/dev/null && echo "true" || echo "false")
|
|
15
|
-
|
|
16
|
-
# ═══════ Q1: 无 ADD + 无 dev → 正常停 ═══════
|
|
17
|
-
if [ -z "$state" ] && [ "$has_dev" != "true" ]; then
|
|
18
|
-
exit 0
|
|
19
|
-
fi
|
|
20
|
-
|
|
21
|
-
# ═══════ Q2: 无 ADD + 有 dev → 严重违规,few-shot 注入 ═══════
|
|
22
|
-
if [ -z "$state" ] && [ "$has_dev" = "true" ]; then
|
|
23
|
-
build_stop_context "no_add_has_dev" >&2
|
|
24
|
-
exit $EXIT_BLOCK
|
|
25
|
-
fi
|
|
26
|
-
|
|
27
|
-
IFS='::' read -r plan step rounds handoff add_route <<< "$state"
|
|
28
|
-
|
|
29
|
-
# ═══════ Q3: 有 ADD + 无 dev → 注入状态 ═══════
|
|
30
|
-
if [ "$has_dev" != "true" ]; then
|
|
31
|
-
echo "[ADD Stop] Plan: ${plan}, 轮次: ${rounds}, Step: ${step}"
|
|
32
|
-
echo "本次无代码改动。下次继续时执行 session-init 恢复上下文。"
|
|
33
|
-
exit 0
|
|
34
|
-
fi
|
|
35
|
-
|
|
36
|
-
# ═══════ Q4: 有 ADD + 有 dev → 验收检查 ═══════
|
|
37
|
-
issues=$(check_add_completeness "$handoff" "$add_route" 2>/dev/null || true)
|
|
38
|
-
if [ -n "$issues" ]; then
|
|
39
|
-
build_stop_context "has_add_dev_unclosed" "$issues" >&2
|
|
40
|
-
exit $EXIT_BLOCK
|
|
41
|
-
fi
|
|
42
|
-
|
|
43
|
-
clear_dev_action 2>/dev/null || true
|
|
44
|
-
echo "[ADD Stop] ✅ 验收通过——checklist 全部勾选,devlog 已记录。"
|
|
45
|
-
exit 0
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# SubagentStart/SubagentStop — 子代理门禁(Claude Code 适配)
|
|
3
|
-
set -euo pipefail
|
|
4
|
-
|
|
5
|
-
HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
6
|
-
SHARED_LIB="$HOOK_DIR/../../shared/hooks-lib/common.sh"
|
|
7
|
-
[ -f "$SHARED_LIB" ] && source "$SHARED_LIB"
|
|
8
|
-
|
|
9
|
-
input=$(parse_input)
|
|
10
|
-
event=$(echo "$input" | jq -r '.hook_event_name // empty')
|
|
11
|
-
|
|
12
|
-
if [ "$event" = "SubagentStart" ]; then
|
|
13
|
-
echo "[ADD SubagentGuard] 子代理启动,请确认其遵循 ADD 规范。"
|
|
14
|
-
fi
|
|
15
|
-
exit 0
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# SubagentStop — 通用版(核心模板,Trae 等适配器继承)
|
|
3
|
-
# 治理卡位 #11: 子agent边界校验 + 审计聚合 + 阻断
|
|
4
|
-
set -euo pipefail
|
|
5
|
-
|
|
6
|
-
HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
7
|
-
COMMON_LIB="$HOOK_DIR/lib/common.sh"
|
|
8
|
-
[ -f "$COMMON_LIB" ] && source "$COMMON_LIB"
|
|
9
|
-
|
|
10
|
-
export PROJECT_DIR="$PWD"
|
|
11
|
-
|
|
12
|
-
input=$(cat 2>/dev/null || echo "{}")
|
|
13
|
-
agent_name=$(echo "$input" | jq -r '.agent_type // .subagent_name // "unknown"' 2>/dev/null || echo "unknown")
|
|
14
|
-
|
|
15
|
-
# ── ① 边界校验:检查子 agent 交付物是否超出 spec 范围 ──
|
|
16
|
-
state=$(detect_active_add 2>/dev/null || true)
|
|
17
|
-
if [ -z "$state" ]; then
|
|
18
|
-
echo "[ADD SubagentStop] ⚠️ ${agent_name} 已完成,但无活跃 ADD Plan 无法校验边界" >&2
|
|
19
|
-
exit 0
|
|
20
|
-
fi
|
|
21
|
-
|
|
22
|
-
plan_kw=$(echo "$state" | awk -F'::' '{print $1}')
|
|
23
|
-
handoff=$(echo "$state" | awk -F'::' '{print $4}')
|
|
24
|
-
|
|
25
|
-
echo "[ADD SubagentStop] ${agent_name} 已完成 — 关联 Plan: ${plan_kw}" >&2
|
|
26
|
-
|
|
27
|
-
# 如果 handoff 中存在允许的文件清单,检查交付物是否越界
|
|
28
|
-
if [ -f "$handoff" ]; then
|
|
29
|
-
deliverables=$(echo "$input" | jq -r '.deliverables // ""' 2>/dev/null || echo "")
|
|
30
|
-
if [ -n "$deliverables" ]; then
|
|
31
|
-
violations=""
|
|
32
|
-
for f in $deliverables; do
|
|
33
|
-
if ! grep -q "$f" "$handoff" 2>/dev/null; then
|
|
34
|
-
violations="${violations} $f"
|
|
35
|
-
fi
|
|
36
|
-
done
|
|
37
|
-
if [ -n "$violations" ]; then
|
|
38
|
-
echo "[ADD SubagentStop] ❌ ${agent_name} 交付物超出 spec 边界: ${violations}" >&2
|
|
39
|
-
echo "[ADD SubagentStop] 要求重做——请检查这些文件是否属于本轮 spec 范围" >&2
|
|
40
|
-
exit "${EXIT_BLOCK:-2}"
|
|
41
|
-
fi
|
|
42
|
-
fi
|
|
43
|
-
fi
|
|
44
|
-
|
|
45
|
-
# ── ② 审计聚合 ──
|
|
46
|
-
echo "[ADD SubagentStop] ${agent_name} 边界校验通过 — $(date -Iseconds)" >&2
|
|
47
|
-
exit 0
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# doc-format-guard.sh — schema.json 驱动的 ADD 文档格式守卫
|
|
3
|
-
set -euo pipefail
|
|
4
|
-
|
|
5
|
-
input=$(cat)
|
|
6
|
-
|
|
7
|
-
# 动态探测 MAGIC_DIR(兼容多 adapter)
|
|
8
|
-
HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
9
|
-
PARENT_DIR="$(dirname "$HOOK_DIR")"
|
|
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
|
|
23
|
-
|
|
24
|
-
# DEBUG: dump stdin for investigation
|
|
25
|
-
mkdir -p "$MAGIC_DIR/debug-dump"
|
|
26
|
-
echo "=== $(date) ===" >> "$MAGIC_DIR/debug-dump/stdin.log"
|
|
27
|
-
echo "file_path: $(echo "$input" | jq -r '.tool_input.file_path // "EMPTY"')" >> "$MAGIC_DIR/debug-dump/stdin.log"
|
|
28
|
-
echo "has_file_content: $(echo "$input" | jq 'has("tool_input") and (.tool_input | has("file_content"))')" >> "$MAGIC_DIR/debug-dump/stdin.log"
|
|
29
|
-
echo "has_replacements: $(echo "$input" | jq 'has("tool_input") and (.tool_input | has("replacements"))')" >> "$MAGIC_DIR/debug-dump/stdin.log"
|
|
30
|
-
if echo "$input" | jq -e 'has("tool_input") and (.tool_input | has("file_content"))' > /dev/null 2>&1; then
|
|
31
|
-
echo "[file_content[500]]: $(echo "$input" | jq -r '.tool_input.file_content' | head -c 500)" >> "$MAGIC_DIR/debug-dump/stdin.log"
|
|
32
|
-
fi
|
|
33
|
-
if echo "$input" | jq -e 'has("tool_input") and (.tool_input | has("replacements"))' > /dev/null 2>&1; then
|
|
34
|
-
echo "[replacement_new_text[500]]: $(echo "$input" | jq -r '.tool_input.replacements[0].new_text' | head -c 500)" >> "$MAGIC_DIR/debug-dump/stdin.log"
|
|
35
|
-
fi
|
|
36
|
-
echo "top_keys: $(echo "$input" | jq -r 'keys | join(", ")')" >> "$MAGIC_DIR/debug-dump/stdin.log"
|
|
37
|
-
echo "tool_input_keys: $(echo "$input" | jq -r '.tool_input | keys | join(", ") // "NO_TOOL_INPUT"')" >> "$MAGIC_DIR/debug-dump/stdin.log"
|
|
38
|
-
echo "=== DONE ===" >> "$MAGIC_DIR/debug-dump/stdin.log"
|
|
39
|
-
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
|
|
40
|
-
# L17: 非文件工具事件(空 stdin)→ 不拦截(由 matcher 层过滤)
|
|
41
|
-
[ -z "$file_path" ] && exit 0
|
|
42
|
-
|
|
43
|
-
if ! echo "$file_path" | grep -qE "$MAGIC_DIR/(plans|specs)/"; then
|
|
44
|
-
exit 0
|
|
45
|
-
fi
|
|
46
|
-
|
|
47
|
-
CONTENT=$(echo "$input" | jq -r '
|
|
48
|
-
if .tool_input.file_content then .tool_input.file_content
|
|
49
|
-
elif .tool_input.content then .tool_input.content
|
|
50
|
-
elif .tool_input.new_string then .tool_input.new_string
|
|
51
|
-
elif .tool_input.new_string then .tool_input.new_string
|
|
52
|
-
elif .tool_input.replacements then .tool_input.replacements[0].new_text
|
|
53
|
-
else "" end')
|
|
54
|
-
# L24: PostToolUse 不可阻断(仅反馈),PreToolUse exit 2 + ask 可拦截
|
|
55
|
-
# L24: 文件在 .qoder/(plans|specs)/ 下但 Write 工具未传 content → 无法校验,阻断
|
|
56
|
-
if [ -z "$CONTENT" ]; then
|
|
57
|
-
echo "⛔ 拒绝:Write 工具未传 file_content,无法校验手写文档格式" >&2
|
|
58
|
-
echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"ask","permissionDecisionReason":"Write 工具未传 file_content,无法校验手写文档。请用 SearchReplace 改写已有文件,或用 Write 工具重试。"}}'
|
|
59
|
-
exit 2
|
|
60
|
-
fi
|
|
61
|
-
|
|
62
|
-
PROJECT_DIR="$PWD"
|
|
63
|
-
TEMPLATES_DIR="$PROJECT_DIR/$MAGIC_DIR/templates"
|
|
64
|
-
|
|
65
|
-
# 通过 filename 匹配模板名
|
|
66
|
-
TEMPLATE_NAME=""
|
|
67
|
-
for tmpl in "$TEMPLATES_DIR"/*.md; do
|
|
68
|
-
base=$(basename "$tmpl")
|
|
69
|
-
if echo "$file_path" | grep -q "$base"; then
|
|
70
|
-
TEMPLATE_NAME="$base"
|
|
71
|
-
break
|
|
72
|
-
fi
|
|
73
|
-
done
|
|
74
|
-
|
|
75
|
-
# 退一步:根据文件内容特征猜测模板类型
|
|
76
|
-
if [ -z "$TEMPLATE_NAME" ]; then
|
|
77
|
-
if echo "$CONTENT" | grep -q "## 四、Handoff"; then
|
|
78
|
-
TEMPLATE_NAME="simple-standard-plan-template.md"
|
|
79
|
-
elif echo "$CONTENT" | grep -q "## PLAN 元信息"; then
|
|
80
|
-
TEMPLATE_NAME="standard-plan-template.md"
|
|
81
|
-
elif echo "$CONTENT" | grep -q "## Review 元信息"; then
|
|
82
|
-
if echo "$CONTENT" | grep -q "运行时验证"; then
|
|
83
|
-
TEMPLATE_NAME="review-runtime-template.md"
|
|
84
|
-
elif echo "$CONTENT" | grep -q "跨仓库格式契约"; then
|
|
85
|
-
TEMPLATE_NAME="review-implementation-template.md"
|
|
86
|
-
else
|
|
87
|
-
TEMPLATE_NAME="review-template.md"
|
|
88
|
-
fi
|
|
89
|
-
elif echo "$CONTENT" | grep -q "## Why"; then
|
|
90
|
-
TEMPLATE_NAME="spec-template.md"
|
|
91
|
-
elif echo "$CONTENT" | grep -q "## Preconditions"; then
|
|
92
|
-
TEMPLATE_NAME="tasks-template.md"
|
|
93
|
-
elif echo "$CONTENT" | grep -q "审计链(证据→devlog→checklist)"; then
|
|
94
|
-
TEMPLATE_NAME="checklist-template.md"
|
|
95
|
-
else
|
|
96
|
-
case "$file_path" in
|
|
97
|
-
*handoff*)
|
|
98
|
-
# ★ 按内容特征区分单/多轮 handoff,不依赖文件名
|
|
99
|
-
if echo "$CONTENT" | grep -qF "## 全局元信息"; then
|
|
100
|
-
TEMPLATE_NAME="handoff-multi-round-template.md"
|
|
101
|
-
elif echo "$CONTENT" | grep -qF "## 1. 交接前状态"; then
|
|
102
|
-
TEMPLATE_NAME="handoff-single-round-template.md"
|
|
103
|
-
else
|
|
104
|
-
echo "⛔ handoff 文件内容无法识别模板类型(缺 '## 全局元信息' 或 '## 1. 交接前状态'),拒绝写入" >&2
|
|
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
|
|
107
|
-
exit 2
|
|
108
|
-
fi
|
|
109
|
-
;;
|
|
110
|
-
*plan*) TEMPLATE_NAME="standard-plan-template.md" ;;
|
|
111
|
-
*add-route*heavy*) TEMPLATE_NAME="add-route-template-heavyweight.md" ;;
|
|
112
|
-
*add-route*) TEMPLATE_NAME="add-route-template.md" ;;
|
|
113
|
-
*tasks*) TEMPLATE_NAME="tasks-template.md" ;;
|
|
114
|
-
*spec*) TEMPLATE_NAME="spec-template.md" ;;
|
|
115
|
-
*checklist*) TEMPLATE_NAME="checklist-template.md" ;;
|
|
116
|
-
*report*runtime*) TEMPLATE_NAME="runtime-report-template.md" ;;
|
|
117
|
-
*report*) TEMPLATE_NAME="report-template.md" ;;
|
|
118
|
-
*fix-verif*) TEMPLATE_NAME="fix-verification-template.md" ;;
|
|
119
|
-
*)
|
|
120
|
-
# 增量修订识别:包含 ~~删除线~~ / → 新增标记 / [修订日期] 任意一个 → 视为增量更新,放行
|
|
121
|
-
if echo "$CONTENT" | grep -qE '~~.+~~|→|\[[0-9]{4}-[0-9]{2}-[0-9]{2}\s+修订'; then
|
|
122
|
-
echo "[doc-format-guard] 检测到增量修订格式,跳过完整章节校验" >&2
|
|
123
|
-
exit 0
|
|
124
|
-
fi
|
|
125
|
-
echo "⛔ 拒绝:无法识别文档类型 (file_path: $file_path),缺少模板匹配规则" >&2
|
|
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
|
|
128
|
-
exit 2
|
|
129
|
-
;;
|
|
130
|
-
esac
|
|
131
|
-
fi
|
|
132
|
-
fi
|
|
133
|
-
|
|
134
|
-
SCHEMA_FILE="$TEMPLATES_DIR/${TEMPLATE_NAME%.md}.schema.json"
|
|
135
|
-
# L84: schema 文件不存在 → 无校验规则,阻断(不允许无规则放行)
|
|
136
|
-
if [ ! -f "$SCHEMA_FILE" ]; then
|
|
137
|
-
echo "⛔ 阻断:模板 ${TEMPLATE_NAME} 缺少对应的 .schema.json 校验规则" >&2
|
|
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
|
|
140
|
-
exit 2
|
|
141
|
-
fi
|
|
142
|
-
|
|
143
|
-
# SearchReplace 只传 patch(replacements[].new_text),不传全文件 → 跳过章节校验
|
|
144
|
-
IS_SEARCH_REPLACE=$(echo "$input" | jq -r '(.tool_input.replacements | length > 0) or (.tool_input.new_string != null) // false')
|
|
145
|
-
|
|
146
|
-
ISSUES=""
|
|
147
|
-
|
|
148
|
-
# ── 章节校验 ──
|
|
149
|
-
# 使用项目目录下的临时文件,避免 /tmp 在沙箱中不可写导致静默跳过
|
|
150
|
-
TMPFILE="$PROJECT_DIR/$MAGIC_DIR/.doc-guard-issues.tmp"
|
|
151
|
-
: > "$TMPFILE"
|
|
152
|
-
trap "rm -f $TMPFILE" EXIT
|
|
153
|
-
# SearchReplace 只传 patch → 跳过章节/子章节校验(无法从 patch 推断完整文档结构)
|
|
154
|
-
if [ "$IS_SEARCH_REPLACE" != "true" ]; then
|
|
155
|
-
jq -r '.sections[] | select(.required == true) | .heading' "$SCHEMA_FILE" 2>/dev/null | while IFS= read -r heading; do
|
|
156
|
-
if ! echo "$CONTENT" | grep -qF "$heading"; then
|
|
157
|
-
echo " 缺章节: $heading"
|
|
158
|
-
fi
|
|
159
|
-
done > "$TMPFILE"
|
|
160
|
-
|
|
161
|
-
# 子章节
|
|
162
|
-
jq -r '.sections[].subsections[]?.heading' "$SCHEMA_FILE" 2>/dev/null | while IFS= read -r sub; do
|
|
163
|
-
if ! echo "$CONTENT" | grep -qF "$sub"; then
|
|
164
|
-
echo " 缺子章节: $sub"
|
|
165
|
-
fi
|
|
166
|
-
done >> "$TMPFILE"
|
|
167
|
-
fi
|
|
168
|
-
|
|
169
|
-
# ── 占位符校验 ──
|
|
170
|
-
jq -r '.placeholders[]?' "$SCHEMA_FILE" 2>/dev/null | while IFS= read -r ph; do
|
|
171
|
-
if echo "$CONTENT" | grep -qF "$ph"; then
|
|
172
|
-
echo " 未替换占位符: $ph"
|
|
173
|
-
fi
|
|
174
|
-
done >> "$TMPFILE"
|
|
175
|
-
|
|
176
|
-
# ── 禁止词校验 ──
|
|
177
|
-
jq -r '.forbidden_terms[]?' "$SCHEMA_FILE" 2>/dev/null | while IFS= read -r term; do
|
|
178
|
-
if echo "$CONTENT" | grep -qw "$term"; then
|
|
179
|
-
echo " 禁止词: $term"
|
|
180
|
-
fi
|
|
181
|
-
done >> "$TMPFILE"
|
|
182
|
-
|
|
183
|
-
ISSUES=$(cat "$TMPFILE" 2>/dev/null)
|
|
184
|
-
|
|
185
|
-
# ── 阻断或放行 ──
|
|
186
|
-
if [ -n "$ISSUES" ]; then
|
|
187
|
-
echo "⛔ $TEMPLATE_NAME 校验不通过:
|
|
188
|
-
$ISSUES" >&2
|
|
189
|
-
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"ask\",\"permissionDecisionReason\":\"文档格式校验不通过,请对照模板修正\"}}"
|
|
190
|
-
write_hook_event "doc-format-guard" "deny" "$file_path" "文档格式校验不通过" "$PLAN_KEYWORD" "$PLAN_STATUS" 2>/dev/null || true
|
|
191
|
-
exit 2
|
|
192
|
-
fi
|
|
193
|
-
|
|
194
|
-
# ── 自动更新 index.md ──
|
|
195
|
-
if echo "$file_path" | grep -q "$MAGIC_DIR/plans/"; then
|
|
196
|
-
if [ -x "$PROJECT_DIR/scripts/gen-plan-index.sh" ]; then
|
|
197
|
-
"$PROJECT_DIR/scripts/gen-plan-index.sh" 2>/dev/null || true
|
|
198
|
-
fi
|
|
199
|
-
fi
|
|
200
|
-
|
|
201
|
-
exit 0
|
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
###
|
|
3
|
-
# @Author : xiaomingming wujixmm@gmail.com
|
|
4
|
-
# @Date : 2026-07-17 13:14:46
|
|
5
|
-
# @LastEditors : xiaomingming wujixmm@gmail.com
|
|
6
|
-
# @LastEditTime : 2026-07-17 13:21:36
|
|
7
|
-
# @FilePath : /add-coder/templates/core/hooks/lib/common.sh
|
|
8
|
-
# @Description : ADD Hook 共享库 — 四端通用函数
|
|
9
|
-
###
|
|
10
|
-
# ADD Hook 共享库 — 四端通用函数
|
|
11
|
-
# 被 Claude/Qoder/VS Code/Trae adapter 的 hook 脚本 source 引用
|
|
12
|
-
# 路径: templates/core/hooks/lib/common.sh
|
|
13
|
-
|
|
14
|
-
# 退出码常量,目前适配的ide都一样
|
|
15
|
-
export EXIT_PASS=0 # 放行
|
|
16
|
-
export EXIT_BLOCK=2 # 阻断
|
|
17
|
-
|
|
18
|
-
# ── 输入解析 ──
|
|
19
|
-
|
|
20
|
-
# 从 stdin 解析 JSON 输入(hook 事件通过 stdin 传入 JSON)
|
|
21
|
-
parse_input() {
|
|
22
|
-
if [ -t 0 ]; then
|
|
23
|
-
echo "{}"
|
|
24
|
-
else
|
|
25
|
-
cat
|
|
26
|
-
fi
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
# 从 JSON 中提取字段值(简单实现,不依赖 jq)
|
|
30
|
-
# 用法: json_get "$json" "field_name"
|
|
31
|
-
json_get() {
|
|
32
|
-
echo "$1" | grep -o "\"$2\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" | head -1 | sed 's/.*: *"\([^"]*\)".*/\1/'
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
# ── ADD 活跃 Plan 检测(裁决定逻辑,SKILL §0.7.1) ──
|
|
36
|
-
#
|
|
37
|
-
# 活跃判定标准:
|
|
38
|
-
# 1. magicDir 优先级: 由 Hook 脚本自身的路径推断(.claude/hooks/xxx.sh → .claude)→ .add → stderr 提示全局搜索
|
|
39
|
-
# 2. 索引优先: 先读 plans/index.md 匹配 → 无匹配才 glob *-handoff*.md
|
|
40
|
-
# 3. 活跃定义: add-route 中存在 [ ] 未勾选项 = 活跃;全部 [x] = 已收敛
|
|
41
|
-
# 4. 多 Plan 冲突: 取 add-route 最近 mtime
|
|
42
|
-
# 5. 无 add-route: Plan 初始态,视为活跃
|
|
43
|
-
#
|
|
44
|
-
# 前置条件: 调用方需设置 PROJECT_DIR 环境变量(项目根目录)
|
|
45
|
-
# 返回: "plan_keyword::step_n/total::round_n/total::handoff_path::add_route_path" 或 ""
|
|
46
|
-
|
|
47
|
-
detect_active_add() {
|
|
48
|
-
local plans_dir=""
|
|
49
|
-
|
|
50
|
-
# 1. magicDir 回退: 当前 IDE(CURRENT_MAGIC)→ 目录检测 → .add → 提示全局搜索
|
|
51
|
-
local magic_dirs=()
|
|
52
|
-
if [ -n "${CURRENT_MAGIC:-}" ]; then
|
|
53
|
-
magic_dirs+=("$CURRENT_MAGIC")
|
|
54
|
-
else
|
|
55
|
-
# 兜底: 检测 PROJECT_DIR 下哪个 magicDir 存在
|
|
56
|
-
for m in ".claude" ".qoder" ".vscode" ".trae"; do
|
|
57
|
-
[ -d "${PROJECT_DIR:-$PWD}/$m" ] && { magic_dirs+=("$m"); break; }
|
|
58
|
-
done
|
|
59
|
-
fi
|
|
60
|
-
magic_dirs+=(".add")
|
|
61
|
-
|
|
62
|
-
for magic in "${magic_dirs[@]}"; do
|
|
63
|
-
if [ -d "${PROJECT_DIR:-$PWD}/$magic/plans" ]; then
|
|
64
|
-
plans_dir="${PROJECT_DIR:-$PWD}/$magic/plans"
|
|
65
|
-
break
|
|
66
|
-
fi
|
|
67
|
-
done
|
|
68
|
-
|
|
69
|
-
if [ -z "$plans_dir" ]; then
|
|
70
|
-
echo "[ADD detect] 未在当前 IDE magicDir 和 .add 中找到 plans 目录。是否需要全局搜索所有 magicDir?" >&2
|
|
71
|
-
return 1
|
|
72
|
-
fi
|
|
73
|
-
|
|
74
|
-
local handoff=""
|
|
75
|
-
local add_route=""
|
|
76
|
-
|
|
77
|
-
# 2. 索引优先: 先读 index.md
|
|
78
|
-
if [ -f "$plans_dir/index.md" ]; then
|
|
79
|
-
# 从 index.md 表格提取最近一个 handoff 相对路径
|
|
80
|
-
# 表格格式: | YYYY-MM/DD/path-to-handoff.md | ...
|
|
81
|
-
handoff=$(grep -oE '[0-9]{4}-[0-9]{2}/[0-9]{2}/[^|]*handoff[^|]*\.md' "$plans_dir/index.md" 2>/dev/null | head -1 | xargs)
|
|
82
|
-
if [ -n "$handoff" ] && [ -f "$plans_dir/$handoff" ]; then
|
|
83
|
-
handoff="$plans_dir/$handoff"
|
|
84
|
-
else
|
|
85
|
-
handoff=""
|
|
86
|
-
fi
|
|
87
|
-
fi
|
|
88
|
-
|
|
89
|
-
# 3. 退路: glob handoff 文件(mtime 7 天内)
|
|
90
|
-
if [ -z "$handoff" ]; then
|
|
91
|
-
local today_dir="$plans_dir/$(date +%Y-%m)"
|
|
92
|
-
[ -d "$today_dir" ] && handoff=$(find "$today_dir" -name "*handoff*.md" -mtime -7 -type f 2>/dev/null | head -1)
|
|
93
|
-
[ -z "$handoff" ] && handoff=$(find "$plans_dir" -name "*handoff*.md" -mtime -7 -type f 2>/dev/null | head -1)
|
|
94
|
-
fi
|
|
95
|
-
[ -z "$handoff" ] && return 1
|
|
96
|
-
|
|
97
|
-
# 提取 plan keyword
|
|
98
|
-
local plan_kw=$(basename "$handoff" | sed 's/-handoff.*//')
|
|
99
|
-
|
|
100
|
-
# 查找 add-route
|
|
101
|
-
local handoff_dir=$(dirname "$handoff")
|
|
102
|
-
add_route=$(find "$handoff_dir" -name "*add-route*.md" -type f 2>/dev/null | head -1)
|
|
103
|
-
[ -z "$add_route" ] && add_route=$(find "$plans_dir" -name "*add-route*.md" -type f 2>/dev/null | head -1)
|
|
104
|
-
|
|
105
|
-
# 4. 活跃判定: 读 add-route,存在 [ ] 未勾选项 = 活跃
|
|
106
|
-
local step_info="?"
|
|
107
|
-
if [ -f "$add_route" ]; then
|
|
108
|
-
local ck=$(grep -c '\[x\]' "$add_route" 2>/dev/null || true)
|
|
109
|
-
local uc=$(grep -c '\[ \]' "$add_route" 2>/dev/null || true)
|
|
110
|
-
ck=${ck:-0}; uc=${uc:-0}
|
|
111
|
-
local total=$((ck + uc))
|
|
112
|
-
[ "$total" -gt 0 ] && step_info="${ck}/${total}"
|
|
113
|
-
# 全部 [x] → 已收敛(但 handoff 还存在 → 可能是遗留,仍返回但标记)
|
|
114
|
-
else
|
|
115
|
-
# 无 add-route → Plan 初始态,视为活跃
|
|
116
|
-
step_info="init"
|
|
117
|
-
fi
|
|
118
|
-
|
|
119
|
-
# 5. 轮次统计(从 handoff)
|
|
120
|
-
local round_info="?"
|
|
121
|
-
if grep -q '<第[0-9]轮>' "$handoff" 2>/dev/null; then
|
|
122
|
-
local ck=$(grep -c '\[x\]' "$handoff" 2>/dev/null || true); ck=${ck:-0}
|
|
123
|
-
local total=$(grep -c '<第[0-9]轮>' "$handoff" 2>/dev/null || true); total=${total:-0}
|
|
124
|
-
[ "$total" -gt 0 ] && round_info="${ck}/${total}"
|
|
125
|
-
else
|
|
126
|
-
round_info="1/1"
|
|
127
|
-
fi
|
|
128
|
-
|
|
129
|
-
echo "${plan_kw}::${step_info}::${round_info}::${handoff}::${add_route:-none}"
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
# ── Dev Action 追踪 ──
|
|
133
|
-
|
|
134
|
-
# dev action 标记文件(项目级,PreToolUse 写入,Stop 读取)
|
|
135
|
-
DEV_FLAG="/tmp/add_dev_$(echo "${PROJECT_DIR:-$PWD}" | md5sum 2>/dev/null | cut -c1-8 || echo "default")"
|
|
136
|
-
|
|
137
|
-
mark_dev_action() {
|
|
138
|
-
touch "$DEV_FLAG" 2>/dev/null || true
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
has_dev_action() {
|
|
142
|
-
[ -f "$DEV_FLAG" ]
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
clear_dev_action() {
|
|
146
|
-
rm -f "$DEV_FLAG" 2>/dev/null || true
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
# ── 验收完整度检查 ──
|
|
150
|
-
|
|
151
|
-
# 检查 handoff + add-route 的验收完整度
|
|
152
|
-
# 用法: check_add_completeness "$handoff_path" "$add_route_path"
|
|
153
|
-
check_add_completeness() {
|
|
154
|
-
local handoff="$1" add_route="$2"
|
|
155
|
-
local issues=""
|
|
156
|
-
|
|
157
|
-
# devlog(内容已回流至 handoff,检查 handoff 是否含验收结果)
|
|
158
|
-
if [ -f "$handoff" ] && ! grep -qE '验收|收敛|闭环|本轮改了什么|devlog' "$handoff" 2>/dev/null; then
|
|
159
|
-
issues="${issues} [ ] devlog 缺失(handoff 无验收记录)\n"
|
|
160
|
-
fi
|
|
161
|
-
|
|
162
|
-
# handoff 验证标准
|
|
163
|
-
if [ -f "$handoff" ]; then
|
|
164
|
-
local uc=$(grep -c '\[ \]' "$handoff" 2>/dev/null || echo "0")
|
|
165
|
-
[ "$uc" -gt 0 ] && issues="${issues} [ ] handoff ${uc} 项未勾选\n"
|
|
166
|
-
fi
|
|
167
|
-
|
|
168
|
-
# add-route Step
|
|
169
|
-
if [ -f "$add_route" ]; then
|
|
170
|
-
local uc=$(grep -c '\[ \]' "$add_route" 2>/dev/null || echo "0")
|
|
171
|
-
[ "$uc" -gt 0 ] && issues="${issues} [ ] add-route ${uc} Step 未闭环\n"
|
|
172
|
-
fi
|
|
173
|
-
|
|
174
|
-
echo -e "$issues"
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
# ── 验收幂等保护 ──
|
|
178
|
-
|
|
179
|
-
# 检查是否已验收(幂等保护)
|
|
180
|
-
# 用法: is_already_accepted "$add_route_path" "$handoff_path"
|
|
181
|
-
# 返回 0 = 已验收,1 = 未验收
|
|
182
|
-
is_already_accepted() {
|
|
183
|
-
local add_route="$1" handoff="$2"
|
|
184
|
-
# add-route Step 8 是否已 [x]
|
|
185
|
-
if [ -f "$add_route" ]; then
|
|
186
|
-
if grep -A 10 'Step 8' "$add_route" 2>/dev/null | grep -q '\[x\].*验证并更新项目状态'; then
|
|
187
|
-
# handoff 是否有验收记录
|
|
188
|
-
if [ -f "$handoff" ] && grep -qE '✅.*验收|收敛|全部闭环|全部.*完成' "$handoff" 2>/dev/null; then
|
|
189
|
-
return 0
|
|
190
|
-
fi
|
|
191
|
-
fi
|
|
192
|
-
fi
|
|
193
|
-
return 1
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
# ── Stop 四象限分流 few-shot 上下文(卡位 #7) ──
|
|
197
|
-
# 用法: build_stop_context "$quadrant" "$info"
|
|
198
|
-
build_stop_context() {
|
|
199
|
-
local quadrant="$1" info="$2"
|
|
200
|
-
case "$quadrant" in
|
|
201
|
-
"no_add_no_dev")
|
|
202
|
-
echo "[ADD Stop] 无活跃 Plan,无代码改动。正常结束。"
|
|
203
|
-
;;
|
|
204
|
-
"no_add_has_dev")
|
|
205
|
-
cat <<'EOF'
|
|
206
|
-
[ADD Stop] ⚠️ 检测到代码修改但无活跃 ADD Plan。
|
|
207
|
-
|
|
208
|
-
Plan 不是"文档开销"——它是代码治理的基础设施。跳过 Plan 的后果:
|
|
209
|
-
· 没有 add-route → 每次改动无法追溯到具体 Task
|
|
210
|
-
· 没有 tasks.md → 后续 AI Session 不知道改了哪些文件
|
|
211
|
-
· 没有 handoff → 交接时上下文全丢,只能靠 git log 猜
|
|
212
|
-
|
|
213
|
-
你必须立即补救,二选一:
|
|
214
|
-
|
|
215
|
-
方案 A — 补 ADD 流程(招安):
|
|
216
|
-
Step 0: 读 .qoder/templates/plan-template.md → 生成 Plan
|
|
217
|
-
生成 add-route → check_dps ≥ {{dpsPass}}
|
|
218
|
-
Step 1: 扩展 AgentAuditPhase(如需要)
|
|
219
|
-
Step 2: 确认 agentAudit() 通道
|
|
220
|
-
Step 3: 将已写代码关联到 tasks.md
|
|
221
|
-
完成后可正常停止。
|
|
222
|
-
|
|
223
|
-
方案 B — 补不上则回滚:
|
|
224
|
-
如果改动太复杂无法追溯生成 Plan,则:
|
|
225
|
-
① git diff 确认改动范围
|
|
226
|
-
② git checkout -- <改动的文件> 撤回
|
|
227
|
-
③ 告知用户 "以下改动已回滚,请先走 ADD 流程再重新实施: <文件列表>"
|
|
228
|
-
|
|
229
|
-
无论选 A 还是 B,完成后告诉用户下次执行 session-init 恢复上下文。
|
|
230
|
-
EOF
|
|
231
|
-
;;
|
|
232
|
-
"has_add_no_dev")
|
|
233
|
-
echo "[ADD Stop] ADD 流程进行中 (${info}),本次无代码改动。下次继续时执行 session-init 恢复上下文。"
|
|
234
|
-
;;
|
|
235
|
-
"has_add_dev_unclosed")
|
|
236
|
-
cat <<EOF
|
|
237
|
-
[ADD Stop] ⚠️ 代码已完成但验收未闭环:
|
|
238
|
-
${info}
|
|
239
|
-
|
|
240
|
-
请依次执行(不要等下次会话):
|
|
241
|
-
① Write devlog → handoff 同目录 devlog-{plan}-v{n}.md
|
|
242
|
-
格式: # Devlog: {plan}\n 日期 / Plan / 轮次 / 本轮改了什么 / 验收结果 / 遗留项 / 架构回看
|
|
243
|
-
② Edit handoff → 更新 §验证标准 全部 [x] + 补充审计 ID
|
|
244
|
-
③ Read docs/ → 回看架构文档确认一致性
|
|
245
|
-
④ Edit add-route → 勾选对应 Step [x]
|
|
246
|
-
|
|
247
|
-
以上全部完成后 Agent 才能停止。
|
|
248
|
-
EOF
|
|
249
|
-
;;
|
|
250
|
-
esac
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
# ── PreToolUse 写入前置守卫上下文(卡位 #4) ──
|
|
254
|
-
build_pretool_context() {
|
|
255
|
-
local plan="$1" round="$2"
|
|
256
|
-
cat <<EOF
|
|
257
|
-
[ADD PreToolUse] 当前 Plan: ${plan},轮次: ${round}。
|
|
258
|
-
本次写入应属于 ADD Step 3 代码实现阶段。
|
|
259
|
-
完成后执行 record_dev_operation 记录审计。
|
|
260
|
-
EOF
|
|
261
|
-
}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# context-inject.sh — 上下文注入模板
|
|
3
|
-
# 共享库
|
|
4
|
-
|
|
5
|
-
# 结构化 SessionStart JSON 注入
|
|
6
|
-
build_session_start_json() {
|
|
7
|
-
local plan="$1" step="$2" round="$3" handoff="$4"
|
|
8
|
-
cat <<EOF
|
|
9
|
-
{
|
|
10
|
-
"continue": true,
|
|
11
|
-
"hookSpecificOutput": {
|
|
12
|
-
"hookEventName": "SessionStart",
|
|
13
|
-
"additionalContext": "上次 ADD 流程未完成:\n Plan: ${plan}\n 轮次: ${round}\n 当前 Step: ${step} (add-route)\n 恢复命令: query_audit_logs({ planKeyword: '${plan}' })\n handoff: ${handoff}"
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
EOF
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
# Stop 四象限分流 few-shot 上下文
|
|
20
|
-
build_stop_context() {
|
|
21
|
-
local quadrant="$1" info="$2"
|
|
22
|
-
case "$quadrant" in
|
|
23
|
-
"no_add_no_dev")
|
|
24
|
-
echo "[ADD Stop] 无活跃 Plan,无代码改动。正常结束。"
|
|
25
|
-
;;
|
|
26
|
-
"no_add_has_dev")
|
|
27
|
-
cat <<'EOF'
|
|
28
|
-
[ADD Stop] ⚠️ 检测到代码修改但无活跃 ADD Plan。
|
|
29
|
-
|
|
30
|
-
Plan 不是"文档开销"——它是代码治理的基础设斻。跳过 Plan 的后果:
|
|
31
|
-
· 没有 add-route → 每次改动无法追溯到具体 Task
|
|
32
|
-
· 没有 tasks.md → 后续 AI Session 不知道改了哪些文件
|
|
33
|
-
· 没有 handoff → 交接时上下文全丢,只能靠 git log 猜
|
|
34
|
-
|
|
35
|
-
你必须立即补救,二选一:
|
|
36
|
-
|
|
37
|
-
方案 A — 补 ADD 流程(招安):
|
|
38
|
-
Step 0: 读 .qoder/templates/plan-template.md → 生成 Plan → .qoder/plans/{today}/{keyword}-plan-v1.md
|
|
39
|
-
生成 add-route → check_dps ≥ {{dpsPass}}
|
|
40
|
-
Step 1: 扩展 AgentAuditPhase(如需要)
|
|
41
|
-
Step 2: 确认 agentAudit() 通道
|
|
42
|
-
Step 3: 将已写代码关联到 tasks.md
|
|
43
|
-
完成后可正常停止。
|
|
44
|
-
|
|
45
|
-
方案 B — 补不上则回滚:
|
|
46
|
-
如果改动太复杂无法追溯生成 Plan,则:
|
|
47
|
-
① git diff 确认改动范围
|
|
48
|
-
② git checkout -- <改动的文件> 撤回
|
|
49
|
-
③ 告知用户 "以下改动已回滚,请先走 ADD 流程再重新实施: <文件列表>"
|
|
50
|
-
|
|
51
|
-
无论选 A 还是 B,完成后告诉用户下次执行 session-init 恢复上下文。
|
|
52
|
-
EOF
|
|
53
|
-
;;
|
|
54
|
-
"has_add_no_dev")
|
|
55
|
-
echo "[ADD Stop] ADD 流程进行中 (${info}),本次无代码改动。下次继续时执行 session-init 恢复上下文。"
|
|
56
|
-
;;
|
|
57
|
-
"has_add_dev_step02")
|
|
58
|
-
echo "[ADD Stop] ADD Step 0-2: 文档先行/审计准备阶段。无需验收闭环。下一步: 进入 Step 3 代码实现。"
|
|
59
|
-
;;
|
|
60
|
-
"has_add_dev_step3")
|
|
61
|
-
echo "[ADD Stop] ADD Step 3: 代码实现进行中 (${info})。完成后进入 Step 3.5 实现审查。"
|
|
62
|
-
;;
|
|
63
|
-
"has_add_dev_unclosed")
|
|
64
|
-
cat <<'EOF'
|
|
65
|
-
[ADD Stop] ⚠️ 代码已完成但验收未闭环:
|
|
66
|
-
${info}
|
|
67
|
-
|
|
68
|
-
请依次执行(不要等下次会话):
|
|
69
|
-
① Write devlog → handoff 同目录 devlog-{plan}-v{n}.md
|
|
70
|
-
格式: # Devlog: {plan}\n 日期 / Plan / 轮次 / 本轮改了什么 / 验收结果 / 遗留项 / 架构回看
|
|
71
|
-
② Edit handoff → 更新 §验证标准 全部 [x] + 补充审计 ID
|
|
72
|
-
★ 同步: checklist 有新 cuid → handoff ADD-7 表必须对应新增行
|
|
73
|
-
★ Step 0 准入: handoff + add-route + Specs 三元组缺一不可,缺则回退 Step 0.5
|
|
74
|
-
③ Read docs/ → 回看架构文档确认一致性
|
|
75
|
-
④ Edit add-route → 勾选对应 Step [x]
|
|
76
|
-
|
|
77
|
-
以上全部完成后 Agent 才能停止。
|
|
78
|
-
|
|
79
|
-
下次恢复: 读 handoff → 查同目录 devlog-*.md → query_audit_logs
|
|
80
|
-
EOF
|
|
81
|
-
;;
|
|
82
|
-
"has_add_dev_closed")
|
|
83
|
-
echo "[ADD Stop] ✅ 验收闭环: add-route全部[x], devlog已记录, handoff已更新。验收幂等——重复触发不覆盖已有结论。"
|
|
84
|
-
;;
|
|
85
|
-
esac
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
# 写操作前置守卫上下文
|
|
89
|
-
build_pretool_context() {
|
|
90
|
-
local plan="$1" round="$2"
|
|
91
|
-
cat <<EOF
|
|
92
|
-
[ADD PreToolUse] 当前 Plan: ${plan},轮次: ${round}。
|
|
93
|
-
本次写入应属于 ADD Step 3 代码实现阶段。
|
|
94
|
-
完成后执行 record_dev_operation 记录审计。
|
|
95
|
-
EOF
|
|
96
|
-
}
|