@fernado03/zoo-flow 0.3.4 → 0.4.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.
- package/bin/zoo-flow.js +79 -7
- package/package.json +1 -1
- package/templates/full/.roo/commands/explore.md +1 -1
- package/templates/full/.roo/commands/update-docs.md +2 -0
- package/templates/full/.roo/skills/engineering/commit-and-document/SKILL.md +12 -1
- package/templates/full/.roo/skills/engineering/grill-with-docs/CONTEXT-FORMAT.md +28 -19
- package/templates/full/.zoo-flow/CONTEXT.md +8 -0
- package/templates/full/.zoo-flow/docs/adr/0001-record-architecture-decisions.md +22 -0
package/bin/zoo-flow.js
CHANGED
|
@@ -80,6 +80,57 @@ function backupIfExists(projectRoot, backupDir, relativePath) {
|
|
|
80
80
|
return true;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
const ZOO_FLOW_GITIGNORE_MARKER = "# Zoo Flow — local context scaffolding";
|
|
84
|
+
|
|
85
|
+
function appendZooFlowToGitignore(projectRoot) {
|
|
86
|
+
const gi = path.join(projectRoot, ".gitignore");
|
|
87
|
+
|
|
88
|
+
if (pathExists(gi)) {
|
|
89
|
+
const content = fs.readFileSync(gi, "utf8");
|
|
90
|
+
if (content.includes(ZOO_FLOW_GITIGNORE_MARKER)) return false;
|
|
91
|
+
const addition = `\n${ZOO_FLOW_GITIGNORE_MARKER} (never committed)\n.zoo-flow/\n`;
|
|
92
|
+
fs.appendFileSync(gi, addition);
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const fresh = `${ZOO_FLOW_GITIGNORE_MARKER} (never committed)\n.zoo-flow/\n`;
|
|
97
|
+
fs.writeFileSync(gi, fresh);
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function migrateRootContextDocs(projectRoot) {
|
|
102
|
+
const moved = [];
|
|
103
|
+
const targetFlowDir = path.join(projectRoot, ".zoo-flow");
|
|
104
|
+
fs.mkdirSync(targetFlowDir, { recursive: true });
|
|
105
|
+
|
|
106
|
+
const rootContext = path.join(projectRoot, "CONTEXT.md");
|
|
107
|
+
const targetContext = path.join(targetFlowDir, "CONTEXT.md");
|
|
108
|
+
if (pathExists(rootContext) && !pathExists(targetContext)) {
|
|
109
|
+
fs.renameSync(rootContext, targetContext);
|
|
110
|
+
moved.push("CONTEXT.md");
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const rootAdr = path.join(projectRoot, "docs", "adr");
|
|
114
|
+
const targetAdr = path.join(targetFlowDir, "docs", "adr");
|
|
115
|
+
if (pathExists(rootAdr) && !pathExists(targetAdr)) {
|
|
116
|
+
fs.mkdirSync(targetAdr, { recursive: true });
|
|
117
|
+
copyRecursive(rootAdr, targetAdr);
|
|
118
|
+
removeRecursive(rootAdr);
|
|
119
|
+
moved.push("docs/adr/");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return moved;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function copyZooFlowIfMissing(projectRoot) {
|
|
126
|
+
const target = path.join(projectRoot, ".zoo-flow");
|
|
127
|
+
if (pathExists(target)) return false;
|
|
128
|
+
const source = path.join(templateRoot, ".zoo-flow");
|
|
129
|
+
if (!pathExists(source)) return false;
|
|
130
|
+
copyRecursive(source, target);
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
|
|
83
134
|
function makeTimestamp() {
|
|
84
135
|
return new Date().toISOString().replace(/[:.]/g, "-");
|
|
85
136
|
}
|
|
@@ -265,13 +316,24 @@ Run again with --force to back up and overwrite:
|
|
|
265
316
|
copyRecursive(sourceRoomodes, targetRoomodes);
|
|
266
317
|
copyRecursive(sourceRoo, targetRoo);
|
|
267
318
|
|
|
319
|
+
const didAddGitignore = appendZooFlowToGitignore(projectRoot);
|
|
320
|
+
const didAddZooFlow = copyZooFlowIfMissing(projectRoot);
|
|
321
|
+
|
|
322
|
+
const copiedLines = [" - .roomodes", " - .roo/"];
|
|
323
|
+
if (didAddZooFlow) {
|
|
324
|
+
copiedLines.push(" - .zoo-flow/CONTEXT.md");
|
|
325
|
+
copiedLines.push(" - .zoo-flow/docs/adr/0001-record-architecture-decisions.md");
|
|
326
|
+
}
|
|
327
|
+
if (didAddGitignore) {
|
|
328
|
+
copiedLines.push(" - appended .zoo-flow/ to .gitignore");
|
|
329
|
+
}
|
|
330
|
+
|
|
268
331
|
console.log(`
|
|
269
332
|
Zoo Flow installed.
|
|
270
333
|
|
|
271
334
|
Copied:
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
335
|
+
${copiedLines.join("\n")}
|
|
336
|
+
${didBackup ? `\nBackup:\n ${backupDir}\n` : ""}
|
|
275
337
|
${didBackup ? `Backup:\n ${backupDir}\n` : ""}Next:
|
|
276
338
|
1. Reload VS Code
|
|
277
339
|
2. Open Zoo Code
|
|
@@ -328,6 +390,12 @@ Run:
|
|
|
328
390
|
}
|
|
329
391
|
|
|
330
392
|
if (dryRun) {
|
|
393
|
+
const rootContext = path.join(projectRoot, "CONTEXT.md");
|
|
394
|
+
const rootAdr = path.join(projectRoot, "docs", "adr");
|
|
395
|
+
const wouldMigrate =
|
|
396
|
+
(pathExists(rootContext) ? ["CONTEXT.md"] : [])
|
|
397
|
+
.concat(pathExists(rootAdr) ? ["docs/adr/"] : []);
|
|
398
|
+
|
|
331
399
|
console.log(`
|
|
332
400
|
Zoo Flow update dry run.
|
|
333
401
|
|
|
@@ -336,6 +404,8 @@ ${hasRoomodes ? " - .roomodes\n" : ""}${hasRoo ? " - .roo/\n" : ""}
|
|
|
336
404
|
Would replace with latest template:
|
|
337
405
|
- .roomodes
|
|
338
406
|
- .roo/
|
|
407
|
+
${wouldMigrate.length > 0 ? `\nWould migrate to .zoo-flow/:\n${wouldMigrate.map((p) => ` - ${p}\n`).join("")}` : ""}
|
|
408
|
+
Would append .zoo-flow/ to .gitignore (idempotent).
|
|
339
409
|
|
|
340
410
|
Run this to update:
|
|
341
411
|
npx @fernado03/zoo-flow@latest update
|
|
@@ -356,20 +426,22 @@ Run this to update:
|
|
|
356
426
|
copyRecursive(sourceRoomodes, targetRoomodes);
|
|
357
427
|
copyRecursive(sourceRoo, targetRoo);
|
|
358
428
|
|
|
429
|
+
const moved = migrateRootContextDocs(projectRoot);
|
|
430
|
+
appendZooFlowToGitignore(projectRoot);
|
|
431
|
+
|
|
359
432
|
console.log(`
|
|
360
433
|
Zoo Flow updated.
|
|
361
434
|
|
|
362
435
|
Replaced:
|
|
363
436
|
- .roomodes
|
|
364
437
|
- .roo/
|
|
365
|
-
|
|
366
|
-
${didBackup ? `Backup:\n ${backupDir}\n\nTo restore the previous config:\n rm -rf .roomodes .roo\n cp -R ${backupDir}/. .\n` : ""}
|
|
367
|
-
Next:
|
|
438
|
+
${moved.length > 0 ? `\nMigrated to .zoo-flow/:\n${moved.map((p) => ` - ${p}\n`).join("")}` : ""}
|
|
439
|
+
${didBackup ? `Backup:\n ${backupDir}\n\nTo restore the previous config:\n rm -rf .roomodes .roo\n cp -R ${backupDir}/. .\n` : ""}Next:
|
|
368
440
|
1. Reload VS Code
|
|
369
441
|
2. Open Zoo Code
|
|
370
442
|
3. Confirm the three custom modes still appear
|
|
371
443
|
`);
|
|
372
|
-
}
|
|
444
|
+
}
|
|
373
445
|
|
|
374
446
|
if (!command || command === "--help" || command === "-h") {
|
|
375
447
|
console.log(HELP);
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@ argument-hint: <feature or folder to map>
|
|
|
4
4
|
mode: system-architect
|
|
5
5
|
---
|
|
6
6
|
EXECUTION RULES:
|
|
7
|
-
1.
|
|
7
|
+
1. APPLY the slot discovery rule from `.roo/skills/engineering/grill-with-docs/CONTEXT-FORMAT.md` to the target area. Missing slots are not an error. If no slots are populated, output one line before step 2: "No context docs found. Run /grill-with-docs to start CONTEXT.md, or continue without context."
|
|
8
8
|
2. RUN skill: `.roo/skills/engineering/zoom-out/SKILL.md`.
|
|
9
9
|
3. OUTPUT MAP: Create markdown with sections: Domain language, Modules, Data flow, Seams/callers, ADRs, Open questions.
|
|
10
10
|
4. NEXT STEPS: Suggest `/grill-with-docs`, `/feature`, `/refactor`, or `/fix`. DO NOT auto-launch.
|
|
@@ -8,6 +8,8 @@ Update repo documentation so it matches the current code. Surgical edits only
|
|
|
8
8
|
|
|
9
9
|
Skill: `.roo/skills/engineering/update-docs/SKILL.md`
|
|
10
10
|
|
|
11
|
+
Apply the slot discovery rule from `.roo/skills/engineering/grill-with-docs/CONTEXT-FORMAT.md` to locate the target doc. If the slot is empty, ask once: "No <slot> found. Create a stub at .zoo-flow/<slot>? (yes / pick-existing / skip)".
|
|
12
|
+
|
|
11
13
|
Do NOT use this for:
|
|
12
14
|
|
|
13
15
|
- Domain glossary terms — use `/grill-with-docs`
|
|
@@ -120,7 +120,18 @@ Date via `date +%Y-%m-%d`. Create `docs/journal/<YYYY-MM-DD>/` if missing. Write
|
|
|
120
120
|
<Gotchas/follow-ups, one paragraph max. Skip if nothing worth saying.>
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
-
## 7.
|
|
123
|
+
## 7. Surface stale docs (if any)
|
|
124
|
+
|
|
125
|
+
Read `git diff --cached --stat`. If any staged path overlaps with a path
|
|
126
|
+
referenced in `.zoo-flow/CONTEXT.md`, `.zoo-flow/ARCHITECTURE.md`,
|
|
127
|
+
`.zoo-flow/APP_MAP.md`, or any nearby `FLOW.md`, output exactly one line
|
|
128
|
+
before "Confirm":
|
|
129
|
+
|
|
130
|
+
"Public surface may have drifted. Run /update-docs? (yes / skip)"
|
|
131
|
+
|
|
132
|
+
On `yes` → suggest `/update-docs <area>`. On `skip` → continue.
|
|
133
|
+
|
|
134
|
+
## 8. Confirm
|
|
124
135
|
|
|
125
136
|
Report: commit hash + message, journal entry path, whether `.gitignore` was updated, and any issue actions taken. Close with: "All of `docs/` is gitignored, so this entry stays local."
|
|
126
137
|
|
|
@@ -26,29 +26,38 @@ _Avoid_: Purchase, transaction
|
|
|
26
26
|
- Include domain terms only; exclude generic programming terms.
|
|
27
27
|
- Group under headings when useful.
|
|
28
28
|
|
|
29
|
-
##
|
|
29
|
+
## Slots
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
| Slot | File (if present) | Authored by | Default location |
|
|
32
|
+
|---|---|---|---|
|
|
33
|
+
| Domain language | `CONTEXT.md` | User via /grill-with-docs | `.zoo-flow/CONTEXT.md` |
|
|
34
|
+
| Decisions | `docs/adr/<NNNN-slug>.md` | User via /grill-with-docs | `.zoo-flow/docs/adr/` |
|
|
35
|
+
| Subsystem flow | `FLOW.md` | Subsystem owner | Next to the code |
|
|
36
|
+
| App map | `APP_MAP.md` | User via /update-docs | `.zoo-flow/APP_MAP.md` |
|
|
37
|
+
| Architecture | `ARCHITECTURE.md` | User via /update-docs | `.zoo-flow/ARCHITECTURE.md` |
|
|
38
|
+
| Setup | `README.md` | Project owner | Project root |
|
|
34
39
|
|
|
35
|
-
|
|
36
|
-
- `CONTEXT-MAP.md`
|
|
37
|
-
- Per-context `CONTEXT.md` + optional `docs/adr/`
|
|
40
|
+
## Discovery rule (used by /explore, /update-docs, /grill-with-docs)
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
1. If `CONTEXT-MAP.md`, read map + relevant contexts.
|
|
41
|
-
2. Else if root `CONTEXT.md`, use it.
|
|
42
|
-
3. Else create root `CONTEXT.md` lazily on first resolved term.
|
|
43
|
-
4. If context ambiguous, ask.
|
|
42
|
+
For each slot, in this order:
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
1. If the file exists at the documented location, read it.
|
|
45
|
+
2. If the slot is empty/missing, that is **not an error**. The user has
|
|
46
|
+
not authored it yet. Do not invent content. Do not lazy-create unless
|
|
47
|
+
the calling command explicitly says so (e.g. /grill-with-docs on a
|
|
48
|
+
first resolved term).
|
|
49
|
+
3. If the calling command depends on a populated slot and none exist,
|
|
50
|
+
surface once: "Slot `<name>` not yet authored. Run /grill-with-docs
|
|
51
|
+
to fill, or continue without."
|
|
46
52
|
|
|
47
|
-
|
|
53
|
+
## Multi-context (rare)
|
|
48
54
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
- `ARCHITECTURE.md` — system-level structure, constraints, seams; root-level.
|
|
52
|
-
- `README.md` — setup and usage; root-level.
|
|
55
|
+
A single project can hold multiple domain contexts when subsystems do
|
|
56
|
+
not share language. Use:
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
- `.zoo-flow/CONTEXT-MAP.md` — index of contexts.
|
|
59
|
+
- `.zoo-flow/contexts/<slug>/CONTEXT.md` — per-context.
|
|
60
|
+
- `.zoo-flow/contexts/<slug>/docs/adr/` — per-context ADRs.
|
|
61
|
+
|
|
62
|
+
`/grill-with-docs` and `/explore` consult the map first, then the
|
|
63
|
+
relevant per-context file.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# 1. Record architecture decisions
|
|
2
|
+
|
|
3
|
+
Date: <YYYY-MM-DD>
|
|
4
|
+
|
|
5
|
+
## Status
|
|
6
|
+
|
|
7
|
+
Accepted.
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
|
|
11
|
+
We need to record significant architectural decisions so future contributors
|
|
12
|
+
(including AI agents) understand why the project is shaped the way it is.
|
|
13
|
+
Use this template: copy the file, rename to `NNNN-slug.md`, fill the three
|
|
14
|
+
sections below.
|
|
15
|
+
|
|
16
|
+
## Decision
|
|
17
|
+
|
|
18
|
+
What we chose to do.
|
|
19
|
+
|
|
20
|
+
## Consequences
|
|
21
|
+
|
|
22
|
+
What becomes easier. What becomes harder. What we trade away.
|