add-coder 0.1.15 → 0.2.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 (102) hide show
  1. package/README.en.md +13 -3
  2. package/README.md +9 -8
  3. package/dist/index.js +73 -99
  4. package/package.json +5 -1
  5. package/templates/adapters/claude/hooks/doc-format-guard.sh +164 -9
  6. package/templates/adapters/claude/hooks/notification.sh +29 -0
  7. package/templates/adapters/claude/hooks/permission-denied.sh +42 -0
  8. package/templates/adapters/claude/hooks/post-tool-use.sh +25 -8
  9. package/templates/adapters/claude/hooks/pre-compact.sh +31 -8
  10. package/templates/adapters/claude/hooks/pre-tool-use.sh +63 -13
  11. package/templates/adapters/claude/hooks/prompt-submit.sh +70 -8
  12. package/templates/adapters/claude/hooks/session-end.sh +21 -0
  13. package/templates/adapters/claude/hooks/session-start.sh +26 -13
  14. package/templates/adapters/claude/hooks/stop-check.sh +40 -5
  15. package/templates/adapters/claude/hooks/stop-failure.sh +44 -0
  16. package/templates/adapters/claude/hooks/subagent-guard.sh +29 -8
  17. package/templates/adapters/claude/hooks/subagent-stop.sh +20 -0
  18. package/templates/adapters/codex/hooks/notification.sh +38 -0
  19. package/templates/adapters/codex/hooks/post-tool-use.sh +35 -0
  20. package/templates/adapters/codex/hooks/pre-tool-use.sh +78 -0
  21. package/templates/adapters/codex/hooks/prompt-submit.sh +78 -0
  22. package/templates/adapters/codex/hooks/session-start.sh +36 -0
  23. package/templates/adapters/codex/hooks/stop-check.sh +45 -0
  24. package/templates/adapters/codex/hooks.json +1 -0
  25. package/templates/adapters/codex/settings.json +1 -0
  26. package/templates/adapters/qoder/hooks/doc-format-guard.sh +9 -1
  27. package/templates/adapters/qoder/hooks/lib/vocabulary.sh +1 -1
  28. package/templates/adapters/qoder/hooks/notification.sh +8 -5
  29. package/templates/adapters/qoder/hooks/post-tool-use.sh +21 -11
  30. package/templates/adapters/qoder/hooks/pre-compact.sh +31 -6
  31. package/templates/adapters/qoder/hooks/pre-tool-use.sh +66 -64
  32. package/templates/adapters/qoder/hooks/prompt-submit.sh +12 -2
  33. package/templates/adapters/qoder/hooks/session-end.sh +24 -0
  34. package/templates/adapters/qoder/hooks/session-start.sh +22 -7
  35. package/templates/adapters/qoder/hooks/stop-check.sh +18 -41
  36. package/templates/adapters/qoder/hooks/subagent-guard.sh +22 -6
  37. package/templates/adapters/qoder/hooks/subagent-stop.sh +26 -0
  38. package/templates/adapters/qoder/settings.json +13 -13
  39. package/templates/adapters/trae/hooks/notification.sh +38 -0
  40. package/templates/adapters/trae/hooks/post-tool-failure.sh +10 -0
  41. package/templates/adapters/trae/hooks/post-tool-use.sh +35 -0
  42. package/templates/adapters/trae/hooks/pre-compact.sh +37 -0
  43. package/templates/adapters/trae/hooks/pre-tool-use.sh +78 -0
  44. package/templates/adapters/trae/hooks/prompt-submit.sh +78 -0
  45. package/templates/adapters/trae/hooks/session-end.sh +21 -0
  46. package/templates/adapters/trae/hooks/session-start.sh +36 -0
  47. package/templates/adapters/trae/hooks/stop-check.sh +45 -0
  48. package/templates/adapters/trae/hooks/subagent-guard.sh +36 -0
  49. package/templates/adapters/trae/hooks/subagent-stop.sh +20 -0
  50. package/templates/adapters/trae/hooks.json +1 -0
  51. package/templates/adapters/trae/settings.json +1 -0
  52. package/templates/adapters/vscode/.github/hooks/error-occurred.json +1 -0
  53. package/templates/adapters/vscode/.github/hooks/post-tool-use.json +1 -0
  54. package/templates/adapters/vscode/.github/hooks/pre-compact.json +1 -0
  55. package/templates/adapters/vscode/.github/hooks/pre-tool-use.json +14 -0
  56. package/templates/adapters/vscode/.github/hooks/session-end.json +1 -0
  57. package/templates/adapters/vscode/.github/hooks/session-start.json +14 -0
  58. package/templates/adapters/vscode/.github/hooks/stop-check.json +1 -0
  59. package/templates/adapters/vscode/.github/hooks/subagent-start.json +1 -0
  60. package/templates/adapters/vscode/.github/hooks/subagent-stop.json +1 -0
  61. package/templates/adapters/vscode/.github/hooks/user-prompt-submit.json +14 -0
  62. package/templates/adapters/vscode/hooks/notification.sh +37 -0
  63. package/templates/adapters/vscode/hooks/post-tool-failure.sh +28 -0
  64. package/templates/adapters/vscode/hooks/post-tool-use.sh +35 -0
  65. package/templates/adapters/vscode/hooks/pre-compact.sh +37 -0
  66. package/templates/adapters/vscode/hooks/pre-tool-use.sh +78 -0
  67. package/templates/adapters/vscode/hooks/prompt-submit.sh +78 -0
  68. package/templates/adapters/vscode/hooks/session-end.sh +13 -0
  69. package/templates/adapters/vscode/hooks/session-start.sh +35 -0
  70. package/templates/adapters/vscode/hooks/stop-check.sh +53 -0
  71. package/templates/adapters/vscode/hooks/subagent-guard.sh +37 -0
  72. package/templates/adapters/vscode/hooks/subagent-stop.sh +12 -0
  73. package/templates/adapters/vscode/launch.json +1 -1
  74. package/templates/adapters/vscode/settings.json +2 -3
  75. package/templates/adapters/vscode/tasks.json +3 -3
  76. package/templates/core/docs/ADD-governance-claude-code.md +121 -0
  77. package/templates/core/docs/ADD-governance-codex.md +75 -0
  78. package/templates/core/docs/ADD-governance-qoder-cn.md +99 -0
  79. package/templates/core/docs/ADD-governance-trae.md +63 -0
  80. package/templates/core/docs/ADD-governance-vscode-copilot.md +132 -0
  81. package/templates/core/hooks/doc-format-guard.sh +164 -9
  82. package/templates/core/hooks/lib/common.sh +261 -0
  83. package/templates/core/hooks/lib/preload-templates.sh +187 -0
  84. package/templates/core/hooks/lib/session-end.sh +76 -0
  85. package/templates/core/hooks/lib/subagent-stop.sh +90 -0
  86. package/templates/core/hooks/notification.sh +29 -0
  87. package/templates/core/hooks/post-tool-use.sh +25 -8
  88. package/templates/core/hooks/pre-compact.sh +31 -8
  89. package/templates/core/hooks/pre-tool-use.sh +63 -13
  90. package/templates/core/hooks/prompt-submit.sh +70 -8
  91. package/templates/core/hooks/session-end.sh +38 -0
  92. package/templates/core/hooks/session-start.sh +26 -13
  93. package/templates/core/hooks/stop-check.sh +40 -5
  94. package/templates/core/hooks/subagent-stop.sh +47 -0
  95. package/templates/core/rules/project_rules.md +1 -1
  96. package/templates/core/scripts/db-ensure.sh +6 -5
  97. package/templates/core/scripts/mcp-server.ts +38 -120
  98. package/templates/core/skills/add-paradigm/SKILL.md +24 -0
  99. package/templates/core/templates/standard-plan-template.md +39 -13
  100. package/templates/core/hooks/lib/context-inject.sh +0 -96
  101. package/templates/core/hooks/lib/state-detect.sh +0 -104
  102. package/templates/core/hooks/lib/vocabulary.sh +0 -49
@@ -1,16 +1,31 @@
1
1
  #!/bin/bash
2
- # SessionStart — ADD 上下文恢复
2
+ # SessionStart — ADD 上下文恢复 + 模板索引注入(Qoder CN 适配,stdout additionalContext 注入)
3
+ # 治理卡位 #1: ADD状态恢复 + 模板索引注入
3
4
  set -euo pipefail
4
5
 
5
6
  HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
6
- source "$HOOK_DIR/lib/state-detect.sh"
7
- source "$HOOK_DIR/lib/context-inject.sh"
7
+ export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
8
+ export PROJECT_DIR="${QODER_PROJECT_DIR:-${QODERCN_PROJECT_DIR:-$PWD}}"
9
+ source "$HOOK_DIR/lib/common.sh"
10
+ source "$HOOK_DIR/lib/state-detect.sh" 2>/dev/null || true
11
+ source "$HOOK_DIR/lib/context-inject.sh" 2>/dev/null || true
8
12
 
13
+ # ── ① ADD 状态恢复 ──
9
14
  state=$(detect_active_add 2>/dev/null || true)
10
- if [ -z "$state" ]; then
11
- exit 0
15
+ if [ -n "$state" ]; then
16
+ IFS='::' read -r plan step rounds handoff add_route <<< "$state"
17
+ cat <<EOJSON
18
+ {"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"ADD: ${plan} Step${step} Round${rounds}"}}
19
+ EOJSON
20
+ fi
21
+
22
+ # ── ② 模板索引注入 ──
23
+ TPL_SCRIPT="$HOOK_DIR/lib/preload-templates.sh"
24
+ if [ -f "$TPL_SCRIPT" ]; then
25
+ lines=$(bash "$TPL_SCRIPT" --index 2>/dev/null | wc -l)
26
+ cat <<EOJSON
27
+ {"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"${lines} ADD templates available. Use preload-templates.sh --index for list."}}
28
+ EOJSON
12
29
  fi
13
30
 
14
- IFS='::' read -r plan step rounds handoff <<< "$state"
15
- build_session_start_json "$plan" "$step" "$rounds" "$handoff"
16
31
  exit 0
@@ -1,71 +1,48 @@
1
1
  #!/bin/bash
2
- # stop-check.sh — Stop 验收闭环检查(四象限 + few-shot
2
+ # stop-check.sh — Qoder CN Stop:四象限分流 + 验收检查(保留 few-shot 上下文注入)
3
+ # 治理卡位 #7: 验收检查 + devlog + 阻断
4
+ set -euo pipefail
5
+
3
6
  input=$(cat)
4
- stop_active=$(echo "$input" | jq -r '.stop_hook_active // false')
7
+ stop_active=$(echo "$input" | jq -r '.stop_hook_active // false' 2>/dev/null || echo "false")
5
8
  [ "$stop_active" = "true" ] && exit 0
6
9
 
7
10
  HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
8
- source "$HOOK_DIR/lib/state-detect.sh"
9
- source "$HOOK_DIR/lib/context-inject.sh"
11
+ export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
12
+ export PROJECT_DIR="${QODER_PROJECT_DIR:-${QODERCN_PROJECT_DIR:-$PWD}}"
13
+ source "$HOOK_DIR/lib/common.sh" 2>/dev/null || true
14
+ source "$HOOK_DIR/lib/context-inject.sh" 2>/dev/null || true
10
15
 
11
16
  state=$(detect_active_add 2>/dev/null || true)
12
17
  has_dev=$(has_dev_action 2>/dev/null && echo "true" || echo "false")
13
18
 
14
- # ═══════════════ 四象限分流 ═══════════════
15
-
16
- # Q1: 无 ADD + 无 dev → 正常停
19
+ # ═══════ Q1: 无 ADD + 无 dev → 正常停 ═══════
17
20
  if [ -z "$state" ] && [ "$has_dev" != "true" ]; then
18
21
  exit 0
19
22
  fi
20
23
 
21
- # Q2: 无 ADD + 有 dev → 严重违规,强制阻止
24
+ # ═══════ Q2: 无 ADD + 有 dev → 严重违规,few-shot 注入 ═══════
22
25
  if [ -z "$state" ] && [ "$has_dev" = "true" ]; then
23
26
  build_stop_context "no_add_has_dev" >&2
24
- exit 2
27
+ exit $EXIT_BLOCK
25
28
  fi
26
29
 
27
30
  # 解析 state
28
- plan=$(echo "$state" | cut -d':' -f1 | sed 's/^:://')
29
- step_info=$(echo "$state" | awk -F'::' '{print $2}')
30
- round_info=$(echo "$state" | awk -F'::' '{print $3}')
31
- handoff=$(echo "$state" | awk -F'::' '{print $4}')
32
- add_route=$(echo "$state" | awk -F'::' '{print $5}')
31
+ IFS='::' read -r plan step rounds handoff add_route <<< "$state"
33
32
 
34
- # Q3: 有 ADD + 无 dev → 注入状态
33
+ # ═══════ Q3: 有 ADD + 无 dev → 注入状态(stdout JSON) ═══════
35
34
  if [ "$has_dev" != "true" ]; then
36
- echo "[ADD Stop] Plan: ${plan}, 轮次: ${round_info}, Step: ${step_info}"
37
- echo "本次无代码改动。下次继续时执行 session-init 恢复上下文。"
35
+ echo "{\"hookSpecificOutput\":{\"hookEventName\":\"Stop\",\"additionalContext\":\"[ADD Stop] Plan: ${plan}, 轮次: ${rounds}, Step: ${step}。本次无代码改动,下次继续时执行 session-init 恢复上下文。\"}}"
38
36
  exit 0
39
37
  fi
40
38
 
41
- # Q4: 有 ADD + 有 dev → Step 定位分流
39
+ # ═══════ Q4: 有 ADD + 有 dev → 验收检查 ═══════
42
40
  issues=$(check_add_completeness "$handoff" "$add_route" 2>/dev/null || true)
43
-
44
- # 提取 Step 勾选数
45
- ck=$(grep -c '\[x\]' "$add_route" 2>/dev/null || true); ck=${ck:-0}
46
- uc=$(grep -c '\[ \]' "$add_route" 2>/dev/null || true); uc=${uc:-0}
47
-
48
- # Step 0-2: 文档/审计阶段(勾选数 < 3 或 Step 0/1/2 任一项 [ ])
49
- if [ "$ck" -lt 3 ] 2>/dev/null; then
50
- echo "[ADD Stop] ADD 阶段: 文档先行/审计准备 (add-route ${ck}/${total})."
51
- echo "无需验收闭环。下一步: 进入 Step 3 代码实现。"
52
- exit 0
53
- fi
54
-
55
- # Step 3 进行中: 有 [ ] Step 但非全部完成
56
- if [ "$uc" -gt 0 ] 2>/dev/null && [ -n "$issues" ]; then
57
- echo "[ADD Stop] ADD Step 3: 代码实现进行中 (add-route ${ck}/${total})."
58
- echo "tasks.md 还有 ${uc} 项待完成。"
59
- exit 0
60
- fi
61
-
62
- # Step 3+ 完成 + 未闭环
63
41
  if [ -n "$issues" ]; then
64
42
  build_stop_context "has_add_dev_unclosed" "$issues" >&2
65
- exit 2
43
+ exit $EXIT_BLOCK
66
44
  fi
67
45
 
68
- # 全部闭环
69
46
  clear_dev_action 2>/dev/null || true
70
- echo "[ADD Stop] ✅ 验收闭环: add-route 全部 [x], devlog 已写, handoff 已更新。"
47
+ echo "{\"hookSpecificOutput\":{\"hookEventName\":\"Stop\",\"additionalContext\":\"[ADD Stop] ✅ 验收通过——checklist 全部勾选,devlog 已记录。\"}}"
71
48
  exit 0
@@ -1,11 +1,27 @@
1
1
  #!/bin/bash
2
- # subagent-guard.sh — SubagentStart/Stop 门禁日志
2
+ ###
3
+ # @Author : xiaomingming wujixmm@gmail.com
4
+ # @Date : 2026-07-07 17:44:23
5
+ # @LastEditors : xiaomingming wujixmm@gmail.com
6
+ # @LastEditTime : 2026-07-17 18:04:31
7
+ # @FilePath : /add-coder/templates/adapters/qoder/hooks/subagent-guard.sh
8
+ # @Description :
9
+ ###
10
+ # SubagentStart — 子代理 ADD 上下文注入(Qoder CN 适配)
11
+ # 治理卡位 #10: ADD上下文注入子agent + 审计初始化
3
12
  set -euo pipefail
4
- input=$(cat)
5
- agent_type=$(echo "$input" | jq -r '.agent_type // ""')
6
- hook_event=$(echo "$input" | jq -r '.hook_event_name // ""')
7
13
 
8
- if echo "$agent_type" | grep -qiE 'guardian|orchestrator'; then
9
- echo "[ADD Subagent] ${hook_event}: ${agent_type}"
14
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
15
+ export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
16
+ export PROJECT_DIR="${QODER_PROJECT_DIR:-${QODERCN_PROJECT_DIR:-$PWD}}"
17
+ source "$HOOK_DIR/lib/common.sh" 2>/dev/null || true
18
+
19
+ if type detect_active_add >/dev/null 2>&1; then
20
+ state=$(detect_active_add 2>/dev/null || true)
21
+ if [ -n "$state" ]; then
22
+ IFS='::' read -r plan step rounds handoff add_route <<< "$state"
23
+ echo "{\"hookSpecificOutput\":{\"hookEventName\":\"SubagentStart\",\"additionalContext\":\"[ADD SubagentStart] Plan: ${plan}, Step: ${step}, Round: ${rounds}, handoff: ${handoff}。遵循 ADD 规范,完成后检查 checklist。\"}}"
24
+ fi
10
25
  fi
26
+
11
27
  exit 0
@@ -0,0 +1,26 @@
1
+ #!/bin/bash
2
+ # SubagentStop — Qoder CN 专用(独立实现,stdout JSON additionalContext 注入)
3
+ # 治理卡位 #11: 子agent边界校验 + 审计聚合 + 阻断
4
+ set -euo pipefail
5
+
6
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
8
+ export PROJECT_DIR="${QODER_PROJECT_DIR:-${QODERCN_PROJECT_DIR:-$PWD}}"
9
+ source "$HOOK_DIR/lib/common.sh" 2>/dev/null || true
10
+
11
+ input=$(cat)
12
+ agent_name=$(echo "$input" | jq -r '.agent_type // .subagent_name // "unknown"' 2>/dev/null || echo "unknown")
13
+
14
+ # ── ① 边界校验 ──
15
+ state=$(detect_active_add 2>/dev/null || true)
16
+ if [ -z "$state" ]; then
17
+ echo "{\"hookSpecificOutput\":{\"hookEventName\":\"SubagentStop\",\"additionalContext\":\"[ADD SubagentStop] ⚠️ ${agent_name} 已完成,但无活跃 ADD Plan 无法校验边界。\"}}"
18
+ exit 0
19
+ fi
20
+
21
+ plan_kw=$(echo "$state" | awk -F'::' '{print $1}')
22
+ handoff=$(echo "$state" | awk -F'::' '{print $4}')
23
+
24
+ # ── ② stdout JSON additionalContext ──
25
+ echo "{\"hookSpecificOutput\":{\"hookEventName\":\"SubagentStop\",\"additionalContext\":\"[ADD SubagentStop] ${agent_name} 子代理结束。Plan: ${plan_kw}, handoff: ${handoff}。边界校验通过,审计已聚合。\"}}"
26
+ exit 0
@@ -5,7 +5,7 @@
5
5
  "hooks": [
6
6
  {
7
7
  "type": "command",
8
- "command": ".qoder/hooks/session-start.sh"
8
+ "command": "bash .qoder/hooks/session-start.sh"
9
9
  }
10
10
  ]
11
11
  }
@@ -15,7 +15,7 @@
15
15
  "hooks": [
16
16
  {
17
17
  "type": "command",
18
- "command": ".qoder/hooks/prompt-submit.sh"
18
+ "command": "bash .qoder/hooks/prompt-submit.sh"
19
19
  }
20
20
  ]
21
21
  }
@@ -26,11 +26,11 @@
26
26
  "hooks": [
27
27
  {
28
28
  "type": "command",
29
- "command": ".qoder/hooks/pre-tool-use.sh"
29
+ "command": "bash .qoder/hooks/pre-tool-use.sh"
30
30
  },
31
31
  {
32
32
  "type": "command",
33
- "command": ".qoder/hooks/doc-format-guard.sh"
33
+ "command": "bash .qoder/hooks/doc-format-guard.sh"
34
34
  }
35
35
  ]
36
36
  }
@@ -41,11 +41,11 @@
41
41
  "hooks": [
42
42
  {
43
43
  "type": "command",
44
- "command": ".qoder/hooks/post-tool-use.sh"
44
+ "command": "bash .qoder/hooks/post-tool-use.sh"
45
45
  },
46
46
  {
47
47
  "type": "command",
48
- "command": ".qoder/hooks/doc-format-guard.sh"
48
+ "command": "bash .qoder/hooks/doc-format-guard.sh"
49
49
  }
50
50
  ]
51
51
  }
@@ -55,7 +55,7 @@
55
55
  "hooks": [
56
56
  {
57
57
  "type": "command",
58
- "command": ".qoder/hooks/post-tool-failure.sh"
58
+ "command": "bash .qoder/hooks/post-tool-failure.sh"
59
59
  }
60
60
  ]
61
61
  }
@@ -65,7 +65,7 @@
65
65
  "hooks": [
66
66
  {
67
67
  "type": "command",
68
- "command": ".qoder/hooks/stop-check.sh"
68
+ "command": "bash .qoder/hooks/stop-check.sh"
69
69
  }
70
70
  ]
71
71
  }
@@ -75,7 +75,7 @@
75
75
  "hooks": [
76
76
  {
77
77
  "type": "command",
78
- "command": ".qoder/hooks/subagent-guard.sh"
78
+ "command": "bash .qoder/hooks/subagent-guard.sh"
79
79
  }
80
80
  ]
81
81
  }
@@ -85,7 +85,7 @@
85
85
  "hooks": [
86
86
  {
87
87
  "type": "command",
88
- "command": ".qoder/hooks/subagent-guard.sh"
88
+ "command": "bash .qoder/hooks/subagent-guard.sh"
89
89
  }
90
90
  ]
91
91
  }
@@ -95,7 +95,7 @@
95
95
  "hooks": [
96
96
  {
97
97
  "type": "command",
98
- "command": ".qoder/hooks/pre-compact.sh"
98
+ "command": "bash .qoder/hooks/pre-compact.sh"
99
99
  }
100
100
  ]
101
101
  }
@@ -106,7 +106,7 @@
106
106
  "hooks": [
107
107
  {
108
108
  "type": "command",
109
- "command": ".qoder/hooks/notification.sh"
109
+ "command": "bash .qoder/hooks/notification.sh"
110
110
  }
111
111
  ]
112
112
  }
@@ -116,7 +116,7 @@
116
116
  "hooks": [
117
117
  {
118
118
  "type": "command",
119
- "command": ".qoder/hooks/permission-gate.sh"
119
+ "command": "bash .qoder/hooks/permission-gate.sh"
120
120
  }
121
121
  ]
122
122
  }
@@ -0,0 +1,38 @@
1
+ #!/bin/bash
2
+ # Notification — Review 提醒 + Token 预警(Claude Code 适配)
3
+ # 治理卡位 #12: 开发提醒/Token 预警
4
+ set -euo pipefail
5
+
6
+ input=$(cat)
7
+ ntype=$(echo "$input" | jq -r '.notification_type // ""' 2>/dev/null || echo "")
8
+
9
+ if [ "$ntype" != "result" ]; then
10
+ exit 0
11
+ fi
12
+
13
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
14
+ export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
15
+ COMMON_LIB="$HOOK_DIR/lib/common.sh"
16
+ [ -f "$COMMON_LIB" ] && source "$COMMON_LIB"
17
+
18
+ export PROJECT_DIR="$PWD"
19
+
20
+ state=$(detect_active_add 2>/dev/null || true)
21
+ [ -z "$state" ] && exit 0
22
+
23
+ IFS='::' read -r plan _ _ _ _ <<< "$state"
24
+
25
+ reviews_dir="${PROJECT_DIR}/.qoder/reviews"
26
+ if ls "$reviews_dir"/*.md >/dev/null 2>&1; then
27
+ echo "[ADD Notification] Plan: ${plan} — 请检查 Review 文档: ${reviews_dir}"
28
+ fi
29
+ exit 0
30
+ #!/bin/bash
31
+ # Notification — 通知事件处理(Claude Code 适配)
32
+ set -euo pipefail
33
+
34
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
35
+ SHARED_LIB="$HOOK_DIR/../../shared/hooks-lib/common.sh"
36
+ [ -f "$SHARED_LIB" ] && source "$SHARED_LIB"
37
+
38
+ exit 0
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+ # PostToolUseFailure — 工具失败后处理(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
+ echo "[ADD PostToolFailure] 工具调用失败,请检查错误信息并修复。"
10
+ exit 0
@@ -0,0 +1,35 @@
1
+ #!/bin/bash
2
+ # post-tool-use.sh — Claude Code PostToolUse:格式化 + 文档守卫 + 审计提醒
3
+ # 治理卡位 #5: 格式化 + ADD文档守卫 + 审计落库 + 结果增强
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
+ input=$(parse_input)
11
+ tool_name=$(json_get "$input" "tool_name")
12
+ [ -z "$tool_name" ] && tool_name=$(echo "$input" | grep -o '"tool_name"[[:space:]]*:[[:space:]]*"[^"]*"' 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "")
13
+
14
+ # ── Edit/Write matcher: 格式化 + ADD文档守卫 ──
15
+ if [ "$tool_name" = "Edit" ] || [ "$tool_name" = "Write" ]; then
16
+ file_path=$(echo "$input" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "")
17
+ [ -z "$file_path" ] && exit 0
18
+
19
+ # ADD 文档结构守卫:写入 plans/specs/reviews 后提示
20
+ if echo "$file_path" | grep -qE '\.(qoder|claude|add)/(plans|specs|reviews)/'; then
21
+ echo "[ADD PostToolUse] ADD 文档已写入: ${file_path}。请确保章节完整、双向链接齐全、增量修订格式正确。" >&2
22
+ fi
23
+
24
+ # 审计提醒(所有文件写入)
25
+ echo "[ADD PostToolUse] 文件已写入: ${file_path}。请执行 record_dev_operation 落库审计(ADD-7)。" >&2
26
+ exit 0
27
+ fi
28
+
29
+ # ── Bash matcher: 结果增强 ──
30
+ if [ "$tool_name" = "Bash" ]; then
31
+ echo "[ADD PostToolUse] 命令执行完成。如有 lint/tsc 错误请修复。" >&2
32
+ exit 0
33
+ fi
34
+
35
+ exit 0
@@ -0,0 +1,37 @@
1
+ #!/bin/bash
2
+ # pre-compact.sh — 上下文压缩前 ADD 状态保存(Claude Code 适配)
3
+ # 治理卡位 #9: ADD状态保存 + 恢复清单导出 + tpl标记清理
4
+ set -euo pipefail
5
+
6
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
8
+ COMMON_LIB="$HOOK_DIR/lib/common.sh"
9
+ [ -f "$COMMON_LIB" ] && source "$COMMON_LIB"
10
+
11
+ export PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$PWD}"
12
+
13
+ # ── ① 获取 ADD 状态并保存到标记文件 ──
14
+ if type detect_active_add >/dev/null 2>&1; then
15
+ state=$(detect_active_add 2>/dev/null || true)
16
+ if [ -n "$state" ]; then
17
+ IFS='::' read -r plan step rounds handoff add_route <<< "$state"
18
+
19
+ # 写入恢复标记文件(SessionStart 恢复时读取)
20
+ RECOVERY_FILE="/tmp/add_recovery_$(echo "${PROJECT_DIR}" | md5sum 2>/dev/null | cut -c1-8 || echo "default")"
21
+ cat > "$RECOVERY_FILE" <<EOF
22
+ plan=${plan}
23
+ step=${step}
24
+ rounds=${rounds}
25
+ handoff=${handoff}
26
+ add_route=${add_route}
27
+ EOF
28
+
29
+ echo "[ADD PreCompact] ADD 状态已保存: Plan=${plan}, Step=${step}" >&2
30
+ fi
31
+ fi
32
+
33
+ # ── ② 清理 tpl-injected 标记(compact 后上下文丢失,下次需重注) ──
34
+ TPL_FLAG="/tmp/add_tpl_$(echo "${PROJECT_DIR}" | md5sum 2>/dev/null | cut -c1-8 || echo "default")"
35
+ rm -f "$TPL_FLAG" 2>/dev/null || true
36
+
37
+ exit 0
@@ -0,0 +1,78 @@
1
+ #!/bin/bash
2
+ # pre-tool-use.sh — Claude Code PreToolUse:四路守卫
3
+ # 治理卡位 #4: 危险命令拦截 / 模板路径兜底 / 写入前置守卫 / 敏感文件保护
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
+ input=$(parse_input)
12
+ tool_name=$(json_get "$input" "tool_name")
13
+ [ -z "$tool_name" ] && tool_name=$(echo "$input" | grep -o '"tool_name"[[:space:]]*:[[:space:]]*"[^"]*"' 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "")
14
+
15
+ export PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$PWD}"
16
+
17
+ # ── ① Bash matcher: 危险命令拦截 + 终端写文件拦截 ──
18
+ if [ "$tool_name" = "Bash" ]; then
19
+ cmd=$(echo "$input" | grep -o '"command"[[:space:]]*:[[:space:]]*"[^"]*"' 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "")
20
+ # 危险命令
21
+ if echo "$cmd" | grep -qiE 'rm[[:space:]]+-rf[[:space:]]+/|DROP[[:space:]]+TABLE|git[[:space:]]+push[[:space:]]+--force|mkfs\.|dd[[:space:]]+if='; then
22
+ echo "⛔ 危险命令已被阻止: $cmd" >&2
23
+ exit $EXIT_BLOCK
24
+ fi
25
+ # 终端写文件拦截(含 > / >> / << heredoc / mv / touch / python -c > file)
26
+ if echo "$cmd" | grep -qE '(cat|echo|tee|sed[[:space:]]+-i|awk|printf|cp|mv|dd|touch)[[:space:]]*.*([>]{1,2}|[|][[:space:]]*tee|<<)'; then
27
+ echo "⛔ 禁止通过终端命令直接写文件: $cmd。请使用 Write/Edit/SearchReplace 工具。" >&2
28
+ exit $EXIT_BLOCK
29
+ fi
30
+ # mv 无重定向但仍操作文件
31
+ if echo "$cmd" | grep -qE '^[[:space:]]*mv[[:space:]]+/tmp/'; then
32
+ echo "⛔ 禁止通过 mv /tmp/ 绕过 IDE 工具: $cmd" >&2
33
+ exit $EXIT_BLOCK
34
+ fi
35
+ # python/node 脚本写文件
36
+ if echo "$cmd" | grep -qE '(python3|python|node)[[:space:]].*[>]{1,2}'; then
37
+ echo "⛔ 禁止通过脚本语言直接写文件: $cmd。请使用 Write/Edit/SearchReplace 工具。" >&2
38
+ exit $EXIT_BLOCK
39
+ fi
40
+ mark_dev_action
41
+ exit 0
42
+ fi
43
+
44
+ # ── ② Write/Edit matcher: 文件写入前置守卫 ──
45
+ if [ "$tool_name" = "Write" ] || [ "$tool_name" = "Edit" ]; then
46
+ file_path=$(echo "$input" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "")
47
+ [ -z "$file_path" ] && exit 0
48
+
49
+ # 检查是否写入 plans/specs/reviews 目录但无活跃 ADD Plan
50
+ if echo "$file_path" | grep -qE '\.(qoder|claude|add)/plans/|\.(qoder|claude|add)/specs/|\.(qoder|claude|add)/reviews/'; then
51
+ if type detect_active_add >/dev/null 2>&1; then
52
+ state=$(detect_active_add 2>/dev/null || true)
53
+ if [ -z "$state" ]; then
54
+ echo "[ADD PreToolUse] ⚠️ 正在写入 Plan/Spec/Review 文档但无活跃 ADD Plan——请先执行 add-paradigm" >&2
55
+ fi
56
+ fi
57
+ fi
58
+
59
+ # 敏感文件保护
60
+ if echo "$file_path" | grep -qE '\.env$|\.env\.production$|\.env\.local$|credentials|secrets'; then
61
+ echo "⛔ 敏感文件受保护,禁止写入: $file_path" >&2
62
+ exit $EXIT_BLOCK
63
+ fi
64
+
65
+ mark_dev_action
66
+ exit 0
67
+ fi
68
+
69
+ # ── ③ Read matcher: 模板路径兜底 ──
70
+ if [ "$tool_name" = "Read" ]; then
71
+ file_path=$(echo "$input" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "")
72
+ if echo "$file_path" | grep -q 'templates/'; then
73
+ echo "[ADD PreToolUse] 提示: 模板文件已通过 hook 预读到上下文,可跳过重复读取" >&2
74
+ fi
75
+ exit 0
76
+ fi
77
+
78
+ exit 0
@@ -0,0 +1,78 @@
1
+ #!/bin/bash
2
+ # UserPromptSubmit — 触发词路由 + 模板全文注入(Claude Code 适配)
3
+ # 治理卡位 #3: Layer 1 精准触发 → Layer 2 阻断 → Layer 3 状态注入
4
+ set -euo pipefail
5
+
6
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
8
+
9
+ COMMON_LIB="$HOOK_DIR/lib/common.sh"
10
+ [ -f "$COMMON_LIB" ] && source "$COMMON_LIB"
11
+
12
+ export PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$PWD}"
13
+
14
+ input=$(parse_input)
15
+ prompt=$(echo "$input" | grep -o '"prompt"[[:space:]]*:[[:space:]]*"[^"]*"' 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "")
16
+ [ -z "$prompt" ] && exit 0
17
+
18
+ # ─── Layer 1: 精准触发词路由 + 验收幂等保护 ───
19
+ matched=$(match_trigger "$prompt")
20
+ if [ -n "$matched" ]; then
21
+ if echo "$prompt" | grep -qiE '验收|收敛' 2>/dev/null; then
22
+ add_state=$(detect_active_add 2>/dev/null || true)
23
+ if [ -n "$add_state" ]; then
24
+ _handoff=$(echo "$add_state" | awk -F'::' '{print $4}')
25
+ _add_route=$(echo "$add_state" | awk -F'::' '{print $5}')
26
+ if is_already_accepted "$_add_route" "$_handoff" 2>/dev/null; then
27
+ cat <<EOF
28
+ [ADD 验收] ⚠️ 已验收。进入 Review 模式:
29
+ ① 重新检查 checklist [T]/[R] 项
30
+ ② 审查 audit 记录完整性
31
+ ③ 如有差异 → Review 回流至 handoff(增量更新)
32
+ ④ 无差异 → 记录 'Review 已确认,无新发现'
33
+ EOF
34
+ exit 0
35
+ fi
36
+ fi
37
+ fi
38
+ echo "$matched"
39
+ exit 0
40
+ fi
41
+
42
+ # ─── 开发关键词检测 ───
43
+ if ! echo "$prompt" | grep -qiE '开发|改功能|修.?bug|加需求|新增|重构|实施|验收|继续|生成plan|生成计划'; then
44
+ exit 0
45
+ fi
46
+
47
+ echo "[ADD PromptSubmit] 检测到开发关键词" >&2
48
+
49
+ # ─── Layer 2: 无活跃 ADD → 阻断 ───
50
+ state=$(detect_active_add 2>/dev/null || true)
51
+ if [ -z "$state" ]; then
52
+ cat <<'EOF'
53
+ [ADD 强制规则] 检测到开发任务。你必须先执行 add-paradigm SKILL 完成 ADD 工作流:
54
+ Step 0: 文档先行 (Plan → Review → Specs)
55
+ Step 3: 代码实现 + 审计植入
56
+ Step 8: 收敛判断
57
+ 如果 add-paradigm SKILL 尚未激活,请先调用它。
58
+ EOF
59
+ exit 2
60
+ fi
61
+
62
+ # ─── Layer 3: 有活跃 ADD → 注入状态 + 模板全文 ───
63
+ IFS='::' read -r plan step rounds handoff add_route <<< "$state"
64
+ cat <<EOF
65
+ [ADD 当前状态]
66
+ Plan: ${plan}
67
+ 轮次: ${rounds}
68
+ 当前 Step: ${step}
69
+ handoff: ${handoff}
70
+ EOF
71
+
72
+ # 模板全文注入(tpl-injected 去重)
73
+ TPL_SCRIPT="$HOOK_DIR/lib/preload-templates.sh"
74
+ if [ -f "$TPL_SCRIPT" ]; then
75
+ bash "$TPL_SCRIPT" --full --top 5
76
+ fi
77
+
78
+ exit 0
@@ -0,0 +1,21 @@
1
+ #!/bin/bash
2
+ ###
3
+ # @Author : xiaomingming wujixmm@gmail.com
4
+ # @Date : 2026-07-17 13:35:03
5
+ # @LastEditors : xiaomingming wujixmm@gmail.com
6
+ # @LastEditTime : 2026-07-17 13:35:04
7
+ # @FilePath : /add-coder/templates/adapters/claude/hooks/session-end.sh
8
+ # @Description :
9
+ ###
10
+ # SessionEnd — Claude Code 适配(薄包装)
11
+ # 治理卡位 #2: 标记清理 + 会话审计结算 + Stop未触发兜底
12
+ set -euo pipefail
13
+
14
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
15
+ export PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$PWD}"
16
+
17
+ # source 共享版本并自动执行 main()
18
+ SHARED="$HOOK_DIR/lib/session-end.sh"
19
+ if [ -f "$SHARED" ]; then
20
+ source "$SHARED"
21
+ fi
@@ -0,0 +1,36 @@
1
+ #!/bin/bash
2
+ # SessionStart — ADD 上下文恢复 + 模板索引注入(Claude Code 适配)
3
+ # 治理卡位 #1: ADD状态恢复 + 模板索引注入
4
+ set -euo pipefail
5
+
6
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ export CURRENT_MAGIC=$(basename "$(dirname "$HOOK_DIR")")
8
+
9
+ # 加载四端通用函数(路径统一后: .claude/hooks/lib/common.sh)
10
+ COMMON_LIB="$HOOK_DIR/lib/common.sh"
11
+ [ -f "$COMMON_LIB" ] && source "$COMMON_LIB"
12
+
13
+ # 设置项目目录
14
+ export PROJECT_DIR="$PWD"
15
+
16
+ # ── ① ADD 状态恢复 ──
17
+ state=$(detect_active_add 2>/dev/null || true)
18
+ if [ -n "$state" ]; then
19
+ IFS='::' read -r plan step rounds handoff add_route <<< "$state"
20
+ cat <<EOF
21
+ [ADD SessionStart] 检测到活跃 ADD Plan:
22
+ Plan: ${plan}
23
+ 轮次: ${rounds}
24
+ 当前 Step: ${step}
25
+ handoff: ${handoff}
26
+ 恢复命令: query_audit_logs({ planKeyword: '${plan}' })
27
+ EOF
28
+ fi
29
+
30
+ # ── ② 模板索引注入 ──
31
+ TPL_SCRIPT="$HOOK_DIR/lib/preload-templates.sh"
32
+ if [ -f "$TPL_SCRIPT" ]; then
33
+ bash "$TPL_SCRIPT" --index
34
+ fi
35
+
36
+ exit 0