@fernado03/zoo-flow 0.12.0 → 0.12.1

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/docs/architecture.md +380 -0
  2. package/docs/bloat-control.md +49 -0
  3. package/docs/command-design.md +38 -0
  4. package/docs/command-flow.md +133 -0
  5. package/docs/comparison.md +86 -0
  6. package/docs/context-packs.md +35 -0
  7. package/docs/dogfood/01-small-library.md +28 -0
  8. package/docs/dogfood/02-web-app.md +29 -0
  9. package/docs/dogfood/03-mixed-monorepo.md +29 -0
  10. package/docs/mode-rules.md +86 -0
  11. package/docs/npm-publishing.md +79 -0
  12. package/docs/out-of-scope/mainstream-issue-trackers-only.md +25 -0
  13. package/docs/out-of-scope/question-limits.md +18 -0
  14. package/docs/out-of-scope/setup-skill-verify-mode.md +15 -0
  15. package/docs/overview.md +61 -0
  16. package/docs/philosophy.md +73 -0
  17. package/docs/quality-scorecard.md +23 -0
  18. package/docs/skill-maintenance.md +32 -0
  19. package/docs/skills-index.md +64 -0
  20. package/docs/team-mode.md +46 -0
  21. package/docs/token-budget.md +22 -0
  22. package/docs/troubleshooting.md +288 -0
  23. package/examples/demo-transcripts/01-small-tweak.md +37 -0
  24. package/examples/demo-transcripts/02-unknown-bug-fix.md +37 -0
  25. package/examples/demo-transcripts/03-new-feature.md +37 -0
  26. package/examples/demo-transcripts/04-refactor.md +37 -0
  27. package/examples/demo-transcripts/05-review-and-verify.md +37 -0
  28. package/examples/feature-flow.md +117 -0
  29. package/examples/fix-flow.md +139 -0
  30. package/package.json +5 -2
  31. package/scripts/check-package-links.js +1 -1
  32. package/scripts/eval-routing.js +1 -1
  33. package/scripts/score-quality.js +3 -3
  34. package/scripts/test-doctor.js +5 -5
  35. package/tests/fixtures/doctor/helper-not-permitted/fixture.json +1 -1
@@ -0,0 +1,139 @@
1
+ # Example: `/fix` flow
2
+
3
+ A worked example of the multi-phase `/fix` chain: orchestrator delegates
4
+ to the architect, architect diagnoses, architect switches to the tweaker
5
+ to implement, tweaker switches back, architect runs the post-mortem,
6
+ tweaker prepares the commit. The whole flow has explicit HITL stops.
7
+
8
+ ## Setup
9
+
10
+ - Active mode: `🪃 Custom Orchestrator`.
11
+ - Workspace has a real bug to fix. For this example, assume:
12
+
13
+ > "The login button does nothing on the second click. First click
14
+ > works."
15
+
16
+ ## Phase 1 — orchestrator routes
17
+
18
+ Type:
19
+
20
+ ```
21
+ /fix The login button does nothing on the second click. First click works.
22
+ ```
23
+
24
+ **Expected**
25
+
26
+ Orchestrator looks up the routing matrix and delegates with `new_task`
27
+ targeting `system-architect`. The delegated message includes the
28
+ slash form, user context, proceed policy, command-protocol pointer,
29
+ skills location, and the completion rule.
30
+
31
+ ## Phase 2 — architect diagnoses
32
+
33
+ The new task window opens in `🏗️ System Architect`. The architect:
34
+
35
+ 1. Loads `/fix` per the command protocol.
36
+ 2. Runs the `diagnose` skill, phases 1–3.
37
+ 3. Produces a short list of hypotheses.
38
+ 4. **Halts** and asks you to pick one.
39
+
40
+ **Expected message (paraphrased)**
41
+
42
+ > Hypotheses:
43
+ > 1. Click handler is wired once and never re-bound after a state change.
44
+ > 2. The button enters a disabled state on first click and never resets.
45
+ > 3. A queued network request is canceling the second click's handler.
46
+ >
47
+ > Which would you like to instrument? (1 / 2 / 3)
48
+
49
+ You answer:
50
+
51
+ ```
52
+ 2
53
+ ```
54
+
55
+ ## Phase 3 — architect instruments
56
+
57
+ The architect runs phase 4 of the `diagnose` skill on hypothesis 2.
58
+ This phase may involve reading state-management code, adding a
59
+ console-log or instrumentation suggestion (Markdown only — the architect
60
+ cannot edit source), and producing a confirmed root cause.
61
+
62
+ **Expected**
63
+
64
+ > Root cause confirmed: `LoginButton` sets `disabled` on the first
65
+ > click and the `onSuccess` handler does not reset it. The second
66
+ > click is being absorbed by the disabled state.
67
+
68
+ The architect summarizes the proposed fix and prepares to hand off.
69
+
70
+ ## Phase 4 — architect switches to tweaker
71
+
72
+ The architect calls `switch_mode` to `code-tweaker` **inside the same
73
+ task window** with a summary of:
74
+
75
+ - The root cause.
76
+ - The proposed fix (`onSuccess` resets `disabled`).
77
+ - The files involved.
78
+ - The tests to add or extend.
79
+
80
+ The tweaker takes over without losing context.
81
+
82
+ ## Phase 5 — tweaker implements
83
+
84
+ The tweaker:
85
+
86
+ 1. Edits the `LoginButton` component to reset `disabled` on success
87
+ and on error.
88
+ 2. Adds or extends tests covering the second-click case.
89
+ 3. Runs the test suite.
90
+ 4. Reports back.
91
+
92
+ **HITL stop**: the tweaker does not commit. Per the git rule, it waits
93
+ for your approval.
94
+
95
+ ## Phase 6 — back to architect for post-mortem
96
+
97
+ The tweaker calls `switch_mode` back to `system-architect`. The
98
+ architect runs phase 6 of `diagnose` (post-mortem):
99
+
100
+ - What was the original assumption that masked the bug?
101
+ - Is this an isolated mistake or a pattern?
102
+ - If a pattern, would `/refactor` help?
103
+
104
+ The architect produces a short post-mortem note in `docs/` or
105
+ `.scratch/` (Markdown only) and either drops the matter there or
106
+ suggests `/refactor`.
107
+
108
+ ## Phase 7 — tweaker prepares the commit
109
+
110
+ The architect switches back to the tweaker. The tweaker suggests
111
+ `/commit-and-document`. **The orchestrator does not auto-launch it.**
112
+ That command runs only when you type it.
113
+
114
+ ## Phase 8 — return to orchestrator
115
+
116
+ When the chain is complete (or blocked), the active mode calls
117
+ `attempt_completion`. The orchestrator summarizes for you and halts.
118
+
119
+ ## Pass criteria
120
+
121
+ - [ ] Orchestrator delegated to `system-architect`, not the tweaker.
122
+ - [ ] Architect halted after phase 3 hypotheses, did not instrument
123
+ until you picked one.
124
+ - [ ] Architect did not edit source code at any point.
125
+ - [ ] Architect used `switch_mode` (same window) to hand off, not
126
+ `new_task`.
127
+ - [ ] Tweaker did not run `git commit` or `git push` without your
128
+ explicit approval.
129
+ - [ ] After return, orchestrator halted instead of auto-launching
130
+ `/commit-and-document`.
131
+
132
+ ## Common slips
133
+
134
+ - Architect tries to edit source: see
135
+ [`docs/troubleshooting.md`](../docs/troubleshooting.md#architect-trying-to-edit-source).
136
+ - Tweaker commits without approval: tighten the git rule in the
137
+ tweaker's `customInstructions`.
138
+ - Orchestrator launches `/commit-and-document` automatically: see
139
+ [`docs/troubleshooting.md`](../docs/troubleshooting.md#slash-command-leakage-from-subtask-summaries).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fernado03/zoo-flow",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "Structured workflow templates for AI coding assistants",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,7 +10,10 @@
10
10
  "bin/",
11
11
  "templates/",
12
12
  "scripts/",
13
- "tests/"
13
+ "tests/",
14
+ "docs/",
15
+ "examples/",
16
+ "LICENSE"
14
17
  ],
15
18
  "keywords": [
16
19
  "ai",
@@ -12,7 +12,7 @@ const packageJsonPath = path.join(packageRoot, "package.json");
12
12
 
13
13
  const failures = [];
14
14
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
15
- const files = Array.isArray(packageJson.files) ? packageJson.files : [];
15
+ const files = Array.isArray(packageJson.files) ? packageJson.files.map((f) => f.replace(/\/$/, "")) : [];
16
16
  const forbidden = [".git", "node_modules", ".scratch", ".zoo-flow-backup", "*.tgz"];
17
17
 
18
18
  for (const entry of files) {
@@ -105,7 +105,7 @@ if (!fs.existsSync(casesPath)) {
105
105
  fail(lineNumber, "expected_command must start with /");
106
106
  } else {
107
107
  const commandName = record.expected_command.slice(1);
108
- const commandPath = path.join(templateRoot, ".roo", "commands", `${commandName}.md`);
108
+ const commandPath = path.join(templateRoot, ".roo", "commands", `zoo-${commandName}.md`);
109
109
  if (!fs.existsSync(commandPath)) {
110
110
  fail(lineNumber, `missing command file for ${record.expected_command}`);
111
111
  } else {
@@ -37,7 +37,7 @@ function check(condition, description, category) {
37
37
  const files = fs.readdirSync(commandsDir).filter((f) => f.endsWith(".md"));
38
38
  for (const file of files) {
39
39
  const text = fs.readFileSync(path.join(commandsDir, file), "utf8");
40
- const isModeless = file === "caveman.md";
40
+ const isModeless = file === "zoo-caveman.md";
41
41
  r.total++;
42
42
  if (isModeless) {
43
43
  r.pass++; // modeless by design, not a failure
@@ -183,7 +183,7 @@ function check(condition, description, category) {
183
183
  (function () {
184
184
  const r = { pass: 0, total: 0 };
185
185
 
186
- const verifyCmd = path.join(templateRoot, ".roo", "commands", "verify.md");
186
+ const verifyCmd = path.join(templateRoot, ".roo", "commands", "zoo-verify.md");
187
187
  r.total++;
188
188
  r.pass += check(fs.existsSync(verifyCmd), "verify command exists", "verification") ? 1 : 0;
189
189
 
@@ -209,7 +209,7 @@ function check(condition, description, category) {
209
209
  (function () {
210
210
  const r = { pass: 0, total: 0 };
211
211
 
212
- const reviewCmd = path.join(templateRoot, ".roo", "commands", "review.md");
212
+ const reviewCmd = path.join(templateRoot, ".roo", "commands", "zoo-review.md");
213
213
  r.total++;
214
214
  r.pass += check(fs.existsSync(reviewCmd), "review command exists", "review_process") ? 1 : 0;
215
215
 
@@ -42,21 +42,21 @@ function mutate(root, mutation) {
42
42
  if (mutation === "missing-roomodes") {
43
43
  fs.rmSync(path.join(root, ".roomodes"));
44
44
  } else if (mutation === "missing-command") {
45
- fs.rmSync(command("review.md"));
45
+ fs.rmSync(command("zoo-review.md"));
46
46
  } else if (mutation === "missing-skill") {
47
47
  fs.rmSync(skill("engineering", "tweak", "SKILL.md"));
48
48
  } else if (mutation === "bad-skill-wrapper") {
49
- replaceInFile(command("caveman.md"), "Skill:", "Run skill:");
49
+ replaceInFile(command("zoo-caveman.md"), "Skill:", "Run skill:");
50
50
  } else if (mutation === "bad-mode-slug") {
51
- replaceInFile(command("review.md"), "mode: system-architect", "mode: architect");
51
+ replaceInFile(command("zoo-review.md"), "mode: system-architect", "mode: architect");
52
52
  } else if (mutation === "bad-built-in-delegation") {
53
53
  fs.appendFileSync(path.join(root, ".roo", "rules-custom-orchestrator", "00-routing.md"), "\nUse new_task to architect for review.\n");
54
54
  } else if (mutation === "bad-zoo-path") {
55
55
  fs.appendFileSync(path.join(root, ".roo", "rules", "00-paths.md"), "\nBad path: .zoo/commands/example.md\n");
56
56
  } else if (mutation === "helper-missing-mode") {
57
- replaceInFile(command("diagnose.md"), /^mode: system-architect\r?\n/m, "");
57
+ replaceInFile(command("zoo-diagnose.md"), /^mode: system-architect\r?\n/m, "");
58
58
  } else if (mutation === "helper-not-permitted") {
59
- replaceInFile(path.join(root, ".roomodes"), "/diagnose, ", "");
59
+ replaceInFile(path.join(root, ".roomodes"), "/zoo-diagnose, ", "");
60
60
  } else {
61
61
  throw new Error(`Unknown mutation: ${mutation}`);
62
62
  }
@@ -1 +1 @@
1
- {"expect":"fail","mutation":"helper-not-permitted","message":"does not permit documented command /diagnose"}
1
+ {"expect":"fail","mutation":"helper-not-permitted","message":"does not permit documented command /zoo-diagnose"}