add-coder 0.1.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 (97) hide show
  1. package/README.md +50 -0
  2. package/bin/add-coder.js +2 -0
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.js +576 -0
  5. package/package.json +64 -0
  6. package/templates/adapters/claude/hooks/doc-format-guard.sh +17 -0
  7. package/templates/adapters/claude/hooks/notification.sh +9 -0
  8. package/templates/adapters/claude/hooks/permission-gate.sh +18 -0
  9. package/templates/adapters/claude/hooks/post-tool-failure.sh +10 -0
  10. package/templates/adapters/claude/hooks/post-tool-use.sh +18 -0
  11. package/templates/adapters/claude/hooks/pre-compact.sh +14 -0
  12. package/templates/adapters/claude/hooks/pre-tool-use.sh +28 -0
  13. package/templates/adapters/claude/hooks/prompt-submit.sh +16 -0
  14. package/templates/adapters/claude/hooks/review-checklist.sh +10 -0
  15. package/templates/adapters/claude/hooks/session-start.sh +23 -0
  16. package/templates/adapters/claude/hooks/stop-check.sh +10 -0
  17. package/templates/adapters/claude/hooks/subagent-guard.sh +15 -0
  18. package/templates/adapters/claude/mcp.json +13 -0
  19. package/templates/adapters/claude/settings.json +125 -0
  20. package/templates/adapters/qoder/hooks/doc-format-guard.sh +164 -0
  21. package/templates/adapters/qoder/hooks/lib/context-inject.sh +96 -0
  22. package/templates/adapters/qoder/hooks/lib/state-detect.sh +104 -0
  23. package/templates/adapters/qoder/hooks/lib/vocabulary.sh +49 -0
  24. package/templates/adapters/qoder/hooks/notification.sh +22 -0
  25. package/templates/adapters/qoder/hooks/permission-gate.sh +8 -0
  26. package/templates/adapters/qoder/hooks/post-tool-failure.sh +8 -0
  27. package/templates/adapters/qoder/hooks/post-tool-use.sh +20 -0
  28. package/templates/adapters/qoder/hooks/pre-compact.sh +12 -0
  29. package/templates/adapters/qoder/hooks/pre-tool-use.sh +77 -0
  30. package/templates/adapters/qoder/hooks/prompt-submit.sh +72 -0
  31. package/templates/adapters/qoder/hooks/review-checklist.sh +157 -0
  32. package/templates/adapters/qoder/hooks/session-start.sh +16 -0
  33. package/templates/adapters/qoder/hooks/stop-check.sh +71 -0
  34. package/templates/adapters/qoder/hooks/subagent-guard.sh +11 -0
  35. package/templates/adapters/qoder/mcp.json +13 -0
  36. package/templates/adapters/qoder/settings.json +125 -0
  37. package/templates/adapters/qoder/sync-policy.json +18 -0
  38. package/templates/adapters/vscode/extensions.json +5 -0
  39. package/templates/adapters/vscode/launch.json +16 -0
  40. package/templates/adapters/vscode/settings.json +16 -0
  41. package/templates/adapters/vscode/tasks.json +38 -0
  42. package/templates/core/agents/add-flow-guardian.md +276 -0
  43. package/templates/core/agents/add-orchestrator.md +217 -0
  44. package/templates/core/plans/2026-07/08/farm-agent-add-coder-npm-package-add-route-v1.md +323 -0
  45. package/templates/core/plans/2026-07/08/farm-agent-add-coder-npm-package-handoff-v1.md +678 -0
  46. package/templates/core/plans/2026-07/08/farm-agent-add-coder-npm-package-plan-v1.md +785 -0
  47. package/templates/core/prisma/add.prisma +34 -0
  48. package/templates/core/reports/REPORT-WORKFLOW.md +250 -0
  49. package/templates/core/reports/boundary-runtime-report.md +134 -0
  50. package/templates/core/reports/code-review-combined-report.md +227 -0
  51. package/templates/core/reports/code-review-fix-verification-report.md +505 -0
  52. package/templates/core/reports/code-review-suggestions.md +66 -0
  53. package/templates/core/reports/index.md +57 -0
  54. package/templates/core/reports/runtime-report/gateway.md +741 -0
  55. package/templates/core/rules/project_rules.md +905 -0
  56. package/templates/core/rules/theory-practice-map.toml +105 -0
  57. package/templates/core/scripts/mcp-server.ts +3492 -0
  58. package/templates/core/skills/add-paradigm/SKILL.md +1086 -0
  59. package/templates/core/skills/session-init/SKILL.md +215 -0
  60. package/templates/core/specs/farm-agent-add-coder-npm-package/checklist.md +125 -0
  61. package/templates/core/specs/farm-agent-add-coder-npm-package/spec.md +343 -0
  62. package/templates/core/specs/farm-agent-add-coder-npm-package/tasks.md +203 -0
  63. package/templates/core/templates/01-/346/236/266/346/236/204//343/200/212ADD/345/274/200/345/217/221/345/267/245/344/275/234/350/267/257/345/276/204/344/270/216/346/226/207/346/241/243/345/215/217/345/220/214/350/247/204/350/214/203/343/200/213.md +386 -0
  64. package/templates/core/templates/TERMINOLOGY.md +81 -0
  65. package/templates/core/templates/add-route-template-heavyweight.md +288 -0
  66. package/templates/core/templates/add-route-template.md +242 -0
  67. package/templates/core/templates/add-route-template.schema.json +35 -0
  68. package/templates/core/templates/checklist-template.md +72 -0
  69. package/templates/core/templates/checklist-template.schema.json +20 -0
  70. package/templates/core/templates/fix-verification-template.md +132 -0
  71. package/templates/core/templates/fix-verification-template.schema.json +54 -0
  72. package/templates/core/templates/handoff-multi-round-template.md +295 -0
  73. package/templates/core/templates/handoff-multi-round.schema.json +48 -0
  74. package/templates/core/templates/handoff-single-round-template.md +145 -0
  75. package/templates/core/templates/handoff-single-round.schema.json +92 -0
  76. package/templates/core/templates/index.md +60 -0
  77. package/templates/core/templates/report-template.md +126 -0
  78. package/templates/core/templates/report-template.schema.json +69 -0
  79. package/templates/core/templates/review-implementation-template.md +66 -0
  80. package/templates/core/templates/review-implementation-template.schema.json +58 -0
  81. package/templates/core/templates/review-runtime-template.md +73 -0
  82. package/templates/core/templates/review-runtime-template.schema.json +47 -0
  83. package/templates/core/templates/review-template.md +37 -0
  84. package/templates/core/templates/review-template.schema.json +42 -0
  85. package/templates/core/templates/runtime-report-template.md +73 -0
  86. package/templates/core/templates/runtime-report-template.schema.json +48 -0
  87. package/templates/core/templates/simple-plan-template.md +166 -0
  88. package/templates/core/templates/simple-plan-template.schema.json +109 -0
  89. package/templates/core/templates/spec-template.md +22 -0
  90. package/templates/core/templates/spec-template.schema.json +41 -0
  91. package/templates/core/templates/standard-plan-template.md +96 -0
  92. package/templates/core/templates/standard-plan-template.schema.json +73 -0
  93. package/templates/core/templates/tasks-template.md +54 -0
  94. package/templates/core/templates/tasks-template.schema.json +43 -0
  95. package/templates/core/tools/README.md +361 -0
  96. package/templates/core/vocabulary/add-governance-vocabulary.md +370 -0
  97. package/templates/shared/hooks-lib/common.sh +22 -0
@@ -0,0 +1,104 @@
1
+ #!/bin/bash
2
+ # state-detect.sh — ADD 活跃流程检测 + dev action 追踪
3
+ # 共享库
4
+
5
+ PROJECT_DIR="${QODER_PROJECT_DIR:-${QODERCN_PROJECT_DIR:-$PWD}}"
6
+ QODER_DIR="$PROJECT_DIR/.qoder"
7
+ PLANS_DIR="$QODER_DIR/plans"
8
+
9
+ # dev action 标记文件(项目级,PreToolUse 写入,Stop 读取)
10
+ DEV_FLAG="/tmp/qoder_dev_$(echo "$PROJECT_DIR" | md5sum 2>/dev/null | cut -c1-8 || echo "default")"
11
+
12
+ # 检测活跃 ADD 流程
13
+ # 返回: "plan_keyword::step_x/total::round_n/total_r::handoff_path::add_route_path" 或 ""
14
+ detect_active_add() {
15
+ local handoff=""
16
+ local today_dir="$PLANS_DIR/$(date +%Y-%m)"
17
+ [ -d "$today_dir" ] && handoff=$(find "$today_dir" -name "*handoff*.md" -mtime -7 -type f 2>/dev/null | head -1)
18
+ [ -z "$handoff" ] && handoff=$(find "$PLANS_DIR" -name "*handoff*.md" -mtime -7 -type f 2>/dev/null | head -1)
19
+ [ -z "$handoff" ] && return 1
20
+
21
+ local plan_kw=$(basename "$handoff" | sed 's/-handoff.*//')
22
+
23
+ # add-route
24
+ local add_route=$(find "$PLANS_DIR" -name "*add-route*.md" -type f 2>/dev/null | head -1)
25
+
26
+ # Step 统计(从 add-route)
27
+ local step_info="?"
28
+ if [ -f "$add_route" ]; then
29
+ local ck=$(grep -c '\[x\]' "$add_route" 2>/dev/null || true)
30
+ local uc=$(grep -c '\[ \]' "$add_route" 2>/dev/null || true)
31
+ ck=${ck:-0}; uc=${uc:-0}
32
+ local total=$((ck + uc))
33
+ [ "$total" -gt 0 ] && step_info="${ck}/${total}"
34
+ fi
35
+
36
+ # 轮次统计(从 handoff)
37
+ local round_info="?"
38
+ if grep -q '<第[0-9]轮>' "$handoff" 2>/dev/null; then
39
+ local ck=$(grep -c '\[x\]' "$handoff" 2>/dev/null || true); ck=${ck:-0}
40
+ local total=$(grep -c '<第[0-9]轮>' "$handoff" 2>/dev/null || true); total=${total:-0}
41
+ [ "$total" -gt 0 ] && round_info="${ck}/${total}"
42
+ else
43
+ round_info="1/1"
44
+ fi
45
+
46
+ echo "${plan_kw}::${step_info}::${round_info}::${handoff}::${add_route:-none}"
47
+ }
48
+
49
+ # 标记 dev action
50
+ mark_dev_action() {
51
+ touch "$DEV_FLAG" 2>/dev/null || true
52
+ }
53
+
54
+ # 检测 dev action
55
+ has_dev_action() {
56
+ [ -f "$DEV_FLAG" ]
57
+ }
58
+
59
+ # 清理 dev action 标记(验收闭环后调用)
60
+ clear_dev_action() {
61
+ rm -f "$DEV_FLAG" 2>/dev/null || true
62
+ }
63
+
64
+ # 检查验收完整度,返回 issues 文本
65
+ check_add_completeness() {
66
+ local handoff="$1" add_route="$2"
67
+ local issues=""
68
+
69
+ # devlog(内容已回流至 handoff,检查 handoff 是否含验收结果)
70
+ if [ -f "$handoff" ] && ! grep -qE '验收|收敛|闭环|本轮改了什么|devlog' "$handoff" 2>/dev/null; then
71
+ issues="${issues} [ ] devlog 缺失(handoff 无验收记录)\n"
72
+ fi
73
+
74
+ # handoff 验证标准
75
+ if [ -f "$handoff" ]; then
76
+ local uc=$(grep -c '\[ \]' "$handoff" 2>/dev/null || echo "0")
77
+ [ "$uc" -gt 0 ] && issues="${issues} [ ] handoff ${uc} 项未勾选\n"
78
+ fi
79
+
80
+ # add-route Step
81
+ if [ -f "$add_route" ]; then
82
+ local uc=$(grep -c '\[ \]' "$add_route" 2>/dev/null || echo "0")
83
+ [ "$uc" -gt 0 ] && issues="${issues} [ ] add-route ${uc} Step 未闭环\n"
84
+ fi
85
+
86
+ echo -e "$issues"
87
+ }
88
+
89
+ # 检查是否已验收(幂等保护)
90
+ # 返回 0 = 未验收,1 = 已验收
91
+ is_already_accepted() {
92
+ local add_route="$1" handoff="$2"
93
+ # add-route Step 8 是否已 [x]
94
+ if [ -f "$add_route" ]; then
95
+ # 检查 Step 8 产出项是否勾选
96
+ if grep -A 10 'Step 8' "$add_route" 2>/dev/null | grep -q '\[x\].*验证并更新项目状态'; then
97
+ # handoff 是否有验收记录
98
+ if [ -f "$handoff" ] && grep -qE '✅.*验收|收敛|全部闭环|全部.*完成' "$handoff" 2>/dev/null; then
99
+ return 0
100
+ fi
101
+ fi
102
+ fi
103
+ return 1
104
+ }
@@ -0,0 +1,49 @@
1
+ #!/bin/bash
2
+ # vocabulary.sh — 从 vocabulary markdown 表格加载触发词
3
+ # 单一数据源: .qoder/vocabulary/add-governance-vocabulary.md §类别 A-F 表格
4
+
5
+ VOCABULARY_FILE="$PWD/.qoder/vocabulary/add-governance-vocabulary.md"
6
+
7
+ # 输出格式: 优先级::触发词正则::响应文本(:: 避免与触发词内的 | 冲突)
8
+ load_triggers() {
9
+ [ ! -f "$VOCABULARY_FILE" ] && return 1
10
+ sed -n '/^## 类别 A: 文档类型/,/^## 类别 [G-Z]/p' "$VOCABULARY_FILE" \
11
+ | grep -E '^\| (P0|P1|P2) ' \
12
+ | while IFS='|' read -r _ prio raw_trigger action; do
13
+ prio=$(echo "$prio" | xargs)
14
+ trigger=$(echo "$raw_trigger" | sed 's/`//g;s/ *\/ */|/g;s/^ *//;s/ *$//')
15
+ action=$(echo "$action" | xargs)
16
+ [ -z "$trigger" ] && continue
17
+ echo "${prio}::${trigger}::${action}"
18
+ done || true
19
+ }
20
+
21
+ match_trigger() {
22
+ local prompt="$1"
23
+ while IFS= read -r line; do
24
+ [ -z "$line" ] && continue
25
+ local prio="${line%%::*}"
26
+ local rest="${line#*::}"
27
+ local regex="${rest%%::*}"
28
+ local action="${rest#*::}"
29
+ # 跳过开发关键词检测行(由 Layer 2/3 分流处理,特征:超长regex含"修bug")
30
+ if echo "$regex" | grep -qE '修\.\?bug|fix\.\?bug' 2>/dev/null; then
31
+ continue
32
+ fi
33
+ if echo "$prompt" | grep -qiE "$regex" 2>/dev/null; then
34
+ echo "[ADD 触发] ${regex} → ${action}"
35
+ fi
36
+ done < <(load_triggers 2>/dev/null)
37
+ }
38
+
39
+ load_dev_keywords() {
40
+ load_triggers 2>/dev/null | while IFS= read -r line; do
41
+ [ -z "$line" ] && continue
42
+ # 只取包含"开发|改功能"的开发关键词检测行
43
+ if echo "$line" | grep -q '开发|改功能' 2>/dev/null; then
44
+ local rest="${line#*::}"
45
+ local regex="${rest%%::*}"
46
+ echo "$regex"
47
+ fi
48
+ done || true
49
+ }
@@ -0,0 +1,22 @@
1
+ #!/bin/bash
2
+ # notification.sh — Notification Review 提醒
3
+ set -euo pipefail
4
+ input=$(cat)
5
+ ntype=$(echo "$input" | jq -r '.notification_type // ""')
6
+
7
+ if [ "$ntype" != "result" ]; then
8
+ exit 0
9
+ fi
10
+
11
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
12
+ source "$HOOK_DIR/lib/state-detect.sh"
13
+
14
+ state=$(detect_active_add 2>/dev/null || true)
15
+ [ -z "$state" ] && exit 0
16
+
17
+ # 检查是否有未读 Review
18
+ reviews_dir="${QODER_DIR:-.qoder}/reviews"
19
+ if ls "$reviews_dir"/*.md >/dev/null 2>&1; then
20
+ echo "[ADD Notification] 请检查 Review 文档: ${reviews_dir}"
21
+ fi
22
+ exit 0
@@ -0,0 +1,8 @@
1
+ #!/bin/bash
2
+ # permission-gate.sh — PermissionRequest 人工卡位(不干预)
3
+ set -euo pipefail
4
+ # ADD Review 卡位由 Qoder 本身的权限弹窗处理,此 hook 仅做日志
5
+ input=$(cat)
6
+ tool_name=$(echo "$input" | jq -r '.tool_name // "unknown"')
7
+ echo "[ADD PermissionRequest] 工具 ${tool_name} 请求权限。如有 Review 文档待确认,请先检查。" >&2
8
+ exit 0
@@ -0,0 +1,8 @@
1
+ #!/bin/bash
2
+ # post-tool-failure.sh — PostToolUseFailure 错误定位
3
+ set -euo pipefail
4
+ input=$(cat)
5
+ tool_name=$(echo "$input" | jq -r '.tool_name // "unknown"')
6
+ error=$(echo "$input" | jq -r '.error // "unknown"')
7
+ echo "[ADD PostToolUseFailure] 工具 ${tool_name} 失败: ${error}。检查是否需要回退到上一 ADD Step 重新执行。" >&2
8
+ exit 0
@@ -0,0 +1,20 @@
1
+ #!/bin/bash
2
+ # post-tool-use.sh — PostToolUse 审计提醒
3
+ set -euo pipefail
4
+ input=$(cat)
5
+ file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
6
+ [ -z "$file_path" ] && exit 0
7
+
8
+ # 只在写入核心文件时提醒
9
+ if ! echo "$file_path" | grep -qE 'src/agents/|src/lib/agent-audit-logger\.ts|src/types/|prisma/schema\.prisma'; then
10
+ exit 0
11
+ fi
12
+
13
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
14
+ source "$HOOK_DIR/lib/state-detect.sh"
15
+
16
+ state=$(detect_active_add 2>/dev/null || true)
17
+ [ -z "$state" ] && exit 0
18
+
19
+ echo "[ADD PostToolUse] 文件已写入: ${file_path}。如果尚未记录,请执行 record_dev_operation({ targetId: '${file_path}' }) 落库审计。"
20
+ exit 0
@@ -0,0 +1,12 @@
1
+ #!/bin/bash
2
+ # pre-compact.sh — PreCompact ADD 状态快照
3
+ set -euo pipefail
4
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
5
+ source "$HOOK_DIR/lib/state-detect.sh"
6
+
7
+ state=$(detect_active_add 2>/dev/null || true)
8
+ [ -z "$state" ] && exit 0
9
+
10
+ IFS='::' read -r plan step rounds handoff add_route <<< "$state"
11
+ echo "[ADD PreCompact] 压缩前状态: Plan=${plan}, 轮次=${rounds}, Step=${step}"
12
+ exit 0
@@ -0,0 +1,77 @@
1
+ #!/bin/bash
2
+ # pre-tool-use.sh — PreToolUse §B:源码 Plan 关联检查(阻断模式 v3)
3
+ set -euo pipefail
4
+
5
+ input=$(cat)
6
+ file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
7
+ [ -z "$file_path" ] && exit 0
8
+
9
+ if ! echo "$file_path" | grep -qE '(src/|/src/).*\.(ts|tsx)$'; then
10
+ exit 0
11
+ fi
12
+
13
+ PROJECT_DIR="${QODER_PROJECT_DIR:-${QODERCN_PROJECT_DIR:-$PWD}}"
14
+ MOD=$(basename "$file_path" | sed 's/\.[jt]sx\?$//')
15
+
16
+ MATCHES=$(grep -rl "$MOD" "$PROJECT_DIR/.qoder/plans" "$PROJECT_DIR/.qoder/specs" "$PROJECT_DIR/.qoder/reports" 2>/dev/null | wc -l)
17
+
18
+ if [ "$MATCHES" -gt 0 ]; then
19
+ echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow","permissionDecisionReason":"相关 ADD Plan 已存在"}}'
20
+ exit 0
21
+ fi
22
+
23
+ echo "⛔ 阻断: ${file_path} 无相关 ADD Plan。请先创建 Plan(plan-template / simple-plan-template)。" >&2
24
+ echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"无相关 ADD Plan。请用 AskUserQuestion 询问用户选择 plan-template 或 simple-plan-template 创建 Plan。"}}'
25
+ exit 2
26
+ #!/bin/bash
27
+ # pre-tool-use.sh — PreToolUse §B:源码 Plan 关联检查(阻断模式)
28
+ set -euo pipefail
29
+
30
+ input=$(cat)
31
+ file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
32
+ [ -z "$file_path" ] && exit 0
33
+
34
+ # 只处理 src/**/*.ts / src/**/*.tsx
35
+ if ! echo "$file_path" | grep -qE '^src/.*\.(ts|tsx)$' && ! echo "$file_path" | grep -qE '^/home/.*/src/.*\.(ts|tsx)$'; then
36
+ exit 0
37
+ fi
38
+
39
+ PROJECT_DIR="${QODER_PROJECT_DIR:-${QODERCN_PROJECT_DIR:-$PWD}}"
40
+ PLANS_DIR="$PROJECT_DIR/.qoder/plans"
41
+ SPECS_DIR="$PROJECT_DIR/.qoder/specs"
42
+ REPORTS_DIR="$PROJECT_DIR/.qoder/reports"
43
+
44
+ MOD=$(basename "$file_path" | sed 's/\.[jt]sx\?$//')
45
+
46
+ MATCHES=$(grep -rl "$MOD" "$PLANS_DIR" "$SPECS_DIR" "$REPORTS_DIR" 2>/dev/null \
47
+ | sed "s|$PROJECT_DIR/||" \
48
+ | grep -oE '[^/]*-(plan|handoff|review|report)-v[0-9]+' \
49
+ | sed 's/\(plan\|handoff\|review\|report\)-v[0-9]\+\.md//' \
50
+ | sort -u | head -10 2>/dev/null || true)
51
+
52
+ if [ -n "$MATCHES" ]; then
53
+ cat >&2 <<EOF
54
+ [ADD PreToolUse] 📋 相关文档:
55
+ $(echo "$MATCHES" | sed 's/^/ - /')
56
+ 允许编辑 $file_path。
57
+ EOF
58
+ exit 0
59
+ fi
60
+
61
+ cat >&2 <<EOF
62
+ [ADD PreToolUse] ⛔ 阻断:${file_path} 无相关 ADD 文档。
63
+
64
+ 必须先生成 Plan 后才能修改源码。请执行:
65
+ ① 用 AskUserQuestion 询问用户:要创建 Plan 吗?
66
+ A) plan-template — 复杂改动,含架构设计 + 独立 Spec
67
+ B) simple-plan-template — 单一修复,Tasks 内联于 Plan 体
68
+ ② 按模板创建 Plan → Plan 中引用此文件路径
69
+ ③ 重新执行修改操作
70
+
71
+ JSON 输出格式(阻断时必须):
72
+ {"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"无相关 ADD Plan,请先生成 Plan 文档"}}
73
+ EOF
74
+
75
+ # 输出阻断 JSON 到 stdout,Qoder 会读它来展示阻断原因
76
+ echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"无相关 ADD Plan,请先生成 Plan 文档"}}'
77
+ exit 2
@@ -0,0 +1,72 @@
1
+ #!/bin/bash
2
+ # prompt-submit.sh — UserPromptSubmit 触发词智能路由(★入口)
3
+ input=$(cat)
4
+ prompt=$(echo "$input" | jq -r '.prompt // empty')
5
+ [ -z "$prompt" ] && exit 0
6
+
7
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
8
+ source "$HOOK_DIR/lib/vocabulary.sh"
9
+ source "$HOOK_DIR/lib/state-detect.sh"
10
+
11
+ # ─── Layer 1: 精准 P0 触发词 ───
12
+ matched=$(match_trigger "$prompt")
13
+ if [ -n "$matched" ]; then
14
+ # 验收幂等保护: 如果已验收,提示不重复
15
+ if echo "$prompt" | grep -qiE '验收|收敛' 2>/dev/null; then
16
+ add_state=$(detect_active_add 2>/dev/null || true)
17
+ if [ -n "$add_state" ]; then
18
+ _handoff=$(echo "$add_state" | awk -F'::' '{print $4}')
19
+ _add_route=$(echo "$add_state" | awk -F'::' '{print $5}')
20
+ if is_already_accepted "$_add_route" "$_handoff" 2>/dev/null; then
21
+ printf '%s\n' \
22
+ "[ADD 验收] ⚠️ 已验收。进入 Review 模式:" \
23
+ " ① 重新检查 checklist [T]/[R] 项" \
24
+ " ② 审查 audit 记录完整性" \
25
+ " ③ 如有差异 → Review 回流至 handoff(增量更新,不覆盖已有结论)" \
26
+ " ④ 无差异 → 记录 'Review 已确认,无新发现'" \
27
+ " ★ 同步检查: 如 checklist 有新 cuid 但 handoff 审计表缺失 → 更新 handoff ADD-7 表 + query_audit_logs 命令"
28
+ # 执行 checklist 质量检查
29
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
30
+ "$HOOK_DIR/review-checklist.sh" "$_handoff" "$_add_route" 2>/dev/null
31
+ exit 0
32
+ fi
33
+ fi
34
+ fi
35
+ echo "$matched"
36
+ exit 0
37
+ fi
38
+
39
+ # ─── 开发关键词检测 ───
40
+ dev_kw=$(load_dev_keywords 2>/dev/null || true)
41
+ if [ -z "$dev_kw" ]; then
42
+ exit 0
43
+ fi
44
+
45
+ if ! echo "$prompt" | grep -qiE "$dev_kw"; then
46
+ exit 0
47
+ fi
48
+
49
+ # ─── Layer 2/3: 按活跃 ADD 分流 ───
50
+ state=$(detect_active_add 2>/dev/null || true)
51
+ if [ -z "$state" ]; then
52
+ # Layer 2: 无活跃 ADD → 强制启动
53
+ cat >&2 <<'EOF'
54
+ [ADD 强制规则] 检测到开发任务。你必须先执行 add-paradigm SKILL 完成 ADD 工作流:
55
+ Step 0: 文档先行 (Plan → Review → Specs)
56
+ Step 1: 扩展 AgentAuditPhase
57
+ Step 2: 确认 agentAudit() 通道
58
+ Step 3: 代码实现 + 审计植入
59
+ ...
60
+ Step 8: 收敛判断
61
+ 如果 add-paradigm SKILL 尚未激活,请先调用它。
62
+ EOF
63
+ exit 2
64
+ fi
65
+
66
+ # Layer 3: 有活跃 ADD → 注入状态
67
+ plan=$(echo "$state" | awk -F'::' '{print $1}')
68
+ step=$(echo "$state" | awk -F'::' '{print $2}')
69
+ rounds=$(echo "$state" | awk -F'::' '{print $3}')
70
+ handoff=$(echo "$state" | awk -F'::' '{print $4}')
71
+ echo "[ADD 状态] Plan: ${plan}, 轮次: ${rounds}, Step: ${step}, handoff: ${handoff}"
72
+ exit 0
@@ -0,0 +1,157 @@
1
+ #!/bin/bash
2
+ # review-checklist.sh — 验收 Review 模式:检查 checklist 质量
3
+ # 被 prompt-submit.sh 的"验收"幂等检查后调用
4
+ #
5
+ # 输入: handoff_path add_route_path
6
+ # 输出: checklist 质量问题清单
7
+
8
+ handoff="$1"
9
+ add_route="$2"
10
+ [ -z "$handoff" ] && exit 0
11
+
12
+ # 从 handoff 关联找到 spec 目录
13
+ plan_dir=$(dirname "$handoff")
14
+ plan_kw=$(basename "$handoff" | sed 's/-handoff.*//')
15
+
16
+ # 找 checklist
17
+ spec_dir=".qoder/specs/${plan_kw}"
18
+ checklist=""
19
+ [ -d "$spec_dir" ] && checklist="$spec_dir/checklist.md"
20
+ # fallback: 搜索
21
+ [ ! -f "$checklist" ] && checklist=$(find .qoder/specs -name "checklist.md" -path "*${plan_kw}*" 2>/dev/null | head -1)
22
+
23
+ tasks_file=""
24
+ [ -d "$spec_dir" ] && tasks_file="$spec_dir/tasks.md"
25
+ [ ! -f "$tasks_file" ] && tasks_file=$(find .qoder/specs -name "tasks.md" -path "*${plan_kw}*" 2>/dev/null | head -1)
26
+
27
+ issues=""
28
+
29
+ # ══════════════════════════════════════════════════════════════════════
30
+ # 0. Step 0 准入: ADD 核心文档存在性(BLOCKING)
31
+ # ══════════════════════════════════════════════════════════════════════
32
+ _missing_docs=""
33
+ if [ ! -f "$handoff" ]; then
34
+ _missing_docs="${_missing_docs} Handoff"
35
+ else
36
+ # 章节完整性: 至少要有 spec 文件/你要改的文件/验证标准/完成后记录 四个关键小节
37
+ _h_sections=0
38
+ grep -q "spec 文件" "$handoff" 2>/dev/null && _h_sections=$((_h_sections + 1))
39
+ grep -q "你要改的文件" "$handoff" 2>/dev/null && _h_sections=$((_h_sections + 1))
40
+ grep -q "验证标准" "$handoff" 2>/dev/null && _h_sections=$((_h_sections + 1))
41
+ grep -q "完成后记录 ADD-7 审计" "$handoff" 2>/dev/null && _h_sections=$((_h_sections + 1))
42
+ if [ "$_h_sections" -lt 4 ]; then
43
+ _missing_docs="${_missing_docs} Handoff(缺章节:${_h_sections}/4)"
44
+ fi
45
+ fi
46
+ if [ ! -f "$add_route" ]; then
47
+ _missing_docs="${_missing_docs} add-route"
48
+ else
49
+ # add-route 至少要有 Task 映射表 + 文件清单
50
+ if ! grep -q "Task 映射表" "$add_route" 2>/dev/null && ! grep -q "文件清单" "$add_route" 2>/dev/null; then
51
+ _missing_docs="${_missing_docs} add-route(缺Task映射/文件清单)"
52
+ fi
53
+ fi
54
+ if [ ! -f "$checklist" ]; then
55
+ _missing_docs="${_missing_docs} checklist"
56
+ else
57
+ # checklist 至少要有 [T] 项
58
+ if ! grep -q '\[T\]' "$checklist" 2>/dev/null; then
59
+ _missing_docs="${_missing_docs} checklist(无[T]项)"
60
+ fi
61
+ fi
62
+ if [ ! -f "$tasks_file" ]; then
63
+ _missing_docs="${_missing_docs} tasks"
64
+ else
65
+ # tasks 至少要有 Task 列表 + 验证
66
+ if ! grep -q 'Task\|\- \[ \]' "$tasks_file" 2>/dev/null; then
67
+ _missing_docs="${_missing_docs} tasks(无Task项)"
68
+ fi
69
+ fi
70
+ if [ -n "$_missing_docs" ]; then
71
+ echo " ❌ Step 0 未完成:$(echo $_missing_docs | sed 's/ /, /g') 文件缺失。回退 Step 0.5/Step 1 补建后再进入代码实现。"
72
+ exit 1
73
+ fi
74
+
75
+ # 1. checklist [x] 数 vs tasks.md [x] 数 是否一致
76
+ if [ -f "$checklist" ] && [ -f "$tasks_file" ]; then
77
+ cl_ck=$(grep -c '\[x\]' "$checklist" 2>/dev/null || true); cl_ck=${cl_ck:-0}
78
+ cl_open=$(grep -c '\[ \]' "$checklist" 2>/dev/null || true); cl_open=${cl_open:-0}
79
+ tk_ck=$(grep -c '\[x\]' "$tasks_file" 2>/dev/null || echo "0")
80
+
81
+ if [ "$cl_open" -gt 0 ]; then
82
+ issues="${issues} ⚠️ checklist 有 ${cl_open} 项未勾选\n"
83
+ fi
84
+
85
+ # 2. [T] 项是否都有 [x](编译期验证项)
86
+ t_items=$(grep -c '\[T\]' "$checklist" 2>/dev/null || true); t_items=${t_items:-0}
87
+ t_checked=$(grep '\[T\]' "$checklist" 2>/dev/null | grep -c '\[x\]' || true); t_checked=${t_checked:-0}
88
+ if [ "$t_items" -gt "$t_checked" ]; then
89
+ issues="${issues} ⚠️ [T] 编译期验证: ${t_checked}/${t_items} 通过\n"
90
+ fi
91
+
92
+ # 3. 证据缺失检测:[x] 但缺 — 证据: 标记
93
+ _no_evidence=0
94
+ while IFS= read -r line; do
95
+ [ -z "$line" ] && continue
96
+ # 有证据: — 证据: 字段 + 具体内容(tsc/vitest/grep/审计ID 等)
97
+ if echo "$line" | grep -qE '—\s*证据:\s*\S' 2>/dev/null; then
98
+ continue
99
+ fi
100
+ # 有验证结果描述也行
101
+ if echo "$line" | grep -qE 'npx|tsc|vitest|grep|✅|cmq[0-9a-z]{10}|18/18|exit.*0' 2>/dev/null; then
102
+ continue
103
+ fi
104
+ _no_evidence=$((_no_evidence + 1))
105
+ done < <(grep '\[x\]' "$checklist" 2>/dev/null)
106
+
107
+ if [ "$_no_evidence" -gt 0 ]; then
108
+ issues="${issues} ❌ ${_no_evidence} 项 [x] 缺少验收证据(需附 — 证据: tsc/vitest/grep/审计ID 等)\n"
109
+ fi
110
+
111
+ # 4. 审计链:[x] 项引用 audit ID 的比例
112
+ # 初验: 有证据即可,审计ID是证据产出物
113
+ # 复验: 有审计ID + 证据仍有效 → 不重复落库;证据失效 → 追写新审计
114
+ _with_audit=$(grep '\[x\]' "$checklist" 2>/dev/null | grep -cE 'cmq[a-z0-9]{10,}' || true); _with_audit=${_with_audit:-0}
115
+ _fake_audit=$(grep '\[x\]' "$checklist" 2>/dev/null | grep -cE 'cmq\.\.\.|cmqxxx|审计.*cmq\.\.' || true); _fake_audit=${_fake_audit:-0}
116
+ if [ "$_fake_audit" -gt 0 ]; then
117
+ issues="${issues} ❌ ${_fake_audit} 项 [x] 使用了占位符审计ID(cmq.../cmqxxx),必须调 record_dev_operation 获取真实 cuid 后替换\n"
118
+ fi
119
+ _with_evidence=$(grep '\[x\]' "$checklist" 2>/dev/null | grep -cE 'tsc|vitest|npx|grep|✅|验证|确认|compgen|审计.*cmq[a-z0-9]{10}' || true); _with_evidence=${_with_evidence:-0}
120
+ if [ "$_with_evidence" -gt 0 ] && [ "$_with_audit" -eq 0 ]; then
121
+ issues="${issues} 📎 初验: ${_with_evidence}/${cl_ck} 项有证据但未写审计 ID(需调 record_dev_operation 落库)\n"
122
+ elif [ "$_with_audit" -gt 0 ] && [ "$_with_audit" -lt "$cl_ck" ]; then
123
+ issues="${issues} 📎 复验: ${_with_audit}/${cl_ck} 项引用审计 ID。${_with_evidence}/${cl_ck} 项有证据。证据一致则不需追写 devlog日志(走mcp)\n"
124
+ fi
125
+ fi
126
+
127
+ # 5. add-route Step 闭环
128
+ if [ -f "$add_route" ]; then
129
+ ar_ck=$(grep -c '\[x\]' "$add_route" 2>/dev/null || true); ar_ck=${ar_ck:-0}
130
+ ar_open=$(grep -c '\[ \]' "$add_route" 2>/dev/null || true); ar_open=${ar_open:-0}
131
+ if [ "$ar_open" -gt 0 ]; then
132
+ issues="${issues} ⚠️ add-route ${ar_open} Step 未闭环\n"
133
+ fi
134
+ fi
135
+
136
+ # 6. handoff 审计表同步:checklist 中的 cuid 是否在 handoff 中有记录
137
+ if [ -f "$handoff" ] && [ -f "$checklist" ]; then
138
+ _new_cuids=""
139
+ while IFS= read -r cuid; do
140
+ [ -z "$cuid" ] && continue
141
+ if ! grep -q "$cuid" "$handoff" 2>/dev/null; then
142
+ [ -n "$_new_cuids" ] && _new_cuids="${_new_cuids}, "
143
+ _new_cuids="${_new_cuids}${cuid}"
144
+ fi
145
+ done < <(grep -oE 'cmq[a-z0-9]{10,}' "$checklist" 2>/dev/null | sort -u)
146
+ if [ -n "$_new_cuids" ]; then
147
+ _new_count=$(echo "$_new_cuids" | tr ',' '\n' | wc -l)
148
+ issues="${issues} ❌ handoff 审计表未同步: ${_new_count} 个 cuid 在 checklist 中存在但 handoff 中缺失(需更新 handoff ADD-7 表 + query_audit_logs 命令)\n"
149
+ fi
150
+ fi
151
+
152
+ if [ -z "$issues" ]; then
153
+ echo " ✅ Review: checklist 质量检查通过"
154
+ else
155
+ echo " 📋 Review 发现问题:"
156
+ echo -e "$issues"
157
+ fi
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+ # SessionStart — ADD 上下文恢复
3
+ set -euo pipefail
4
+
5
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+ source "$HOOK_DIR/lib/state-detect.sh"
7
+ source "$HOOK_DIR/lib/context-inject.sh"
8
+
9
+ state=$(detect_active_add 2>/dev/null || true)
10
+ if [ -z "$state" ]; then
11
+ exit 0
12
+ fi
13
+
14
+ IFS='::' read -r plan step rounds handoff <<< "$state"
15
+ build_session_start_json "$plan" "$step" "$rounds" "$handoff"
16
+ exit 0
@@ -0,0 +1,71 @@
1
+ #!/bin/bash
2
+ # stop-check.sh — Stop 验收闭环检查(四象限 + few-shot)
3
+ input=$(cat)
4
+ stop_active=$(echo "$input" | jq -r '.stop_hook_active // false')
5
+ [ "$stop_active" = "true" ] && exit 0
6
+
7
+ HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
8
+ source "$HOOK_DIR/lib/state-detect.sh"
9
+ source "$HOOK_DIR/lib/context-inject.sh"
10
+
11
+ state=$(detect_active_add 2>/dev/null || true)
12
+ has_dev=$(has_dev_action 2>/dev/null && echo "true" || echo "false")
13
+
14
+ # ═══════════════ 四象限分流 ═══════════════
15
+
16
+ # Q1: 无 ADD + 无 dev → 正常停
17
+ if [ -z "$state" ] && [ "$has_dev" != "true" ]; then
18
+ exit 0
19
+ fi
20
+
21
+ # Q2: 无 ADD + 有 dev → 严重违规,强制阻止
22
+ if [ -z "$state" ] && [ "$has_dev" = "true" ]; then
23
+ build_stop_context "no_add_has_dev" >&2
24
+ exit 2
25
+ fi
26
+
27
+ # 解析 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}')
33
+
34
+ # Q3: 有 ADD + 无 dev → 注入状态
35
+ if [ "$has_dev" != "true" ]; then
36
+ echo "[ADD Stop] Plan: ${plan}, 轮次: ${round_info}, Step: ${step_info}"
37
+ echo "本次无代码改动。下次继续时执行 session-init 恢复上下文。"
38
+ exit 0
39
+ fi
40
+
41
+ # Q4: 有 ADD + 有 dev → Step 定位分流
42
+ 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
+ if [ -n "$issues" ]; then
64
+ build_stop_context "has_add_dev_unclosed" "$issues" >&2
65
+ exit 2
66
+ fi
67
+
68
+ # 全部闭环
69
+ clear_dev_action 2>/dev/null || true
70
+ echo "[ADD Stop] ✅ 验收闭环: add-route 全部 [x], devlog 已写, handoff 已更新。"
71
+ exit 0
@@ -0,0 +1,11 @@
1
+ #!/bin/bash
2
+ # subagent-guard.sh — SubagentStart/Stop 门禁日志
3
+ 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
+
8
+ if echo "$agent_type" | grep -qiE 'guardian|orchestrator'; then
9
+ echo "[ADD Subagent] ${hook_event}: ${agent_type}"
10
+ fi
11
+ exit 0
@@ -0,0 +1,13 @@
1
+ {
2
+ "mcpServers": {
3
+ "add-dev-tools": {
4
+ "command": "{{mcpServerCommand}}",
5
+ "args": [
6
+ "{{projectRoot}}/.qoder/scripts/mcp-server.ts"
7
+ ],
8
+ "env": {
9
+ "NODE_ENV": "development"
10
+ }
11
+ }
12
+ }
13
+ }