@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 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
- - .roomodes
273
- - .roo/
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fernado03/zoo-flow",
3
3
  "description": "Workflow control plane for Zoo Code.",
4
- "version": "0.3.4",
4
+ "version": "0.4.1",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "zoo-flow": "bin/zoo-flow.js"
@@ -4,7 +4,7 @@ argument-hint: <feature or folder to map>
4
4
  mode: system-architect
5
5
  ---
6
6
  EXECUTION RULES:
7
- 1. READ: `CONTEXT.md`, `CONTEXT-MAP.md`, `docs/adr/`, `FLOW.md`, `ARCHITECTURE.md`, `APP_MAP.md` in target area.
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. Confirm
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
- ## Layout
29
+ ## Slots
30
30
 
31
- Single-context:
32
- - `CONTEXT.md`
33
- - `docs/adr/`
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
- Multi-context:
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
- Detection:
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
- ## Companion docs
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
- Canonical names for code-explanation docs (read by `/explore`, edited by `/update-docs`):
53
+ ## Multi-context (rare)
48
54
 
49
- - `FLOW.md` subsystem flow / data path; lives next to the code it describes.
50
- - `APP_MAP.md` — app-wide module/navigation map; root-level.
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
- Use these names when creating new docs of these kinds. A subsystem may have its own `FLOW.md`; `APP_MAP.md` and `ARCHITECTURE.md` are typically singular per repo.
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,8 @@
1
+ # Context
2
+ <!-- Domain language, terms, and ambiguities for this project. Run /grill-with-docs to fill. -->
3
+
4
+ ## Language
5
+ <!-- Term: 1-2 sentence definition. _Avoid_: aliases. -->
6
+
7
+ ## Flagged ambiguities
8
+ <!-- "X means Y, not Z." -->
@@ -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.