@entelligentsia/forgecli 1.0.10 → 1.0.14

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 (167) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/dist/CHANGELOG-forge-plugin.md +150 -0
  3. package/dist/bin/forge.js +0 -0
  4. package/dist/extensions/forgecli/config-layer.d.ts +16 -0
  5. package/dist/extensions/forgecli/config-layer.js +5 -0
  6. package/dist/extensions/forgecli/config-layer.js.map +1 -1
  7. package/dist/extensions/forgecli/dashboard/component.d.ts +102 -0
  8. package/dist/extensions/forgecli/dashboard/component.js +882 -0
  9. package/dist/extensions/forgecli/dashboard/component.js.map +1 -0
  10. package/dist/extensions/forgecli/dashboard/register.d.ts +2 -0
  11. package/dist/extensions/forgecli/dashboard/register.js +45 -0
  12. package/dist/extensions/forgecli/dashboard/register.js.map +1 -0
  13. package/dist/extensions/forgecli/dashboard/view-model.d.ts +35 -0
  14. package/dist/extensions/forgecli/dashboard/view-model.js +54 -0
  15. package/dist/extensions/forgecli/dashboard/view-model.js.map +1 -0
  16. package/dist/extensions/forgecli/fix-bug.js +72 -7
  17. package/dist/extensions/forgecli/fix-bug.js.map +1 -1
  18. package/dist/extensions/forgecli/forge-cli-schema.json +4 -0
  19. package/dist/extensions/forgecli/forge-commands.js +1 -0
  20. package/dist/extensions/forgecli/forge-commands.js.map +1 -1
  21. package/dist/extensions/forgecli/forge-init/phase4-register.js +53 -0
  22. package/dist/extensions/forgecli/forge-init/phase4-register.js.map +1 -1
  23. package/dist/extensions/forgecli/forge-subagent.js +6 -4
  24. package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
  25. package/dist/extensions/forgecli/index.js +5 -0
  26. package/dist/extensions/forgecli/index.js.map +1 -1
  27. package/dist/extensions/forgecli/lib/halt-advisor.d.ts +54 -0
  28. package/dist/extensions/forgecli/lib/halt-advisor.js +90 -0
  29. package/dist/extensions/forgecli/lib/halt-advisor.js.map +1 -0
  30. package/dist/extensions/forgecli/migration-engine.js +25 -12
  31. package/dist/extensions/forgecli/migration-engine.js.map +1 -1
  32. package/dist/extensions/forgecli/orchestrator-status-bar.d.ts +25 -0
  33. package/dist/extensions/forgecli/orchestrator-status-bar.js +183 -0
  34. package/dist/extensions/forgecli/orchestrator-status-bar.js.map +1 -0
  35. package/dist/extensions/forgecli/orchestrator-tree.d.ts +96 -0
  36. package/dist/extensions/forgecli/orchestrator-tree.js +390 -0
  37. package/dist/extensions/forgecli/orchestrator-tree.js.map +1 -0
  38. package/dist/extensions/forgecli/project-orientation.js +12 -8
  39. package/dist/extensions/forgecli/project-orientation.js.map +1 -1
  40. package/dist/extensions/forgecli/regenerate.d.ts +16 -0
  41. package/dist/extensions/forgecli/regenerate.js +110 -0
  42. package/dist/extensions/forgecli/regenerate.js.map +1 -1
  43. package/dist/extensions/forgecli/run-sprint.js +33 -3
  44. package/dist/extensions/forgecli/run-sprint.js.map +1 -1
  45. package/dist/extensions/forgecli/run-task.d.ts +32 -0
  46. package/dist/extensions/forgecli/run-task.js +185 -12
  47. package/dist/extensions/forgecli/run-task.js.map +1 -1
  48. package/dist/extensions/forgecli/thread-switcher.js +105 -764
  49. package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
  50. package/dist/extensions/forgecli/viewport-events.js +32 -0
  51. package/dist/extensions/forgecli/viewport-events.js.map +1 -1
  52. package/dist/forge-payload/.base-pack/commands/fix-bug.md +1 -1
  53. package/dist/forge-payload/.base-pack/commands/run-sprint.md +1 -1
  54. package/dist/forge-payload/.base-pack/commands/run-task.md +1 -1
  55. package/dist/forge-payload/.base-pack/personas/architect.md +1 -1
  56. package/dist/forge-payload/.base-pack/personas/bug-fixer.md +1 -1
  57. package/dist/forge-payload/.base-pack/personas/collator.md +3 -3
  58. package/dist/forge-payload/.base-pack/personas/engineer.md +1 -1
  59. package/dist/forge-payload/.base-pack/personas/librarian.md +1 -1
  60. package/dist/forge-payload/.base-pack/personas/orchestrator.md +1 -1
  61. package/dist/forge-payload/.base-pack/personas/product-manager.md +1 -1
  62. package/dist/forge-payload/.base-pack/personas/qa-engineer.md +1 -1
  63. package/dist/forge-payload/.base-pack/personas/supervisor.md +1 -1
  64. package/dist/forge-payload/.base-pack/workflows/_fragments/event-emission-schema.md +1 -1
  65. package/dist/forge-payload/.base-pack/workflows/_fragments/friction-emit.md +1 -1
  66. package/dist/forge-payload/.base-pack/workflows/_fragments/iron-laws.md +1 -1
  67. package/dist/forge-payload/.base-pack/workflows/_fragments/progress-reporting.md +2 -2
  68. package/dist/forge-payload/.base-pack/workflows/_fragments/store-cli-verbs.md +11 -2
  69. package/dist/forge-payload/.base-pack/workflows/architect_approve.md +6 -7
  70. package/dist/forge-payload/.base-pack/workflows/architect_review_sprint_completion.md +2 -2
  71. package/dist/forge-payload/.base-pack/workflows/architect_sprint_intake.md +2 -2
  72. package/dist/forge-payload/.base-pack/workflows/architect_sprint_plan.md +5 -5
  73. package/dist/forge-payload/.base-pack/workflows/collator_agent.md +4 -6
  74. package/dist/forge-payload/.base-pack/workflows/commit_task.md +5 -6
  75. package/dist/forge-payload/.base-pack/workflows/enhance.md +5 -5
  76. package/dist/forge-payload/.base-pack/workflows/implement_plan.md +6 -7
  77. package/dist/forge-payload/.base-pack/workflows/migrate_structural.md +12 -13
  78. package/dist/forge-payload/.base-pack/workflows/plan_task.md +5 -6
  79. package/dist/forge-payload/.base-pack/workflows/review_code.md +8 -8
  80. package/dist/forge-payload/.base-pack/workflows/review_plan.md +8 -8
  81. package/dist/forge-payload/.base-pack/workflows/sprint_retrospective.md +3 -3
  82. package/dist/forge-payload/.base-pack/workflows/triage.md +12 -9
  83. package/dist/forge-payload/.base-pack/workflows/update_implementation.md +2 -2
  84. package/dist/forge-payload/.base-pack/workflows/update_plan.md +2 -2
  85. package/dist/forge-payload/.base-pack/workflows/validate_task.md +5 -6
  86. package/dist/forge-payload/.base-pack/workflows-js/wfl-fix-bug.js +490 -0
  87. package/dist/forge-payload/.base-pack/workflows-js/wfl-run-sprint.js +416 -0
  88. package/dist/forge-payload/.base-pack/workflows-js/wfl-run-task.js +608 -0
  89. package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
  90. package/dist/forge-payload/.schemas/config.schema.json +2 -3
  91. package/dist/forge-payload/.schemas/enum-catalog.json +2 -2
  92. package/dist/forge-payload/.schemas/event.schema.json +16 -0
  93. package/dist/forge-payload/.schemas/migrations.json +236 -0
  94. package/dist/forge-payload/commands/health.md +29 -0
  95. package/dist/forge-payload/commands/rebuild.md +143 -15
  96. package/dist/forge-payload/commands/update.md +28 -27
  97. package/dist/forge-payload/hooks/preflight-session.cjs +99 -0
  98. package/dist/forge-payload/init/phases/phase-3-materialize.md +18 -5
  99. package/dist/forge-payload/integrity.json +7 -6
  100. package/dist/forge-payload/meta/fragments/tool-discipline.md +1 -1
  101. package/dist/forge-payload/meta/personas/meta-architect.md +1 -1
  102. package/dist/forge-payload/meta/personas/meta-bug-fixer.md +1 -1
  103. package/dist/forge-payload/meta/personas/meta-collator.md +7 -7
  104. package/dist/forge-payload/meta/personas/meta-engineer.md +1 -1
  105. package/dist/forge-payload/meta/personas/meta-orchestrator.md +1 -1
  106. package/dist/forge-payload/meta/personas/meta-supervisor.md +1 -1
  107. package/dist/forge-payload/meta/tool-specs/store-cli.spec.md +1 -1
  108. package/dist/forge-payload/meta/workflows/_fragments/event-emission-schema.md +1 -1
  109. package/dist/forge-payload/meta/workflows/_fragments/friction-emit.md +1 -1
  110. package/dist/forge-payload/meta/workflows/_fragments/iron-laws.md +1 -1
  111. package/dist/forge-payload/meta/workflows/_fragments/progress-reporting.md +2 -2
  112. package/dist/forge-payload/meta/workflows/_fragments/store-cli-verbs.md +11 -2
  113. package/dist/forge-payload/meta/workflows/meta-approve.md +6 -7
  114. package/dist/forge-payload/meta/workflows/meta-bug-triage.md +12 -9
  115. package/dist/forge-payload/meta/workflows/meta-collate.md +5 -7
  116. package/dist/forge-payload/meta/workflows/meta-commit.md +5 -6
  117. package/dist/forge-payload/meta/workflows/meta-enhance.md +5 -5
  118. package/dist/forge-payload/meta/workflows/meta-fix-bug.md +35 -11
  119. package/dist/forge-payload/meta/workflows/meta-implement.md +15 -7
  120. package/dist/forge-payload/meta/workflows/meta-migrate.md +13 -14
  121. package/dist/forge-payload/meta/workflows/meta-new-sprint.md +3 -3
  122. package/dist/forge-payload/meta/workflows/meta-orchestrate.md +138 -39
  123. package/dist/forge-payload/meta/workflows/meta-plan-sprint.md +6 -6
  124. package/dist/forge-payload/meta/workflows/meta-plan-task.md +12 -6
  125. package/dist/forge-payload/meta/workflows/meta-retro.md +4 -4
  126. package/dist/forge-payload/meta/workflows/meta-retrospective.md +4 -4
  127. package/dist/forge-payload/meta/workflows/meta-review-implementation.md +8 -8
  128. package/dist/forge-payload/meta/workflows/meta-review-plan.md +8 -8
  129. package/dist/forge-payload/meta/workflows/meta-review-sprint-completion.md +3 -3
  130. package/dist/forge-payload/meta/workflows/meta-sprint-intake.md +3 -3
  131. package/dist/forge-payload/meta/workflows/meta-sprint-plan.md +6 -6
  132. package/dist/forge-payload/meta/workflows/meta-update-implementation.md +2 -2
  133. package/dist/forge-payload/meta/workflows/meta-update-plan.md +2 -2
  134. package/dist/forge-payload/meta/workflows/meta-validate.md +5 -6
  135. package/dist/forge-payload/schemas/config.schema.json +2 -3
  136. package/dist/forge-payload/schemas/enum-catalog.json +2 -2
  137. package/dist/forge-payload/schemas/event.schema.json +16 -0
  138. package/dist/forge-payload/schemas/structure-manifest.json +75 -73
  139. package/dist/forge-payload/skills/refresh-kb-links/SKILL.md +14 -7
  140. package/dist/forge-payload/tools/banners.cjs +29 -10
  141. package/dist/forge-payload/tools/check-structure.cjs +88 -7
  142. package/dist/forge-payload/tools/collate.cjs +16 -2
  143. package/dist/forge-payload/tools/manage-config.cjs +5 -7
  144. package/dist/forge-payload/tools/parse-gates.cjs +73 -1
  145. package/dist/forge-payload/tools/postflight-gate.cjs +252 -0
  146. package/dist/forge-payload/tools/preflight-gate.cjs +47 -0
  147. package/dist/forge-payload/tools/substitute-placeholders.cjs +5 -4
  148. package/dist/forge-payload/tools/verify-phase.cjs +17 -0
  149. package/package.json +1 -1
  150. package/dist/bin/forgecli.d.ts +0 -2
  151. package/dist/bin/forgecli.js +0 -6
  152. package/dist/bin/forgecli.js.map +0 -1
  153. package/dist/extensions/forgecli/config-tui/index.d.ts +0 -5
  154. package/dist/extensions/forgecli/config-tui/index.js +0 -5
  155. package/dist/extensions/forgecli/config-tui/index.js.map +0 -1
  156. package/dist/extensions/forgecli/loaders/persona-skill-loader.d.ts +0 -45
  157. package/dist/extensions/forgecli/loaders/persona-skill-loader.js +0 -227
  158. package/dist/extensions/forgecli/loaders/persona-skill-loader.js.map +0 -1
  159. package/dist/extensions/forgecli/loaders/template-render.d.ts +0 -20
  160. package/dist/extensions/forgecli/loaders/template-render.js +0 -85
  161. package/dist/extensions/forgecli/loaders/template-render.js.map +0 -1
  162. package/dist/extensions/forgecli/loaders/workflow-loader.d.ts +0 -41
  163. package/dist/extensions/forgecli/loaders/workflow-loader.js +0 -164
  164. package/dist/extensions/forgecli/loaders/workflow-loader.js.map +0 -1
  165. package/dist/forge-payload/.base-pack/workflows/fix_bug.md +0 -446
  166. package/dist/forge-payload/.base-pack/workflows/orchestrate_task.md +0 -928
  167. package/dist/forge-payload/.base-pack/workflows/run_sprint.md +0 -225
@@ -27,7 +27,7 @@ deps:
27
27
 
28
28
  - Evaluate the plan against what the task actually requires, not against what the plan claims to deliver. Plans routinely understate complexity, omit edge cases, or skip security steps. Your job is adversarial review, not approval.
29
29
  - Read `.forge/personas/supervisor.md` first; print the persona identity line (emoji, name, tagline) to stdout before any other tool use.
30
- - All store I/O via `forge_store` (or `node "$FORGE_ROOT/tools/store-cli.cjs"`). Never edit `.forge/store/*.json` directly.
30
+ - All store I/O via `forge_store` (or `node .forge/tools/store-cli.cjs`). Never edit `.forge/store/*.json` directly.
31
31
 
32
32
  ## Store-Write Verification
33
33
 
@@ -38,9 +38,8 @@ deps:
38
38
  ```
39
39
 
40
40
  0a. Pre-flight Gate Check:
41
- - Resolve FORGE_ROOT (`node -e "console.log(require('./.forge/config.json').paths.forgeRoot)"`).
42
41
  - **Entity-mode resolution:** read the kickoff arguments. `--task {id}` → `entity_kind = "task"`, `record_id = {id}`. `--bug {id}` → `entity_kind = "bug"`, `record_id = {id}`. All store-cli calls below substitute `{entity_kind}` and `{record_id}` for the literal "task"/{taskId} placeholders.
43
- - Run: `node "$FORGE_ROOT/tools/preflight-gate.cjs" --phase review-plan --{entity_kind} {record_id}`
42
+ - Run: `node .forge/tools/preflight-gate.cjs --phase review-plan --{entity_kind} {record_id}`
44
43
  - Exit 1 (gate failed) → print stderr and HALT. Do not proceed; do not attempt to produce the artifact.
45
44
  - Exit 2 (misconfiguration) → print stderr and HALT.
46
45
  - Exit 0 → continue.
@@ -49,7 +48,7 @@ deps:
49
48
  - If `--force` is present in the invocation arguments, skip this step entirely.
50
49
  - If `entity_kind == "bug"`, skip this step entirely (bug state is managed by meta-fix-bug.md).
51
50
  - Read current task state:
52
- `node "$FORGE_ROOT/tools/store-cli.cjs" read task {record_id} --json`
51
+ `node .forge/tools/store-cli.cjs read task {record_id} --json`
53
52
  - Extract the `status` field from the JSON output.
54
53
  - Allowed states for this phase: `planned`.
55
54
  - If the current status is NOT in the allowed set:
@@ -96,7 +95,7 @@ deps:
96
95
  - Approved → `plan-approved`
97
96
  - Revision Required → `plan-revision-required`
98
97
  - Out-of-band escapes (any state): `code-revision-required`, `blocked`, `escalated`, `abandoned`
99
- Update status: `node "$FORGE_ROOT/tools/store-cli.cjs" update-status task {taskId} status plan-approved` (if Approved) or `... status plan-revision-required` (if Revision Required)
98
+ Update status: `node .forge/tools/store-cli.cjs update-status task {taskId} status plan-approved` (if Approved) or `... status plan-revision-required` (if Revision Required)
100
99
  - **Bug mode** — NO status write. The bug remains `in-progress`. The verdict signal travels through `summaries.review_plan.verdict` (read by `read-verdict.cjs § BUG_PHASE_VERDICT_SOURCE`), not `bug.status`. Writing `bug.status` here violates `meta-fix-bug.md § Iron Laws #2`.
101
100
  - **Do NOT emit a phase event yourself.** The orchestrator owns event emission — it composes the canonical event from runtime telemetry (model, provider, tokens, wall times) plus the SUMMARY you write in the next step. Subagents that call `store-cli emit` for phase events hallucinate runtime facts (see Plan 11 / Slice 2). Write the SUMMARY and return.
102
101
 
@@ -114,13 +113,14 @@ deps:
114
113
  ```
115
114
  - Call (task mode):
116
115
  ```
117
- forge_store({ command:"set-summary", entity:"task", id:"{record_id}", phase:"review_plan" })
116
+ forge_store({ command:"set-summary", args:["{record_id}", "review_plan"] })
118
117
  ```
119
118
  Or (bug mode):
120
119
  ```
121
- forge_store({ command:"set-bug-summary", entity:"bug", id:"{record_id}", phase:"review_plan" })
120
+ forge_store({ command:"set-bug-summary", args:["{record_id}", "review_plan"] })
122
121
  ```
123
- - If the set-summary call exits non-zero, fix the sidecar JSON and retry. Do not proceed without a valid summary.
122
+ `args[1]` is the LITERAL phase key `review_plan`, never the record id; `forge_store` has no `entity`/`id`/`phase` field (see `_fragments/store-cli-verbs.md`).
123
+ - If set-summary exits non-zero (guard: `expected summary key 'review_plan'`), `args[1]` was wrong — fix it to `review_plan` and retry. Do not return without a valid summary; the orchestrator halts as "verdict missing" if `summaries.review_plan` is absent.
124
124
  ```
125
125
 
126
126
  <!-- See _fragments/generation-instructions.md for Generation Instructions template -->
@@ -42,10 +42,10 @@ Verify that all tasks in a sprint have been completed, committed, and validated
42
42
  4. Finalize:
43
43
  - If step-3 verdict is `Approved`:
44
44
  - Update sprint status to `completed` via
45
- `node "$FORGE_ROOT/tools/store-cli.cjs" update-status sprint {sprintId} status completed`
45
+ `node .forge/tools/store-cli.cjs update-status sprint {sprintId} status completed`
46
46
  - If step-3 verdict is `Revision Required` and orchestrator passed `mode=partial`:
47
47
  - Update sprint status to `partially-completed` via
48
- `node "$FORGE_ROOT/tools/store-cli.cjs" update-status sprint {sprintId} status partially-completed`
48
+ `node .forge/tools/store-cli.cjs update-status sprint {sprintId} status partially-completed`
49
49
  - If step-3 verdict is `Revision Required` and orchestrator passed `mode=complete`:
50
50
  - Do NOT transition status. Leave the sprint at its current status and exit;
51
51
  the orchestrator will surface the verdict to the user.
@@ -64,5 +64,5 @@ Verify that all tasks in a sprint have been completed, committed, and validated
64
64
  (Claude Code only); on any other runtime treat as unavailable and proceed.
65
65
  Do NOT shell out to a `cost-cli.cjs` — there is no such tool.
66
66
  2. Parse: `inputTokens`, `outputTokens`, `cacheReadTokens`, `cacheWriteTokens`, `estimatedCostUSD`.
67
- 3. Write the usage sidecar via `node "$FORGE_ROOT/tools/store-cli.cjs" emit {sprintId} '{sidecar-json}' --sidecar`.
67
+ 3. Write the usage sidecar via `node .forge/tools/store-cli.cjs emit {sprintId} '{sidecar-json}' --sidecar`.
68
68
  - **Event Emission:** Ensure the "complete" event includes the `eventId` passed by the orchestrator.
@@ -23,7 +23,7 @@ Capture sprint requirements via a structured interview and document them for pla
23
23
 
24
24
  - Capture requirements accurately; do not editorialize or pre-select options on the user's behalf. The product manager documents what the user says, not what the agent thinks is best.
25
25
  - Read `.forge/personas/product-manager.md` first; print the persona identity line (emoji, name, tagline) to stdout before any other tool use.
26
- - All store I/O via `forge_store` (or `node "$FORGE_ROOT/tools/store-cli.cjs"`). Never edit `.forge/store/*.json` directly.
26
+ - All store I/O via `forge_store` (or `node .forge/tools/store-cli.cjs`). Never edit `.forge/store/*.json` directly.
27
27
 
28
28
  ## Algorithm
29
29
 
@@ -56,7 +56,7 @@ Capture sprint requirements via a structured interview and document them for pla
56
56
  - Ensure all deliverables are measurable and testable
57
57
 
58
58
  5. Finalize:
59
- - Update sprint status via `node "$FORGE_ROOT/tools/store-cli.cjs" update-status sprint {sprintId} status planning`
59
+ - Update sprint status via `node .forge/tools/store-cli.cjs update-status sprint {sprintId} status planning`
60
60
  - **Do NOT emit a phase event yourself.** The orchestrator (or kickoff handler) owns event emission — it composes the canonical event from runtime telemetry (model, provider, tokens, wall times) plus the SUMMARY you write in the next step. Subagents that call `store-cli emit` for phase events hallucinate runtime facts (see Plan 11 / Slice 2). Write the SUMMARY and return.
61
61
  ```
62
62
 
@@ -79,6 +79,6 @@ Capture sprint requirements via a structured interview and document them for pla
79
79
  - Set token fields to `null`: `"inputTokens": null, "outputTokens": null, "estimatedCostUSD": null`.
80
80
  - Add `"source": "missing"` to sidecar JSON.
81
81
  - Log: "Token data unavailable (cost probe failed). Backfill later via estimate-usage.cjs."
82
- 4. Write the usage sidecar via `node "$FORGE_ROOT/tools/store-cli.cjs" emit {sprintId} '{sidecar-json}' --sidecar`.
82
+ 4. Write the usage sidecar via `node .forge/tools/store-cli.cjs emit {sprintId} '{sidecar-json}' --sidecar`.
83
83
  5. **NEVER skip sidecar write.** Always emit (reported or placeholder with nulls).
84
84
  - **Event Emission:** Ensure the "complete" event includes the `eventId` passed by the orchestrator.
@@ -31,8 +31,8 @@ Break sprint requirements into a set of estimated tasks with a dependency graph.
31
31
  1. Load Context:
32
32
  - Query the store to orient on current project state before reading docs:
33
33
  ```sh
34
- node "$FORGE_ROOT/tools/store-cli.cjs" nlp "latest sprint"
35
- node "$FORGE_ROOT/tools/store-cli.cjs" nlp "open bugs"
34
+ node .forge/tools/store-cli.cjs nlp "latest sprint"
35
+ node .forge/tools/store-cli.cjs nlp "open bugs"
36
36
  ```
37
37
  Use results (titles, statuses, excerpts, file refs) to skip manual MASTER_INDEX.md navigation where sufficient.
38
38
  - Read SPRINT_REQUIREMENTS.md
@@ -52,11 +52,11 @@ Break sprint requirements into a set of estimated tasks with a dependency graph.
52
52
 
53
53
  4. Documentation:
54
54
  - Write SPRINT_PLAN.md to `engineering/sprints/{sprintId}/SPRINT_PLAN.md`
55
- - Create each task via `node "$FORGE_ROOT/tools/store-cli.cjs" write task '{task-json}'`.
55
+ - Create each task via `node .forge/tools/store-cli.cjs write task '{task-json}'`.
56
56
  If the command exits non-zero or the PreToolUse hook blocks the write:
57
57
  parse the error, correct the JSON, and retry (see Store-Write Verification).
58
58
  Do not proceed to the next task until this write succeeds.
59
- - Update the sprint record with all new task IDs via `node "$FORGE_ROOT/tools/store-cli.cjs" write sprint '{updated-sprint-json}'` (the sprint JSON must include the complete `taskIds` array with all newly created task IDs).
59
+ - Update the sprint record with all new task IDs via `node .forge/tools/store-cli.cjs write sprint '{updated-sprint-json}'` (the sprint JSON must include the complete `taskIds` array with all newly created task IDs).
60
60
  If the command exits non-zero or the PreToolUse hook blocks the write:
61
61
  parse the error, correct the JSON, and retry (see Store-Write Verification).
62
62
  Do not proceed until this write succeeds.
@@ -64,7 +64,7 @@ Break sprint requirements into a set of estimated tasks with a dependency graph.
64
64
  * Folder: `engineering/sprints/{sprintId}/{taskId}/`
65
65
  * File: `TASK_PROMPT.md` — populate from `.forge/templates/TASK_PROMPT_TEMPLATE.md`
66
66
  filling in title, objective, acceptance criteria, entities, DSL/CLI changes, and operational impact
67
- - Update sprint status via `node "$FORGE_ROOT/tools/store-cli.cjs" update-status sprint {sprintId} status active`.
67
+ - Update sprint status via `node .forge/tools/store-cli.cjs update-status sprint {sprintId} status active`.
68
68
  If the command exits non-zero, parse the error and retry
69
69
  (see Store-Write Verification). Do not proceed until this write succeeds.
70
70
 
@@ -141,7 +141,7 @@ environment variable is reserved for emergency operator repair only.
141
141
  - Set token fields to `null`: `"inputTokens": null, "outputTokens": null, "estimatedCostUSD": null`.
142
142
  - Add `"source": "missing"` to sidecar JSON.
143
143
  - Log: "Token data unavailable (cost probe failed). Backfill later via estimate-usage.cjs."
144
- 4. Write the usage sidecar via `node "$FORGE_ROOT/tools/store-cli.cjs" emit {sprintId} '{sidecar-json}' --sidecar`.
144
+ 4. Write the usage sidecar via `node .forge/tools/store-cli.cjs emit {sprintId} '{sidecar-json}' --sidecar`.
145
145
  5. **NEVER skip sidecar write.** Always emit (reported or placeholder with nulls).
146
146
  - **Event Emission:** Ensure the "complete" event includes the `eventId` passed by the orchestrator.
147
147
  - **Store-Write Verification:** The generated workflow MUST include the "Store-Write
@@ -31,7 +31,7 @@ Update the implementation of a task based on a "Revision Required" verdict from
31
31
 
32
32
  - Address every "Revision Required" item from the review artifact at the correct code location; do not paper over them with comments. If a finding is wrong, escalate rather than ignore.
33
33
  - Read `.forge/personas/engineer.md` first; print the persona identity line (emoji, name, tagline) to stdout before any other tool use.
34
- - All store I/O via `forge_store` (or `node "$FORGE_ROOT/tools/store-cli.cjs"`). Never edit `.forge/store/*.json` directly.
34
+ - All store I/O via `forge_store` (or `node .forge/tools/store-cli.cjs`). Never edit `.forge/store/*.json` directly.
35
35
 
36
36
  ## Store-Write Verification
37
37
 
@@ -55,7 +55,7 @@ Update the implementation of a task based on a "Revision Required" verdict from
55
55
  - Update PROGRESS.md with a summary of the revisions
56
56
 
57
57
  4. Finalize:
58
- - Update task status via `node "$FORGE_ROOT/tools/store-cli.cjs" update-status task {taskId} status implemented`
58
+ - Update task status via `node .forge/tools/store-cli.cjs update-status task {taskId} status implemented`
59
59
  - **Do NOT emit a phase event yourself.** The orchestrator (or kickoff handler) owns event emission — it composes the canonical event from runtime telemetry (model, provider, tokens, wall times) plus the SUMMARY you write in the next step. Subagents that call `store-cli emit` for phase events hallucinate runtime facts (see Plan 11 / Slice 2). Write the SUMMARY and return.
60
60
  ```
61
61
 
@@ -31,7 +31,7 @@ Update the implementation plan of a task based on a "Revision Required" verdict
31
31
 
32
32
  - Address every numbered finding in the review artifact. Do not silently drop items; if a finding is wrong, note the reason in the revised plan rather than ignoring it.
33
33
  - Read `.forge/personas/architect.md` first; print the persona identity line (emoji, name, tagline) to stdout before any other tool use.
34
- - All store I/O via `forge_store` (or `node "$FORGE_ROOT/tools/store-cli.cjs"`). Never edit `.forge/store/*.json` directly.
34
+ - All store I/O via `forge_store` (or `node .forge/tools/store-cli.cjs`). Never edit `.forge/store/*.json` directly.
35
35
 
36
36
  ## Store-Write Verification
37
37
 
@@ -55,7 +55,7 @@ Update the implementation plan of a task based on a "Revision Required" verdict
55
55
  - Update the "Operational Impact" or "Testing Strategy" if the revision changed them
56
56
 
57
57
  4. Finalize:
58
- - Update task status via `node "$FORGE_ROOT/tools/store-cli.cjs" update-status task {taskId} status planned`
58
+ - Update task status via `node .forge/tools/store-cli.cjs update-status task {taskId} status planned`
59
59
  - **Do NOT emit a phase event yourself.** The orchestrator (or kickoff handler) owns event emission — it composes the canonical event from runtime telemetry (model, provider, tokens, wall times) plus the SUMMARY you write in the next step. Subagents that call `store-cli emit` for phase events hallucinate runtime facts (see Plan 11 / Slice 2). Write the SUMMARY and return.
60
60
  ```
61
61
 
@@ -31,7 +31,7 @@ The Supervisor performs a final validation of the implementation against the acc
31
31
 
32
32
  - Validate against the acceptance criteria as written; do not soften, expand, or reinterpret them. The validator's job is to catch what the implementer optimistically considered "done".
33
33
  - Read `.forge/personas/qa-engineer.md` first; print the persona identity line (emoji, name, tagline) to stdout before any other tool use.
34
- - All store I/O via `forge_store` (or `node "$FORGE_ROOT/tools/store-cli.cjs"`). Never edit `.forge/store/*.json` directly.
34
+ - All store I/O via `forge_store` (or `node .forge/tools/store-cli.cjs`). Never edit `.forge/store/*.json` directly.
35
35
 
36
36
  ## Store-Write Verification
37
37
 
@@ -42,9 +42,8 @@ The Supervisor performs a final validation of the implementation against the acc
42
42
  ```
43
43
 
44
44
  0a. Pre-flight Gate Check:
45
- - Resolve FORGE_ROOT (`node -e "console.log(require('./.forge/config.json').paths.forgeRoot)"`).
46
45
  - **Entity-mode resolution:** read the kickoff arguments. `--task {id}` → `entity_kind = "task"`, `record_id = {id}`. `--bug {id}` → `entity_kind = "bug"`, `record_id = {id}`. All store-cli calls below substitute `{entity_kind}` and `{record_id}` for the literal "task"/{taskId} placeholders.
47
- - Run: `node "$FORGE_ROOT/tools/preflight-gate.cjs" --phase validate --{entity_kind} {record_id}`
46
+ - Run: `node .forge/tools/preflight-gate.cjs --phase validate --{entity_kind} {record_id}`
48
47
  - Exit 1 (gate failed) → print stderr and HALT. Do not proceed; do not attempt to produce the artifact.
49
48
  - Exit 2 (misconfiguration) → print stderr and HALT.
50
49
  - Exit 0 → continue.
@@ -53,7 +52,7 @@ The Supervisor performs a final validation of the implementation against the acc
53
52
  - If `--force` is present in the invocation arguments, skip this step entirely.
54
53
  - If `entity_kind == "bug"`, skip this step entirely (bug state is managed by meta-fix-bug.md).
55
54
  - Read current task state:
56
- `node "$FORGE_ROOT/tools/store-cli.cjs" read task {record_id} --json`
55
+ `node .forge/tools/store-cli.cjs read task {record_id} --json`
57
56
  - Extract the `status` field from the JSON output.
58
57
  - Allowed states for this phase: `implemented`, `review-approved`.
59
58
  - If the current status is NOT in the allowed set:
@@ -99,7 +98,7 @@ The Supervisor performs a final validation of the implementation against the acc
99
98
  - See step 1 for iteration header and final-iteration Next Steps requirements.
100
99
 
101
100
  5. Finalize:
102
- - Update task status via `node "$FORGE_ROOT/tools/store-cli.cjs" update-status task {taskId} status review-approved` (if Approved) or `node "$FORGE_ROOT/tools/store-cli.cjs" update-status task {taskId} status code-revision-required` (if Revision Required)
101
+ - Update task status via `node .forge/tools/store-cli.cjs update-status task {taskId} status review-approved` (if Approved) or `node .forge/tools/store-cli.cjs update-status task {taskId} status code-revision-required` (if Revision Required)
103
102
  - **Do NOT emit a phase event yourself.** The orchestrator owns event emission — it composes the canonical event from runtime telemetry (model, provider, tokens, wall times) plus the SUMMARY you write in the next step. Subagents that call `store-cli emit` for phase events hallucinate runtime facts (see Plan 11 / Slice 2). Write the SUMMARY and return.
104
103
 
105
104
  6. Emit Summary Sidecar:
@@ -117,7 +116,7 @@ The Supervisor performs a final validation of the implementation against the acc
117
116
  ```
118
117
  - Call (the sidecar path is auto-resolved from the task record's `path` — never pass it):
119
118
  ```
120
- node "$FORGE_ROOT/tools/store-cli.cjs" set-summary {task_id} validation
119
+ node .forge/tools/store-cli.cjs set-summary {task_id} validation
121
120
  ```
122
121
  - If set-summary exits non-zero, fix the sidecar JSON and retry. Do not proceed without a valid summary.
123
122
  ```
@@ -61,7 +61,7 @@
61
61
  },
62
62
  "paths": {
63
63
  "type": "object",
64
- "required": ["engineering", "store", "forgeRoot"],
64
+ "required": ["engineering", "store"],
65
65
  "properties": {
66
66
  "engineering": { "type": "string", "default": "engineering" },
67
67
  "store": { "type": "string", "default": ".forge/store" },
@@ -69,8 +69,7 @@
69
69
  "commands": { "type": "string", "default": ".claude/commands" },
70
70
  "templates": { "type": "string", "default": ".forge/templates" },
71
71
  "customCommands": { "type": "string", "default": "engineering/commands", "description": "Directory for project-specific custom pipeline phase commands. Files here are workflow scripts invoked directly by the orchestrator via the phase workflow field." },
72
- "forgeRoot": { "type": "string", "description": "Absolute path to the installed Forge plugin root. Set at init time and refreshed by /forge:update. Used by generated workflows to invoke Forge tools without requiring $CLAUDE_PLUGIN_ROOT in subagent contexts." },
73
- "forgeRef": { "type": "string", "description": "Pinned Forge plugin reference (tag or commit) the project was generated against." }
72
+ "forgeRef": { "type": "string", "description": "Pinned Forge plugin reference (tag or commit) the project was generated against. Used to resolve the plugin root via cache lookup." }
74
73
  }
75
74
  },
76
75
  "pipeline": {
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.0.10",
3
- "generated": "2026-05-31",
2
+ "version": "1.2.13",
3
+ "generated": "2026-06-03",
4
4
  "note": "Authoritative enum catalog. Source: build-enum-catalog.cjs. Regenerate via node forge/tools/build-manifest.cjs.",
5
5
  "enums": {
6
6
  "task.status": [
@@ -55,8 +55,10 @@
55
55
  "task-approved",
56
56
  "task-validated",
57
57
  "task-committed",
58
+ "sprint-start",
58
59
  "sprint-complete",
59
60
  "sprint-halted",
61
+ "task-dispatch",
60
62
  "bug-fixed",
61
63
 
62
64
  "bug-triaged", "fix-planned", "fix-review-passed", "fix-review-failed",
@@ -135,6 +137,20 @@
135
137
  },
136
138
  "then": { "required": ["bugId", "phase", "iteration"] }
137
139
  },
140
+ {
141
+ "if": { "properties": { "type": { "const": "sprint-start" } }, "required": ["type"] },
142
+ "then": {
143
+ "required": [
144
+ "eventId", "sprintId", "role", "action",
145
+ "startTimestamp", "endTimestamp", "durationMinutes",
146
+ "model", "provider",
147
+ "taskCount"
148
+ ],
149
+ "properties": {
150
+ "taskCount": { "type": "integer", "minimum": 0 }
151
+ }
152
+ }
153
+ },
138
154
  {
139
155
  "if": { "properties": { "type": { "const": "sprint-complete" } }, "required": ["type"] },
140
156
  "then": {
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.0.10",
3
- "generatedAt": "2026-05-31T03:19:45.318Z",
2
+ "version": "1.2.13",
3
+ "generatedAt": "2026-06-03T05:20:45.625Z",
4
4
  "generatedByTool": "build-manifest.cjs",
5
5
  "namespaces": {
6
6
  "personas": {
@@ -38,15 +38,12 @@
38
38
  "architect_sprint_plan.md",
39
39
  "collator_agent.md",
40
40
  "commit_task.md",
41
- "fix_bug.md",
42
41
  "implement_plan.md",
43
42
  "migrate_structural.md",
44
- "orchestrate_task.md",
45
43
  "plan_task.md",
46
44
  "quiz_agent.md",
47
45
  "review_code.md",
48
46
  "review_plan.md",
49
- "run_sprint.md",
50
47
  "sprint_retrospective.md",
51
48
  "triage.md",
52
49
  "update_implementation.md",
@@ -106,6 +103,15 @@
106
103
  "store-write-verification.md"
107
104
  ]
108
105
  },
106
+ "workflows-js": {
107
+ "logicalKey": "workflows-js",
108
+ "dir": ".claude/workflows",
109
+ "files": [
110
+ "wfl-fix-bug.js",
111
+ "wfl-run-sprint.js",
112
+ "wfl-run-task.js"
113
+ ]
114
+ },
109
115
  "schemas": {
110
116
  "logicalKey": "schemas",
111
117
  "dir": ".forge/schemas",
@@ -126,6 +132,70 @@
126
132
  "structure-versions.schema.json",
127
133
  "task.schema.json"
128
134
  ]
135
+ },
136
+ "tools": {
137
+ "logicalKey": "tools",
138
+ "dir": ".forge/tools",
139
+ "files": [
140
+ "artifact-store.cjs",
141
+ "artifact.cjs",
142
+ "backfill-provider.cjs",
143
+ "banners.cjs",
144
+ "build-base-pack.cjs",
145
+ "build-context-pack.cjs",
146
+ "build-enum-catalog.cjs",
147
+ "build-init-context.cjs",
148
+ "build-manifest.cjs",
149
+ "build-overlay.cjs",
150
+ "build-persona-pack.cjs",
151
+ "check-no-skipped-tests.cjs",
152
+ "check-structure.cjs",
153
+ "collate.cjs",
154
+ "compression-gate.cjs",
155
+ "delete-candidate-detector.cjs",
156
+ "estimate-usage.cjs",
157
+ "forge-preflight.cjs",
158
+ "friction-emit.cjs",
159
+ "gen-integrity.cjs",
160
+ "generation-manifest.cjs",
161
+ "judge-proposal.cjs",
162
+ "manage-config.cjs",
163
+ "manage-versions.cjs",
164
+ "migrate-slug-maxlen.cjs",
165
+ "parse-gates.cjs",
166
+ "postflight-gate.cjs",
167
+ "preflight-gate.cjs",
168
+ "proposal-normalize.cjs",
169
+ "query-logger.cjs",
170
+ "queue-drain.cjs",
171
+ "read-verdict.cjs",
172
+ "replay-scoring.cjs",
173
+ "rewrite-plugin-urls.cjs",
174
+ "seed-store.cjs",
175
+ "store-cli.cjs",
176
+ "store-query.cjs",
177
+ "store.cjs",
178
+ "substitute-placeholders.cjs",
179
+ "token-forensics.cjs",
180
+ "validate-store.cjs",
181
+ "verify-apply.cjs",
182
+ "verify-integrity.cjs",
183
+ "verify-phase.cjs",
184
+ "lib/artifact-kinds.cjs",
185
+ "lib/forge-root.cjs",
186
+ "lib/frontmatter.cjs",
187
+ "lib/fsutil.cjs",
188
+ "lib/json-io.cjs",
189
+ "lib/paths.cjs",
190
+ "lib/pricing.cjs",
191
+ "lib/project-root.cjs",
192
+ "lib/schema-loader.cjs",
193
+ "lib/slug.cjs",
194
+ "lib/store-facade.cjs",
195
+ "lib/store-nlp.cjs",
196
+ "lib/store-query-exec.cjs",
197
+ "lib/suggest.cjs"
198
+ ]
129
199
  }
130
200
  },
131
201
  "edges": {
@@ -200,41 +270,6 @@
200
270
  "paths.engineering"
201
271
  ]
202
272
  },
203
- "fix_bug": {
204
- "personas": [
205
- ".forge/personas/bug-fixer.md",
206
- ".forge/personas/supervisor.md",
207
- ".forge/personas/architect.md",
208
- ".forge/personas/engineer.md",
209
- ".forge/personas/collator.md"
210
- ],
211
- "skills": [
212
- ".forge/skills/bug-fixer-skills.md",
213
- ".forge/skills/supervisor-skills.md",
214
- ".forge/skills/architect-skills.md",
215
- ".forge/skills/engineer-skills.md",
216
- ".forge/skills/generic-skills.md"
217
- ],
218
- "templates": [
219
- ".forge/templates/PROGRESS_TEMPLATE.md"
220
- ],
221
- "sub_workflows": [
222
- ".forge/workflows/plan_task.md",
223
- ".forge/workflows/implement_plan.md",
224
- ".forge/workflows/review_plan.md",
225
- ".forge/workflows/review_code.md",
226
- ".forge/workflows/architect_approve.md",
227
- ".forge/workflows/commit_task.md"
228
- ],
229
- "kb_docs": [
230
- "{KB_PATH}/architecture/stack.md",
231
- "{KB_PATH}/architecture/routing.md"
232
- ],
233
- "config_fields": [
234
- "commands.test",
235
- "paths.engineering"
236
- ]
237
- },
238
273
  "implement_plan": {
239
274
  "personas": [
240
275
  ".forge/personas/engineer.md"
@@ -258,39 +293,6 @@
258
293
  "paths.engineering"
259
294
  ]
260
295
  },
261
- "orchestrate_task": {
262
- "personas": [
263
- ".forge/personas/architect.md",
264
- ".forge/personas/engineer.md",
265
- ".forge/personas/supervisor.md",
266
- ".forge/personas/bug-fixer.md",
267
- ".forge/personas/collator.md",
268
- ".forge/personas/qa-engineer.md"
269
- ],
270
- "skills": [
271
- ".forge/skills/architect-skills.md",
272
- ".forge/skills/engineer-skills.md",
273
- ".forge/skills/supervisor-skills.md",
274
- ".forge/skills/generic-skills.md"
275
- ],
276
- "templates": [],
277
- "sub_workflows": [
278
- ".forge/workflows/plan_task.md",
279
- ".forge/workflows/implement_plan.md",
280
- ".forge/workflows/review_plan.md",
281
- ".forge/workflows/review_code.md",
282
- ".forge/workflows/fix_bug.md",
283
- ".forge/workflows/architect_approve.md",
284
- ".forge/workflows/commit_task.md",
285
- ".forge/workflows/validate_task.md"
286
- ],
287
- "kb_docs": [
288
- "{KB_PATH}/architecture/stack.md"
289
- ],
290
- "config_fields": [
291
- "paths.engineering"
292
- ]
293
- },
294
296
  "plan_task": {
295
297
  "personas": [
296
298
  ".forge/personas/architect.md"
@@ -89,14 +89,21 @@ Personas live in `.forge/personas/`.
89
89
 
90
90
  Only include rows for workflow files that actually exist on disk. Check each:
91
91
 
92
+ Atomic workflows (LLM-generated markdown in `.forge/workflows/`):
93
+
92
94
  - `.forge/workflows/plan_task.md` → "Research codebase → implementation plan"
93
95
  - `.forge/workflows/implement_plan.md` → "Execute approved plan → code changes"
94
- - `.forge/workflows/fix_bug.md` → "Triage → fix → verify"
95
- - `.forge/workflows/orchestrate_task.md` → "Full task pipeline (plan → implement → review → commit)"
96
- - `.forge/workflows/run_sprint.md` → "Full sprint orchestration"
97
96
  - `.forge/workflows/architect_sprint_plan.md` → "Sprint planning and task decomposition"
98
97
  - `.forge/workflows/architect_sprint_intake.md` → "Sprint intake and requirements elicitation"
99
98
 
99
+ Orchestration is deterministic JS, not prose. The LLM orchestration workflows
100
+ (`orchestrate_task` / `run_sprint` / `fix_bug`) are **retired** — link the JS
101
+ drivers in `.claude/workflows/` instead (only include rows where the file exists):
102
+
103
+ - `.claude/workflows/wfl-run-task.js` → "Full task pipeline (plan → implement → review → approve → commit)"
104
+ - `.claude/workflows/wfl-run-sprint.js` → "Full sprint orchestration"
105
+ - `.claude/workflows/wfl-fix-bug.js` → "Triage → fix → verify"
106
+
100
107
  ```markdown
101
108
  <!-- forge-workflow-links: managed by Forge — do not edit manually -->
102
109
  ## Forge Workflows
@@ -105,13 +112,13 @@ Only include rows for workflow files that actually exist on disk. Check each:
105
112
  |----------|---------|
106
113
  | [Plan](.forge/workflows/plan_task.md) | Research codebase → implementation plan |
107
114
  | [Implement](.forge/workflows/implement_plan.md) | Execute approved plan → code changes |
108
- | [Fix bug](.forge/workflows/fix_bug.md) | Triagefixverify |
109
- | [Run task](.forge/workflows/orchestrate_task.md) | Full task pipeline (plan → implement → review → commit) |
110
- | [Run sprint](.forge/workflows/run_sprint.md) | Full sprint orchestration |
115
+ | [Run task](.claude/workflows/wfl-run-task.js) | Full task pipeline (plan implementreview → approve → commit) |
116
+ | [Run sprint](.claude/workflows/wfl-run-sprint.js) | Full sprint orchestration |
117
+ | [Fix bug](.claude/workflows/wfl-fix-bug.js) | Triage fix → verify |
111
118
  <!-- /forge-workflow-links -->
112
119
  ```
113
120
 
114
- (Only include rows where the referenced `.forge/workflows/` file exists on disk.)
121
+ (Only include rows where the referenced file exists on disk.)
115
122
 
116
123
  ## KB Integrity Check
117
124
 
@@ -32,6 +32,7 @@
32
32
  // node banners.cjs --subtitle "Forging your SDLC"
33
33
  // node banners.cjs --progress 5 12 "Templates"
34
34
  // node banners.cjs --phase 7 12 "Workflows" ember
35
+ // node banners.cjs --badge forge --quiet (automated/orchestrator use: zero stdout)
35
36
 
36
37
  // ─── Plain-mode detection ─────────────────────────────────────────────────────
37
38
  // Resolved at call-time so tests can flip env vars dynamically.
@@ -51,6 +52,12 @@ function stripAnsi(s) {
51
52
  // Soft override — set by `--plain` CLI flag to force plain mode for one run.
52
53
  let FORCE_PLAIN = false;
53
54
 
55
+ // Quiet mode — set by `--quiet` CLI flag to suppress all stdout output.
56
+ // Used by the orchestrator loop so banner output does not enter the LLM context
57
+ // window (output remains visible on a real TTY via the human's terminal but is
58
+ // not fed back as tool-call response text).
59
+ let QUIET_MODE = false;
60
+
54
61
  // ─── ANSI helpers ─────────────────────────────────────────────────────────────
55
62
  const R = '\x1b[0m';
56
63
  const B = '\x1b[1m';
@@ -376,6 +383,7 @@ function _maybePlain(s) {
376
383
 
377
384
  // ─── CLI ───────────────────────────────────────────────────────────────────────
378
385
  // node banners.cjs [<name>] [--gallery] [--badge <name>] [--mark <name>] [--list]
386
+ // node banners.cjs --badge <name> --quiet (suppress all stdout; orchestrator use)
379
387
 
380
388
  if (require.main === module) {
381
389
  let args = process.argv.slice(2);
@@ -387,38 +395,49 @@ if (require.main === module) {
387
395
  args = args.slice(0, plainIdx).concat(args.slice(plainIdx + 1));
388
396
  }
389
397
 
398
+ // --quiet may appear anywhere; consume it before dispatch.
399
+ // When set, all stdout is suppressed (exit 0 still guaranteed on success).
400
+ const quietIdx = args.indexOf('--quiet');
401
+ if (quietIdx !== -1) {
402
+ QUIET_MODE = true;
403
+ args = args.slice(0, quietIdx).concat(args.slice(quietIdx + 1));
404
+ }
405
+
406
+ // Helper: write to stdout only when not in quiet mode.
407
+ const emit = (s) => { if (!QUIET_MODE) process.stdout.write(s); };
408
+
390
409
  try {
391
410
  if (!args.length || args[0] === '--gallery') {
392
- process.stdout.write(gallery() + '\n');
411
+ emit(gallery() + '\n');
393
412
  } else if (args[0] === '--list') {
394
- console.log(list().map(n => {
413
+ emit(list().map(n => {
395
414
  const b = BANNERS[n];
396
415
  return `${b.emoji} ${n.padEnd(8)} — ${b.tagline}`;
397
- }).join('\n'));
416
+ }).join('\n') + '\n');
398
417
  } else if (args[0] === '--badge') {
399
- console.log(badge(args[1] || ''));
418
+ emit(badge(args[1] || '') + '\n');
400
419
  } else if (args[0] === '--mark') {
401
- console.log(mark(args[1] || ''));
420
+ emit(mark(args[1] || '') + '\n');
402
421
  } else if (args[0] === '--subtitle') {
403
- console.log(subtitle(args.slice(1).join(' ')));
422
+ emit(subtitle(args.slice(1).join(' ')) + '\n');
404
423
  } else if (args[0] === '--progress') {
405
424
  const n = Number(args[1]);
406
425
  const total = Number(args[2]);
407
426
  const label = args.slice(3).join(' ') || undefined;
408
- console.log(progressBar(n, total, { label }));
427
+ emit(progressBar(n, total, { label }) + '\n');
409
428
  } else if (args[0] === '--phase') {
410
429
  const n = Number(args[1]);
411
430
  const total = Number(args[2]);
412
431
  const name = args[3] || '';
413
432
  const bannerKey = args[4] || 'forge';
414
433
  const mode = args[5]; // optional 'fast' | 'full'
415
- console.log(phaseHeader(n, total, name, bannerKey, mode ? { mode } : undefined));
434
+ emit(phaseHeader(n, total, name, bannerKey, mode ? { mode } : undefined) + '\n');
416
435
  } else if (args[0] === '--rule') {
417
436
  // --rule [text] Zen-blue em-dash horizontal rule (with optional label)
418
437
  const text = args.slice(1).join(' ') || undefined;
419
- console.log(ruleLine(text));
438
+ emit(ruleLine(text) + '\n');
420
439
  } else {
421
- process.stdout.write(render(args[0]) + '\n');
440
+ emit(render(args[0]) + '\n');
422
441
  }
423
442
  } catch (e) {
424
443
  console.error(e.message);