@entelligentsia/forgecli 0.21.0 → 1.0.3

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 (364) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +31 -33
  3. package/dist/CHANGELOG-forge-plugin.md +142 -0
  4. package/dist/CHANGELOG-pi.md +24 -1
  5. package/dist/bin/forgecli.d.ts +2 -0
  6. package/dist/bin/forgecli.js +6 -0
  7. package/dist/bin/forgecli.js.map +1 -0
  8. package/dist/extensions/forgecli/add-pipeline.js +1 -1
  9. package/dist/extensions/forgecli/add-pipeline.js.map +1 -1
  10. package/dist/extensions/forgecli/add-task.js +1 -1
  11. package/dist/extensions/forgecli/add-task.js.map +1 -1
  12. package/dist/extensions/forgecli/approve.js +17 -2
  13. package/dist/extensions/forgecli/approve.js.map +1 -1
  14. package/dist/extensions/forgecli/audience-gate.js +1 -1
  15. package/dist/extensions/forgecli/audience-gate.js.map +1 -1
  16. package/dist/extensions/forgecli/calibrate.js +11 -8
  17. package/dist/extensions/forgecli/calibrate.js.map +1 -1
  18. package/dist/extensions/forgecli/collate.js +1 -1
  19. package/dist/extensions/forgecli/collate.js.map +1 -1
  20. package/dist/extensions/forgecli/commit.js +17 -2
  21. package/dist/extensions/forgecli/commit.js.map +1 -1
  22. package/dist/extensions/forgecli/enhance.js +1 -1
  23. package/dist/extensions/forgecli/enhance.js.map +1 -1
  24. package/dist/extensions/forgecli/fix-bug.d.ts +1 -2
  25. package/dist/extensions/forgecli/fix-bug.js +678 -609
  26. package/dist/extensions/forgecli/fix-bug.js.map +1 -1
  27. package/dist/extensions/forgecli/forge-artifact-tool.d.ts +6 -8
  28. package/dist/extensions/forgecli/forge-artifact-tool.js +94 -197
  29. package/dist/extensions/forgecli/forge-artifact-tool.js.map +1 -1
  30. package/dist/extensions/forgecli/forge-commands.js +57 -18
  31. package/dist/extensions/forgecli/forge-commands.js.map +1 -1
  32. package/dist/extensions/forgecli/forge-init/phase4-register.js +6 -7
  33. package/dist/extensions/forgecli/forge-init/phase4-register.js.map +1 -1
  34. package/dist/extensions/forgecli/forge-init/run-phases.d.ts +4 -0
  35. package/dist/extensions/forgecli/forge-init/run-phases.js +304 -0
  36. package/dist/extensions/forgecli/forge-init/run-phases.js.map +1 -0
  37. package/dist/extensions/forgecli/forge-init/verifiers.d.ts +14 -5
  38. package/dist/extensions/forgecli/forge-init/verifiers.js +79 -62
  39. package/dist/extensions/forgecli/forge-init/verifiers.js.map +1 -1
  40. package/dist/extensions/forgecli/forge-init.js +131 -76
  41. package/dist/extensions/forgecli/forge-init.js.map +1 -1
  42. package/dist/extensions/forgecli/forge-subagent.d.ts +26 -0
  43. package/dist/extensions/forgecli/forge-subagent.js +42 -18
  44. package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
  45. package/dist/extensions/forgecli/forge-tools.d.ts +34 -4
  46. package/dist/extensions/forgecli/forge-tools.js +191 -79
  47. package/dist/extensions/forgecli/forge-tools.js.map +1 -1
  48. package/dist/extensions/forgecli/health-check.js +3 -3
  49. package/dist/extensions/forgecli/health-check.js.map +1 -1
  50. package/dist/extensions/forgecli/hook-dispatcher.d.ts +1 -1
  51. package/dist/extensions/forgecli/hooks/check-update.d.ts +8 -0
  52. package/dist/extensions/forgecli/hooks/check-update.js +29 -1
  53. package/dist/extensions/forgecli/hooks/check-update.js.map +1 -1
  54. package/dist/extensions/forgecli/hooks/post-init-hook.js +6 -6
  55. package/dist/extensions/forgecli/hooks/post-init-hook.js.map +1 -1
  56. package/dist/extensions/forgecli/hooks/post-sprint-hook.js +6 -6
  57. package/dist/extensions/forgecli/hooks/post-sprint-hook.js.map +1 -1
  58. package/dist/extensions/forgecli/hooks/triage-error.js +1 -0
  59. package/dist/extensions/forgecli/hooks/triage-error.js.map +1 -1
  60. package/dist/extensions/forgecli/implement.js +20 -2
  61. package/dist/extensions/forgecli/implement.js.map +1 -1
  62. package/dist/extensions/forgecli/index.js +39 -32
  63. package/dist/extensions/forgecli/index.js.map +1 -1
  64. package/dist/extensions/forgecli/lib/pipeline-guard.d.ts +41 -0
  65. package/dist/extensions/forgecli/lib/pipeline-guard.js +100 -0
  66. package/dist/extensions/forgecli/lib/pipeline-guard.js.map +1 -0
  67. package/dist/extensions/forgecli/loaders/persona-skill-loader.js +2 -2
  68. package/dist/extensions/forgecli/loaders/persona-skill-loader.js.map +1 -1
  69. package/dist/extensions/forgecli/migrate.d.ts +3 -0
  70. package/dist/extensions/forgecli/migrate.js +4 -2
  71. package/dist/extensions/forgecli/migrate.js.map +1 -1
  72. package/dist/extensions/forgecli/plan.js +21 -2
  73. package/dist/extensions/forgecli/plan.js.map +1 -1
  74. package/dist/extensions/forgecli/quiz-agent.js +7 -7
  75. package/dist/extensions/forgecli/quiz-agent.js.map +1 -1
  76. package/dist/extensions/forgecli/regenerate.js +49 -18
  77. package/dist/extensions/forgecli/regenerate.js.map +1 -1
  78. package/dist/extensions/forgecli/remove-command.js +1 -1
  79. package/dist/extensions/forgecli/remove-command.js.map +1 -1
  80. package/dist/extensions/forgecli/report-bug.js +1 -1
  81. package/dist/extensions/forgecli/report-bug.js.map +1 -1
  82. package/dist/extensions/forgecli/retrospective.js +9 -9
  83. package/dist/extensions/forgecli/retrospective.js.map +1 -1
  84. package/dist/extensions/forgecli/review-code.d.ts +13 -0
  85. package/dist/extensions/forgecli/review-code.js +62 -3
  86. package/dist/extensions/forgecli/review-code.js.map +1 -1
  87. package/dist/extensions/forgecli/review-plan.d.ts +13 -0
  88. package/dist/extensions/forgecli/review-plan.js +65 -3
  89. package/dist/extensions/forgecli/review-plan.js.map +1 -1
  90. package/dist/extensions/forgecli/run-task.js +461 -391
  91. package/dist/extensions/forgecli/run-task.js.map +1 -1
  92. package/dist/extensions/forgecli/session-registry.d.ts +12 -0
  93. package/dist/extensions/forgecli/session-registry.js +23 -0
  94. package/dist/extensions/forgecli/session-registry.js.map +1 -1
  95. package/dist/extensions/forgecli/skill-curator-subagent.d.ts +2 -1
  96. package/dist/extensions/forgecli/skill-curator-subagent.js +2 -1
  97. package/dist/extensions/forgecli/skill-curator-subagent.js.map +1 -1
  98. package/dist/extensions/forgecli/sprint-intake.js +6 -6
  99. package/dist/extensions/forgecli/sprint-intake.js.map +1 -1
  100. package/dist/extensions/forgecli/sprint-plan.js +9 -9
  101. package/dist/extensions/forgecli/sprint-plan.js.map +1 -1
  102. package/dist/extensions/forgecli/status-command.js +1 -1
  103. package/dist/extensions/forgecli/status-command.js.map +1 -1
  104. package/dist/extensions/forgecli/store-query.js +11 -11
  105. package/dist/extensions/forgecli/store-query.js.map +1 -1
  106. package/dist/extensions/forgecli/store-repair.js +7 -7
  107. package/dist/extensions/forgecli/store-repair.js.map +1 -1
  108. package/dist/extensions/forgecli/subagent/caller-context.d.ts +35 -11
  109. package/dist/extensions/forgecli/subagent/caller-context.js +49 -21
  110. package/dist/extensions/forgecli/subagent/caller-context.js.map +1 -1
  111. package/dist/extensions/forgecli/subagent/orchestrator-transcript.d.ts +66 -0
  112. package/dist/extensions/forgecli/subagent/orchestrator-transcript.js +66 -0
  113. package/dist/extensions/forgecli/subagent/orchestrator-transcript.js.map +1 -0
  114. package/dist/extensions/forgecli/subagent/phase-guard.d.ts +34 -0
  115. package/dist/extensions/forgecli/subagent/phase-guard.js +139 -0
  116. package/dist/extensions/forgecli/subagent/phase-guard.js.map +1 -0
  117. package/dist/extensions/forgecli/subagent/phase-summary-map.d.ts +1 -0
  118. package/dist/extensions/forgecli/subagent/phase-summary-map.js +22 -0
  119. package/dist/extensions/forgecli/subagent/phase-summary-map.js.map +1 -0
  120. package/dist/extensions/forgecli/thread-switcher.js +2 -2
  121. package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
  122. package/dist/extensions/forgecli/validate.js +17 -2
  123. package/dist/extensions/forgecli/validate.js.map +1 -1
  124. package/dist/extensions/forgecli/viewport-events.d.ts +4 -0
  125. package/dist/extensions/forgecli/viewport-events.js +18 -1
  126. package/dist/extensions/forgecli/viewport-events.js.map +1 -1
  127. package/dist/extensions/forgecli/viewport-renderer.d.ts +12 -2
  128. package/dist/extensions/forgecli/viewport-renderer.js +8 -6
  129. package/dist/extensions/forgecli/viewport-renderer.js.map +1 -1
  130. package/dist/forge-payload/.base-pack/commands/check-agent.md +22 -0
  131. package/dist/forge-payload/.base-pack/commands/new-sprint.md +22 -0
  132. package/dist/forge-payload/.base-pack/commands/plan-sprint.md +22 -0
  133. package/dist/forge-payload/.base-pack/commands/quiz-agent.md +2 -18
  134. package/dist/forge-payload/.base-pack/commands/retro.md +22 -0
  135. package/dist/forge-payload/.base-pack/commands/retrospective.md +2 -18
  136. package/dist/forge-payload/.base-pack/commands/sprint-intake.md +2 -18
  137. package/dist/forge-payload/.base-pack/commands/sprint-plan.md +2 -18
  138. package/dist/forge-payload/.base-pack/workflows/_fragments/friction-emit.md +2 -2
  139. package/dist/forge-payload/.base-pack/workflows/_fragments/generation-instructions.md +4 -4
  140. package/dist/forge-payload/.base-pack/workflows/_fragments/iron-laws.md +1 -1
  141. package/dist/forge-payload/.base-pack/workflows/architect_approve.md +13 -1
  142. package/dist/forge-payload/.base-pack/workflows/commit_task.md +12 -1
  143. package/dist/forge-payload/.base-pack/workflows/enhance.md +6 -6
  144. package/dist/forge-payload/.base-pack/workflows/fix_bug.md +11 -29
  145. package/dist/forge-payload/.base-pack/workflows/implement_plan.md +14 -2
  146. package/dist/forge-payload/.base-pack/workflows/migrate_structural.md +2 -2
  147. package/dist/forge-payload/.base-pack/workflows/orchestrate_task.md +20 -4
  148. package/dist/forge-payload/.base-pack/workflows/plan_task.md +14 -2
  149. package/dist/forge-payload/.base-pack/workflows/review_code.md +37 -7
  150. package/dist/forge-payload/.base-pack/workflows/review_plan.md +36 -6
  151. package/dist/forge-payload/.base-pack/workflows/run_sprint.md +2 -2
  152. package/dist/forge-payload/.base-pack/workflows/triage.md +190 -0
  153. package/dist/forge-payload/.base-pack/workflows/validate_task.md +37 -7
  154. package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
  155. package/dist/forge-payload/.schemas/config.schema.json +0 -5
  156. package/dist/forge-payload/.schemas/enum-catalog.json +9 -13
  157. package/dist/forge-payload/.schemas/migrations.json +63 -0
  158. package/dist/forge-payload/agents/tomoshibi.md +150 -6
  159. package/dist/forge-payload/commands/add-pipeline.md +1 -1
  160. package/dist/forge-payload/commands/add-task.md +1 -1
  161. package/dist/forge-payload/commands/calibrate.md +4 -350
  162. package/dist/forge-payload/commands/check-agent.md +38 -0
  163. package/dist/forge-payload/commands/config.md +3 -113
  164. package/dist/forge-payload/commands/enhance.md +5 -32
  165. package/dist/forge-payload/commands/health.md +155 -13
  166. package/dist/forge-payload/commands/init.md +25 -31
  167. package/dist/forge-payload/commands/migrate.md +6 -154
  168. package/dist/forge-payload/commands/quiz-agent.md +2 -34
  169. package/dist/forge-payload/commands/rebuild.md +664 -0
  170. package/dist/forge-payload/commands/regenerate.md +2 -774
  171. package/dist/forge-payload/commands/remove.md +10 -13
  172. package/dist/forge-payload/commands/repair.md +187 -0
  173. package/dist/forge-payload/commands/search.md +73 -0
  174. package/dist/forge-payload/commands/status.md +105 -0
  175. package/dist/forge-payload/commands/store-query.md +2 -69
  176. package/dist/forge-payload/commands/store-repair.md +2 -183
  177. package/dist/forge-payload/commands/update-tools.md +4 -50
  178. package/dist/forge-payload/commands/update.md +64 -58
  179. package/dist/forge-payload/hooks/check-update.cjs +1 -1
  180. package/dist/forge-payload/hooks/post-init.cjs +2 -2
  181. package/dist/forge-payload/hooks/post-sprint.cjs +2 -2
  182. package/dist/forge-payload/hooks/triage-error.cjs +11 -10
  183. package/dist/forge-payload/init/phases/phase-1-collect.md +138 -0
  184. package/dist/forge-payload/init/phases/phase-2-discover.md +127 -0
  185. package/dist/forge-payload/init/phases/phase-3-materialize.md +113 -0
  186. package/dist/forge-payload/init/phases/phase-4-register.md +159 -0
  187. package/dist/forge-payload/integrity.json +21 -24
  188. package/dist/forge-payload/meta/fragments/tool-discipline.md +41 -0
  189. package/dist/forge-payload/meta/templates/meta-retro.md +28 -0
  190. package/dist/forge-payload/meta/workflows/_fragments/friction-emit.md +2 -2
  191. package/dist/forge-payload/meta/workflows/_fragments/generation-instructions.md +4 -4
  192. package/dist/forge-payload/meta/workflows/_fragments/iron-laws.md +1 -1
  193. package/dist/forge-payload/meta/workflows/meta-approve.md +13 -1
  194. package/dist/forge-payload/meta/workflows/meta-bug-triage.md +210 -0
  195. package/dist/forge-payload/meta/workflows/meta-check-agent.md +138 -0
  196. package/dist/forge-payload/meta/workflows/meta-commit.md +12 -1
  197. package/dist/forge-payload/meta/workflows/meta-enhance.md +5 -5
  198. package/dist/forge-payload/meta/workflows/meta-fix-bug.md +11 -29
  199. package/dist/forge-payload/meta/workflows/meta-implement.md +13 -1
  200. package/dist/forge-payload/meta/workflows/meta-migrate.md +3 -3
  201. package/dist/forge-payload/meta/workflows/meta-new-sprint.md +84 -0
  202. package/dist/forge-payload/meta/workflows/meta-orchestrate.md +20 -4
  203. package/dist/forge-payload/meta/workflows/meta-plan-sprint.md +152 -0
  204. package/dist/forge-payload/meta/workflows/meta-plan-task.md +13 -1
  205. package/dist/forge-payload/meta/workflows/meta-retro.md +73 -0
  206. package/dist/forge-payload/meta/workflows/meta-review-implementation.md +37 -7
  207. package/dist/forge-payload/meta/workflows/meta-review-plan.md +36 -6
  208. package/dist/forge-payload/meta/workflows/meta-validate.md +37 -7
  209. package/dist/forge-payload/schemas/config.schema.json +0 -5
  210. package/dist/forge-payload/schemas/enum-catalog.json +9 -13
  211. package/dist/forge-payload/schemas/structure-manifest.json +25 -8
  212. package/dist/forge-payload/tools/artifact.cjs +324 -0
  213. package/dist/forge-payload/tools/banners.cjs +3 -4
  214. package/dist/forge-payload/tools/build-context-pack.cjs +1 -1
  215. package/dist/forge-payload/tools/check-structure.cjs +8 -3
  216. package/dist/forge-payload/tools/store-cli.cjs +67 -7
  217. package/dist/forge-payload/tools/substitute-placeholders.cjs +1 -1
  218. package/dist/forge-payload/tools/verify-apply.cjs +75 -0
  219. package/dist/forge-payload/tools/verify-phase.cjs +259 -0
  220. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  221. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +0 -17
  222. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  223. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +21 -38
  224. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
  225. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  226. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +5 -4
  227. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  228. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts +2 -1
  229. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  230. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +5 -2
  231. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
  232. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  233. package/node_modules/@earendil-works/pi-coding-agent/CHANGELOG.md +24 -1
  234. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/file-processor.d.ts.map +1 -1
  235. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/file-processor.js +2 -3
  236. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/file-processor.js.map +1 -1
  237. package/node_modules/@earendil-works/pi-coding-agent/dist/core/output-guard.d.ts +1 -0
  238. package/node_modules/@earendil-works/pi-coding-agent/dist/core/output-guard.d.ts.map +1 -1
  239. package/node_modules/@earendil-works/pi-coding-agent/dist/core/output-guard.js +52 -22
  240. package/node_modules/@earendil-works/pi-coding-agent/dist/core/output-guard.js.map +1 -1
  241. package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  242. package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js +16 -4
  243. package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  244. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  245. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/bash.js +45 -50
  246. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  247. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  248. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit.js +43 -81
  249. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  250. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  251. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/file-mutation-queue.js +27 -12
  252. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/file-mutation-queue.js.map +1 -1
  253. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
  254. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/find.js +2 -3
  255. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/find.js.map +1 -1
  256. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
  257. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/grep.js +3 -3
  258. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
  259. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
  260. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.js +5 -5
  261. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
  262. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/path-utils.d.ts +2 -0
  263. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/path-utils.d.ts.map +1 -1
  264. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/path-utils.js +37 -0
  265. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/path-utils.js.map +1 -1
  266. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  267. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.js +9 -8
  268. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  269. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  270. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.js +20 -35
  271. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  272. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts +3 -0
  273. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  274. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-client.js +64 -7
  275. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
  276. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  277. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-mode.js +15 -3
  278. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  279. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/clipboard-native.d.ts +3 -1
  280. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/clipboard-native.d.ts.map +1 -1
  281. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/clipboard-native.js +14 -8
  282. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/clipboard-native.js.map +1 -1
  283. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-resize-core.d.ts +30 -0
  284. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-resize-core.d.ts.map +1 -0
  285. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-resize-core.js +124 -0
  286. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-resize-core.js.map +1 -0
  287. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-resize-worker.d.ts +2 -0
  288. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-resize-worker.d.ts.map +1 -0
  289. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-resize-worker.js +31 -0
  290. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-resize-worker.js.map +1 -0
  291. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-resize.d.ts +7 -27
  292. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-resize.d.ts.map +1 -1
  293. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-resize.js +75 -115
  294. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-resize.js.map +1 -1
  295. package/node_modules/@earendil-works/pi-coding-agent/docs/terminal-setup.md +6 -0
  296. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-anthropic/package.json +1 -1
  297. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  298. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/sandbox/package.json +1 -1
  299. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/with-deps/package.json +1 -1
  300. package/node_modules/@earendil-works/pi-coding-agent/npm-shrinkwrap.json +12 -14
  301. package/node_modules/@earendil-works/pi-coding-agent/package.json +5 -5
  302. package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.d.ts +3 -0
  303. package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.d.ts.map +1 -0
  304. package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.js +53 -0
  305. package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.js.map +1 -0
  306. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +1 -1
  307. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +4 -1
  308. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +1 -1
  309. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +2 -0
  310. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
  311. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +13 -1
  312. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
  313. package/node_modules/@earendil-works/pi-tui/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node +0 -0
  314. package/node_modules/@earendil-works/pi-tui/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node +0 -0
  315. package/node_modules/@earendil-works/pi-tui/package.json +2 -2
  316. package/node_modules/@entelligentsia/forge-compress/dist/compressor.d.ts +6 -0
  317. package/node_modules/@entelligentsia/forge-compress/dist/compressor.js +137 -0
  318. package/node_modules/@entelligentsia/forge-compress/dist/entropy.d.ts +3 -0
  319. package/node_modules/@entelligentsia/forge-compress/dist/entropy.js +99 -0
  320. package/node_modules/@entelligentsia/forge-compress/dist/forge/entity.d.ts +8 -0
  321. package/node_modules/@entelligentsia/forge-compress/dist/forge/entity.js +149 -0
  322. package/node_modules/@entelligentsia/forge-compress/dist/forge/index.d.ts +7 -0
  323. package/node_modules/@entelligentsia/forge-compress/dist/forge/index.js +4 -0
  324. package/node_modules/@entelligentsia/forge-compress/dist/forge/markdown.d.ts +5 -0
  325. package/node_modules/@entelligentsia/forge-compress/dist/forge/markdown.js +92 -0
  326. package/node_modules/@entelligentsia/forge-compress/dist/forge/query.d.ts +7 -0
  327. package/node_modules/@entelligentsia/forge-compress/dist/forge/query.js +60 -0
  328. package/node_modules/@entelligentsia/forge-compress/dist/forge/validate.d.ts +1 -0
  329. package/node_modules/@entelligentsia/forge-compress/dist/forge/validate.js +82 -0
  330. package/node_modules/@entelligentsia/forge-compress/dist/index.d.ts +6 -0
  331. package/node_modules/@entelligentsia/forge-compress/dist/index.js +5 -0
  332. package/node_modules/@entelligentsia/forge-compress/dist/progressive.d.ts +1 -0
  333. package/node_modules/@entelligentsia/forge-compress/dist/progressive.js +108 -0
  334. package/node_modules/@entelligentsia/forge-compress/dist/strip.d.ts +4 -0
  335. package/node_modules/@entelligentsia/forge-compress/dist/strip.js +55 -0
  336. package/node_modules/@entelligentsia/forge-compress/dist/tokens.d.ts +2 -0
  337. package/node_modules/@entelligentsia/forge-compress/dist/tokens.js +17 -0
  338. package/node_modules/@entelligentsia/forge-compress/package.json +45 -0
  339. package/node_modules/@entelligentsia/forge-compress/src/__tests__/compress.test.ts +409 -0
  340. package/node_modules/@entelligentsia/forge-compress/src/compressor.ts +147 -0
  341. package/node_modules/@entelligentsia/forge-compress/src/entropy.ts +105 -0
  342. package/node_modules/@entelligentsia/forge-compress/src/forge/entity.ts +184 -0
  343. package/node_modules/@entelligentsia/forge-compress/src/forge/index.ts +10 -0
  344. package/node_modules/@entelligentsia/forge-compress/src/forge/markdown.ts +122 -0
  345. package/node_modules/@entelligentsia/forge-compress/src/forge/query.ts +105 -0
  346. package/node_modules/@entelligentsia/forge-compress/src/forge/validate.ts +86 -0
  347. package/node_modules/@entelligentsia/forge-compress/src/index.ts +22 -0
  348. package/node_modules/@entelligentsia/forge-compress/src/progressive.ts +123 -0
  349. package/node_modules/@entelligentsia/forge-compress/src/strip.ts +58 -0
  350. package/node_modules/@entelligentsia/forge-compress/src/tokens.ts +19 -0
  351. package/package.json +10 -15
  352. package/dist/extensions/forgecli/forge-init/phase-descriptors.d.ts +0 -72
  353. package/dist/extensions/forgecli/forge-init/phase-descriptors.js +0 -359
  354. package/dist/extensions/forgecli/forge-init/phase-descriptors.js.map +0 -1
  355. package/dist/extensions/forgecli/forge-init/prompts.d.ts +0 -10
  356. package/dist/extensions/forgecli/forge-init/prompts.js +0 -91
  357. package/dist/extensions/forgecli/forge-init/prompts.js.map +0 -1
  358. package/dist/extensions/forgecli/lib/store-error-remediation.d.ts +0 -65
  359. package/dist/extensions/forgecli/lib/store-error-remediation.js +0 -298
  360. package/dist/extensions/forgecli/lib/store-error-remediation.js.map +0 -1
  361. package/dist/forge-payload/hooks/check-update.js +0 -378
  362. package/dist/forge-payload/hooks/forge-permissions.js +0 -164
  363. package/dist/forge-payload/hooks/triage-error.js +0 -77
  364. package/dist/forge-payload/hooks/validate-write.js +0 -250
@@ -204,11 +204,6 @@
204
204
  }
205
205
  }
206
206
  }
207
- },
208
- "mode": {
209
- "type": "string",
210
- "enum": ["full", "fast"],
211
- "description": "Init mode. 'fast' means scaffolding was generated by /forge:init --fast (stubs present, heavy artifacts deferred to first use). 'full' means all artifacts are generated. Absent on pre-0.12 projects — treated as 'full' by all readers. Flipped to 'full' by /forge:regenerate (default) or /forge:materialize --all."
212
207
  }
213
208
  },
214
209
  "additionalProperties": false
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "0.51.4",
3
- "generated": "2026-05-26",
2
+ "version": "1.0.2",
3
+ "generated": "2026-05-28",
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": [
@@ -35,34 +35,30 @@
35
35
  ]
36
36
  },
37
37
  "commandNames": [
38
- "forge:sprint-intake",
38
+ "forge:new-sprint",
39
39
  "forge:plan",
40
40
  "forge:review-plan",
41
41
  "forge:implement",
42
42
  "forge:review-code",
43
43
  "forge:fix-bug",
44
- "forge:sprint-plan",
44
+ "forge:plan-sprint",
45
45
  "forge:run-task",
46
46
  "forge:run-sprint",
47
- "forge:collate",
48
- "forge:retrospective",
47
+ "forge:retro",
49
48
  "forge:approve",
50
49
  "forge:commit",
51
- "forge:enhance",
52
- "forge:quiz-agent",
50
+ "forge:check-agent",
53
51
  "forge:validate",
54
52
  "forge:init",
55
53
  "forge:health",
56
- "forge:regenerate",
54
+ "forge:rebuild",
57
55
  "forge:update",
58
56
  "forge:add-task",
59
57
  "forge:add-pipeline",
60
- "forge:calibrate",
61
- "forge:materialize",
62
58
  "forge:remove",
63
59
  "forge:report-bug",
64
- "forge:store-query",
65
- "forge:store-repair",
60
+ "forge:search",
61
+ "forge:repair",
66
62
  "forge:config",
67
63
  "forge:ask",
68
64
  "forge:store-custodian",
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "0.51.4",
3
- "generatedAt": "2026-05-26T04:50:57.503Z",
2
+ "version": "1.0.2",
3
+ "generatedAt": "2026-05-28T05:59:32.606Z",
4
4
  "generatedByTool": "build-manifest.cjs",
5
5
  "namespaces": {
6
6
  "personas": {
@@ -48,6 +48,7 @@
48
48
  "review_plan.md",
49
49
  "run_sprint.md",
50
50
  "sprint_retrospective.md",
51
+ "triage.md",
51
52
  "update_implementation.md",
52
53
  "update_plan.md",
53
54
  "validate_task.md"
@@ -75,20 +76,18 @@
75
76
  "prefixed": true,
76
77
  "files": [
77
78
  "approve.md",
78
- "collate.md",
79
+ "check-agent.md",
79
80
  "commit.md",
80
- "enhance.md",
81
81
  "fix-bug.md",
82
82
  "implement.md",
83
+ "new-sprint.md",
84
+ "plan-sprint.md",
83
85
  "plan.md",
84
- "quiz-agent.md",
85
- "retrospective.md",
86
+ "retro.md",
86
87
  "review-code.md",
87
88
  "review-plan.md",
88
89
  "run-sprint.md",
89
90
  "run-task.md",
90
- "sprint-intake.md",
91
- "sprint-plan.md",
92
91
  "validate.md"
93
92
  ]
94
93
  },
@@ -182,6 +181,24 @@
182
181
  "paths.engineering"
183
182
  ]
184
183
  },
184
+ "triage": {
185
+ "personas": [
186
+ ".forge/personas/bug-fixer.md"
187
+ ],
188
+ "skills": [
189
+ ".forge/skills/bug-fixer-skills.md",
190
+ ".forge/skills/generic-skills.md"
191
+ ],
192
+ "templates": [],
193
+ "sub_workflows": [],
194
+ "kb_docs": [
195
+ "{KB_PATH}/architecture/stack.md"
196
+ ],
197
+ "config_fields": [
198
+ "commands.test",
199
+ "paths.engineering"
200
+ ]
201
+ },
185
202
  "fix_bug": {
186
203
  "personas": [
187
204
  ".forge/personas/bug-fixer.md",
@@ -0,0 +1,324 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // Forge tool: artifact
5
+ // Read, write, or list phase artifacts (PLAN.md, PROGRESS.md, *-SUMMARY.json, etc.)
6
+ // for a task, bug, or sprint. Resolves paths from entity store record.
7
+ //
8
+ // Usage:
9
+ // node artifact.cjs read <entity> <entityId> <artifact>
10
+ // node artifact.cjs write <entity> <entityId> <artifact> <content|@file>
11
+ // node artifact.cjs list <entity> <entityId>
12
+ //
13
+ // Exit codes: 0 = success, 1 = usage/validation error, 2 = not found
14
+
15
+ const fs = require('fs');
16
+ const path = require('path');
17
+ const { execFileSync } = require('child_process');
18
+ const { findProjectRoot } = require('./lib/project-root.cjs');
19
+
20
+ // ── 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();
70
+
71
+ // ── Summary JSON validation ──────────────────────────────────────────────────
72
+
73
+ const SUMMARY_REQUIRED = ['objective', 'key_changes', 'verdict', 'written_at'];
74
+
75
+ function validateSummaryJson(content) {
76
+ let obj;
77
+ try {
78
+ obj = JSON.parse(content);
79
+ } catch (e) {
80
+ return `Invalid JSON: ${e.message}`;
81
+ }
82
+ const missing = SUMMARY_REQUIRED.filter((f) => !(f in obj));
83
+ if (missing.length > 0) return `Missing required fields: ${missing.join(', ')}`;
84
+ if (typeof obj.objective !== 'string') return `"objective" must be a string`;
85
+ if (!Array.isArray(obj.key_changes)) return `"key_changes" must be an array`;
86
+ if (typeof obj.verdict !== 'string') return `"verdict" must be a string`;
87
+ if (typeof obj.written_at !== 'string') return `"written_at" must be a string`;
88
+ return null;
89
+ }
90
+
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
+ // ── CLI ───────────────────────────────────────────────────────────────────────
152
+
153
+ if (require.main === module) {
154
+
155
+ const argv = process.argv.slice(2);
156
+
157
+ if (argv.length === 0 || argv[0] === '--help' || argv[0] === '-h') {
158
+ process.stderr.write([
159
+ 'Usage: node artifact.cjs <subcommand> <entity> <entityId> [artifact] [content|@file]',
160
+ '',
161
+ 'Subcommands:',
162
+ ' list <entity> <entityId> List existing artifacts',
163
+ ' read <entity> <entityId> <artifact> Read artifact content',
164
+ ' write <entity> <entityId> <artifact> <content|@file>',
165
+ ' Write artifact (content or @/path/to/file)',
166
+ '',
167
+ 'Entities: task, bug, sprint',
168
+ `Known artifacts: ${ARTIFACT_NAMES.join(', ')}`,
169
+ '',
170
+ 'Exit codes: 0=success, 1=usage/validation error, 2=not found',
171
+ ].join('\n') + '\n');
172
+ process.exit(1);
173
+ }
174
+
175
+ const [subcmd, entity, entityId] = argv;
176
+
177
+ if (!subcmd || !entity || !entityId) {
178
+ process.stderr.write('Usage: artifact.cjs <list|read|write> <entity> <entityId> [artifact] [content]\n');
179
+ process.exit(1);
180
+ }
181
+
182
+ const VALID_ENTITIES = ['task', 'bug', 'sprint'];
183
+ if (!VALID_ENTITIES.includes(entity)) {
184
+ process.stderr.write(`Unknown entity type: ${entity}. Valid: ${VALID_ENTITIES.join(', ')}\n`);
185
+ process.exit(1);
186
+ }
187
+
188
+ const projectRoot = findProjectRoot();
189
+ if (!projectRoot) {
190
+ process.stderr.write('Cannot find project root (.forge/config.json not found)\n');
191
+ process.exit(1);
192
+ }
193
+
194
+ // Read engineering path from config
195
+ let engineeringPath = 'engineering';
196
+ try {
197
+ const cfg = JSON.parse(fs.readFileSync(path.join(projectRoot, '.forge', 'config.json'), 'utf8'));
198
+ if (typeof cfg.paths?.engineering === 'string') engineeringPath = cfg.paths.engineering;
199
+ } catch (_) { /* default */ }
200
+
201
+ const toolDir = __dirname;
202
+
203
+ const entityDir = resolveEntityDir(entity, entityId, engineeringPath, toolDir, projectRoot);
204
+ if (!entityDir) {
205
+ process.stderr.write(
206
+ `Cannot resolve ${entity} directory for "${entityId}". ` +
207
+ `Expected ID pattern: task=PREFIX-SNN-TNN, bug=PREFIX-BNN[-slug], sprint=PREFIX-SNN.\n`
208
+ );
209
+ process.exit(1);
210
+ }
211
+
212
+ const absDir = path.resolve(projectRoot, entityDir);
213
+
214
+ // ── list ────────────────────────────────────────────────────────────────────
215
+
216
+ if (subcmd === 'list') {
217
+ if (!fs.existsSync(absDir)) {
218
+ process.stdout.write(`No artifacts found — directory does not exist: ${entityDir}/\n`);
219
+ process.exit(0);
220
+ }
221
+ const files = fs.readdirSync(absDir).filter((f) => f.endsWith('.md') || f.endsWith('.json'));
222
+ const known = [];
223
+ const other = [];
224
+ for (const f of files) {
225
+ // Recognise the per-entity overrides as well, so e.g. BUG_FIX_PLAN.md
226
+ // surfaces as the `plan` artifact in bug-mode listings.
227
+ const overrideEntry = ARTIFACT_FILENAME_OVERRIDES[entity]
228
+ ? Object.entries(ARTIFACT_FILENAME_OVERRIDES[entity]).find(([, fn]) => fn === f)
229
+ : undefined;
230
+ const catalogEntry = overrideEntry
231
+ || Object.entries(ARTIFACT_CATALOG).find(([, v]) => v.filename === f);
232
+ if (catalogEntry) {
233
+ known.push(` ${catalogEntry[0]} → ${f}`);
234
+ } else {
235
+ other.push(` (unlisted) ${f}`);
236
+ }
237
+ }
238
+ const lines = [`Artifacts in ${entityDir}/:`];
239
+ if (known.length > 0) lines.push(...known);
240
+ if (other.length > 0) lines.push(...other);
241
+ if (known.length === 0 && other.length === 0) lines.push(' (empty)');
242
+ process.stdout.write(lines.join('\n') + '\n');
243
+ process.exit(0);
244
+ }
245
+
246
+ // ── read / write — need artifact name ───────────────────────────────────────
247
+
248
+ const artifactName = argv[3];
249
+ if (!artifactName) {
250
+ process.stderr.write(`"artifact" is required for ${subcmd}. Known: ${ARTIFACT_NAMES.join(', ')}\n`);
251
+ process.exit(1);
252
+ }
253
+
254
+ const catalogEntry = ARTIFACT_CATALOG[artifactName];
255
+ if (!catalogEntry) {
256
+ const suggestions = ARTIFACT_NAMES.filter((n) => n.includes(artifactName.toLowerCase()));
257
+ process.stderr.write(
258
+ `Unknown artifact "${artifactName}". Known: ${ARTIFACT_NAMES.join(', ')}.` +
259
+ (suggestions.length > 0 ? ` Did you mean: ${suggestions.join(', ')}?` : '') + '\n'
260
+ );
261
+ process.exit(1);
262
+ }
263
+
264
+ const resolvedFilename = resolveArtifactFilename(entity, artifactName);
265
+ const filePath = path.join(absDir, resolvedFilename);
266
+
267
+ // ── read ─────────────────────────────────────────────────────────────────────
268
+
269
+ if (subcmd === 'read') {
270
+ if (!fs.existsSync(filePath)) {
271
+ process.stderr.write(`Artifact not found: ${path.join(entityDir, resolvedFilename)}\n`);
272
+ process.exit(2);
273
+ }
274
+ process.stdout.write(fs.readFileSync(filePath, 'utf8'));
275
+ process.exit(0);
276
+ }
277
+
278
+ // ── write ─────────────────────────────────────────────────────────────────────
279
+
280
+ if (subcmd === 'write') {
281
+ let rawContent = argv[4];
282
+ if (!rawContent) {
283
+ process.stderr.write('"content" is required for write. Pass inline or use @/path/to/file for large content.\n');
284
+ process.exit(1);
285
+ }
286
+
287
+ // @-prefix convention: read content from file when arg starts with @
288
+ let content;
289
+ if (rawContent.startsWith('@')) {
290
+ const contentFile = rawContent.slice(1);
291
+ if (!fs.existsSync(contentFile)) {
292
+ process.stderr.write(`@-file not found: ${contentFile}\n`);
293
+ process.exit(1);
294
+ }
295
+ content = fs.readFileSync(contentFile, 'utf8');
296
+ } else {
297
+ content = rawContent;
298
+ }
299
+
300
+ if (catalogEntry.type === 'json') {
301
+ const validationError = validateSummaryJson(content);
302
+ if (validationError) {
303
+ process.stderr.write(
304
+ `Summary validation failed for ${resolvedFilename}: ${validationError}. ` +
305
+ `Required fields: ${SUMMARY_REQUIRED.join(', ')}.\n`
306
+ );
307
+ process.exit(1);
308
+ }
309
+ }
310
+
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
+ );
316
+ process.exit(0);
317
+ }
318
+
319
+ process.stderr.write(`Unknown subcommand: ${subcmd}. Valid: list, read, write\n`);
320
+ process.exit(1);
321
+
322
+ } // end if (require.main === module)
323
+
324
+ module.exports = { ARTIFACT_CATALOG, ARTIFACT_NAMES, validateSummaryJson, resolveEntityDir };
@@ -31,7 +31,7 @@
31
31
  // node banners.cjs --plain forge
32
32
  // node banners.cjs --subtitle "Forging your SDLC"
33
33
  // node banners.cjs --progress 5 12 "Templates"
34
- // node banners.cjs --phase 7 12 "Workflows" ember fast
34
+ // node banners.cjs --phase 7 12 "Workflows" ember
35
35
 
36
36
  // ─── Plain-mode detection ─────────────────────────────────────────────────────
37
37
  // Resolved at call-time so tests can flip env vars dynamically.
@@ -61,14 +61,13 @@ const f = (r, g, b) => `\x1b[38;2;${r};${g};${b}m`;
61
61
  // ─── Mode tints ───────────────────────────────────────────────────────────────
62
62
  // Mode-aware accent colour for progress bars and subtitles. Used by phaseHeader.
63
63
  const MODE_TINTS = {
64
- fast: [255, 208, 122], // lantern yellow
65
64
  full: [255, 138, 60], // ember orange
66
65
  };
67
66
 
68
67
  // ─── Zen blue ─────────────────────────────────────────────────────────────────
69
68
  // System-wide horizontal-rule tint. Applied to em-dash separators in
70
- // phaseHeader, ruleLine, and ensure-ready.cjs --announce framing. Picked to
71
- // read calm and cool without competing with banner colours.
69
+ // phaseHeader and ruleLine. Picked to read calm and cool without competing
70
+ // with banner colours.
72
71
  const ZEN_BLUE = [100, 140, 200];
73
72
 
74
73
  // ─── Banner registry ───────────────────────────────────────────────────────────
@@ -196,7 +196,7 @@ function buildContextPack({ archDir, existingPackPath }) {
196
196
  if (realLineCount > PACK_LINE_LIMIT) {
197
197
  // Keep PACK_LINE_LIMIT - 1 lines so the marker fits within the cap
198
198
  const truncated = splitLines.slice(0, PACK_LINE_LIMIT - 1);
199
- truncated.push('<!-- TRUNCATED: pack exceeded 400 lines. Architecture KB has grown beyond summary capacity. Run /forge:regenerate after pruning docs. -->');
199
+ truncated.push('<!-- TRUNCATED: pack exceeded 400 lines. Architecture KB has grown beyond summary capacity. Run /forge:rebuild after pruning docs. -->');
200
200
  markdown = truncated.join('\n') + '\n';
201
201
  }
202
202
 
@@ -59,11 +59,16 @@ function checkNamespaces(manifest, projectRoot, options = {}) {
59
59
 
60
60
  for (const [nsKey, ns] of Object.entries(manifest.namespaces)) {
61
61
  const logicalKey = ns.logicalKey || nsKey;
62
- let resolvedDir = (resolvedConfigPaths[logicalKey] && typeof resolvedConfigPaths[logicalKey] === 'string')
62
+ const configHasPath = resolvedConfigPaths[logicalKey] && typeof resolvedConfigPaths[logicalKey] === 'string';
63
+ let resolvedDir = configHasPath
63
64
  ? resolvedConfigPaths[logicalKey]
64
65
  : ns.dir;
65
- if (ns.prefixed && projectPrefix) {
66
- resolvedDir = resolvedDir + '/' + projectPrefix;
66
+ // When config provides the path, use it verbatim (it already includes any
67
+ // prefix subdirectory). Only apply the prefixed append when falling back
68
+ // to the manifest's base dir.
69
+ if (ns.prefixed && !configHasPath) {
70
+ const suffix = projectPrefix || getCommandsSubdir('forge');
71
+ resolvedDir = resolvedDir + '/' + suffix;
67
72
  }
68
73
  const absDir = path.join(projectRoot, resolvedDir);
69
74
 
@@ -558,10 +558,17 @@ function cmdWrite() {
558
558
  function cmdRead() {
559
559
  const entity = args[1];
560
560
  const id = args[2];
561
- const asJson = args.includes('--json');
561
+ const asJson = args.includes('--json');
562
+ const noSummaries = args.includes('--no-summaries');
563
+
564
+ let fieldsProjection = null;
565
+ const fieldsIdx = args.indexOf('--fields');
566
+ if (fieldsIdx !== -1 && args[fieldsIdx + 1] && !args[fieldsIdx + 1].startsWith('--')) {
567
+ fieldsProjection = args[fieldsIdx + 1].split(',').map((f) => f.trim()).filter(Boolean);
568
+ }
562
569
 
563
570
  if (!entity || !id) {
564
- console.error('Usage: store-cli.cjs read <entity> <id> [--json]');
571
+ console.error('Usage: store-cli.cjs read <entity> <id> [--json] [--no-summaries] [--fields <comma-list>]');
565
572
  process.exit(1);
566
573
  }
567
574
 
@@ -590,10 +597,19 @@ function cmdRead() {
590
597
  process.exit(1);
591
598
  }
592
599
 
600
+ // Apply projection before formatting
601
+ let projected = record;
602
+ if (noSummaries) {
603
+ projected = Object.fromEntries(Object.entries(projected).filter(([k]) => k !== 'summaries'));
604
+ }
605
+ if (fieldsProjection) {
606
+ projected = Object.fromEntries(fieldsProjection.map((f) => [f, projected[f]]).filter(([, v]) => v !== undefined));
607
+ }
608
+
593
609
  if (asJson) {
594
- console.log(JSON.stringify(record));
610
+ console.log(JSON.stringify(projected));
595
611
  } else {
596
- console.log(JSON.stringify(record, null, 2));
612
+ console.log(JSON.stringify(projected, null, 2));
597
613
  }
598
614
  }
599
615
 
@@ -601,7 +617,7 @@ function cmdList() {
601
617
  const entity = args[1];
602
618
 
603
619
  if (!entity) {
604
- console.error('Usage: store-cli.cjs list <entity> [key=value ...]');
620
+ console.error('Usage: store-cli.cjs list <entity> [key=value ...] [--no-summaries] [--fields <comma-list>] [--limit N] [--count]');
605
621
  process.exit(1);
606
622
  }
607
623
 
@@ -610,9 +626,27 @@ function cmdList() {
610
626
  process.exit(1);
611
627
  }
612
628
 
613
- // Parse key=value filter pairs from remaining args
629
+ // Parse projection flags and key=value filter pairs from remaining args
630
+ const noSummaries = args.includes('--no-summaries');
631
+ const countOnly = args.includes('--count');
632
+
633
+ let fieldsProjection = null;
634
+ const fieldsIdx = args.indexOf('--fields');
635
+ if (fieldsIdx !== -1 && args[fieldsIdx + 1] && !args[fieldsIdx + 1].startsWith('--')) {
636
+ fieldsProjection = args[fieldsIdx + 1].split(',').map((f) => f.trim()).filter(Boolean);
637
+ }
638
+
639
+ let limitN = null;
640
+ const limitIdx = args.indexOf('--limit');
641
+ if (limitIdx !== -1 && args[limitIdx + 1] && !args[limitIdx + 1].startsWith('--')) {
642
+ const n = parseInt(args[limitIdx + 1], 10);
643
+ if (!isNaN(n) && n >= 0) limitN = n;
644
+ }
645
+
614
646
  const filter = {};
615
647
  for (let i = 2; i < args.length; i++) {
648
+ // Skip flag arguments and their value arguments
649
+ if (args[i].startsWith('--')) { i++; continue; }
616
650
  const eqIdx = args[i].indexOf('=');
617
651
  if (eqIdx > 0) {
618
652
  const key = args[i].slice(0, eqIdx);
@@ -623,7 +657,33 @@ function cmdList() {
623
657
  }
624
658
  }
625
659
 
626
- const records = listEntities(entity, Object.keys(filter).length > 0 ? filter : undefined);
660
+ let records = listEntities(entity, Object.keys(filter).length > 0 ? filter : undefined);
661
+
662
+ // --count: emit bare integer and exit (mutually exclusive with other flags)
663
+ if (countOnly) {
664
+ console.log(String(records.length));
665
+ return;
666
+ }
667
+
668
+ // --limit: truncate after filtering
669
+ if (limitN !== null) {
670
+ records = records.slice(0, limitN);
671
+ }
672
+
673
+ // Apply projection
674
+ if (fieldsProjection || noSummaries) {
675
+ records = records.map((rec) => {
676
+ let projected = rec;
677
+ if (noSummaries) {
678
+ projected = Object.fromEntries(Object.entries(projected).filter(([k]) => k !== 'summaries'));
679
+ }
680
+ if (fieldsProjection) {
681
+ projected = Object.fromEntries(fieldsProjection.map((f) => [f, projected[f]]).filter(([, v]) => v !== undefined));
682
+ }
683
+ return projected;
684
+ });
685
+ }
686
+
627
687
  console.log(JSON.stringify(records, null, 2));
628
688
  }
629
689
 
@@ -9,7 +9,7 @@
9
9
  * output to the appropriate output directories.
10
10
  *
11
11
  * Output path mapping (--target claude-code, default):
12
- * base-pack/commands/ → <outRoot>/.claude/commands/forge/
12
+ * base-pack/commands/ → <outRoot>/.claude/commands/<prefix>/
13
13
  * base-pack/personas/ → <outRoot>/.forge/personas/
14
14
  * base-pack/skills/ → <outRoot>/.forge/skills/
15
15
  * base-pack/workflows/ → <outRoot>/.forge/workflows/