@entelligentsia/forgecli 1.0.3 β†’ 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 (497) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/README.md +2 -1
  3. package/dist/CHANGELOG-forge-plugin.md +250 -0
  4. package/dist/CHANGELOG-pi.md +94 -0
  5. package/dist/bin/forge.js +0 -0
  6. package/dist/extensions/forgecli/config-layer.d.ts +16 -0
  7. package/dist/extensions/forgecli/config-layer.js +5 -0
  8. package/dist/extensions/forgecli/config-layer.js.map +1 -1
  9. package/dist/extensions/forgecli/dashboard/component.d.ts +102 -0
  10. package/dist/extensions/forgecli/dashboard/component.js +882 -0
  11. package/dist/extensions/forgecli/dashboard/component.js.map +1 -0
  12. package/dist/extensions/forgecli/dashboard/register.d.ts +2 -0
  13. package/dist/extensions/forgecli/dashboard/register.js +45 -0
  14. package/dist/extensions/forgecli/dashboard/register.js.map +1 -0
  15. package/dist/extensions/forgecli/dashboard/view-model.d.ts +35 -0
  16. package/dist/extensions/forgecli/dashboard/view-model.js +54 -0
  17. package/dist/extensions/forgecli/dashboard/view-model.js.map +1 -0
  18. package/dist/extensions/forgecli/fix-bug.js +72 -7
  19. package/dist/extensions/forgecli/fix-bug.js.map +1 -1
  20. package/dist/extensions/forgecli/forge-artifact-tool.js +27 -4
  21. package/dist/extensions/forgecli/forge-artifact-tool.js.map +1 -1
  22. package/dist/extensions/forgecli/forge-cli-schema.json +4 -0
  23. package/dist/extensions/forgecli/forge-commands.js +1 -0
  24. package/dist/extensions/forgecli/forge-commands.js.map +1 -1
  25. package/dist/extensions/forgecli/forge-init/phase4-register.js +53 -0
  26. package/dist/extensions/forgecli/forge-init/phase4-register.js.map +1 -1
  27. package/dist/extensions/forgecli/forge-subagent.js +6 -4
  28. package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
  29. package/dist/extensions/forgecli/forge-tools.js +2 -2
  30. package/dist/extensions/forgecli/forge-tools.js.map +1 -1
  31. package/dist/extensions/forgecli/index.js +5 -0
  32. package/dist/extensions/forgecli/index.js.map +1 -1
  33. package/dist/extensions/forgecli/lib/halt-advisor.d.ts +54 -0
  34. package/dist/extensions/forgecli/lib/halt-advisor.js +90 -0
  35. package/dist/extensions/forgecli/lib/halt-advisor.js.map +1 -0
  36. package/dist/extensions/forgecli/migration-engine.js +25 -12
  37. package/dist/extensions/forgecli/migration-engine.js.map +1 -1
  38. package/dist/extensions/forgecli/orchestrator-status-bar.d.ts +25 -0
  39. package/dist/extensions/forgecli/orchestrator-status-bar.js +183 -0
  40. package/dist/extensions/forgecli/orchestrator-status-bar.js.map +1 -0
  41. package/dist/extensions/forgecli/orchestrator-tree.d.ts +96 -0
  42. package/dist/extensions/forgecli/orchestrator-tree.js +390 -0
  43. package/dist/extensions/forgecli/orchestrator-tree.js.map +1 -0
  44. package/dist/extensions/forgecli/project-orientation.js +12 -8
  45. package/dist/extensions/forgecli/project-orientation.js.map +1 -1
  46. package/dist/extensions/forgecli/regenerate.d.ts +16 -0
  47. package/dist/extensions/forgecli/regenerate.js +110 -0
  48. package/dist/extensions/forgecli/regenerate.js.map +1 -1
  49. package/dist/extensions/forgecli/run-sprint.js +33 -3
  50. package/dist/extensions/forgecli/run-sprint.js.map +1 -1
  51. package/dist/extensions/forgecli/run-task.d.ts +32 -0
  52. package/dist/extensions/forgecli/run-task.js +185 -12
  53. package/dist/extensions/forgecli/run-task.js.map +1 -1
  54. package/dist/extensions/forgecli/subagent/phase-guard.js +15 -5
  55. package/dist/extensions/forgecli/subagent/phase-guard.js.map +1 -1
  56. package/dist/extensions/forgecli/subagent/phase-summary-map.d.ts +1 -0
  57. package/dist/extensions/forgecli/subagent/phase-summary-map.js +17 -0
  58. package/dist/extensions/forgecli/subagent/phase-summary-map.js.map +1 -1
  59. package/dist/extensions/forgecli/thread-switcher.js +105 -764
  60. package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
  61. package/dist/extensions/forgecli/viewport-events.js +32 -0
  62. package/dist/extensions/forgecli/viewport-events.js.map +1 -1
  63. package/dist/forge-payload/.base-pack/commands/fix-bug.md +1 -1
  64. package/dist/forge-payload/.base-pack/commands/run-sprint.md +1 -1
  65. package/dist/forge-payload/.base-pack/commands/run-task.md +1 -1
  66. package/dist/forge-payload/.base-pack/personas/architect.md +1 -1
  67. package/dist/forge-payload/.base-pack/personas/bug-fixer.md +1 -1
  68. package/dist/forge-payload/.base-pack/personas/collator.md +3 -3
  69. package/dist/forge-payload/.base-pack/personas/engineer.md +1 -1
  70. package/dist/forge-payload/.base-pack/personas/librarian.md +1 -1
  71. package/dist/forge-payload/.base-pack/personas/orchestrator.md +1 -1
  72. package/dist/forge-payload/.base-pack/personas/product-manager.md +1 -1
  73. package/dist/forge-payload/.base-pack/personas/qa-engineer.md +1 -1
  74. package/dist/forge-payload/.base-pack/personas/supervisor.md +1 -1
  75. package/dist/forge-payload/.base-pack/workflows/_fragments/event-emission-schema.md +1 -1
  76. package/dist/forge-payload/.base-pack/workflows/_fragments/friction-emit.md +1 -1
  77. package/dist/forge-payload/.base-pack/workflows/_fragments/iron-laws.md +1 -1
  78. package/dist/forge-payload/.base-pack/workflows/_fragments/progress-reporting.md +2 -2
  79. package/dist/forge-payload/.base-pack/workflows/_fragments/store-cli-verbs.md +29 -5
  80. package/dist/forge-payload/.base-pack/workflows/architect_approve.md +8 -10
  81. package/dist/forge-payload/.base-pack/workflows/architect_review_sprint_completion.md +2 -2
  82. package/dist/forge-payload/.base-pack/workflows/architect_sprint_intake.md +2 -2
  83. package/dist/forge-payload/.base-pack/workflows/architect_sprint_plan.md +5 -5
  84. package/dist/forge-payload/.base-pack/workflows/collator_agent.md +5 -7
  85. package/dist/forge-payload/.base-pack/workflows/commit_task.md +7 -9
  86. package/dist/forge-payload/.base-pack/workflows/enhance.md +5 -5
  87. package/dist/forge-payload/.base-pack/workflows/implement_plan.md +9 -9
  88. package/dist/forge-payload/.base-pack/workflows/migrate_structural.md +12 -13
  89. package/dist/forge-payload/.base-pack/workflows/plan_task.md +5 -6
  90. package/dist/forge-payload/.base-pack/workflows/review_code.md +8 -8
  91. package/dist/forge-payload/.base-pack/workflows/review_plan.md +8 -8
  92. package/dist/forge-payload/.base-pack/workflows/sprint_retrospective.md +3 -3
  93. package/dist/forge-payload/.base-pack/workflows/triage.md +13 -10
  94. package/dist/forge-payload/.base-pack/workflows/update_implementation.md +2 -2
  95. package/dist/forge-payload/.base-pack/workflows/update_plan.md +2 -2
  96. package/dist/forge-payload/.base-pack/workflows/validate_task.md +6 -8
  97. package/dist/forge-payload/.base-pack/workflows-js/wfl-fix-bug.js +490 -0
  98. package/dist/forge-payload/.base-pack/workflows-js/wfl-run-sprint.js +416 -0
  99. package/dist/forge-payload/.base-pack/workflows-js/wfl-run-task.js +608 -0
  100. package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
  101. package/dist/forge-payload/.schemas/_defs/locator.schema.json +13 -0
  102. package/dist/forge-payload/.schemas/bug.schema.json +1 -0
  103. package/dist/forge-payload/.schemas/config.schema.json +2 -3
  104. package/dist/forge-payload/.schemas/enum-catalog.json +2 -2
  105. package/dist/forge-payload/.schemas/event.schema.json +16 -0
  106. package/dist/forge-payload/.schemas/migrations.json +299 -0
  107. package/dist/forge-payload/.schemas/sprint.schema.json +1 -0
  108. package/dist/forge-payload/.schemas/task.schema.json +1 -0
  109. package/dist/forge-payload/commands/health.md +29 -0
  110. package/dist/forge-payload/commands/rebuild.md +143 -15
  111. package/dist/forge-payload/commands/update.md +28 -27
  112. package/dist/forge-payload/hooks/preflight-session.cjs +99 -0
  113. package/dist/forge-payload/init/phases/phase-3-materialize.md +18 -5
  114. package/dist/forge-payload/integrity.json +7 -6
  115. package/dist/forge-payload/meta/fragments/tool-discipline.md +1 -1
  116. package/dist/forge-payload/meta/personas/meta-architect.md +1 -1
  117. package/dist/forge-payload/meta/personas/meta-bug-fixer.md +1 -1
  118. package/dist/forge-payload/meta/personas/meta-collator.md +7 -7
  119. package/dist/forge-payload/meta/personas/meta-engineer.md +1 -1
  120. package/dist/forge-payload/meta/personas/meta-orchestrator.md +1 -1
  121. package/dist/forge-payload/meta/personas/meta-supervisor.md +1 -1
  122. package/dist/forge-payload/meta/tool-specs/store-cli.spec.md +1 -1
  123. package/dist/forge-payload/meta/workflows/_fragments/event-emission-schema.md +1 -1
  124. package/dist/forge-payload/meta/workflows/_fragments/friction-emit.md +1 -1
  125. package/dist/forge-payload/meta/workflows/_fragments/iron-laws.md +1 -1
  126. package/dist/forge-payload/meta/workflows/_fragments/progress-reporting.md +2 -2
  127. package/dist/forge-payload/meta/workflows/_fragments/store-cli-verbs.md +29 -5
  128. package/dist/forge-payload/meta/workflows/meta-approve.md +8 -10
  129. package/dist/forge-payload/meta/workflows/meta-bug-triage.md +13 -10
  130. package/dist/forge-payload/meta/workflows/meta-collate.md +6 -8
  131. package/dist/forge-payload/meta/workflows/meta-commit.md +7 -9
  132. package/dist/forge-payload/meta/workflows/meta-enhance.md +5 -5
  133. package/dist/forge-payload/meta/workflows/meta-fix-bug.md +35 -11
  134. package/dist/forge-payload/meta/workflows/meta-implement.md +18 -9
  135. package/dist/forge-payload/meta/workflows/meta-migrate.md +13 -14
  136. package/dist/forge-payload/meta/workflows/meta-new-sprint.md +3 -3
  137. package/dist/forge-payload/meta/workflows/meta-orchestrate.md +175 -82
  138. package/dist/forge-payload/meta/workflows/meta-plan-sprint.md +6 -6
  139. package/dist/forge-payload/meta/workflows/meta-plan-task.md +12 -6
  140. package/dist/forge-payload/meta/workflows/meta-retro.md +4 -4
  141. package/dist/forge-payload/meta/workflows/meta-retrospective.md +4 -4
  142. package/dist/forge-payload/meta/workflows/meta-review-implementation.md +8 -8
  143. package/dist/forge-payload/meta/workflows/meta-review-plan.md +8 -8
  144. package/dist/forge-payload/meta/workflows/meta-review-sprint-completion.md +3 -3
  145. package/dist/forge-payload/meta/workflows/meta-sprint-intake.md +3 -3
  146. package/dist/forge-payload/meta/workflows/meta-sprint-plan.md +6 -6
  147. package/dist/forge-payload/meta/workflows/meta-update-implementation.md +2 -2
  148. package/dist/forge-payload/meta/workflows/meta-update-plan.md +2 -2
  149. package/dist/forge-payload/meta/workflows/meta-validate.md +6 -8
  150. package/dist/forge-payload/schemas/_defs/locator.schema.json +13 -0
  151. package/dist/forge-payload/schemas/bug.schema.json +1 -0
  152. package/dist/forge-payload/schemas/config.schema.json +2 -3
  153. package/dist/forge-payload/schemas/enum-catalog.json +2 -2
  154. package/dist/forge-payload/schemas/event.schema.json +16 -0
  155. package/dist/forge-payload/schemas/sprint.schema.json +1 -0
  156. package/dist/forge-payload/schemas/structure-manifest.json +76 -73
  157. package/dist/forge-payload/schemas/task.schema.json +1 -0
  158. package/dist/forge-payload/skills/refresh-kb-links/SKILL.md +14 -7
  159. package/dist/forge-payload/tools/artifact-store.cjs +242 -0
  160. package/dist/forge-payload/tools/artifact.cjs +60 -120
  161. package/dist/forge-payload/tools/banners.cjs +29 -10
  162. package/dist/forge-payload/tools/check-structure.cjs +88 -7
  163. package/dist/forge-payload/tools/collate.cjs +16 -2
  164. package/dist/forge-payload/tools/lib/artifact-kinds.cjs +95 -0
  165. package/dist/forge-payload/tools/lib/store-nlp.cjs +6 -0
  166. package/dist/forge-payload/tools/lib/store-query-exec.cjs +39 -5
  167. package/dist/forge-payload/tools/lib/suggest.cjs +2 -1
  168. package/dist/forge-payload/tools/manage-config.cjs +5 -7
  169. package/dist/forge-payload/tools/parse-gates.cjs +73 -1
  170. package/dist/forge-payload/tools/postflight-gate.cjs +252 -0
  171. package/dist/forge-payload/tools/preflight-gate.cjs +102 -5
  172. package/dist/forge-payload/tools/store-cli.cjs +50 -15
  173. package/dist/forge-payload/tools/substitute-placeholders.cjs +5 -4
  174. package/dist/forge-payload/tools/verify-phase.cjs +17 -0
  175. package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.d.ts +5 -2
  176. package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.d.ts.map +1 -1
  177. package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.js +81 -18
  178. package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
  179. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
  180. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/branch-summarization.js +1 -0
  181. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/branch-summarization.js.map +1 -1
  182. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.d.ts.map +1 -1
  183. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js +19 -24
  184. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js.map +1 -1
  185. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.d.ts +1 -0
  186. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.d.ts.map +1 -1
  187. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.js +14 -1
  188. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.js.map +1 -1
  189. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts +22 -8
  190. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts.map +1 -1
  191. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js.map +1 -1
  192. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  193. package/node_modules/@earendil-works/pi-ai/README.md +1 -1
  194. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +374 -122
  195. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  196. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +424 -232
  197. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
  198. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts +1 -1
  199. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  200. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +38 -2
  201. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  202. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  203. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +21 -12
  204. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
  205. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  206. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js +6 -10
  207. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  208. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.d.ts.map +1 -1
  209. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js +1 -1
  210. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js.map +1 -1
  211. package/node_modules/@earendil-works/pi-ai/dist/providers/google.d.ts.map +1 -1
  212. package/node_modules/@earendil-works/pi-ai/dist/providers/google.js +5 -3
  213. package/node_modules/@earendil-works/pi-ai/dist/providers/google.js.map +1 -1
  214. package/node_modules/@earendil-works/pi-ai/dist/providers/images/openrouter.d.ts.map +1 -1
  215. package/node_modules/@earendil-works/pi-ai/dist/providers/images/openrouter.js +3 -4
  216. package/node_modules/@earendil-works/pi-ai/dist/providers/images/openrouter.js.map +1 -1
  217. package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.d.ts.map +1 -1
  218. package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.js +2 -3
  219. package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.js.map +1 -1
  220. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  221. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +159 -78
  222. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  223. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  224. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +16 -11
  225. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js.map +1 -1
  226. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.d.ts.map +1 -1
  227. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js +4 -1
  228. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js.map +1 -1
  229. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  230. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js +6 -10
  231. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js.map +1 -1
  232. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  233. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js +1 -0
  234. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js.map +1 -1
  235. package/node_modules/@earendil-works/pi-ai/dist/stream.d.ts.map +1 -1
  236. package/node_modules/@earendil-works/pi-ai/dist/stream.js +14 -2
  237. package/node_modules/@earendil-works/pi-ai/dist/stream.js.map +1 -1
  238. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +14 -4
  239. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  240. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  241. package/node_modules/@earendil-works/pi-ai/dist/utils/abort-signals.d.ts +6 -0
  242. package/node_modules/@earendil-works/pi-ai/dist/utils/abort-signals.d.ts.map +1 -0
  243. package/node_modules/@earendil-works/pi-ai/dist/utils/abort-signals.js +34 -0
  244. package/node_modules/@earendil-works/pi-ai/dist/utils/abort-signals.js.map +1 -0
  245. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.d.ts +9 -7
  246. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.d.ts.map +1 -1
  247. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.js +8 -7
  248. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.js.map +1 -1
  249. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  250. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.js +1 -1
  251. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  252. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.d.ts +1 -1
  253. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.d.ts.map +1 -1
  254. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.js +1 -1
  255. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.js.map +1 -1
  256. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.d.ts +10 -1
  257. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.d.ts.map +1 -1
  258. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js +179 -79
  259. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js.map +1 -1
  260. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  261. package/node_modules/@earendil-works/pi-coding-agent/CHANGELOG.md +94 -0
  262. package/node_modules/@earendil-works/pi-coding-agent/README.md +9 -0
  263. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.d.ts +3 -0
  264. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
  265. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.js +27 -0
  266. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.js.map +1 -1
  267. package/node_modules/@earendil-works/pi-coding-agent/dist/config.d.ts.map +1 -1
  268. package/node_modules/@earendil-works/pi-coding-agent/dist/config.js +15 -2
  269. package/node_modules/@earendil-works/pi-coding-agent/dist/config.js.map +1 -1
  270. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.d.ts +1 -0
  271. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.d.ts.map +1 -1
  272. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.js +1 -0
  273. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.js.map +1 -1
  274. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.d.ts +5 -1
  275. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  276. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js +28 -4
  277. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  278. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  279. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.js +18 -24
  280. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  281. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.d.ts +1 -1
  282. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  283. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.js +8 -2
  284. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  285. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/types.d.ts +7 -5
  286. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  287. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  288. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  289. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.js +65 -13
  290. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  291. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  292. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.js +1 -1
  293. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  294. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resolve-config-value.d.ts +9 -1
  295. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resolve-config-value.d.ts.map +1 -1
  296. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resolve-config-value.js +134 -11
  297. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resolve-config-value.js.map +1 -1
  298. package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.d.ts +2 -0
  299. package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  300. package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.js +10 -6
  301. package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.js.map +1 -1
  302. package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.d.ts +6 -7
  303. package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  304. package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.js +75 -28
  305. package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  306. package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.d.ts +2 -0
  307. package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  308. package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js +14 -9
  309. package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  310. package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  311. package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js +0 -3
  312. package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  313. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  314. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit.js +7 -10
  315. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  316. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
  317. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/find.js.map +1 -1
  318. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
  319. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
  320. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
  321. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.js +5 -7
  322. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
  323. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  324. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.js +6 -7
  325. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  326. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/render-utils.d.ts +5 -2
  327. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/render-utils.d.ts.map +1 -1
  328. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/render-utils.js +17 -1
  329. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/render-utils.js.map +1 -1
  330. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  331. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.js +5 -6
  332. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  333. package/node_modules/@earendil-works/pi-coding-agent/dist/index.d.ts +2 -0
  334. package/node_modules/@earendil-works/pi-coding-agent/dist/index.d.ts.map +1 -1
  335. package/node_modules/@earendil-works/pi-coding-agent/dist/index.js +2 -0
  336. package/node_modules/@earendil-works/pi-coding-agent/dist/index.js.map +1 -1
  337. package/node_modules/@earendil-works/pi-coding-agent/dist/main.d.ts.map +1 -1
  338. package/node_modules/@earendil-works/pi-coding-agent/dist/main.js +69 -16
  339. package/node_modules/@earendil-works/pi-coding-agent/dist/main.js.map +1 -1
  340. package/node_modules/@earendil-works/pi-coding-agent/dist/migrations.d.ts.map +1 -1
  341. package/node_modules/@earendil-works/pi-coding-agent/dist/migrations.js +118 -1
  342. package/node_modules/@earendil-works/pi-coding-agent/dist/migrations.js.map +1 -1
  343. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts +1 -3
  344. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  345. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +2 -4
  346. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  347. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  348. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/user-message.js +1 -1
  349. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  350. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +3 -0
  351. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  352. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js +59 -6
  353. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  354. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  355. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.js +10 -0
  356. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  357. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  358. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-mode.js +3 -1
  359. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  360. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +1 -0
  361. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  362. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
  363. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/deprecation.d.ts +4 -0
  364. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/deprecation.d.ts.map +1 -0
  365. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/deprecation.js +13 -0
  366. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/deprecation.js.map +1 -0
  367. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/json.d.ts +3 -0
  368. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/json.d.ts.map +1 -0
  369. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/json.js +7 -0
  370. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/json.js.map +1 -0
  371. package/node_modules/@earendil-works/pi-coding-agent/docs/custom-provider.md +13 -10
  372. package/node_modules/@earendil-works/pi-coding-agent/docs/development.md +1 -1
  373. package/node_modules/@earendil-works/pi-coding-agent/docs/extensions.md +12 -6
  374. package/node_modules/@earendil-works/pi-coding-agent/docs/models.md +25 -12
  375. package/node_modules/@earendil-works/pi-coding-agent/docs/providers.md +13 -5
  376. package/node_modules/@earendil-works/pi-coding-agent/docs/quickstart.md +1 -0
  377. package/node_modules/@earendil-works/pi-coding-agent/docs/rpc.md +2 -1
  378. package/node_modules/@earendil-works/pi-coding-agent/docs/sdk.md +6 -0
  379. package/node_modules/@earendil-works/pi-coding-agent/docs/session-format.md +1 -1
  380. package/node_modules/@earendil-works/pi-coding-agent/docs/sessions.md +8 -0
  381. package/node_modules/@earendil-works/pi-coding-agent/docs/settings.md +7 -3
  382. package/node_modules/@earendil-works/pi-coding-agent/docs/terminal-setup.md +2 -0
  383. package/node_modules/@earendil-works/pi-coding-agent/docs/tui.md +2 -2
  384. package/node_modules/@earendil-works/pi-coding-agent/docs/usage.md +9 -0
  385. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/README.md +1 -0
  386. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-anthropic/index.ts +1 -1
  387. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-anthropic/package.json +1 -1
  388. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-gitlab-duo/index.ts +54 -3
  389. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  390. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/git-merge-and-resolve.ts +115 -0
  391. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/input-transform-streaming.ts +39 -0
  392. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/sandbox/package.json +1 -1
  393. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/with-deps/package.json +1 -1
  394. package/node_modules/@earendil-works/pi-coding-agent/npm-shrinkwrap.json +443 -61
  395. package/node_modules/@earendil-works/pi-coding-agent/package.json +6 -6
  396. package/node_modules/@earendil-works/pi-tui/README.md +2 -2
  397. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
  398. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +24 -83
  399. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
  400. package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts.map +1 -1
  401. package/node_modules/@earendil-works/pi-tui/dist/components/input.js +7 -55
  402. package/node_modules/@earendil-works/pi-tui/dist/components/input.js.map +1 -1
  403. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts +7 -1
  404. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +1 -1
  405. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +12 -2
  406. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +1 -1
  407. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
  408. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  409. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  410. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts +1 -1
  411. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +1 -1
  412. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +34 -7
  413. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +1 -1
  414. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +33 -10
  415. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
  416. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +172 -37
  417. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
  418. package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts +6 -1
  419. package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +1 -1
  420. package/node_modules/@earendil-works/pi-tui/dist/utils.js +27 -15
  421. package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -1
  422. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts +25 -0
  423. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts.map +1 -0
  424. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js +96 -0
  425. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js.map +1 -0
  426. package/node_modules/@earendil-works/pi-tui/package.json +2 -2
  427. package/node_modules/@entelligentsia/forge-compress/LICENSE +21 -0
  428. package/node_modules/@entelligentsia/forge-compress/README.md +85 -0
  429. package/node_modules/@mariozechner/clipboard/Cargo.toml +3 -3
  430. package/node_modules/@mariozechner/clipboard/index.d.ts +34 -20
  431. package/node_modules/@mariozechner/clipboard/index.js +546 -257
  432. package/node_modules/@mariozechner/clipboard/package.json +5 -6
  433. package/node_modules/@mariozechner/clipboard/package.json.prepack-backup +14 -14
  434. package/node_modules/@mariozechner/clipboard/src/lib.rs +4 -9
  435. package/node_modules/@mariozechner/clipboard-linux-x64-gnu/clipboard.linux-x64-gnu.node +0 -0
  436. package/node_modules/@mariozechner/clipboard-linux-x64-gnu/package.json +2 -2
  437. package/package.json +7 -7
  438. package/dist/bin/forgecli.d.ts +0 -2
  439. package/dist/bin/forgecli.js +0 -6
  440. package/dist/bin/forgecli.js.map +0 -1
  441. package/dist/extensions/forgecli/config-tui/index.d.ts +0 -5
  442. package/dist/extensions/forgecli/config-tui/index.js +0 -5
  443. package/dist/extensions/forgecli/config-tui/index.js.map +0 -1
  444. package/dist/extensions/forgecli/loaders/persona-skill-loader.d.ts +0 -45
  445. package/dist/extensions/forgecli/loaders/persona-skill-loader.js +0 -227
  446. package/dist/extensions/forgecli/loaders/persona-skill-loader.js.map +0 -1
  447. package/dist/extensions/forgecli/loaders/template-render.d.ts +0 -20
  448. package/dist/extensions/forgecli/loaders/template-render.js +0 -85
  449. package/dist/extensions/forgecli/loaders/template-render.js.map +0 -1
  450. package/dist/extensions/forgecli/loaders/workflow-loader.d.ts +0 -41
  451. package/dist/extensions/forgecli/loaders/workflow-loader.js +0 -164
  452. package/dist/extensions/forgecli/loaders/workflow-loader.js.map +0 -1
  453. package/dist/forge-payload/.base-pack/commands/quiz-agent.md +0 -6
  454. package/dist/forge-payload/.base-pack/commands/retrospective.md +0 -6
  455. package/dist/forge-payload/.base-pack/commands/sprint-intake.md +0 -6
  456. package/dist/forge-payload/.base-pack/commands/sprint-plan.md +0 -6
  457. package/dist/forge-payload/.base-pack/workflows/fix_bug.md +0 -446
  458. package/dist/forge-payload/.base-pack/workflows/orchestrate_task.md +0 -934
  459. package/dist/forge-payload/.base-pack/workflows/run_sprint.md +0 -225
  460. package/dist/forge-payload/commands/calibrate.md +0 -10
  461. package/dist/forge-payload/commands/materialize.md +0 -119
  462. package/dist/forge-payload/commands/migrate.md +0 -12
  463. package/dist/forge-payload/commands/quiz-agent.md +0 -6
  464. package/dist/forge-payload/commands/regenerate.md +0 -6
  465. package/dist/forge-payload/commands/store-query.md +0 -6
  466. package/dist/forge-payload/commands/store-repair.md +0 -6
  467. package/dist/forge-payload/commands/update-tools.md +0 -10
  468. package/dist/forge-payload/meta/templates/meta-retrospective.md +0 -28
  469. package/dist/forge-payload/tools/prompts/sprint-plan-prompt.md +0 -70
  470. package/dist/forge-payload/tools/schemas/task-list.schema.json +0 -53
  471. package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.d.ts +0 -4
  472. package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.d.ts.map +0 -1
  473. package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.js +0 -3
  474. package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.js.map +0 -1
  475. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.d.ts +0 -20
  476. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.d.ts.map +0 -1
  477. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.js +0 -92
  478. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.js.map +0 -1
  479. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.d.ts +0 -18
  480. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.d.ts.map +0 -1
  481. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.js +0 -42
  482. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.js.map +0 -1
  483. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.d.ts +0 -10
  484. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.d.ts.map +0 -1
  485. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.js +0 -31
  486. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.js.map +0 -1
  487. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.d.ts +0 -30
  488. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.d.ts.map +0 -1
  489. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.js +0 -170
  490. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.js.map +0 -1
  491. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.d.ts +0 -26
  492. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.d.ts.map +0 -1
  493. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.js +0 -90
  494. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.js.map +0 -1
  495. package/node_modules/@mariozechner/clipboard-linux-x64-musl/README.md +0 -3
  496. package/node_modules/@mariozechner/clipboard-linux-x64-musl/clipboard.linux-x64-musl.node +0 -0
  497. package/node_modules/@mariozechner/clipboard-linux-x64-musl/package.json +0 -25
@@ -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) | Triage β†’ fix β†’ verify |
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 β†’ implement β†’ review β†’ 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
 
@@ -0,0 +1,242 @@
1
+ 'use strict';
2
+
3
+ // ── ArtifactStore β€” backend-agnostic artifact provider ───────────────────────
4
+ //
5
+ // Mirrors the store.cjs `Store`/`FSImpl` pattern (ADR
6
+ // `doc/decisions/artifact-resolution-abstraction.md`, issue #111 Phase 3):
7
+ // a backend-agnostic facade delegating to a swappable, SYNCHRONOUS impl,
8
+ // default-wired to the filesystem, impl exported for substitution.
9
+ //
10
+ // class ArtifactStore { read|write|exists|url|list|delete(handle) β†’ impl }
11
+ // class FsArtifactImpl { engineering/ files }
12
+ // module.exports = new ArtifactStore(new FsArtifactImpl())
13
+ // module.exports.FsArtifactImpl = FsArtifactImpl // swap for S3Impl / CmsImpl / DbBlobImpl
14
+ //
15
+ // A `handle` is the logical address (entityType, entityId, artifactKind) β€” never
16
+ // a path. The fs impl resolves it from the store record's `path` (the locator)
17
+ // plus the canonical kind registry, so callers never construct paths.
18
+ //
19
+ // SYNC CONSTRAINT (load-bearing): in-process callers (store-cli.cjs,
20
+ // preflight-gate.cjs, collate.cjs) invoke this without `await`, so every method
21
+ // is synchronous β€” same constraint that blocks the store's async InstantDbImpl
22
+ // (see doc/decisions/instantdb-store-backend.md). A future remote impl must
23
+ // either stay sync or be reached only through the forge-cli subprocess surface.
24
+
25
+ const fs = require('fs');
26
+ const path = require('path');
27
+ const { execFileSync } = require('child_process');
28
+ const { resolveArtifactFilename } = require('./lib/artifact-kinds.cjs');
29
+
30
+ // ── Locator helpers ({ backend, ref }) ───────────────────────────────────────
31
+
32
+ // Derive the backend-agnostic locator from a store record. Prefers an explicit
33
+ // `record.locator`; otherwise treats the legacy `record.path` as an fs locator
34
+ // (the back-compat alias maintained during migration).
35
+ function toLocator(record) {
36
+ if (record && record.locator && record.locator.backend) return record.locator;
37
+ if (record && typeof record.path === 'string' && record.path.length > 0) {
38
+ return { backend: 'fs', ref: record.path };
39
+ }
40
+ return null;
41
+ }
42
+
43
+ // For an fs locator ref, return the entity *directory* (strip a trailing filename).
44
+ function fsRefToDir(ref) {
45
+ const norm = String(ref).replace(/\\/g, '/').replace(/\/+$/, '');
46
+ return /\.[a-zA-Z0-9]+$/.test(norm) ? norm.replace(/\/[^/]*$/, '') : norm;
47
+ }
48
+
49
+ // ── Default dir resolution (store record path) ───────────────────────────────
50
+ // Reads a record's `path` via store-cli (out-of-process) so this module has no
51
+ // hard dependency on store internals. Returns the entity directory or null.
52
+ function readStorePath(entity, entityId, toolDir, projectRoot) {
53
+ const cliPath = path.join(toolDir, 'store-cli.cjs');
54
+ try {
55
+ const result = execFileSync('node', [cliPath, 'read', entity, entityId, '--json'], {
56
+ cwd: projectRoot, encoding: 'utf8', timeout: 10_000,
57
+ });
58
+ const record = JSON.parse(result);
59
+ const loc = toLocator(record);
60
+ if (loc && loc.backend === 'fs') return fsRefToDir(loc.ref);
61
+ } catch (_) { /* store unavailable / record not found β€” fall through */ }
62
+ return null;
63
+ }
64
+
65
+ // Resolve entity directory from the store record's path, falling back to
66
+ // ID-only construction. (Moved verbatim from artifact.cjs; re-exported there.)
67
+ function resolveEntityDir(entity, entityId, engineeringPath, toolDir, projectRoot) {
68
+ switch (entity) {
69
+ case 'bug': {
70
+ const storePath = readStorePath('bug', entityId, toolDir, projectRoot);
71
+ if (storePath) return storePath;
72
+ return path.join(engineeringPath, 'bugs', entityId);
73
+ }
74
+ case 'sprint': {
75
+ const storePath = readStorePath('sprint', entityId, toolDir, projectRoot);
76
+ if (storePath) return storePath;
77
+ return path.join(engineeringPath, 'sprints', entityId);
78
+ }
79
+ case 'task': {
80
+ const storePath = readStorePath('task', entityId, toolDir, projectRoot);
81
+ if (storePath) return storePath;
82
+ const match = entityId.match(/^(.+-S\d+)-T\d+$/);
83
+ if (!match) return null;
84
+ const sprintId = match[1];
85
+ const sprintPath = readStorePath('sprint', sprintId, toolDir, projectRoot);
86
+ if (sprintPath) return path.join(sprintPath, entityId);
87
+ return path.join(engineeringPath, 'sprints', sprintId, entityId);
88
+ }
89
+ default:
90
+ return null;
91
+ }
92
+ }
93
+
94
+ // ── Facade ───────────────────────────────────────────────────────────────────
95
+
96
+ class ArtifactStore {
97
+ // The constructor impl is the default backend (`fs`). Additional backends are
98
+ // added with register(name, impl) β€” Phase 4. Each call routes to the impl for
99
+ // the handle's `backend` (default 'fs'), so adding a backend requires
100
+ // implementing the method surface only β€” no call-site or prompt changes.
101
+ constructor(impl) {
102
+ this.impl = impl; // default (fs) backend
103
+ this._backends = new Map([['fs', impl]]);
104
+ }
105
+
106
+ // Register an additional backend impl (e.g. an S3/CMS/DB provider). Returns
107
+ // `this` for chaining; re-registering the same name replaces the impl.
108
+ register(backend, impl) {
109
+ this._backends.set(backend, impl);
110
+ return this;
111
+ }
112
+
113
+ _implFor(handle) {
114
+ const backend = (handle && handle.backend) || 'fs';
115
+ const impl = this._backends.get(backend);
116
+ if (!impl) {
117
+ throw new Error(
118
+ `No ArtifactStore backend registered for "${backend}". ` +
119
+ `Registered: ${[...this._backends.keys()].join(', ')}. ` +
120
+ `Add one with artifactStore.register("${backend}", impl).`
121
+ );
122
+ }
123
+ return impl;
124
+ }
125
+
126
+ read(handle) { return this._implFor(handle).read(handle); }
127
+ write(handle, content) { return this._implFor(handle).write(handle, content); }
128
+ exists(handle) { return this._implFor(handle).exists(handle); }
129
+ url(handle) { return this._implFor(handle).url(handle); }
130
+ list(handle) { return this._implFor(handle).list(handle); }
131
+ delete(handle) { return this._implFor(handle).delete(handle); }
132
+ }
133
+
134
+ // ── Filesystem impl ───────────────────────────────────────────────────────────
135
+
136
+ class FsArtifactImpl {
137
+ // opts: { projectRoot, engineeringPath, toolDir, resolveDir }
138
+ // resolveDir(entity, entityId) β†’ dir (relative to projectRoot) | null.
139
+ // Injectable for testing; defaults to the store-record resolver above.
140
+ constructor(opts = {}) {
141
+ this.projectRoot = opts.projectRoot || process.cwd();
142
+ this.engineeringPath = opts.engineeringPath || 'engineering';
143
+ this.toolDir = opts.toolDir || __dirname;
144
+ this._resolveDir = opts.resolveDir
145
+ || ((entity, entityId) => resolveEntityDir(entity, entityId, this.engineeringPath, this.toolDir, this.projectRoot));
146
+ }
147
+
148
+ _absDir(handle) {
149
+ const dir = this._resolveDir(handle.entity, handle.entityId);
150
+ if (!dir) {
151
+ throw new Error(
152
+ `Cannot resolve ${handle.entity} directory for "${handle.entityId}". ` +
153
+ `Expected ID pattern: task=PREFIX-SNN-TNN, bug=PREFIX-BNN[-slug], sprint=PREFIX-SNN.`
154
+ );
155
+ }
156
+ return path.resolve(this.projectRoot, dir);
157
+ }
158
+
159
+ _absFile(handle) {
160
+ return path.join(this._absDir(handle), resolveArtifactFilename(handle.entity, handle.kind));
161
+ }
162
+
163
+ read(handle) {
164
+ const file = this._absFile(handle);
165
+ if (!fs.existsSync(file)) {
166
+ const err = new Error(`Artifact not found: ${path.relative(this.projectRoot, file)}`);
167
+ err.code = 'ENOENT';
168
+ throw err;
169
+ }
170
+ return fs.readFileSync(file, 'utf8');
171
+ }
172
+
173
+ write(handle, content) {
174
+ const dir = this._absDir(handle);
175
+ fs.mkdirSync(dir, { recursive: true });
176
+ const file = path.join(dir, resolveArtifactFilename(handle.entity, handle.kind));
177
+ fs.writeFileSync(file, content, 'utf8');
178
+ return { bytes: Buffer.byteLength(content, 'utf8'), ref: path.relative(this.projectRoot, file) };
179
+ }
180
+
181
+ exists(handle) {
182
+ try { return fs.existsSync(this._absFile(handle)); }
183
+ catch (_) { return false; }
184
+ }
185
+
186
+ url(handle) {
187
+ return 'file://' + this._absFile(handle);
188
+ }
189
+
190
+ // Entity-level listing: handle without `kind`. Returns existing filenames.
191
+ list(handle) {
192
+ const dir = this._absDir(handle);
193
+ if (!fs.existsSync(dir)) return [];
194
+ return fs.readdirSync(dir).filter((f) => f.endsWith('.md') || f.endsWith('.json'));
195
+ }
196
+
197
+ delete(handle) {
198
+ const file = this._absFile(handle);
199
+ if (fs.existsSync(file)) { fs.unlinkSync(file); return true; }
200
+ return false;
201
+ }
202
+ }
203
+
204
+ // ── Reference non-fs backend (Phase 4) ───────────────────────────────────────
205
+ //
206
+ // A complete, synchronous, in-memory implementation of the ArtifactStore method
207
+ // surface. It exists as the canonical *reference* for adding a backend: a real
208
+ // S3/CMS/DB provider implements these same six methods and is wired with
209
+ // `artifactStore.register('<backend>', new XxxArtifactImpl(...))` β€” no prompt or
210
+ // call-site changes. (A networked impl is sync-bound for in-process callers per
211
+ // the ADR; it is reachable async-internally only through the forge-cli
212
+ // subprocess surface. This in-memory impl is fully functional and dependency-free.)
213
+ class MemArtifactImpl {
214
+ constructor() { this.files = new Map(); }
215
+ _key(h) { return `${h.entity}/${h.entityId}/${resolveArtifactFilename(h.entity, h.kind)}`; }
216
+ read(handle) {
217
+ const k = this._key(handle);
218
+ if (!this.files.has(k)) { const e = new Error(`Artifact not found: mem:${k}`); e.code = 'ENOENT'; throw e; }
219
+ return this.files.get(k);
220
+ }
221
+ write(handle, content) {
222
+ const k = this._key(handle);
223
+ this.files.set(k, content);
224
+ return { bytes: Buffer.byteLength(content, 'utf8'), ref: `mem:${k}` };
225
+ }
226
+ exists(handle) { return this.files.has(this._key(handle)); }
227
+ url(handle) { return `mem://${this._key(handle)}`; }
228
+ list(handle) {
229
+ const prefix = `${handle.entity}/${handle.entityId}/`;
230
+ return [...this.files.keys()].filter((k) => k.startsWith(prefix)).map((k) => k.slice(prefix.length));
231
+ }
232
+ delete(handle) { return this.files.delete(this._key(handle)); }
233
+ }
234
+
235
+ module.exports = new ArtifactStore(new FsArtifactImpl());
236
+ module.exports.ArtifactStore = ArtifactStore;
237
+ module.exports.FsArtifactImpl = FsArtifactImpl;
238
+ module.exports.MemArtifactImpl = MemArtifactImpl;
239
+ module.exports.toLocator = toLocator;
240
+ module.exports.fsRefToDir = fsRefToDir;
241
+ module.exports.resolveEntityDir = resolveEntityDir;
242
+ module.exports.readStorePath = readStorePath;
@@ -14,59 +14,26 @@
14
14
 
15
15
  const fs = require('fs');
16
16
  const path = require('path');
17
- const { execFileSync } = require('child_process');
18
17
  const { findProjectRoot } = require('./lib/project-root.cjs');
19
18
 
20
19
  // ── Artifact catalog ─────────────────────────────────────────────────────────
21
-
22
- const ARTIFACT_CATALOG = {
23
- 'plan': { filename: 'PLAN.md', type: 'md' },
24
- 'plan-review': { filename: 'PLAN_REVIEW.md', type: 'md' },
25
- 'progress': { filename: 'PROGRESS.md', type: 'md' },
26
- 'code-review': { filename: 'CODE_REVIEW.md', type: 'md' },
27
- 'validation-report': { filename: 'VALIDATION_REPORT.md', type: 'md' },
28
- 'architect-approval': { filename: 'ARCHITECT_APPROVAL.md', type: 'md' },
29
- 'triage': { filename: 'TRIAGE.md', type: 'md' },
30
- 'bug-report': { filename: 'BUG_REPORT.md', type: 'md' },
31
- 'index': { filename: 'INDEX.md', type: 'md' },
32
- 'task-prompt': { filename: 'TASK_PROMPT.md', type: 'md' },
33
- 'sprint-requirements': { filename: 'SPRINT_REQUIREMENTS.md', type: 'md' },
34
- 'sprint-completion-review': { filename: 'SPRINT_COMPLETION_REVIEW.md', type: 'md' },
35
- 'cost-report': { filename: 'COST_REPORT.md', type: 'md' },
36
- 'timesheet': { filename: 'TIMESHEET.md', type: 'md' },
37
- 'plan-summary': { filename: 'PLAN-SUMMARY.json', type: 'json' },
38
- 'review-plan-summary': { filename: 'REVIEW-PLAN-SUMMARY.json', type: 'json' },
39
- 'implementation-summary': { filename: 'IMPLEMENTATION-SUMMARY.json', type: 'json' },
40
- 'review-code-summary': { filename: 'REVIEW-CODE-SUMMARY.json', type: 'json' },
41
- 'review-impl-summary': { filename: 'REVIEW-IMPL-SUMMARY.json', type: 'json' },
42
- 'validation-summary': { filename: 'VALIDATION-SUMMARY.json', type: 'json' },
43
- 'approve-summary': { filename: 'APPROVE-SUMMARY.json', type: 'json' },
44
- 'commit-summary': { filename: 'COMMIT-SUMMARY.json', type: 'json' },
45
- 'triage-summary': { filename: 'TRIAGE-SUMMARY.json', type: 'json' },
46
- 'writeback-summary': { filename: 'WRITEBACK-SUMMARY.json', type: 'json' },
47
- 'collation-summary': { filename: 'COLLATION-SUMMARY.json', type: 'json' },
48
- };
49
-
50
- // Per-entity filename overrides. Bug-mode plans and plan-summaries use the
51
- // BUG_FIX_PLAN prefix to match the long-standing forge convention and the
52
- // preflight-gate.cjs expectations for review-plan in bug mode. Without this
53
- // override, plan-fix (routed via plan_task.md post FORGE-BUG-040) writes
54
- // PLAN.md and review-plan preflight then fails "artifact missing:
55
- // BUG_FIX_PLAN.md" β€” see FORGE-BUG-041.
56
- const ARTIFACT_FILENAME_OVERRIDES = {
57
- bug: {
58
- 'plan': 'BUG_FIX_PLAN.md',
59
- 'plan-summary': 'BUG-FIX-PLAN-SUMMARY.json',
60
- },
61
- };
62
-
63
- function resolveArtifactFilename(entity, artifactName) {
64
- const override = ARTIFACT_FILENAME_OVERRIDES[entity];
65
- if (override && override[artifactName]) return override[artifactName];
66
- return ARTIFACT_CATALOG[artifactName].filename;
67
- }
68
-
69
- const ARTIFACT_NAMES = Object.keys(ARTIFACT_CATALOG).sort();
20
+ //
21
+ // The catalog, bug-mode overrides, and filename resolution now live in the
22
+ // canonical registry at lib/artifact-kinds.cjs (ADR artifact-resolution Phase 1),
23
+ // consumed here and by store-cli.cjs so there is ONE source of truth.
24
+ const {
25
+ ARTIFACT_CATALOG,
26
+ ARTIFACT_FILENAME_OVERRIDES,
27
+ ARTIFACT_NAMES,
28
+ resolveArtifactFilename,
29
+ } = require('./lib/artifact-kinds.cjs');
30
+
31
+ // The provider seam (ArtifactStore/FsArtifactImpl) and entity-dir resolution
32
+ // live in artifact-store.cjs (ADR Phase 3). This CLI is a thin layer over the
33
+ // facade: it owns arg parsing, @-file expansion, JSON validation, and display;
34
+ // all filesystem access goes through the provider.
35
+ const artifactStore = require('./artifact-store.cjs');
36
+ const { ArtifactStore, FsArtifactImpl, resolveEntityDir } = artifactStore;
70
37
 
71
38
  // ── Summary JSON validation ──────────────────────────────────────────────────
72
39
 
@@ -88,66 +55,6 @@ function validateSummaryJson(content) {
88
55
  return null;
89
56
  }
90
57
 
91
- // ── Entity path resolution ───────────────────────────────────────────────────
92
-
93
- /** Read a store record via store-cli and return its `path` field, or null on failure. */
94
- function readStorePath(entity, entityId, toolDir, projectRoot) {
95
- const cliPath = path.join(toolDir, 'store-cli.cjs');
96
- try {
97
- const result = execFileSync('node', [cliPath, 'read', entity, entityId, '--json'], {
98
- cwd: projectRoot,
99
- encoding: 'utf8',
100
- timeout: 10_000,
101
- });
102
- const record = JSON.parse(result);
103
- if (typeof record.path === 'string' && record.path.length > 0) {
104
- // Defensive: if the path ends with a file extension, the store record
105
- // was written with a filename (e.g. "…/PROGRESS.md") instead of the
106
- // directory. Strip the trailing filename to get the entity directory.
107
- const p = record.path;
108
- if (/\.(md|json)$/i.test(p)) return path.dirname(p);
109
- return p;
110
- }
111
- } catch (_) {
112
- // Store unavailable or record not found β€” fall through.
113
- }
114
- return null;
115
- }
116
-
117
- /**
118
- * Resolve entity directory using the store record's `path` field when available,
119
- * falling back to ID-only construction.
120
- */
121
- function resolveEntityDir(entity, entityId, engineeringPath, toolDir, projectRoot) {
122
- switch (entity) {
123
- case 'bug': {
124
- const storePath = readStorePath('bug', entityId, toolDir, projectRoot);
125
- if (storePath) return storePath;
126
- return path.join(engineeringPath, 'bugs', entityId);
127
- }
128
- case 'sprint': {
129
- const storePath = readStorePath('sprint', entityId, toolDir, projectRoot);
130
- if (storePath) return storePath;
131
- return path.join(engineeringPath, 'sprints', entityId);
132
- }
133
- case 'task': {
134
- const storePath = readStorePath('task', entityId, toolDir, projectRoot);
135
- if (storePath) return storePath;
136
- // Fallback: derive from sprint prefix + sprint record path.
137
- const match = entityId.match(/^(.+-S\d+)-T\d+$/);
138
- if (!match) return null;
139
- const sprintId = match[1];
140
- const sprintPath = readStorePath('sprint', sprintId, toolDir, projectRoot);
141
- if (sprintPath) {
142
- return path.join(sprintPath, entityId);
143
- }
144
- return path.join(engineeringPath, 'sprints', sprintId, entityId);
145
- }
146
- default:
147
- return null;
148
- }
149
- }
150
-
151
58
  // ── CLI ───────────────────────────────────────────────────────────────────────
152
59
 
153
60
  if (require.main === module) {
@@ -163,6 +70,9 @@ if (argv.length === 0 || argv[0] === '--help' || argv[0] === '-h') {
163
70
  ' read <entity> <entityId> <artifact> Read artifact content',
164
71
  ' write <entity> <entityId> <artifact> <content|@file>',
165
72
  ' Write artifact (content or @/path/to/file)',
73
+ ' exists <entity> <entityId> <artifact> Exit 0 if present, 2 if absent',
74
+ ' url <entity> <entityId> <artifact> Print the backend URL (file:// for fs)',
75
+ ' delete <entity> <entityId> <artifact> Delete an artifact',
166
76
  '',
167
77
  'Entities: task, bug, sprint',
168
78
  `Known artifacts: ${ARTIFACT_NAMES.join(', ')}`,
@@ -211,6 +121,14 @@ if (!entityDir) {
211
121
 
212
122
  const absDir = path.resolve(projectRoot, entityDir);
213
123
 
124
+ // Provider instance β€” all filesystem access for read/write/exists/url/delete
125
+ // goes through the facade (ADR Phase 3). Wired with the already-resolved dir so
126
+ // the CLI and the provider agree on location without a second store read.
127
+ const store = new ArtifactStore(new FsArtifactImpl({
128
+ projectRoot, engineeringPath, toolDir,
129
+ resolveDir: () => entityDir,
130
+ }));
131
+
214
132
  // ── list ────────────────────────────────────────────────────────────────────
215
133
 
216
134
  if (subcmd === 'list') {
@@ -262,16 +180,41 @@ if (!catalogEntry) {
262
180
  }
263
181
 
264
182
  const resolvedFilename = resolveArtifactFilename(entity, artifactName);
265
- const filePath = path.join(absDir, resolvedFilename);
183
+ const displayPath = path.join(entityDir, resolvedFilename);
184
+ const handle = { entity, entityId, kind: artifactName };
266
185
 
267
186
  // ── read ─────────────────────────────────────────────────────────────────────
268
187
 
269
188
  if (subcmd === 'read') {
270
- if (!fs.existsSync(filePath)) {
271
- process.stderr.write(`Artifact not found: ${path.join(entityDir, resolvedFilename)}\n`);
189
+ if (!store.exists(handle)) {
190
+ process.stderr.write(`Artifact not found: ${displayPath}\n`);
272
191
  process.exit(2);
273
192
  }
274
- process.stdout.write(fs.readFileSync(filePath, 'utf8'));
193
+ process.stdout.write(store.read(handle));
194
+ process.exit(0);
195
+ }
196
+
197
+ // ── exists ─────────────────────────────────────────────────────────────────────
198
+
199
+ if (subcmd === 'exists') {
200
+ // Boolean check: always exit 0 with a "true"/"false" token so callers
201
+ // (including the forge-cli subprocess surface) never treat absence as an error.
202
+ process.stdout.write(store.exists(handle) ? 'true\n' : 'false\n');
203
+ process.exit(0);
204
+ }
205
+
206
+ // ── url ────────────────────────────────────────────────────────────────────────
207
+
208
+ if (subcmd === 'url') {
209
+ process.stdout.write(store.url(handle) + '\n');
210
+ process.exit(0);
211
+ }
212
+
213
+ // ── delete ─────────────────────────────────────────────────────────────────────
214
+
215
+ if (subcmd === 'delete') {
216
+ const removed = store.delete(handle);
217
+ process.stdout.write(removed ? `Deleted ${displayPath}\n` : `Nothing to delete: ${displayPath}\n`);
275
218
  process.exit(0);
276
219
  }
277
220
 
@@ -308,15 +251,12 @@ if (subcmd === 'write') {
308
251
  }
309
252
  }
310
253
 
311
- fs.mkdirSync(absDir, { recursive: true });
312
- fs.writeFileSync(filePath, content, 'utf8');
313
- process.stdout.write(
314
- `Wrote ${Buffer.byteLength(content, 'utf8')} bytes to ${path.join(entityDir, resolvedFilename)}\n`
315
- );
254
+ const res = store.write(handle, content);
255
+ process.stdout.write(`Wrote ${res.bytes} bytes to ${displayPath}\n`);
316
256
  process.exit(0);
317
257
  }
318
258
 
319
- process.stderr.write(`Unknown subcommand: ${subcmd}. Valid: list, read, write\n`);
259
+ process.stderr.write(`Unknown subcommand: ${subcmd}. Valid: list, read, write, exists, url, delete\n`);
320
260
  process.exit(1);
321
261
 
322
262
  } // end if (require.main === module)
@@ -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);