claude-mcp-workflow 0.1.8 → 0.1.9

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 (56) hide show
  1. package/.claude-plugin/plugin.json +4 -2
  2. package/README.md +37 -0
  3. package/build/engine.d.ts +13 -1
  4. package/build/engine.d.ts.map +1 -1
  5. package/build/engine.js +41 -2
  6. package/build/engine.js.map +1 -1
  7. package/build/types.d.ts +20 -20
  8. package/build/types.js +1 -1
  9. package/build/types.js.map +1 -1
  10. package/hooks/hooks.json +4 -2
  11. package/hooks/workflow-cleanup.sh +8 -4
  12. package/hooks/workflow-start.sh +60 -32
  13. package/package.json +1 -1
  14. package/templates/bug-fix.yaml +98 -16
  15. package/templates/code-review.yaml +30 -12
  16. package/templates/coding.yaml +49 -4
  17. package/templates/debugging.yaml +39 -14
  18. package/templates/explore.yaml +48 -14
  19. package/templates/file-code.yaml +13 -4
  20. package/templates/file-review.yaml +25 -6
  21. package/templates/github-init.yaml +24 -8
  22. package/templates/investigate.yaml +13 -4
  23. package/templates/master.yaml +16 -13
  24. package/templates/new-feature.yaml +24 -26
  25. package/templates/planning.yaml +34 -7
  26. package/templates/reflection.yaml +11 -4
  27. package/templates/review-push.yaml +26 -7
  28. package/templates/skills/architecture/SKILL.md +131 -1
  29. package/templates/skills/aws-lambda/SKILL.md +9 -9
  30. package/templates/skills/browser-verify/SKILL.md +58 -0
  31. package/templates/skills/build-cmake/SKILL.md +24 -8
  32. package/templates/skills/ci-github-actions/SKILL.md +34 -18
  33. package/templates/skills/claude-code-config/SKILL.md +41 -19
  34. package/templates/skills/cleanup/SKILL.md +57 -0
  35. package/templates/skills/coding-skill-selector/SKILL.md +2 -1
  36. package/templates/skills/debug-bridge-scaffold/SKILL.md +98 -0
  37. package/templates/skills/domain-gamedev/SKILL.md +56 -6
  38. package/templates/skills/domain-pixi/SKILL.md +256 -7
  39. package/templates/skills/domain-reid/SKILL.md +39 -5
  40. package/templates/skills/domain-yolo/SKILL.md +18 -7
  41. package/templates/skills/ide-zed/SKILL.md +23 -0
  42. package/templates/skills/lang-as3/SKILL.md +7 -5
  43. package/templates/skills/lang-haxe/SKILL.md +538 -19
  44. package/templates/skills/lang-python/SKILL.md +6 -2
  45. package/templates/skills/math/SKILL.md +64 -2
  46. package/templates/skills/mcp-setup/SKILL.md +14 -2
  47. package/templates/skills/preferences/SKILL.md +10 -10
  48. package/templates/skills/skill-manager/SKILL.md +264 -0
  49. package/templates/skills/target-openfl-native/SKILL.md +52 -17
  50. package/templates/skills/target-openfl-native/references/build-and-versions.md +7 -4
  51. package/templates/skills/task-delegation/SKILL.md +76 -4
  52. package/templates/skills/web-reading/SKILL.md +33 -25
  53. package/templates/skills/workflow-authoring/SKILL.md +47 -12
  54. package/templates/subagent.yaml +29 -8
  55. package/templates/testing.yaml +64 -10
  56. package/templates/web-research.yaml +23 -13
@@ -21,77 +21,105 @@ if [ -d "$SKILLS_SRC" ]; then
21
21
  done
22
22
  fi
23
23
 
24
+ ZED_SUFFIX=""
25
+ if [[ -n "$ZED_ENVIRONMENT" ]]; then
26
+ ZED_SUFFIX=" Then load skill ide-zed (Skill tool)."
27
+ fi
28
+
29
+ # Everything below requires jq — without it, still emit the fresh-start prompt.
30
+ command -v jq >/dev/null 2>&1 || { echo "STOP. Call mcp__plugin_workflow_wf__start (no args) first.$ZED_SUFFIX"; exit 0; }
31
+
24
32
  read -t 1 -r INPUT
33
+ SOURCE=$(echo "$INPUT" | jq -r '.source // empty')
25
34
  TRANSCRIPT=$(echo "$INPUT" | jq -r '.transcript_path // empty')
35
+ HOOK_CWD=$(echo "$INPUT" | jq -r '.cwd // empty')
36
+ # Physical path (pwd -P) so a symlinked cwd (e.g. /tmp → /private/tmp)
37
+ # compares equal to the engine's getcwd()-resolved context.cwd.
38
+ HOOK_CWD=$(cd "${HOOK_CWD:-$PWD}" 2>/dev/null && pwd -P || echo "$PWD")
26
39
  STATE_DIR="${STATE_DIR:-$HOME/.claude/workflow-state}"
27
40
  PLANS_DIR="$HOME/.claude/plans"
28
41
 
29
- ZED_SUFFIX=""
30
- if [[ -n "$ZED_ENVIRONMENT" ]]; then
31
- ZED_SUFFIX=" Then load skill ide-zed (Skill tool)."
32
- fi
42
+ # Session IDs are 8 hex chars; the {7,} length filter skips shorter incidental hex words.
43
+ SID_RE='[a-f0-9]{7,}'
44
+
45
+ # --- Helper: apply a jq filter to a file in place (atomic tmp+rename) ---
46
+ # $$ makes the temp name unique per hook instance, so concurrent hooks
47
+ # cannot clobber each other's half-written temp files.
48
+ jq_inplace() {
49
+ local filter="$1" f="$2" tmp="$2.tmp.$$"
50
+ jq "$filter" "$f" 2>/dev/null > "$tmp" && mv "$tmp" "$f" || rm -f "$tmp"
51
+ }
52
+
53
+ # --- Helper: check <sid> refers to a live planning session ---
54
+ # Live = state file exists + top stack frame is "planning" + not abandoned.
55
+ validate_planning_session() {
56
+ local sf="$STATE_DIR/$1.json"
57
+ [ -f "$sf" ] || return 1
58
+ jq -e '.outcome != "abandoned" and (.stack | length > 0) and .stack[-1].workflow == "planning"' "$sf" >/dev/null 2>&1
59
+ }
33
60
 
34
61
  # --- Helper: increment skill_epoch in a session JSON by ID ---
35
62
  bump_skill_epoch_by_id() {
36
- local sid="$1"
37
- local sf="$STATE_DIR/${sid}.json"
63
+ local sf="$STATE_DIR/$1.json"
38
64
  [ -f "$sf" ] || return
39
- jq '.skill_epoch = ((.skill_epoch // 0) + 1)' "$sf" 2>/dev/null > "${sf}.tmp" && mv "${sf}.tmp" "$sf" || rm -f "${sf}.tmp"
65
+ jq_inplace '.skill_epoch = ((.skill_epoch // 0) + 1)' "$sf"
40
66
  }
41
67
 
42
68
  # --- Helper: increment skill_epoch in active sessions for current PID ---
43
69
  bump_skill_epoch_by_pid() {
44
70
  [ -d "$STATE_DIR" ] || return
71
+ # $PPID is the Claude Code process: hook commands run as single-command
72
+ # `bash -c` invocations, which bash exec-optimizes (the shell replaces
73
+ # itself), so no intermediate shell sits between this script and Claude Code.
45
74
  local cc_pid=$PPID
46
75
  for sf in "$STATE_DIR"/*.json; do
47
76
  [ -f "$sf" ] || continue
48
77
  local pid
49
78
  pid=$(jq -r '.context.claude_code_pid // empty' "$sf" 2>/dev/null)
50
79
  [ "$pid" = "$cc_pid" ] || continue
51
- jq 'if .stack | length > 0 then .skill_epoch = ((.skill_epoch // 0) + 1) else . end' "$sf" 2>/dev/null > "${sf}.tmp" && mv "${sf}.tmp" "$sf" || rm -f "${sf}.tmp"
80
+ jq_inplace 'if .stack | length > 0 then .skill_epoch = ((.skill_epoch // 0) + 1) else . end' "$sf"
52
81
  done
53
82
  }
54
83
 
55
- # --- Helper: find active planning session from plan files ---
84
+ # --- Helper: find a live planning session for this project from plan files ---
85
+ # Only plans whose session context.cwd matches the hook's cwd are considered;
86
+ # candidates are checked newest-first by plan file mtime.
56
87
  find_plan_session() {
57
88
  [ -d "$PLANS_DIR" ] || return
58
- for plan in "$PLANS_DIR"/*.md; do
89
+ local plan sid
90
+ while IFS= read -r plan; do
59
91
  [ -f "$plan" ] || continue
60
- # Extract session ID from ## Workflow section (Session line: `<hex>`)
61
- local sid
62
- sid=$(grep -A5 '^## Workflow' "$plan" | grep 'Session' | grep -oE '[a-f0-9]{7,}' | head -1)
92
+ # Session ID from the ## Workflow section. -A5: the section contract is
93
+ # 5 list lines after the heading (Session / Current state / After approve /
94
+ # Execution workflow / Resume) Session is always within that window.
95
+ sid=$(grep -A5 '^## Workflow' "$plan" | grep 'Session' | grep -oE "$SID_RE" | head -1)
63
96
  [ -n "$sid" ] || continue
64
- # Check if this session is active and in planning state
65
- local state_file="$STATE_DIR/${sid}.json"
66
- [ -f "$state_file" ] || continue
67
- local wf
68
- wf=$(jq -r 'select(.stack | length > 0) | .stack[-1].workflow // empty' "$state_file" 2>/dev/null)
69
- if [ "$wf" = "planning" ]; then
70
- echo "$sid"
71
- return
72
- fi
73
- done
97
+ validate_planning_session "$sid" || continue
98
+ [ "$(jq -r '.context.cwd // empty' "$STATE_DIR/${sid}.json" 2>/dev/null)" = "$HOOK_CWD" ] || continue
99
+ echo "$sid"
100
+ return
101
+ done < <(ls -t "$PLANS_DIR"/*.md 2>/dev/null)
74
102
  }
75
103
 
76
- # --- 1. Transcript exists and has content → same process ---
77
- if [ -n "$TRANSCRIPT" ] && [ -s "$TRANSCRIPT" ]; then
78
- # Check for ExitPlanMode plan resume after context clear
79
- if grep -q 'ExitPlanMode' "$TRANSCRIPT" 2>/dev/null; then
80
- PLAN_SID=$(grep -oE 'transition\(\\"[a-f0-9]+\\"' "$TRANSCRIPT" | tail -1 | grep -oE '[a-f0-9]{7,}')
81
- if [ -n "$PLAN_SID" ]; then
104
+ # --- 1. clear/compact → same process, context lost ---
105
+ if [ "$SOURCE" = "clear" ] || [ "$SOURCE" = "compact" ]; then
106
+ # Transcript grep is only used to recover the planning session hex;
107
+ # validity is checked against the state file, not the transcript.
108
+ if [ -n "$TRANSCRIPT" ] && grep -q 'ExitPlanMode' "$TRANSCRIPT" 2>/dev/null; then
109
+ PLAN_SID=$(grep -oE 'transition\(\\"[a-f0-9]+\\"' "$TRANSCRIPT" | tail -1 | grep -oE "$SID_RE")
110
+ if [ -n "$PLAN_SID" ] && validate_planning_session "$PLAN_SID"; then
82
111
  bump_skill_epoch_by_id "$PLAN_SID"
83
112
  echo "PLAN RESUME (same process): call transition(\"$PLAN_SID\", \"planned\") to resume planning session.$ZED_SUFFIX"
84
113
  exit 0
85
114
  fi
86
115
  fi
87
- # Has content but no plan → context clear
88
116
  bump_skill_epoch_by_pid
89
117
  echo "Context was cleared. Call status() to check for active session and restore context.$ZED_SUFFIX"
90
118
  exit 0
91
119
  fi
92
120
 
93
- # --- 2. Transcript empty or missing → new process ---
94
- # Check plans/ for active planning sessions (cross-process plan resume)
121
+ # --- 2. startup/resume → new process ---
122
+ # Check plans/ for live planning sessions (cross-process plan resume)
95
123
  PLAN_SID=$(find_plan_session)
96
124
  if [ -n "$PLAN_SID" ]; then
97
125
  bump_skill_epoch_by_id "$PLAN_SID"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-mcp-workflow",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Structured workflow orchestration for AI agents via finite-state machines",
5
5
  "author": "AxGord <axgord@gmail.com> (https://github.com/AxGord)",
6
6
  "license": "MIT",
@@ -13,6 +13,9 @@ states:
13
13
  - Does it include a screenshot or describe a VISUAL problem (layout, overlap, wrong color, missing element)?
14
14
  - Or is it a LOGIC problem (wrong data, crash, incorrect calculation, serialization error)?
15
15
 
16
+ Persist the classification for verify_route:
17
+ `context_set({ key: "bug_type", value: "visual" })` (or `"logic"`)
18
+
16
19
  Choose:
17
20
  - `visual` → UI/layout bug — requires debug bridge, screenshots, visual reproduction
18
21
  - `logic` → data/logic bug — reproducible via unit tests or logs
@@ -34,7 +37,7 @@ states:
34
37
  Reproduce the bug VISUALLY before proceeding — reading code is NOT reproduction.
35
38
 
36
39
  DO NOT fix the bug here. You may add trace/log statements to help reproduce,
37
- but do NOT modify production logic. The fix belongs in the `fix` state.
40
+ but do NOT modify production logic. The fix comes later, after diagnosis.
38
41
 
39
42
  REPRODUCTION TOOLING — find the right tool:
40
43
  1. Check available MCP tools for browser/screenshot/debug-bridge capabilities.
@@ -64,9 +67,8 @@ states:
64
67
  `cant_reproduce` = you tried but can't see it. This leads to asking the user for help.
65
68
  NEVER use `reproduced` when you haven't seen the bug yourself.
66
69
 
67
- If the bug requires simulated input or file operations, use the chosen tool's
68
- recipes: Playwright `browser_evaluate` / `browser_press_key` for web,
69
- tm-interactive-debug for native.
70
+ If the bug requires simulated input or file operations, use the chosen
71
+ tool's input-simulation capabilities.
70
72
  transitions:
71
73
  reproduced: diagnose
72
74
  cant_reproduce: clarify
@@ -76,8 +78,9 @@ states:
76
78
  prompt: |
77
79
  Reproduce the bug by EXECUTING code — reading source is NOT reproduction.
78
80
 
79
- DO NOT fix the bug here. You may add trace/log statements or write test code
80
- to help reproduce, but do NOT modify production logic. The fix belongs in the `fix` state.
81
+ DO NOT fix the bug here, and do NOT touch production code at all — not even
82
+ trace/log statements. Write test code to reproduce. The fix comes later,
83
+ after diagnosis.
81
84
 
82
85
  FILE RESTRICTION: You may ONLY create or edit test files.
83
86
  Any edit to production code is a workflow violation.
@@ -88,18 +91,32 @@ states:
88
91
  3. BUILD and RUN the test — show the actual output
89
92
  4. Describe: EXPECTED vs ACTUAL — what should happen vs what does happen
90
93
 
94
+ Delegate the build+run to a flat `general-purpose` subagent
95
+ (build/run/report — no workflow, no skills) to keep build output
96
+ out of main context.
97
+ A flat subagent inherits none of this project's skills or env
98
+ rules — it only knows what YOU put in its spawn prompt. So include
99
+ VERBATIM in that prompt: (a) any tooling/hook constraints that
100
+ apply in this project (required CLIs, blocked commands), and
101
+ (b) "Strip noise, but quote every error, failing assertion, and
102
+ number VERBATIM — don't paraphrase the signal or replace it with
103
+ a verdict; the parent judges."
104
+ Spawn with `run_in_background: false` — you need the result before transitioning.
105
+
91
106
  STOP — self-check before transitioning:
92
107
  - Did you EXECUTE something (build + run)? Reading code ≠ reproduction.
93
108
  - Can you paste the failing output? If not, you haven't reproduced yet.
94
109
  - "I can see from the code that..." is NOT evidence. Run the code.
95
110
  - Run `git diff --name-only` — if ANY file outside test directories was modified,
96
- you violated the workflow. Revert with `git checkout -- <file>` before transitioning.
111
+ you violated the workflow. Revert before transitioning: revert only the hunks
112
+ you added, and verify the file was clean before your first edit.
97
113
 
98
114
  DO NOT transition to `reproduced` without concrete executed evidence
99
115
  (test failure output, wrong runtime output, crash log).
100
116
 
101
117
  If the bug is hard to cover with a unit test (UI state, complex setup, timing),
102
118
  transition `try_visual` to reproduce via debug bridge instead.
119
+ If you genuinely cannot reproduce at all → `cant_reproduce` (asks the user for help).
103
120
  transitions:
104
121
  reproduced: diagnose
105
122
  try_visual: load_skills_visual
@@ -111,19 +128,36 @@ states:
111
128
  Find the root cause of the bug.
112
129
 
113
130
  DO NOT fix the bug here. You may add trace/log statements to narrow down
114
- the cause, but do NOT modify production logic. The fix belongs in the `fix` state.
131
+ the cause, but do NOT modify production logic. The fix comes later, after diagnosis.
115
132
 
116
133
  FILE RESTRICTION: Do NOT add new methods, fields, or change signatures.
117
134
  Only trace/log statements are allowed. Any structural code change is a workflow violation.
118
135
 
119
136
  STOP — self-check before transitioning:
120
- - Run `git diff --name-only` — if any production file was modified beyond trace statements,
121
- revert with `git checkout -- <file>` before transitioning.
137
+ - Run `git diff --name-only` — if any production file was modified beyond trace
138
+ statements, revert before transitioning: revert only the hunks you added, and
139
+ verify the file was clean before your first edit.
140
+
141
+ Delegating root-cause analysis to a subagent (it reads code to judge —
142
+ ANALYTICAL)? Include in the agent prompt VERBATIM:
143
+ ---
144
+ IMPORTANT: Override the default CLAUDE.md rule about start().
145
+ Do NOT call start() without arguments.
146
+ Instead, your FIRST action must be:
147
+ mcp__plugin_workflow_wf__start({ workflow: "subagent", parent_session_id: "<SESSION_ID>" })
148
+ where <SESSION_ID> is the current session ID (substitute it before sending).
149
+ Then follow the subagent workflow until completion — its `route` state
150
+ self-classifies (analytical → skill-loaded sub-workflow; trivial → execute).
151
+ start() returns `SESSION: <id>` — pass that session_id explicitly in every subsequent workflow tool call (transition, context_set); parallel siblings share the same ppid.
152
+ ---
153
+ After collecting reports: `sessions` → `abort` orphaned child `subagent`
154
+ sessions. NEVER spawn an analytical subagent flat (no workflow = no skills).
122
155
 
123
156
  After diagnosing, assess the fix scope:
124
157
  - 1 file → `single`
125
158
  - 2+ files, tightly coupled (one logical chain, shared context) → `multi_coupled`
126
159
  - 2+ files, independent (can be done in parallel with clear interfaces) → `multi_independent`
160
+ - root cause still unclear → `unclear` (add diagnostic logging and retry)
127
161
  transitions:
128
162
  single: fix_single
129
163
  multi_coupled: load_skills_coupled
@@ -132,8 +166,22 @@ states:
132
166
 
133
167
  add_logging:
134
168
  task: "Add diagnostic logging"
135
- prompt: "Add logging for diagnostics, run again."
136
169
  max_visits: 3
170
+ prompt: |
171
+ Root cause is still unclear. Gather more evidence:
172
+
173
+ 1. Add targeted log/trace statements with unique prefixes (`[DBG1]`, `[DBG2]`)
174
+ at the locations you suspect — trace statements only, no structural changes
175
+ 2. Re-run the reproduction and read the output
176
+ 3. Analyze: does the output confirm or rule out a suspected location?
177
+
178
+ Budget: 3 visits to this state (engine-enforced); when nearly exhausted, choose `still_unclear` instead of retrying.
179
+
180
+ After analyzing, assess the fix scope (same as diagnose):
181
+ - 1 file → `single`
182
+ - 2+ files, tightly coupled → `multi_coupled`
183
+ - 2+ files, independent → `multi_independent`
184
+ - still no root cause → `still_unclear` (escalate to the user)
137
185
  transitions:
138
186
  single: fix_single
139
187
  multi_coupled: load_skills_coupled
@@ -188,6 +236,7 @@ states:
188
236
  mcp__plugin_workflow_wf__start({ workflow: "file-code", parent_session_id: "<SESSION_ID>" })
189
237
  where <SESSION_ID> is the current session ID (substitute it before sending).
190
238
  Then follow the file-code workflow states until completion.
239
+ start() returns `SESSION: <id>` — pass that session_id explicitly in every subsequent workflow tool call (transition, context_set); parallel siblings share the same ppid.
191
240
  ---
192
241
  Also include:
193
242
  - The file path
@@ -229,9 +278,19 @@ states:
229
278
 
230
279
  review_single:
231
280
  sub_workflow: file-review
232
- on_complete: test
281
+ on_complete: review_decision
233
282
  on_fail: write_fix
234
283
 
284
+ review_decision:
285
+ task: "Decide on review results"
286
+ prompt: |
287
+ The file-review sub-workflow completed. Read its report and decide:
288
+ - `ok` → no issues (or notes only), proceed to testing
289
+ - `fix` → found issues that need fixing
290
+ transitions:
291
+ ok: test
292
+ fix: write_fix
293
+
235
294
  review_delegate:
236
295
  task: "Delegate per-file review to agents"
237
296
  prompt: |
@@ -246,6 +305,7 @@ states:
246
305
  mcp__plugin_workflow_wf__start({ workflow: "file-review", parent_session_id: "<SESSION_ID>" })
247
306
  where <SESSION_ID> is the current session ID (substitute it before sending).
248
307
  Then follow the file-review workflow states until completion.
308
+ start() returns `SESSION: <id>` — pass that session_id explicitly in every subsequent workflow tool call (transition, context_set); parallel siblings share the same ppid.
249
309
  ---
250
310
  Also include:
251
311
  - The file path
@@ -279,7 +339,9 @@ states:
279
339
  write_fix:
280
340
  task: "Fix review issues"
281
341
  prompt: |
282
- Fix the issues found during review. After fixing, transition back to review.
342
+ Fix the issues found review findings or test failures reported by the
343
+ testing workflow (read the failure report for what broke).
344
+ After fixing → transition `done` (returns to review for re-verification).
283
345
  transitions:
284
346
  done: review
285
347
 
@@ -291,7 +353,10 @@ states:
291
353
  verify_route:
292
354
  task: "Route to correct verification"
293
355
  prompt: |
294
- Check the bug type classified at the start:
356
+ Bug type classified at the start: {{context.bug_type}}
357
+ (If empty — context was lost. Re-classify now: was the original report a
358
+ visual problem or a logic problem?)
359
+
295
360
  - Visual bug → `visual` (needs screenshot verification)
296
361
  - Logic bug → `logic` (tests already passed in testing workflow)
297
362
  transitions:
@@ -324,20 +389,37 @@ states:
324
389
  5. Compare before/after — describe the visual difference
325
390
 
326
391
  DO NOT transition to `confirmed` without a screenshot proving the fix works.
392
+
393
+ Choose transition:
394
+ - `confirmed` → your screenshot proves the bug is gone
395
+ - `still_broken` → bug still visible, back to diagnosis
327
396
  transitions:
328
397
  confirmed: done
329
398
  still_broken: diagnose
330
399
 
331
400
  clarify:
332
401
  task: "Clarify bug details"
333
- prompt: "Ask the user for more details about the bug."
402
+ prompt: |
403
+ You could not reproduce the bug. Ask the user for more details:
404
+ - Exact steps to reproduce
405
+ - Error messages, logs, or screenshots
406
+ - Environment (platform, version, configuration)
407
+
408
+ If there is no interactive user (you are running as a subagent), do NOT ask — state your assumptions and continue, or take the failure path.
409
+
410
+ Choose transition:
411
+ - `got_info_visual` → new details point to a visual reproduction attempt
412
+ - `got_info_logic` → new details point to a test/log reproduction attempt
413
+ - `escalate` → no way to get more information; give up
334
414
  transitions:
335
415
  got_info_visual: load_skills_visual
336
416
  got_info_logic: reproduce_logic
417
+ escalate: escalate
337
418
 
338
419
  escalate:
339
- prompt: "Could not diagnose. Report to the user."
420
+ prompt: "Could not reproduce or diagnose the bug. Report to the user: what was tried, what was ruled out, what information would help."
340
421
  terminal: true
422
+ outcome: fail
341
423
 
342
424
  done:
343
425
  prompt: "Bug fixed and verified."
@@ -14,7 +14,7 @@ states:
14
14
  1. **User specified files** — user named concrete file paths → use those.
15
15
  Do NOT touch git.
16
16
  2. **User specified directories** — user named directories or patterns
17
- (e.g. "src/api/", "src/ без editor", "src/*.hx, src/api/, src/drill/").
17
+ (e.g. "src/api/", "src/ without editor", "src/*.hx, src/api/, src/drill/").
18
18
  Parse the request in natural language:
19
19
  - `"src/"` → all source files recursively, auto-group by first-level subdirectories
20
20
  - `"src/api/, src/drill/"` → only these dirs recursively, each = one package
@@ -34,17 +34,21 @@ states:
34
34
  **Step 2 — Determine review depth:**
35
35
  - Coming from testing/coding / "check changes" / "review diff" / default
36
36
  → `scope: diff` (only review changed lines)
37
- - "review file" / "целиком" / "check whole file" / "bring to order" / "привести в порядок"
38
- → `scope: full` (review entire file)
37
+ - "review file" / "check whole file" / "bring to order" (or equivalent
38
+ phrases in the user's language) → `scope: full` (review entire file)
39
39
  - Directory mode → always `scope: full`
40
40
  Save the scope via `context_set(key: "review_scope", value: "diff" or "full")`.
41
41
 
42
42
  **Step 3 — Get file names:**
43
43
  - If source is user-specified files or directories → already have the list.
44
44
  - If source is git → get ALL changed file names (modified AND new/untracked):
45
- - Modified/staged: `git diff HEAD --name-only`
45
+ - Modified/staged: `git diff HEAD --name-only --diff-filter=d`
46
+ (lowercase `d` excludes deleted files)
46
47
  - New untracked: `git ls-files --others --exclude-standard`
47
48
  Combine both lists. Do NOT read full diffs yet — names only.
49
+ Deleted files (`git diff HEAD --name-only --diff-filter=D`) get NO
50
+ per-file review — note them for the cross-file step instead
51
+ (their callers/imports may break).
48
52
  **Git pathspec gotcha (zsh):** to exclude paths, use `-- . ':(exclude)path'`,
49
53
  NOT `-- ':!path'` — the latter silently returns empty results in zsh.
50
54
 
@@ -96,6 +100,9 @@ states:
96
100
  mcp__plugin_workflow_wf__start({ workflow: "file-review", parent_session_id: "<SESSION_ID>" })
97
101
  where <SESSION_ID> is the current session ID (substitute it before sending).
98
102
  Then follow the file-review workflow states until completion.
103
+ start() returns `SESSION: <id>` — pass that session_id explicitly in every
104
+ subsequent workflow tool call (transition, context_set); parallel siblings
105
+ share the same ppid.
99
106
  ---
100
107
  Also include:
101
108
  - The file path
@@ -110,8 +117,12 @@ states:
110
117
  The file-review workflow has its own skill-loading state — agents will load all
111
118
  relevant skills themselves. Manual rule lists are lossy and cause missed issues.
112
119
 
113
- Launch ALL file agents in parallel (single message, multiple Agent tool calls).
114
- Wait for all to complete. Collect their reports.
120
+ Split the files into batches of 8. Launch each batch's agents in parallel
121
+ (single message, multiple Agent tool calls). Wait for the whole batch to
122
+ complete before starting the next batch. Collect their reports.
123
+
124
+ If a child agent fails or returns no report — re-spawn it once;
125
+ if it fails again, mark that file as unreviewed in the summary.
115
126
 
116
127
  After ALL reports are collected:
117
128
  1. Abort orphaned child workflow sessions — call `sessions` to find
@@ -128,7 +139,11 @@ states:
128
139
  CRITICAL: You are a DISPATCHER in this state, not a reviewer.
129
140
  Do NOT read files or code yourself — only spawn agents and collect results.
130
141
 
131
- 1. Read `packages` and `current_package_index` from context.
142
+ 1. Your package list and position, embedded from context (re-rendered on
143
+ every visit — survives context compression; if they look stale, call
144
+ `status()` and re-read context):
145
+ - packages: {{context.packages}}
146
+ - current_package_index: {{context.current_package_index}}
132
147
  2. If `current_package_index` >= number of packages → transition `all_done`.
133
148
  3. Take the current package. Output: "**Package: <name>** (<N> files)".
134
149
  4. Split the package's files into batches of 8.
@@ -143,16 +158,20 @@ states:
143
158
  mcp__plugin_workflow_wf__start({ workflow: "file-review", parent_session_id: "<SESSION_ID>" })
144
159
  where <SESSION_ID> is the current session ID (substitute it before sending).
145
160
  Then follow the file-review workflow states until completion.
161
+ start() returns `SESSION: <id>` — pass that session_id explicitly in every
162
+ subsequent workflow tool call (transition, context_set); parallel siblings
163
+ share the same ppid.
146
164
  ---
147
165
  Also include:
148
166
  - The file path
149
- - "This is a full file review — read the entire file and review all code."
150
- - "Review the ENTIRE file for all issues (scope: full)."
167
+ - "Review the ENTIRE file for all issues (scope: full) — read the whole file."
151
168
 
152
169
  Do NOT include style rules or coding preferences — agents load their own skills.
153
170
 
154
171
  Launch the batch agents in parallel (single message, multiple Agent tool calls).
155
172
  Wait for all to complete before starting the next batch.
173
+ If a child agent fails or returns no report — re-spawn it once;
174
+ if it fails again, mark that file as unreviewed in the package report.
156
175
 
157
176
  6. Collect all reports for this package. Save to context:
158
177
  `context_set(key: "package_<index>_report", value: "<aggregated report>")`
@@ -183,7 +202,7 @@ states:
183
202
  - [ ] Classes to merge: tiny classes that always appear together and share state
184
203
  - [ ] Layer violations: data flowing through unnecessary intermediary layers
185
204
 
186
- Add any cross-file findings to the review.
205
+ Add any cross-file findings to the review. Then → transition `done`.
187
206
  transitions:
188
207
  done: summarize
189
208
 
@@ -301,8 +320,7 @@ states:
301
320
  consumers of what changed.
302
321
 
303
322
  After verification, transition `complete`. The coding sub-workflow already
304
- reviewed the files it modified. Planning produces a plan only — review
305
- happens later when the plan is executed via the coding workflow.
323
+ reviewed the files it modified.
306
324
  transitions:
307
325
  complete: done
308
326
 
@@ -27,8 +27,24 @@ states:
27
27
  that must match across file boundaries
28
28
  7. Identify dependencies between files — which must be written first
29
29
 
30
+ Delegating analysis to a subagent (blast-radius / recon / deep code
31
+ investigation — correctness depends on project skills, or it returns
32
+ a judgement)? Include in the agent prompt VERBATIM:
33
+ ---
34
+ IMPORTANT: Override the default CLAUDE.md rule about start().
35
+ Do NOT call start() without arguments.
36
+ Instead, your FIRST action must be:
37
+ mcp__plugin_workflow_wf__start({ workflow: "subagent", parent_session_id: "<SESSION_ID>" })
38
+ where <SESSION_ID> is the current session ID (substitute it before sending).
39
+ Then follow the subagent workflow until completion — its `route` state
40
+ self-classifies (analytical → skill-loaded sub-workflow; trivial → execute).
41
+ start() returns `SESSION: <id>` — pass that session_id explicitly in every subsequent workflow tool call (transition, context_set); parallel siblings share the same ppid.
42
+ ---
43
+ After collecting reports: `sessions` → `abort` orphaned child `subagent`
44
+ sessions. NEVER spawn an analytical subagent flat (no workflow = no skills).
45
+
30
46
  Route based on scope:
31
- - `single` → 1 file to change (or tightly coupled changes best done together)
47
+ - `single` → 1 file to change
32
48
  - `multi` → 2+ independent files to change in parallel via agents
33
49
  - `multi_self` → 2+ files but high coupling / detailed plan already exists → write yourself
34
50
  transitions:
@@ -47,6 +63,22 @@ states:
47
63
  Write changes across multiple files yourself (high coupling or detailed plan).
48
64
  Implement layer by layer respecting dependencies.
49
65
 
66
+ Delegating a pre-code check to a subagent (blast-radius / impact
67
+ analysis — correctness depends on project skills, or it returns
68
+ a judgement)? Include in the agent prompt VERBATIM:
69
+ ---
70
+ IMPORTANT: Override the default CLAUDE.md rule about start().
71
+ Do NOT call start() without arguments.
72
+ Instead, your FIRST action must be:
73
+ mcp__plugin_workflow_wf__start({ workflow: "subagent", parent_session_id: "<SESSION_ID>" })
74
+ where <SESSION_ID> is the current session ID (substitute it before sending).
75
+ Then follow the subagent workflow until completion — its `route` state
76
+ self-classifies (analytical → skill-loaded sub-workflow; trivial → execute).
77
+ start() returns `SESSION: <id>` — pass that session_id explicitly in every subsequent workflow tool call (transition, context_set); parallel siblings share the same ppid.
78
+ ---
79
+ After collecting reports: `sessions` → `abort` orphaned child `subagent`
80
+ sessions. NEVER spawn an analytical subagent flat (no workflow = no skills).
81
+
50
82
  Do NOT build or verify compilation here — testing workflow handles that.
51
83
  Just write code and transition `done`.
52
84
  transitions:
@@ -66,6 +98,7 @@ states:
66
98
  mcp__plugin_workflow_wf__start({ workflow: "file-code", parent_session_id: "<SESSION_ID>" })
67
99
  where <SESSION_ID> is the current session ID (substitute it before sending).
68
100
  Then follow the file-code workflow states until completion.
101
+ start() returns `SESSION: <id>` — pass that session_id explicitly in every subsequent workflow tool call (transition, context_set); parallel siblings share the same ppid.
69
102
  ---
70
103
  Also include:
71
104
  - The file path
@@ -114,9 +147,19 @@ states:
114
147
 
115
148
  review_single:
116
149
  sub_workflow: file-review
117
- on_complete: verify
150
+ on_complete: review_decision
118
151
  on_fail: write_fix
119
152
 
153
+ review_decision:
154
+ task: "Decide on review results"
155
+ prompt: |
156
+ The file-review sub-workflow completed. Read its report and decide:
157
+ - `ok` → no issues (or notes only), proceed to testing
158
+ - `fix` → found issues that need fixing
159
+ transitions:
160
+ ok: verify
161
+ fix: write_fix
162
+
120
163
  review_delegate:
121
164
  task: "Delegate per-file review to agents"
122
165
  prompt: |
@@ -131,6 +174,7 @@ states:
131
174
  mcp__plugin_workflow_wf__start({ workflow: "file-review", parent_session_id: "<SESSION_ID>" })
132
175
  where <SESSION_ID> is the current session ID (substitute it before sending).
133
176
  Then follow the file-review workflow states until completion.
177
+ start() returns `SESSION: <id>` — pass that session_id explicitly in every subsequent workflow tool call (transition, context_set); parallel siblings share the same ppid.
134
178
  ---
135
179
  Also include:
136
180
  - The file path
@@ -169,8 +213,9 @@ states:
169
213
  write_fix:
170
214
  task: "Fix review issues"
171
215
  prompt: |
172
- Fix the issues found during review. After fixing, transition back to review
173
- for re-verification.
216
+ Fix the issues found review findings or test failures reported by the
217
+ testing workflow (read the failure report for what broke).
218
+ After fixing → transition `done` (returns to review for re-verification).
174
219
  transitions:
175
220
  done: review
176
221