cc-workspace 4.7.1 → 5.2.2

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 (35) hide show
  1. package/CHANGELOG.md +307 -0
  2. package/README.md +123 -41
  3. package/bin/cli.js +333 -134
  4. package/global-skills/agents/e2e-validator.md +152 -33
  5. package/global-skills/agents/implementer.md +77 -71
  6. package/global-skills/agents/reviewer.md +192 -0
  7. package/global-skills/agents/security-auditor.md +345 -0
  8. package/global-skills/agents/team-lead.md +93 -101
  9. package/global-skills/agents/workspace-init.md +16 -5
  10. package/global-skills/bootstrap-repo/SKILL.md +1 -0
  11. package/global-skills/cleanup/SKILL.md +35 -25
  12. package/global-skills/cross-service-check/SKILL.md +1 -0
  13. package/global-skills/cycle-retrospective/SKILL.md +6 -4
  14. package/global-skills/dispatch-feature/SKILL.md +225 -173
  15. package/global-skills/dispatch-feature/references/anti-patterns.md +52 -35
  16. package/global-skills/dispatch-feature/references/spawn-templates.md +140 -97
  17. package/global-skills/doctor/SKILL.md +124 -25
  18. package/global-skills/e2e-validator/references/container-strategies.md +55 -23
  19. package/global-skills/hooks/orphan-cleanup.sh +60 -0
  20. package/global-skills/hooks/permission-auto-approve.sh +61 -4
  21. package/global-skills/hooks/session-start-context.sh +10 -47
  22. package/global-skills/hooks/test_hooks.sh +242 -0
  23. package/global-skills/hooks/user-prompt-guard.sh +6 -6
  24. package/global-skills/hooks/validate-spawn-prompt.sh +40 -30
  25. package/global-skills/incident-debug/SKILL.md +1 -0
  26. package/global-skills/merge-prep/SKILL.md +1 -0
  27. package/global-skills/metrics/SKILL.md +139 -0
  28. package/global-skills/plan-review/SKILL.md +2 -1
  29. package/global-skills/qa-ruthless/SKILL.md +2 -0
  30. package/global-skills/refresh-profiles/SKILL.md +1 -0
  31. package/global-skills/rules/context-hygiene.md +4 -19
  32. package/global-skills/rules/model-routing.md +31 -18
  33. package/global-skills/session/SKILL.md +41 -20
  34. package/global-skills/templates/workspace.template.md +1 -1
  35. package/package.json +4 -3
@@ -0,0 +1,242 @@
1
+ #!/usr/bin/env bash
2
+ # test_hooks.sh — Unit tests for cc-workspace hooks
3
+ # Run from the hooks directory: cd global-skills/hooks && bash test_hooks.sh
4
+ # Requirements: jq, bash 4+
5
+ set -euo pipefail
6
+
7
+ HOOKS_DIR="$(cd "$(dirname "$0")" && pwd)"
8
+ PASS=0
9
+ FAIL=0
10
+ TOTAL=0
11
+
12
+ # ─── Helpers ────────────────────────────────────────────────
13
+ RED='\033[0;31m'
14
+ GREEN='\033[0;32m'
15
+ DIM='\033[2m'
16
+ RESET='\033[0m'
17
+
18
+ assert_contains() {
19
+ local label="$1" output="$2" expected="$3"
20
+ TOTAL=$((TOTAL + 1))
21
+ if echo "$output" | grep -qF "$expected"; then
22
+ PASS=$((PASS + 1))
23
+ printf " ${GREEN}✓${RESET} %s\n" "$label"
24
+ else
25
+ FAIL=$((FAIL + 1))
26
+ printf " ${RED}✗${RESET} %s\n" "$label"
27
+ printf " ${DIM}expected to contain: %s${RESET}\n" "$expected"
28
+ printf " ${DIM}got: %s${RESET}\n" "$output"
29
+ fi
30
+ }
31
+
32
+ assert_empty() {
33
+ local label="$1" output="$2"
34
+ TOTAL=$((TOTAL + 1))
35
+ if [ -z "$output" ]; then
36
+ PASS=$((PASS + 1))
37
+ printf " ${GREEN}✓${RESET} %s\n" "$label"
38
+ else
39
+ FAIL=$((FAIL + 1))
40
+ printf " ${RED}✗${RESET} %s\n" "$label"
41
+ printf " ${DIM}expected empty, got: %s${RESET}\n" "$output"
42
+ fi
43
+ }
44
+
45
+ assert_exit_code() {
46
+ local label="$1" actual="$2" expected="$3"
47
+ TOTAL=$((TOTAL + 1))
48
+ if [ "$actual" -eq "$expected" ]; then
49
+ PASS=$((PASS + 1))
50
+ printf " ${GREEN}✓${RESET} %s\n" "$label"
51
+ else
52
+ FAIL=$((FAIL + 1))
53
+ printf " ${RED}✗${RESET} %s\n" "$label"
54
+ printf " ${DIM}expected exit %s, got %s${RESET}\n" "$expected" "$actual"
55
+ fi
56
+ }
57
+
58
+ run_hook() {
59
+ local hook="$1" input="$2"
60
+ echo "$input" | bash "$HOOKS_DIR/$hook" 2>/dev/null || true
61
+ }
62
+
63
+ run_hook_exit() {
64
+ local hook="$1" input="$2"
65
+ echo "$input" | bash "$HOOKS_DIR/$hook" 2>/dev/null
66
+ echo $?
67
+ }
68
+
69
+ # ─── permission-auto-approve.sh ─────────────────────────────
70
+ echo ""
71
+ echo "▸ permission-auto-approve.sh"
72
+
73
+ # Should auto-approve Read tool
74
+ OUT=$(run_hook "permission-auto-approve.sh" '{"tool_name":"Read"}')
75
+ assert_contains "approves Read tool" "$OUT" '"behavior":"allow"'
76
+
77
+ # Should auto-approve Glob tool
78
+ OUT=$(run_hook "permission-auto-approve.sh" '{"tool_name":"Glob"}')
79
+ assert_contains "approves Glob tool" "$OUT" '"behavior":"allow"'
80
+
81
+ # Should auto-approve Grep tool
82
+ OUT=$(run_hook "permission-auto-approve.sh" '{"tool_name":"Grep"}')
83
+ assert_contains "approves Grep tool" "$OUT" '"behavior":"allow"'
84
+
85
+ # Should NOT auto-approve Write tool
86
+ OUT=$(run_hook "permission-auto-approve.sh" '{"tool_name":"Write"}')
87
+ assert_empty "does not approve Write tool" "$OUT"
88
+
89
+ # Should approve simple git log
90
+ OUT=$(run_hook "permission-auto-approve.sh" '{"tool_name":"Bash","tool_input":{"command":"git log --oneline -5"}}')
91
+ assert_contains "approves git log" "$OUT" '"behavior":"allow"'
92
+
93
+ # Should approve git --no-pager log (hardened regex)
94
+ OUT=$(run_hook "permission-auto-approve.sh" '{"tool_name":"Bash","tool_input":{"command":"git --no-pager log --oneline -5"}}')
95
+ assert_contains "approves git --no-pager log" "$OUT" '"behavior":"allow"'
96
+
97
+ # Should approve git -C path status
98
+ OUT=$(run_hook "permission-auto-approve.sh" '{"tool_name":"Bash","tool_input":{"command":"git -C ../api status --short"}}')
99
+ assert_contains "approves git -C status" "$OUT" '"behavior":"allow"'
100
+
101
+ # Should approve git branch session/xxx
102
+ OUT=$(run_hook "permission-auto-approve.sh" '{"tool_name":"Bash","tool_input":{"command":"git branch session/feature-auth preprod"}}')
103
+ assert_contains "approves git branch session/" "$OUT" '"behavior":"allow"'
104
+
105
+ # Should approve git -C ../repo branch session/xxx
106
+ OUT=$(run_hook "permission-auto-approve.sh" '{"tool_name":"Bash","tool_input":{"command":"git -C ../api branch session/feature-auth preprod"}}')
107
+ assert_contains "approves git -C branch session/" "$OUT" '"behavior":"allow"'
108
+
109
+ # Should approve git worktree add in /tmp/
110
+ OUT=$(run_hook "permission-auto-approve.sh" '{"tool_name":"Bash","tool_input":{"command":"git worktree add /tmp/api-feature-auth session/feature-auth"}}')
111
+ assert_contains "approves git worktree add /tmp/" "$OUT" '"behavior":"allow"'
112
+
113
+ # Should approve test commands in /tmp/ worktrees
114
+ OUT=$(run_hook "permission-auto-approve.sh" '{"tool_name":"Bash","tool_input":{"command":"cd /tmp/api-feature-auth && npm run typecheck"}}')
115
+ assert_contains "approves npm typecheck in /tmp/" "$OUT" '"behavior":"allow"'
116
+
117
+ OUT=$(run_hook "permission-auto-approve.sh" '{"tool_name":"Bash","tool_input":{"command":"cd /tmp/api-feature-auth && php artisan test --filter=UserTest"}}')
118
+ assert_contains "approves php artisan test in /tmp/" "$OUT" '"behavior":"allow"'
119
+
120
+ # Should NOT approve rm -rf
121
+ OUT=$(run_hook "permission-auto-approve.sh" '{"tool_name":"Bash","tool_input":{"command":"rm -rf /"}}')
122
+ assert_empty "does not approve rm -rf" "$OUT"
123
+
124
+ # Should NOT approve git checkout (not a safe read op)
125
+ OUT=$(run_hook "permission-auto-approve.sh" '{"tool_name":"Bash","tool_input":{"command":"git checkout main"}}')
126
+ assert_empty "does not approve git checkout" "$OUT"
127
+
128
+ # Should approve git diff in /tmp/ worktrees
129
+ OUT=$(run_hook "permission-auto-approve.sh" '{"tool_name":"Bash","tool_input":{"command":"git -C /tmp/api-feature-auth diff HEAD~1 HEAD"}}')
130
+ assert_contains "approves git diff in /tmp/" "$OUT" '"behavior":"allow"'
131
+
132
+
133
+ # ─── validate-spawn-prompt.sh ────────────────────────────────
134
+ echo ""
135
+ echo "▸ validate-spawn-prompt.sh"
136
+
137
+ # Complete prompt should have no warnings
138
+ GOOD_PROMPT='{"tool_input":{"prompt":"## Constitution\n1. **Multi-tenancy** is sacred.\n2. **No hardcoded secrets.**\n\n## Your complete plan — all 3 commit units\n### Commit 1: Data layer\nCreate models\n\n## Your workspace\n- Worktree (ready, go directly here): /tmp/svc-feature-auth\n- Session branch: session/feature-auth\n\n## Signal protocol (MANDATORY)\nAfter EACH commit: SendMessage commit N done. Then WAIT for my green light.\n\nRead the repo CLAUDE.md first.\nIf you hit an architectural decision not in the plan: SendMessage immediately and wait."}}'
139
+ OUT=$(run_hook "validate-spawn-prompt.sh" "$GOOD_PROMPT")
140
+ assert_empty "complete prompt (non-API/non-frontend) — no warnings" "$OUT"
141
+
142
+ # Missing constitution should warn
143
+ NO_CONST='{"tool_input":{"prompt":"## Your plan\n### Commit 1: stuff\nworktree_path: /tmp/api-x\nSendMessage after each commit and wait for green light."}}'
144
+ OUT=$(run_hook "validate-spawn-prompt.sh" "$NO_CONST")
145
+ assert_contains "warns on missing constitution" "$OUT" "project-specific rules"
146
+
147
+ # Missing plan should warn
148
+ NO_PLAN='{"tool_input":{"prompt":"## Constitution\n1. **Rule one.**\nworktree_path: /tmp/api-x\nSendMessage after each commit."}}'
149
+ OUT=$(run_hook "validate-spawn-prompt.sh" "$NO_PLAN")
150
+ assert_contains "warns on missing plan/tasks" "$OUT" "plan/tasks"
151
+
152
+ # Missing worktree path should warn
153
+ NO_WT='{"tool_input":{"prompt":"## Constitution\n1. **Rule one.**\n## Your plan\n### Commit 1: stuff\nSendMessage after each commit."}}'
154
+ OUT=$(run_hook "validate-spawn-prompt.sh" "$NO_WT")
155
+ assert_contains "warns on missing worktree_path" "$OUT" "worktree_path"
156
+
157
+ # Missing signal protocol should warn
158
+ NO_SIGNAL='{"tool_input":{"prompt":"## Constitution\n1. **Rule one.**\n## Your plan\n### Commit 1: stuff\nWorktree ready: /tmp/api-x"}}'
159
+ OUT=$(run_hook "validate-spawn-prompt.sh" "$NO_SIGNAL")
160
+ assert_contains "warns on missing signal protocol" "$OUT" "signal protocol"
161
+
162
+ # Frontend without UX standards should warn
163
+ FRONT_NO_UX='{"tool_input":{"prompt":"## Constitution\n1. **Rule one.**\nfrontend Vue component\n## Your plan\n### Commit 1: UI\n/tmp/front-x\nSendMessage commit N done. WAIT for green light."}}'
164
+ OUT=$(run_hook "validate-spawn-prompt.sh" "$FRONT_NO_UX")
165
+ assert_contains "warns frontend without UX standards" "$OUT" "UX standards"
166
+
167
+ # Empty prompt should produce no output (no crash)
168
+ OUT=$(run_hook "validate-spawn-prompt.sh" '{"tool_input":{"prompt":""}}')
169
+ assert_empty "empty prompt — no crash, no output" "$OUT"
170
+
171
+ # No prompt field should produce no output
172
+ OUT=$(run_hook "validate-spawn-prompt.sh" '{"tool_input":{}}')
173
+ assert_empty "missing prompt field — no crash" "$OUT"
174
+
175
+
176
+ # ─── session-start-context.sh ────────────────────────────────
177
+ echo ""
178
+ echo "▸ session-start-context.sh"
179
+
180
+ # Note: session-start-context.sh has a glob pattern (for wt in /tmp/*-session-*)
181
+ # that can fail on systems with no matching files unless nullglob is set.
182
+ # We test the parts we can control without needing the orphan cleanup loop.
183
+
184
+ # Setup temp workspace for session-start-context tests
185
+ TEMP_WS=$(mktemp -d)
186
+ mkdir -p "$TEMP_WS/.sessions" "$TEMP_WS/plans"
187
+
188
+ # Create a dummy /tmp/*-session-* dir to prevent glob failure
189
+ DUMMY_WT=$(mktemp -d /tmp/test-session-XXXXXX)
190
+
191
+ # With no workspace.md, should warn
192
+ OUT=$(CLAUDE_PROJECT_DIR="$TEMP_WS" run_hook "session-start-context.sh" '{}')
193
+ assert_contains "warns on missing workspace.md" "$OUT" "No workspace.md"
194
+
195
+ # Create a configured workspace.md
196
+ echo "# Workspace: Test" > "$TEMP_WS/workspace.md"
197
+ OUT=$(CLAUDE_PROJECT_DIR="$TEMP_WS" run_hook "session-start-context.sh" '{}')
198
+ # Should be empty or just orphan cleanup (our dummy dir)
199
+ TOTAL=$((TOTAL + 1))
200
+ if echo "$OUT" | grep -qE "(WARNING|FIRST SESSION|Active plans)"; then
201
+ FAIL=$((FAIL + 1))
202
+ printf " ${RED}✗${RESET} configured workspace — unexpected warnings\n"
203
+ printf " ${DIM}got: %s${RESET}\n" "$OUT"
204
+ else
205
+ PASS=$((PASS + 1))
206
+ printf " ${GREEN}✓${RESET} configured workspace — no unexpected warnings\n"
207
+ fi
208
+
209
+ # Create an unconfigured workspace.md
210
+ echo "[UNCONFIGURED]" > "$TEMP_WS/workspace.md"
211
+ OUT=$(CLAUDE_PROJECT_DIR="$TEMP_WS" run_hook "session-start-context.sh" '{}')
212
+ assert_contains "detects UNCONFIGURED workspace" "$OUT" "FIRST SESSION"
213
+
214
+ # Create an active session and restore configured workspace
215
+ echo "# Workspace: Test" > "$TEMP_WS/workspace.md"
216
+ cat > "$TEMP_WS/.sessions/test.json" << 'SESS'
217
+ {
218
+ "name": "test-session",
219
+ "status": "active",
220
+ "repos": {
221
+ "api": { "worktree_path": "/tmp/nonexistent-test-wt-12345" }
222
+ }
223
+ }
224
+ SESS
225
+ OUT=$(CLAUDE_PROJECT_DIR="$TEMP_WS" run_hook "session-start-context.sh" '{}')
226
+ assert_contains "shows active sessions" "$OUT" "test-session"
227
+
228
+ # Cleanup
229
+ rm -rf "$TEMP_WS" "$DUMMY_WT"
230
+
231
+
232
+ # ─── Summary ────────────────────────────────────────────────
233
+ echo ""
234
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
235
+ if [ "$FAIL" -eq 0 ]; then
236
+ printf "${GREEN}All %d tests passed ✓${RESET}\n" "$TOTAL"
237
+ else
238
+ printf "${RED}%d/%d tests failed${RESET}\n" "$FAIL" "$TOTAL"
239
+ fi
240
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
241
+
242
+ exit "$FAIL"
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/env bash
2
2
  # user-prompt-guard.sh
3
3
  # UserPromptSubmit hook: conditionally reminds the orchestrator of its role.
4
- # Only injects the reminder when the user prompt contains patterns suggesting
5
- # a direct code request. This saves tokens on routine messages.
4
+ # v5.0: Updated to reflect that Opus can run git/bash on repos for orchestration
5
+ # purposes (branch creation, worktree management, micro-QA), but not code changes.
6
6
  # Non-blocking (exit 0 + stdout = context injection).
7
7
  set -euo pipefail
8
8
 
9
9
  INPUT=$(cat)
10
10
 
11
- # Extract the user prompt text from stdin JSON
11
+ # Extract the user prompt text
12
12
  PROMPT=$(echo "$INPUT" | jq -r '.prompt // empty' 2>/dev/null) || true
13
13
 
14
- # Only inject reminder if user prompt matches code-request patterns
15
- if echo "$PROMPT" | grep -qiE '(dans le repo|dans [a-z-]+/|modifie.*repo|édite.*(api|front|light|spring|scraper|krakend|dashboard)|patch.*service)' 2>/dev/null; then
16
- echo "Role reminder: Writing in sibling repos is for teammates. You can write in orchestrator/ (plans, workspace.md, constitution.md). For repo changes, spawn a teammate."
14
+ # Only inject reminder if user prompt matches direct code-writing patterns
15
+ if echo "$PROMPT" | grep -qiE '(modifie.*fichier|édite.*(api|front|light|spring|scraper|krakend|dashboard)|patch.*service|écris.*dans.*repo|write.*in.*repo|code.*dans.*repo)' 2>/dev/null; then
16
+ echo "Role reminder: Writing application code in sibling repos is for teammates. You can write in orchestrator/ (plans, workspace.md, constitution.md) and run git commands (branch, worktree, log) and test commands in /tmp/ worktrees for micro-QA. For repo application code changes: spawn a teammate."
17
17
  fi
18
18
 
19
19
  exit 0
@@ -2,7 +2,8 @@
2
2
  # validate-spawn-prompt.sh
3
3
  # PreToolUse hook (matcher: Teammate): validates that teammate spawn prompts
4
4
  # contain the required context before allowing the spawn.
5
- # v4.0: ALL checks are non-blocking warnings (exit 0 + stdout).
5
+ # v5.0: Updated for one-teammate-per-repo model with worktree_path and signal protocol.
6
+ # ALL checks are non-blocking warnings (exit 0 + stdout).
6
7
  set -euo pipefail
7
8
 
8
9
  INPUT=$(cat)
@@ -17,65 +18,74 @@ fi
17
18
  WARNINGS=""
18
19
  BLOCKERS=""
19
20
 
20
- # Check 1: Project-specific rules require numbered rules (13., 14., etc.)
21
- # or explicit section header, not just mention of the word "rules"
21
+ # Check 1: Project-specific rules / constitution
22
+ # Uses multiple heuristics: section headers, numbered rules (3+), keyword density
22
23
  RULES_FOUND=0
23
- if echo "$PROMPT" | grep -qiE '(## project rules|## non-negotiable|project-specific rules|rules spécifiques)' 2>/dev/null; then
24
+ # Heuristic A: explicit section headers
25
+ if echo "$PROMPT" | grep -qiE '(## (project )?rules|## non-negotiable|## constitution|project-specific rules|rules spécifiques|## engineering principles)' 2>/dev/null; then
24
26
  RULES_FOUND=1
25
27
  fi
26
- if echo "$PROMPT" | grep -qE '(1[3-9]\.|[2-9][0-9]\.).*\*\*' 2>/dev/null; then
28
+ # Heuristic B: numbered bold rules (at least 3 = likely a constitution)
29
+ NUMBERED_RULES=$(echo "$PROMPT" | grep -cE '^[0-9]+\.\s+\*\*' 2>/dev/null || echo "0")
30
+ if [ "$NUMBERED_RULES" -ge 3 ]; then
27
31
  RULES_FOUND=1
28
32
  fi
29
- if echo "$PROMPT" | grep -qiE '(constitution|project rules)' 2>/dev/null && echo "$PROMPT" | grep -cqiE '(tenant|scoping|precision|rollback|feature flag)' 2>/dev/null; then
30
- RULES_FOUND=1
33
+ # Heuristic C: constitution keyword + domain-specific terms (2+ matches)
34
+ if echo "$PROMPT" | grep -qiE '(constitution|project rules|non-negotiable)' 2>/dev/null; then
35
+ DOMAIN_HITS=$(echo "$PROMPT" | grep -ciE '(tenant|scoping|precision|rollback|feature flag|naming convention|error handling|code review|test coverage|migration|security|auth|validation)' 2>/dev/null || echo "0")
36
+ if [ "$DOMAIN_HITS" -ge 2 ]; then
37
+ RULES_FOUND=1
38
+ fi
31
39
  fi
32
40
  if [ "$RULES_FOUND" -eq 0 ]; then
33
- BLOCKERS+="- Missing project-specific rules in spawn prompt. Include the project constitution rules (numbered rules from workspace constitution.md, translated to English).\n"
41
+ BLOCKERS+="- Missing project-specific rules in spawn prompt. Include ALL rules from constitution.md (numbered, in English).\n"
34
42
  fi
35
43
 
36
- # Check 2: Tasks section must be present with actual task content
37
- if ! echo "$PROMPT" | grep -qiE '(your tasks|## tasks|assigned tasks|tâches|### tasks)' 2>/dev/null; then
38
- BLOCKERS+="- Missing tasks section in spawn prompt. Include the specific tasks from the plan.\n"
44
+ # Check 2: Tasks / plan section must be present
45
+ if ! echo "$PROMPT" | grep -qiE '(your (complete )?plan|## (commit|tasks|plan)|commit [0-9]+:|all [0-9]+ commit)' 2>/dev/null; then
46
+ BLOCKERS+="- Missing plan/tasks section in spawn prompt. Include the complete repo plan with all commit units.\n"
39
47
  fi
40
48
 
41
- # Check 3: CLAUDE.md instruction
49
+ # Check 3: Worktree path (v5 — teammates receive a ready worktree)
50
+ if ! echo "$PROMPT" | grep -qiE '(worktree.path|worktree.ready|go directly|/tmp/[a-z])' 2>/dev/null; then
51
+ BLOCKERS+="- Missing worktree_path in spawn prompt. Teammate needs the /tmp/ path prepared by Opus.\n"
52
+ fi
53
+
54
+ # Check 4: Signal protocol instruction
55
+ if ! echo "$PROMPT" | grep -qiE '(SendMessage|signal protocol|commit N done|green light|wait for)' 2>/dev/null; then
56
+ BLOCKERS+="- Missing signal protocol instruction. Teammate must know to SendMessage after each commit and wait for green light.\n"
57
+ fi
58
+
59
+ # Check 5: CLAUDE.md instruction
42
60
  if ! echo "$PROMPT" | grep -qiE '(CLAUDE\.md|read the repo|repo conventions|read.*conventions)' 2>/dev/null; then
43
61
  WARNINGS+="- Missing instruction to read repo CLAUDE.md.\n"
44
62
  fi
45
63
 
46
- # Check 4: Frontend teammates need UX standards — check for actual UX content
47
- if echo "$PROMPT" | grep -qiE '(front|frontend|vue|quasar|nuxt|react|ui|ux)' 2>/dev/null; then
64
+ # Check 6: Frontend teammates need UX standards
65
+ if echo "$PROMPT" | grep -qiE '(front|frontend|vue|quasar|nuxt|react|ui component)' 2>/dev/null; then
48
66
  UX_SIGNALS=0
49
67
  echo "$PROMPT" | grep -qiE '(4 (mandatory )?states|skeleton|empty state)' 2>/dev/null && UX_SIGNALS=$((UX_SIGNALS + 1))
50
68
  echo "$PROMPT" | grep -qiE '(responsive|mobile.first)' 2>/dev/null && UX_SIGNALS=$((UX_SIGNALS + 1))
51
69
  echo "$PROMPT" | grep -qiE '(accessib|aria.label|wcag)' 2>/dev/null && UX_SIGNALS=$((UX_SIGNALS + 1))
52
70
  echo "$PROMPT" | grep -qiE '(ux standard|error.state|loading.state)' 2>/dev/null && UX_SIGNALS=$((UX_SIGNALS + 1))
53
71
  if [ "$UX_SIGNALS" -lt 2 ]; then
54
- BLOCKERS+="- Frontend teammate detected but UX standards not sufficiently included (found $UX_SIGNALS/4 UX signals). Inject frontend-ux-standards content.\n"
72
+ BLOCKERS+="- Frontend teammate detected but UX standards not included (found $UX_SIGNALS/4 signals). Inject frontend-ux-standards.md content.\n"
55
73
  fi
56
74
  fi
57
75
 
58
- # Check 5: API teammates need contract shapes
59
- if echo "$PROMPT" | grep -qiE '(api|backend|endpoint|rest|graphql)' 2>/dev/null; then
60
- if ! echo "$PROMPT" | grep -qiE '(contract|response shape|request shape|interface|payload|schema|GET /|POST /|PUT /|DELETE /)' 2>/dev/null; then
76
+ # Check 7: API teammates need contract shapes
77
+ if echo "$PROMPT" | grep -qiE '(api|backend|endpoint|rest)' 2>/dev/null; then
78
+ if ! echo "$PROMPT" | grep -qiE '(contract|response shape|request shape|interface|payload|GET /|POST /|PUT /|DELETE /)' 2>/dev/null; then
61
79
  WARNINGS+="- API teammate detected but no contract/shapes found in prompt. Consider including the API contract.\n"
62
80
  fi
63
81
  fi
64
82
 
65
- # Check 6: Escalation instruction
66
- if ! echo "$PROMPT" | grep -qiE '(escalat|STOP and report|STOP and escalate|report.*dilemma|architectural decision)' 2>/dev/null; then
67
- WARNINGS+="- Missing escalation instruction. Include: 'If you hit an architectural decision NOT covered by the plan: STOP and escalate.'\n"
68
- fi
69
-
70
- # Check 7: Session branch instruction (if sessions exist)
71
- SESSIONS_DIR="${CLAUDE_PROJECT_DIR:-.}/.sessions"
72
- if [ -d "$SESSIONS_DIR" ] && ls "$SESSIONS_DIR"/*.json >/dev/null 2>&1; then
73
- if ! echo "$PROMPT" | grep -qiE '(session/|session branch|ALREADY EXISTS.*branch)' 2>/dev/null; then
74
- WARNINGS+="- Active sessions exist but no session branch found in spawn prompt. Include the session branch instruction.\n"
75
- fi
83
+ # Check 8: Escalation instruction
84
+ if ! echo "$PROMPT" | grep -qiE '(escalat|STOP|SendMessage.*blocker|architectural decision)' 2>/dev/null; then
85
+ WARNINGS+="- Missing escalation instruction. Include: 'If you hit an architectural decision not in the plan: SendMessage immediately and wait.'\n"
76
86
  fi
77
87
 
78
- # Report — ALL checks are warnings only (v4.0)
88
+ # Report — ALL checks are warnings only (v5.0)
79
89
  ISSUES=""
80
90
  [ -n "$BLOCKERS" ] && ISSUES+="$BLOCKERS"
81
91
  [ -n "$WARNINGS" ] && ISSUES+="$WARNINGS"
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: incident-debug
3
+ prompt_version: 5.2.1
3
4
  description: >
4
5
  Debug incidents across a multi-service stack. Spawns parallel
5
6
  investigators per layer. Use when user reports a bug, says "erreur",
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: merge-prep
3
+ prompt_version: 5.2.1
3
4
  description: >
4
5
  Prepare branches for merge after QA passes. Checks for conflicts between
5
6
  teammate branches, generates PR summaries, lists review points.
@@ -0,0 +1,139 @@
1
+ ---
2
+ name: metrics
3
+ prompt_version: 5.2.1
4
+ description: >
5
+ Quantitative analysis of orchestrator performance. Parses session logs,
6
+ completed plans, and QA reports to produce KPIs: re-dispatch rate,
7
+ micro-QA first-pass rate, commits per session, QA findings distribution,
8
+ escalation rate, and phase timing estimates.
9
+ Use: /metrics, /metrics last-5, /metrics session-name.
10
+ Helps justify model routing decisions and prompt improvements.
11
+ argument-hint: "[all | last-N | session-name]"
12
+ context: fork
13
+ allowed-tools: Bash, Read, Glob, Grep
14
+ ---
15
+
16
+ # Metrics — Orchestrator Performance Dashboard
17
+
18
+ You analyze completed sessions and plans to produce quantitative KPIs.
19
+ You do NOT modify any files — read-only analysis.
20
+
21
+ ## Data sources
22
+
23
+ 1. `./plans/*.md` — completed plans with progress trackers, QA reports, session logs
24
+ 2. `./.sessions/*.json` — session metadata with commit tracking
25
+ 3. `./plans/retro-*.md` — retrospectives with finding summaries
26
+
27
+ ## Scope detection
28
+
29
+ | Argument | Behavior |
30
+ |----------|----------|
31
+ | `all` or no argument | Analyze all completed plans |
32
+ | `last-N` (e.g., last-5) | Analyze the N most recent completed plans |
33
+ | `{session-name}` | Analyze one specific session/plan |
34
+
35
+ ## Metrics to extract
36
+
37
+ ### Per-session metrics
38
+
39
+ For each completed plan, extract:
40
+
41
+ ```bash
42
+ PLAN="./plans/{name}.md"
43
+
44
+ # 1. Commit metrics
45
+ TOTAL_COMMITS=$(grep -c '✅\|❌' "$PLAN" 2>/dev/null || echo 0)
46
+ SUCCESSFUL_COMMITS=$(grep -c '✅' "$PLAN" 2>/dev/null || echo 0)
47
+ FAILED_COMMITS=$(grep -c '❌' "$PLAN" 2>/dev/null || echo 0)
48
+ ESCALATED=$(grep -c 'ESCALATED' "$PLAN" 2>/dev/null || echo 0)
49
+
50
+ # 2. Re-dispatch metrics (from session log entries)
51
+ REDISPATCHES=$(grep -c 're-dispatch\|retry\|fix instruction' "$PLAN" 2>/dev/null || echo 0)
52
+
53
+ # 3. QA findings (from QA Report section)
54
+ BUGS=$(grep -c '🔴' "$PLAN" 2>/dev/null || echo 0)
55
+ SMELLS=$(grep -c '🟡' "$PLAN" 2>/dev/null || echo 0)
56
+ DEAD_CODE=$(grep -c '🟠' "$PLAN" 2>/dev/null || echo 0)
57
+ MISSING_TESTS=$(grep -c '🔵' "$PLAN" 2>/dev/null || echo 0)
58
+ UX_VIOLATIONS=$(grep -c '🟣' "$PLAN" 2>/dev/null || echo 0)
59
+ NITPICKS=$(grep -c '⚪' "$PLAN" 2>/dev/null || echo 0)
60
+
61
+ # 4. Cross-service check results
62
+ CROSS_PASS=$(grep -c '✅' "$PLAN" 2>/dev/null || echo 0) # within cross-service section
63
+ CROSS_FAIL=$(grep -c '❌' "$PLAN" 2>/dev/null || echo 0) # within cross-service section
64
+
65
+ # 5. Services impacted
66
+ REPOS_COUNT=$(jq '.repos | length' "./.sessions/{name}.json" 2>/dev/null || echo "?")
67
+
68
+ # 6. Waves used
69
+ WAVES=$(grep -c 'Wave [0-9]' "$PLAN" 2>/dev/null || echo 1)
70
+ ```
71
+
72
+ ### Aggregate KPIs (across all analyzed sessions)
73
+
74
+ Calculate and present:
75
+
76
+ | KPI | Formula | Target |
77
+ |-----|---------|--------|
78
+ | **Micro-QA first-pass rate** | successful_commits / total_commits × 100 | > 80% |
79
+ | **Re-dispatch rate** | re-dispatches / total_commits × 100 | < 15% |
80
+ | **Escalation rate** | escalations / total_commits × 100 | < 5% |
81
+ | **QA bug density** | 🔴 findings / total_commits | < 0.3 |
82
+ | **UX violation rate** | 🟣 findings / frontend_commits × 100 | < 10% |
83
+ | **Dead code per session** | avg 🟠 findings per session | trending ↓ |
84
+ | **Cross-service consistency** | cross_pass / (cross_pass + cross_fail) × 100 | > 90% |
85
+
86
+ ### Trend analysis (if multiple sessions)
87
+
88
+ If analyzing 3+ sessions, show trends:
89
+ - Are QA findings decreasing over time? (retrospective loop working?)
90
+ - Are re-dispatches decreasing? (plan quality improving?)
91
+ - Are UX violations decreasing? (UX standards being learned?)
92
+
93
+ ## Output format
94
+
95
+ ```markdown
96
+ ## Metrics Report — [DATE]
97
+
98
+ ### Scope: [all / last-N / session-name]
99
+ Sessions analyzed: N | Plans: N | Total commits: N
100
+
101
+ ### KPI Dashboard
102
+
103
+ | KPI | Value | Target | Status |
104
+ |-----|-------|--------|--------|
105
+ | Micro-QA first-pass | 85% | >80% | ✅ |
106
+ | Re-dispatch rate | 12% | <15% | ✅ |
107
+ | Escalation rate | 3% | <5% | ✅ |
108
+ | QA bug density | 0.4 | <0.3 | ⚠️ |
109
+ | UX violation rate | 8% | <10% | ✅ |
110
+ | Cross-service consistency | 95% | >90% | ✅ |
111
+
112
+ ### QA Findings Distribution
113
+
114
+ | Category | Count | % | Trend |
115
+ |----------|-------|---|-------|
116
+ | 🔴 Bugs | N | N% | ↑↓→ |
117
+ | 🟡 Smells | N | N% | ↑↓→ |
118
+ | 🟠 Dead code | N | N% | ↑↓→ |
119
+ | 🔵 Missing tests | N | N% | ↑↓→ |
120
+ | 🟣 UX violations | N | N% | ↑↓→ |
121
+ | ⚪ Nitpicks | N | N% | ↑↓→ |
122
+
123
+ ### Per-Session Breakdown
124
+
125
+ | Session | Repos | Commits | Pass | Fail | Re-dispatch | QA 🔴 | QA 🟣 |
126
+ |---------|-------|---------|------|------|-------------|--------|--------|
127
+ | {name} | N | N | N | N | N | N | N |
128
+
129
+ ### Insights
130
+ - [Actionable observation based on data]
131
+ - [Suggestion for prompt/process improvement backed by numbers]
132
+ ```
133
+
134
+ Present the report to the user. Do NOT write it to a file unless asked.
135
+
136
+ ## Anti-patterns
137
+ - NEVER fabricate metrics — only report what's extractable from actual files
138
+ - NEVER compare to other teams/projects — only compare to own history
139
+ - If data is insufficient (< 3 sessions), say so instead of producing meaningless trends
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: plan-review
3
+ prompt_version: 5.2.1
3
4
  description: >
4
5
  Quick sanity check on a plan before the user validates it. Verifies
5
6
  structural completeness: all tasks have a service, waves respect
@@ -9,7 +10,7 @@ argument-hint: "[plan-name.md]"
9
10
  context: fork
10
11
  agent: Explore
11
12
  disable-model-invocation: true
12
- model: haiku
13
+ model: sonnet
13
14
  allowed-tools: Read, Glob, Grep
14
15
  ---
15
16
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: qa-ruthless
3
+ prompt_version: 5.2.1
3
4
  description: >
4
5
  Adversarial QA review after feature implementation. MUST find problems —
5
6
  a clean report is a failed review. Executes tests, hunts dead code,
@@ -8,6 +9,7 @@ description: >
8
9
  "test", "quality", "qa ruthless", "find bugs".
9
10
  argument-hint: "[plan-name or 'all']"
10
11
  context: fork
12
+ model: opus
11
13
  allowed-tools: Read, Write, Glob, Grep, Task, Teammate, SendMessage
12
14
  ---
13
15
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: refresh-profiles
3
+ prompt_version: 5.2.1
3
4
  description: >
4
5
  Regenerate service-profiles.md by reading CLAUDE.md from all repos
5
6
  listed in workspace.md. Use when conventions changed, or user says
@@ -16,28 +16,13 @@ globs: ["workspace.md", "plans/**", "constitution.md", "templates/**"]
16
16
  ## Response limits
17
17
  - No code in repos — delegate repo code to teammates
18
18
  - Writing in orchestrator/ (plans, workspace.md, constitution.md) is allowed and expected
19
- - Teammate results: summarize to status + files + problems, then compact
19
+ - Teammate results: summarize to status + files + problems
20
20
 
21
- ## Compaction
22
- - Context compaction triggers automatically (Opus 4.6 adaptive)
23
- - Additionally, compact manually after each full cycle
24
- (plan → teammates → collect → QA)
25
- - Also compact when responses visibly slow down
21
+ ## Context compaction
22
+ - Claude Code handles compaction automatically no manual `/compact` needed
23
+ - The SessionStart hook re-injects active plan context after any `/clear`
26
24
 
27
25
  ## Triggers for /clear
28
26
  - Switching to a completely different feature/epic
29
27
  - After merging a completed feature
30
28
  - Start of day / new work session
31
-
32
- ## Monitoring
33
- - The `SessionStart` hook automatically injects active plan context
34
- at startup or after a `/clear`
35
- - If a config issue is suspected, use `/hooks` to inspect
36
-
37
- ## Context compaction (Opus 4.6)
38
- - Opus 4.6 supports native context compaction — the model can summarize
39
- its own context to continue longer-running tasks without hitting limits
40
- - The 1M context window (beta) is available but token-intensive.
41
- Disable with `CLAUDE_CODE_DISABLE_1M_CONTEXT=1` if cost is a concern
42
- - For orchestration sessions, prefer compact-after-cycle over 1M context:
43
- smaller context = faster responses = cheaper