@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
@@ -14,14 +14,14 @@ import { promisify } from "node:util";
14
14
  import { resolveToolDir } from "./store-resolver.js";
15
15
  const execFileAsync = promisify(execFile);
16
16
  // ── Usage message ─────────────────────────────────────────────────────────────
17
- const USAGE = `Usage: /forge:store-query <intent or flags>
17
+ const USAGE = `Usage: /forge:search <intent or flags>
18
18
 
19
19
  Examples:
20
- /forge:store-query open bugs in S12
21
- /forge:store-query FORGE-BUG-047
22
- /forge:store-query --sprint FORGE-S12 --status in-progress
23
- /forge:store-query --keyword auth
24
- /forge:store-query schema`;
20
+ /forge:search open bugs in S12
21
+ /forge:search FORGE-BUG-047
22
+ /forge:search --sprint FORGE-S12 --status in-progress
23
+ /forge:search --keyword auth
24
+ /forge:search schema`;
25
25
  /**
26
26
  * Run store-cli in query or nlp mode.
27
27
  * - Args starting with "--" → query branch: `store-cli query ...flags`
@@ -73,7 +73,7 @@ export async function runStoreQuery(args, forgeRoot, cwd) {
73
73
  * forgeRoot is nullable — null means we're outside a Forge project.
74
74
  */
75
75
  export function registerStoreQuery(pi, opts) {
76
- pi.registerCommand("forge:store-query", {
76
+ pi.registerCommand("forge:search", {
77
77
  description: "Query the Forge store by natural language or exact flags. " +
78
78
  "Use flags (--sprint, --task, --keyword) for exact queries; " +
79
79
  "use plain text for NLP intent queries.",
@@ -81,7 +81,7 @@ export function registerStoreQuery(pi, opts) {
81
81
  const cwd = process.cwd();
82
82
  // Outside-project guard
83
83
  if (!opts.forgeRoot) {
84
- ctx.ui.notify("× forge:store-query — not inside a Forge project. Run /forge:init first.", "error");
84
+ ctx.ui.notify("× forge:search — not inside a Forge project. Run /forge:init first.", "error");
85
85
  return;
86
86
  }
87
87
  const trimmed = args.trim();
@@ -89,11 +89,11 @@ export function registerStoreQuery(pi, opts) {
89
89
  ctx.ui.notify(USAGE, "info");
90
90
  return;
91
91
  }
92
- ctx.ui.setStatus?.("forge:store-query", "Querying store…");
92
+ ctx.ui.setStatus?.("forge:search", "Querying store…");
93
93
  const result = await runStoreQuery(trimmed, opts.forgeRoot, cwd);
94
- ctx.ui.setStatus?.("forge:store-query", undefined);
94
+ ctx.ui.setStatus?.("forge:search", undefined);
95
95
  if (!result.ok && result.errorMessage) {
96
- ctx.ui.notify(`× forge:store-query — ${result.errorMessage}`, "error");
96
+ ctx.ui.notify(`× forge:search — ${result.errorMessage}`, "error");
97
97
  // Still show partial stdout if available
98
98
  if (result.stdout.trim()) {
99
99
  ctx.ui.notify(result.stdout.trim(), "info");
@@ -1 +1 @@
1
- {"version":3,"file":"store-query.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/store-query.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store-query.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/store-query.ts"],"names":[],"mappings":"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"}
@@ -58,7 +58,7 @@ export function parseStoreRepairArgs(rawArgs, cwd) {
58
58
  }
59
59
  export function composeStoreRepairKickoff(opts) {
60
60
  const { commandMd, parsed } = opts;
61
- const sections = ["# /forge:store-repair", ""];
61
+ const sections = ["# /forge:repair", ""];
62
62
  sections.push("## Dispatch", "");
63
63
  sections.push("Diagnose and repair the Forge JSON store. Run the repair workflow below. Specifically:");
64
64
  sections.push("");
@@ -80,15 +80,15 @@ export function composeStoreRepairKickoff(opts) {
80
80
  // ── Registration ──────────────────────────────────────────────────────────
81
81
  const COMMAND_NAME = "store-repair";
82
82
  export function registerStoreRepair(pi, options) {
83
- pi.registerCommand("forge:store-repair", {
83
+ pi.registerCommand("forge:repair", {
84
84
  description: "Diagnose and repair corrupted Forge store records. " +
85
- "Usage: /forge:store-repair [--dry-run]. " +
85
+ "Usage: /forge:repair [--dry-run]. " +
86
86
  "--dry-run shows what would be repaired without making changes.",
87
87
  async handler(args, ctx) {
88
88
  const { forgeRoot } = options;
89
89
  const cwd = options.cwd ?? process.cwd();
90
90
  if (!forgeRoot) {
91
- ctx.ui.notify("× forge:store-repair — no Forge project at cwd; run /forge:init to bootstrap", "warning");
91
+ ctx.ui.notify("× forge:repair — no Forge project at cwd; run /forge:init to bootstrap", "warning");
92
92
  return;
93
93
  }
94
94
  const commandPath = path.join(forgeRoot, "commands", `${COMMAND_NAME}.md`);
@@ -99,10 +99,10 @@ export function registerStoreRepair(pi, options) {
99
99
  catch (err) {
100
100
  const e = err;
101
101
  if (e.code === "ENOENT") {
102
- ctx.ui.notify(`× forge:store-repair — command file not found at commands/${COMMAND_NAME}.md; run /forge:init or /forge:regenerate first.`, "error");
102
+ ctx.ui.notify(`× forge:repair — command file not found at commands/${COMMAND_NAME}.md; run /forge:init or /forge:rebuild first.`, "error");
103
103
  }
104
104
  else {
105
- ctx.ui.notify(`× forge:store-repair — failed to read command file: ${e.message ?? "unknown error"}`, "error");
105
+ ctx.ui.notify(`× forge:repair — failed to read command file: ${e.message ?? "unknown error"}`, "error");
106
106
  }
107
107
  return;
108
108
  }
@@ -112,7 +112,7 @@ export function registerStoreRepair(pi, options) {
112
112
  }
113
113
  catch (err) {
114
114
  const e = err;
115
- ctx.ui.notify(`× forge:store-repair — failed to parse args: ${e.message ?? "unknown"}`, "error");
115
+ ctx.ui.notify(`× forge:repair — failed to parse args: ${e.message ?? "unknown"}`, "error");
116
116
  return;
117
117
  }
118
118
  const kickoff = composeStoreRepairKickoff({ commandMd, parsed });
@@ -1 +1 @@
1
- {"version":3,"file":"store-repair.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/store-repair.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store-repair.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/store-repair.ts"],"names":[],"mappings":"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"}
@@ -1,26 +1,50 @@
1
- /** Caller context of the current handler invocation. */
2
- export type CallerContext = "orchestrator" | "subagent";
1
+ /**
2
+ * Canonical phase identifiers used by both `meta-orchestrate.md` and
3
+ * `meta-fix-bug.md` (the latter adds `triage`). When a subagent is
4
+ * dispatched, its phase tag MUST be one of these values — that lets the
5
+ * phase-ownership guard compare the caller's phase against the tool's
6
+ * named `--phase` argument.
7
+ */
8
+ export type PhaseRole = "triage" | "plan" | "plan-fix" | "review-plan" | "implement" | "review-code" | "validate" | "approve" | "writeback" | "commit" | "finalize";
9
+ /**
10
+ * Caller context of the current handler invocation. Discriminated union:
11
+ * orchestrator (default) or subagent + phase. Subagent context is set
12
+ * exclusively by `asSubagent(phase, fn)` — the single setter point in
13
+ * the per-phase orchestrator dispatch loop.
14
+ */
15
+ export type CallerContext = {
16
+ kind: "orchestrator";
17
+ } | {
18
+ kind: "subagent";
19
+ phase: PhaseRole;
20
+ };
3
21
  /**
4
22
  * Singleton that tracks the caller context for the current handler turn.
5
23
  *
6
24
  * Usage:
7
- * - Read with `CallerContextStore.get()` — used by `assertAudience()`.
8
- * - Set with `CallerContextStore.set("subagent")` — used by T02/T03/T07 orchestrator handlers.
9
- * - Use `CallerContextStore.asSubagent(fn)` / `asOrchestrator(fn)` for RAII-style scoping.
25
+ * - Read with `CallerContextStore.get()` — used by `assertAudience()`
26
+ * and `assertPhaseOwnership()`.
27
+ * - Set with `CallerContextStore.set(...)` used by orchestrator
28
+ * handlers when RAII scoping is not viable (avoid where possible).
29
+ * - Use `CallerContextStore.asSubagent(phase, fn)` /
30
+ * `asOrchestrator(fn)` for RAII-style scoping. The async overload
31
+ * accepts an `async () => Promise<T>` and awaits before restoring
32
+ * prior context.
10
33
  */
11
34
  export declare const CallerContextStore: {
12
- /** Get the current caller context. Defaults to "orchestrator". */
35
+ /** Get the current caller context. Defaults to `{ kind: "orchestrator" }`. */
13
36
  get(): CallerContext;
14
37
  /** Set the current caller context. */
15
38
  set(ctx: CallerContext): void;
16
39
  /**
17
- * Execute fn with context set to "subagent"; restore prior context on
18
- * return or throw.
40
+ * Execute fn with context set to `{ kind: "subagent", phase }`; restore
41
+ * prior context on return or throw. Supports sync and async fn — the
42
+ * return type is preserved so `await` works at the call site.
19
43
  */
20
- asSubagent<T>(fn: () => T): T;
44
+ asSubagent<T>(phase: PhaseRole, fn: () => T): T;
21
45
  /**
22
- * Execute fn with context set to "orchestrator"; restore prior context on
23
- * return or throw.
46
+ * Execute fn with context set to `{ kind: "orchestrator" }`; restore prior
47
+ * context on return or throw.
24
48
  */
25
49
  asOrchestrator<T>(fn: () => T): T;
26
50
  };
@@ -1,13 +1,19 @@
1
1
  // caller-context.ts — Tracks whether the current handler execution
2
- // is running in orchestrator or subagent context (FORGE-S21-T01).
2
+ // is running in orchestrator or subagent context (FORGE-S21-T01),
3
+ // and — when in subagent context — which phase is executing
4
+ // (FORGE-BUG-040).
3
5
  //
4
- // Default: "orchestrator". Handlers in T02/T03/T07 orchestrators set
5
- // to "subagent" during sub-workflow dispatch to enable assertAudience
6
- // to refuse orchestrator-only workflows when invoked from a subagent chain.
6
+ // Default: orchestrator. The fix-bug and run-task orchestrators wrap
7
+ // per-phase runForgeSubagent dispatch in CallerContextStore.asSubagent(
8
+ // phase.role, ...) so downstream tool calls (forge_preflight, forge_store
9
+ // update-status / set-bug-summary / set-summary / emit) can verify the
10
+ // caller's phase matches the phase named in the tool arguments. See
11
+ // subagent/phase-guard.ts.
7
12
  //
8
13
  // Critical invariant: pi-runtime has NO caller-context API (confirmed by
9
14
  // FORGE-S21-T01 spike — see SPIKE-LESSONS.md). This singleton is the
10
- // ONLY mechanism for passing caller context into assertAudience.
15
+ // ONLY mechanism for passing caller context into assertAudience and the
16
+ // phase-ownership guard.
11
17
  //
12
18
  // Thread safety: Pi serialises agent turns; the RAII scopers (asSubagent /
13
19
  // asOrchestrator) restore prior state on return-or-throw, so interleaving
@@ -17,17 +23,22 @@
17
23
  // IL1 — code only under forge-cli/src/extensions/forgecli/.
18
24
  // IL7 — no silent continuation; all errors are thrown.
19
25
  // No pi-runtime dependency: pure in-memory singleton.
20
- let _current = "orchestrator";
26
+ let _current = { kind: "orchestrator" };
21
27
  /**
22
28
  * Singleton that tracks the caller context for the current handler turn.
23
29
  *
24
30
  * Usage:
25
- * - Read with `CallerContextStore.get()` — used by `assertAudience()`.
26
- * - Set with `CallerContextStore.set("subagent")` — used by T02/T03/T07 orchestrator handlers.
27
- * - Use `CallerContextStore.asSubagent(fn)` / `asOrchestrator(fn)` for RAII-style scoping.
31
+ * - Read with `CallerContextStore.get()` — used by `assertAudience()`
32
+ * and `assertPhaseOwnership()`.
33
+ * - Set with `CallerContextStore.set(...)` used by orchestrator
34
+ * handlers when RAII scoping is not viable (avoid where possible).
35
+ * - Use `CallerContextStore.asSubagent(phase, fn)` /
36
+ * `asOrchestrator(fn)` for RAII-style scoping. The async overload
37
+ * accepts an `async () => Promise<T>` and awaits before restoring
38
+ * prior context.
28
39
  */
29
40
  export const CallerContextStore = {
30
- /** Get the current caller context. Defaults to "orchestrator". */
41
+ /** Get the current caller context. Defaults to `{ kind: "orchestrator" }`. */
31
42
  get() {
32
43
  return _current;
33
44
  },
@@ -36,31 +47,48 @@ export const CallerContextStore = {
36
47
  _current = ctx;
37
48
  },
38
49
  /**
39
- * Execute fn with context set to "subagent"; restore prior context on
40
- * return or throw.
50
+ * Execute fn with context set to `{ kind: "subagent", phase }`; restore
51
+ * prior context on return or throw. Supports sync and async fn — the
52
+ * return type is preserved so `await` works at the call site.
41
53
  */
42
- asSubagent(fn) {
54
+ asSubagent(phase, fn) {
43
55
  const prev = _current;
44
- _current = "subagent";
56
+ _current = { kind: "subagent", phase };
45
57
  try {
46
- return fn();
58
+ const out = fn();
59
+ if (out instanceof Promise) {
60
+ return out.finally(() => {
61
+ _current = prev;
62
+ });
63
+ }
64
+ _current = prev;
65
+ return out;
47
66
  }
48
- finally {
67
+ catch (err) {
49
68
  _current = prev;
69
+ throw err;
50
70
  }
51
71
  },
52
72
  /**
53
- * Execute fn with context set to "orchestrator"; restore prior context on
54
- * return or throw.
73
+ * Execute fn with context set to `{ kind: "orchestrator" }`; restore prior
74
+ * context on return or throw.
55
75
  */
56
76
  asOrchestrator(fn) {
57
77
  const prev = _current;
58
- _current = "orchestrator";
78
+ _current = { kind: "orchestrator" };
59
79
  try {
60
- return fn();
80
+ const out = fn();
81
+ if (out instanceof Promise) {
82
+ return out.finally(() => {
83
+ _current = prev;
84
+ });
85
+ }
86
+ _current = prev;
87
+ return out;
61
88
  }
62
- finally {
89
+ catch (err) {
63
90
  _current = prev;
91
+ throw err;
64
92
  }
65
93
  },
66
94
  };
@@ -1 +1 @@
1
- {"version":3,"file":"caller-context.js","sourceRoot":"","sources":["../../../../src/extensions/forgecli/subagent/caller-context.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,kEAAkE;AAClE,EAAE;AACF,qEAAqE;AACrE,sEAAsE;AACtE,4EAA4E;AAC5E,EAAE;AACF,yEAAyE;AACzE,qEAAqE;AACrE,iEAAiE;AACjE,EAAE;AACF,2EAA2E;AAC3E,0EAA0E;AAC1E,mCAAmC;AACnC,EAAE;AACF,aAAa;AACb,8DAA8D;AAC9D,yDAAyD;AACzD,wDAAwD;AAKxD,IAAI,QAAQ,GAAkB,cAAc,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IACjC,kEAAkE;IAClE,GAAG;QACF,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,sCAAsC;IACtC,GAAG,CAAC,GAAkB;QACrB,QAAQ,GAAG,GAAG,CAAC;IAChB,CAAC;IACD;;;OAGG;IACH,UAAU,CAAI,EAAW;QACxB,MAAM,IAAI,GAAG,QAAQ,CAAC;QACtB,QAAQ,GAAG,UAAU,CAAC;QACtB,IAAI,CAAC;YACJ,OAAO,EAAE,EAAE,CAAC;QACb,CAAC;gBAAS,CAAC;YACV,QAAQ,GAAG,IAAI,CAAC;QACjB,CAAC;IACF,CAAC;IACD;;;OAGG;IACH,cAAc,CAAI,EAAW;QAC5B,MAAM,IAAI,GAAG,QAAQ,CAAC;QACtB,QAAQ,GAAG,cAAc,CAAC;QAC1B,IAAI,CAAC;YACJ,OAAO,EAAE,EAAE,CAAC;QACb,CAAC;gBAAS,CAAC;YACV,QAAQ,GAAG,IAAI,CAAC;QACjB,CAAC;IACF,CAAC;CACD,CAAC"}
1
+ {"version":3,"file":"caller-context.js","sourceRoot":"","sources":["../../../../src/extensions/forgecli/subagent/caller-context.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,kEAAkE;AAClE,4DAA4D;AAC5D,mBAAmB;AACnB,EAAE;AACF,qEAAqE;AACrE,wEAAwE;AACxE,0EAA0E;AAC1E,uEAAuE;AACvE,oEAAoE;AACpE,2BAA2B;AAC3B,EAAE;AACF,yEAAyE;AACzE,qEAAqE;AACrE,wEAAwE;AACxE,yBAAyB;AACzB,EAAE;AACF,2EAA2E;AAC3E,0EAA0E;AAC1E,mCAAmC;AACnC,EAAE;AACF,aAAa;AACb,8DAA8D;AAC9D,yDAAyD;AACzD,wDAAwD;AA8BxD,IAAI,QAAQ,GAAkB,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;AAEvD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IACjC,8EAA8E;IAC9E,GAAG;QACF,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,sCAAsC;IACtC,GAAG,CAAC,GAAkB;QACrB,QAAQ,GAAG,GAAG,CAAC;IAChB,CAAC;IACD;;;;OAIG;IACH,UAAU,CAAI,KAAgB,EAAE,EAAW;QAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC;QACtB,QAAQ,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;QACvC,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,EAAE,EAAE,CAAC;YACjB,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC5B,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE;oBACvB,QAAQ,GAAG,IAAI,CAAC;gBACjB,CAAC,CAAiB,CAAC;YACpB,CAAC;YACD,QAAQ,GAAG,IAAI,CAAC;YAChB,OAAO,GAAG,CAAC;QACZ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,QAAQ,GAAG,IAAI,CAAC;YAChB,MAAM,GAAG,CAAC;QACX,CAAC;IACF,CAAC;IACD;;;OAGG;IACH,cAAc,CAAI,EAAW;QAC5B,MAAM,IAAI,GAAG,QAAQ,CAAC;QACtB,QAAQ,GAAG,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;QACpC,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,EAAE,EAAE,CAAC;YACjB,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC5B,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE;oBACvB,QAAQ,GAAG,IAAI,CAAC;gBACjB,CAAC,CAAiB,CAAC;YACpB,CAAC;YACD,QAAQ,GAAG,IAAI,CAAC;YAChB,OAAO,GAAG,CAAC;QACZ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,QAAQ,GAAG,IAAI,CAAC;YAChB,MAAM,GAAG,CAAC;QACX,CAAC;IACF,CAAC;CACD,CAAC"}
@@ -0,0 +1,66 @@
1
+ export type OrchestratorEvent = {
2
+ kind: "pipeline-start";
3
+ ts: string;
4
+ entityKind: "bug" | "task" | "sprint";
5
+ entityId: string;
6
+ sessionId?: string;
7
+ } | {
8
+ kind: "phase-start";
9
+ ts: string;
10
+ phase: string;
11
+ phaseIndex: number;
12
+ phaseCount: number;
13
+ attempt: number;
14
+ workflowFile: string;
15
+ persona: string;
16
+ } | {
17
+ kind: "phase-end";
18
+ ts: string;
19
+ phase: string;
20
+ phaseIndex: number;
21
+ attempt: number;
22
+ verdict: "approved" | "revision" | "n/a" | "error" | "cancelled" | "halted";
23
+ elapsedMs: number;
24
+ turns?: number;
25
+ toolCount?: number;
26
+ errCount?: number;
27
+ subagentTranscriptPath?: string;
28
+ } | {
29
+ kind: "phase-loopback";
30
+ ts: string;
31
+ fromPhase: string;
32
+ toPhase: string;
33
+ fromPhaseIndex: number;
34
+ toPhaseIndex: number;
35
+ reason: string;
36
+ } | {
37
+ kind: "pipeline-end";
38
+ ts: string;
39
+ outcome: "complete" | "halted" | "cancelled" | "error";
40
+ elapsedMs: number;
41
+ reason?: string;
42
+ } | {
43
+ kind: "notify";
44
+ ts: string;
45
+ level: "info" | "warn" | "error" | "success";
46
+ message: string;
47
+ };
48
+ export interface OpenOrchestratorTranscriptOpts {
49
+ cwd: string;
50
+ entityKind: "bug" | "task" | "sprint";
51
+ entityId: string;
52
+ startedAt?: Date;
53
+ sessionId?: string;
54
+ }
55
+ export declare class OrchestratorTranscriptWriter {
56
+ readonly filePath: string;
57
+ readonly startedAt: Date;
58
+ private closed;
59
+ constructor(opts: OpenOrchestratorTranscriptOpts);
60
+ /**
61
+ * Append a single event to the JSONL log. Non-fatal on write failure —
62
+ * the orchestrator transcript is observability data, not load-bearing.
63
+ */
64
+ record(event: OrchestratorEvent): void;
65
+ close(outcome: "complete" | "halted" | "cancelled" | "error", reason?: string): void;
66
+ }
@@ -0,0 +1,66 @@
1
+ // orchestrator-transcript.ts — JSONL log of the orchestrator loop's own
2
+ // activity (fix-bug, run-task, run-sprint). Sibling to the per-subagent
3
+ // transcripts but captures what the orchestrator did between phases:
4
+ // phase boundaries, verdicts, loop-backs, halt/cancel reasons.
5
+ //
6
+ // Filename mirrors the subagent-transcript scheme:
7
+ // .forge/transcripts/<entityId>/<ISO-compact>__<entityId>__orchestrator.jsonl
8
+ //
9
+ // JSONL (one JSON object per line) so we can append safely even if the
10
+ // process crashes mid-stream. The reader stitches lines back together.
11
+ import * as fs from "node:fs";
12
+ import * as path from "node:path";
13
+ import { formatTranscriptTimestamp } from "../forge-subagent.js";
14
+ export class OrchestratorTranscriptWriter {
15
+ filePath;
16
+ startedAt;
17
+ closed = false;
18
+ constructor(opts) {
19
+ this.startedAt = opts.startedAt ?? new Date();
20
+ const base = path.join(opts.cwd, ".forge", "transcripts");
21
+ const sanitizedId = opts.entityId
22
+ .replace(/[^a-zA-Z0-9._-]/g, "_")
23
+ .replace(/\.{2,}/g, "_")
24
+ .slice(0, 80);
25
+ const dir = path.join(base, sanitizedId);
26
+ const ts = formatTranscriptTimestamp(this.startedAt);
27
+ const filename = `${ts}__${sanitizedId}__orchestrator.jsonl`;
28
+ this.filePath = path.join(dir, filename);
29
+ fs.mkdirSync(dir, { recursive: true });
30
+ this.record({
31
+ kind: "pipeline-start",
32
+ ts: this.startedAt.toISOString(),
33
+ entityKind: opts.entityKind,
34
+ entityId: opts.entityId,
35
+ sessionId: opts.sessionId,
36
+ });
37
+ }
38
+ /**
39
+ * Append a single event to the JSONL log. Non-fatal on write failure —
40
+ * the orchestrator transcript is observability data, not load-bearing.
41
+ */
42
+ record(event) {
43
+ if (this.closed)
44
+ return;
45
+ try {
46
+ fs.appendFileSync(this.filePath, `${JSON.stringify(event)}\n`, "utf-8");
47
+ }
48
+ catch (err) {
49
+ const e = err;
50
+ process.stderr.write(`[orchestrator-transcript] append failed (non-fatal): ${e.message ?? "unknown"}\n`);
51
+ }
52
+ }
53
+ close(outcome, reason) {
54
+ if (this.closed)
55
+ return;
56
+ this.record({
57
+ kind: "pipeline-end",
58
+ ts: new Date().toISOString(),
59
+ outcome,
60
+ elapsedMs: Date.now() - this.startedAt.getTime(),
61
+ reason,
62
+ });
63
+ this.closed = true;
64
+ }
65
+ }
66
+ //# sourceMappingURL=orchestrator-transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator-transcript.js","sourceRoot":"","sources":["../../../../src/extensions/forgecli/subagent/orchestrator-transcript.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,wEAAwE;AACxE,qEAAqE;AACrE,+DAA+D;AAC/D,EAAE;AACF,mDAAmD;AACnD,gFAAgF;AAChF,EAAE;AACF,uEAAuE;AACvE,uEAAuE;AAEvE,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AA+CjE,MAAM,OAAO,4BAA4B;IAC/B,QAAQ,CAAS;IACjB,SAAS,CAAO;IACjB,MAAM,GAAG,KAAK,CAAC;IAEvB,YAAY,IAAoC;QAC/C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;QAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ;aAC/B,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC;aAChC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;aACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACzC,MAAM,EAAE,GAAG,yBAAyB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,GAAG,EAAE,KAAK,WAAW,sBAAsB,CAAC;QAC7D,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACzC,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC;YACX,IAAI,EAAE,gBAAgB;YACtB,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE;YAChC,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS,EAAE,IAAI,CAAC,SAAS;SACzB,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAwB;QAC9B,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC;YACJ,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACzE,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,GAA2B,CAAC;YACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC,OAAO,IAAI,SAAS,IAAI,CAAC,CAAC;QAC1G,CAAC;IACF,CAAC;IAED,KAAK,CAAC,OAAsD,EAAE,MAAe;QAC5E,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,CAAC;YACX,IAAI,EAAE,cAAc;YACpB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,OAAO;YACP,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;YAChD,MAAM;SACN,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACpB,CAAC;CACD"}
@@ -0,0 +1,34 @@
1
+ import type { PhaseRole } from "./caller-context.js";
2
+ export declare class PhaseOwnershipError extends Error {
3
+ readonly toolName: string;
4
+ readonly callerPhase: PhaseRole | "orchestrator";
5
+ readonly attemptedPhase: string;
6
+ readonly hint: string;
7
+ constructor(toolName: string, callerPhase: PhaseRole | "orchestrator", attemptedPhase: string, hint?: string);
8
+ }
9
+ /**
10
+ * Assert that the calling subagent's phase context matches the phase
11
+ * named in the tool's arguments. From an orchestrator caller, this is
12
+ * a no-op. From a subagent caller with a mismatched phase, throws
13
+ * `PhaseOwnershipError`.
14
+ *
15
+ * @param toolName Display name of the tool / subcommand for the error message.
16
+ * @param namedPhase The phase string passed to the tool (e.g. `--phase commit`
17
+ * or the `phase` positional arg of `set-bug-summary`).
18
+ */
19
+ export declare function assertPhaseOwnership(toolName: string, namedPhase: string): void;
20
+ /**
21
+ * Assert that a `forge_store update-status bug X status <statusValue>`
22
+ * call is permitted from the current caller context. Status transitions
23
+ * are owned by specific phases or by the orchestrator; calling outside
24
+ * the allowed set is rejected.
25
+ */
26
+ export declare function assertBugStatusOwnership(toolName: string, statusValue: string): void;
27
+ /**
28
+ * Phase-event emissions (`forge_store emit` with a phase token in the
29
+ * payload) are always orchestrator-owned per `meta-fix-bug.md § Iron
30
+ * Laws`. The orchestrator composes the canonical event from runtime
31
+ * telemetry plus the subagent's SUMMARY and emits it; subagents that
32
+ * call emit themselves hallucinate runtime facts.
33
+ */
34
+ export declare function assertOrchestratorOnlyEmit(toolName: string): void;
@@ -0,0 +1,139 @@
1
+ // phase-guard.ts — Defense-in-depth tool-layer enforcement that a
2
+ // subagent only acts within its own phase (FORGE-BUG-040).
3
+ //
4
+ // Background: prior to the fix landed for FORGE-BUG-040, the triage
5
+ // subagent received `fix_bug.md` (the orchestrator-only algorithm) as
6
+ // its workflow body and silently executed the full lifecycle — preflight
7
+ // for every phase, set-bug-summary for every phase, update-status bug
8
+ // X status fixed. The root cause (forge-cli BUG_PHASES wiring + meta
9
+ // source orchestrator-only-body) is fixed at those layers; this guard
10
+ // catches future regressions of the same shape at the tool boundary
11
+ // so they fail loudly with a structured error rather than silently
12
+ // corrupting state.
13
+ //
14
+ // Rule (per BUG_FIX_PLAN.md § Per-tool guard rule):
15
+ // For any tool that names a phase (explicitly or implicitly), the
16
+ // tool's *named phase parameter* MUST equal the caller's `phase`
17
+ // tag when called from a subagent context. From an orchestrator
18
+ // context, the guard is a no-op.
19
+ //
20
+ // Phase ↔ summary-key mapping for set-bug-summary / set-summary is
21
+ // imported from the canonical phase-summary-map.ts. The guard does NOT
22
+ // duplicate the mapping inline — a divergence between the runtime guard
23
+ // and the dispatcher's summary writes would be undetectable otherwise.
24
+ //
25
+ // Iron Laws:
26
+ // IL1 — code only under forge-cli/src/extensions/forgecli/.
27
+ // IL7 — every refusal path throws PhaseOwnershipError (no silent
28
+ // continuation past a guard failure).
29
+ import { CallerContextStore } from "./caller-context.js";
30
+ import { BUG_SUMMARY_KEY_BY_ROLE } from "./phase-summary-map.js";
31
+ /**
32
+ * Bug-status transitions that may only be written by a specific phase
33
+ * (subagent caller) or by the orchestrator. Used by the guard for
34
+ * `forge_store update-status bug X status ...` calls.
35
+ */
36
+ const BUG_STATUS_OWNERSHIP = {
37
+ // commit phase makes the git commit then transitions bug.status to fixed
38
+ fixed: { allowedSubagentPhases: ["commit"], orchestratorAllowed: true },
39
+ // triaged and in-progress are orchestrator-only transitions
40
+ triaged: { allowedSubagentPhases: [], orchestratorAllowed: true },
41
+ "in-progress": { allowedSubagentPhases: [], orchestratorAllowed: true },
42
+ // escalation paths — allowed from orchestrator OR the current phase
43
+ // (the calling subagent is in some phase; escalation is in-band)
44
+ escalated: { allowedSubagentPhases: [], orchestratorAllowed: true, anySubagent: true },
45
+ blocked: { allowedSubagentPhases: [], orchestratorAllowed: true, anySubagent: true },
46
+ abandoned: { allowedSubagentPhases: [], orchestratorAllowed: true, anySubagent: true },
47
+ };
48
+ export class PhaseOwnershipError extends Error {
49
+ toolName;
50
+ callerPhase;
51
+ attemptedPhase;
52
+ hint;
53
+ constructor(toolName, callerPhase, attemptedPhase, hint = "") {
54
+ super(`phase-ownership: subagent in phase '${callerPhase}' attempted ${toolName} for phase '${attemptedPhase}'` +
55
+ (hint ? ` — ${hint}` : ""));
56
+ this.name = "PhaseOwnershipError";
57
+ this.toolName = toolName;
58
+ this.callerPhase = callerPhase;
59
+ this.attemptedPhase = attemptedPhase;
60
+ this.hint = hint;
61
+ }
62
+ }
63
+ /**
64
+ * Assert that the calling subagent's phase context matches the phase
65
+ * named in the tool's arguments. From an orchestrator caller, this is
66
+ * a no-op. From a subagent caller with a mismatched phase, throws
67
+ * `PhaseOwnershipError`.
68
+ *
69
+ * @param toolName Display name of the tool / subcommand for the error message.
70
+ * @param namedPhase The phase string passed to the tool (e.g. `--phase commit`
71
+ * or the `phase` positional arg of `set-bug-summary`).
72
+ */
73
+ export function assertPhaseOwnership(toolName, namedPhase) {
74
+ const caller = CallerContextStore.get();
75
+ if (caller.kind === "orchestrator")
76
+ return;
77
+ // set-bug-summary / set-summary callers pass the legacy summary-key
78
+ // (e.g. "implementation") rather than the PhaseRole (e.g. "implement").
79
+ // Always route through the summary-key path for these tools — a
80
+ // direct-name match (caller.phase === namedPhase) would falsely allow
81
+ // a commit-phase caller to call `set-bug-summary <bug> commit ...` even
82
+ // though commit writes no summary at all.
83
+ const isSummaryTool = toolName.includes("set-bug-summary") || toolName.includes("set-summary");
84
+ if (!isSummaryTool && caller.phase === namedPhase)
85
+ return;
86
+ if (isSummaryTool) {
87
+ const expectedKey = BUG_SUMMARY_KEY_BY_ROLE[caller.phase];
88
+ if (expectedKey === null) {
89
+ throw new PhaseOwnershipError(toolName, caller.phase, namedPhase, `phase '${caller.phase}' writes no summary — set-bug-summary is forbidden from this phase`);
90
+ }
91
+ if (expectedKey === undefined) {
92
+ throw new PhaseOwnershipError(toolName, caller.phase, namedPhase, `phase '${caller.phase}' is not a recognised bug-mode phase`);
93
+ }
94
+ if (expectedKey !== namedPhase) {
95
+ throw new PhaseOwnershipError(toolName, caller.phase, namedPhase, `expected summary key '${expectedKey}' for caller phase`);
96
+ }
97
+ return;
98
+ }
99
+ throw new PhaseOwnershipError(toolName, caller.phase, namedPhase);
100
+ }
101
+ /**
102
+ * Assert that a `forge_store update-status bug X status <statusValue>`
103
+ * call is permitted from the current caller context. Status transitions
104
+ * are owned by specific phases or by the orchestrator; calling outside
105
+ * the allowed set is rejected.
106
+ */
107
+ export function assertBugStatusOwnership(toolName, statusValue) {
108
+ const caller = CallerContextStore.get();
109
+ const rule = BUG_STATUS_OWNERSHIP[statusValue];
110
+ if (!rule) {
111
+ // Unknown status — let downstream schema validation reject it
112
+ // with its own (more informative) error.
113
+ return;
114
+ }
115
+ if (caller.kind === "orchestrator") {
116
+ if (rule.orchestratorAllowed)
117
+ return;
118
+ throw new PhaseOwnershipError(toolName, "orchestrator", `update-status bug ${statusValue}`, "this status transition is not orchestrator-allowed");
119
+ }
120
+ if (rule.anySubagent)
121
+ return;
122
+ if (rule.allowedSubagentPhases.includes(caller.phase))
123
+ return;
124
+ throw new PhaseOwnershipError(toolName, caller.phase, `update-status bug ${statusValue}`, `status '${statusValue}' may only be written from phase(s): ${rule.allowedSubagentPhases.join(", ") || "(orchestrator only)"}`);
125
+ }
126
+ /**
127
+ * Phase-event emissions (`forge_store emit` with a phase token in the
128
+ * payload) are always orchestrator-owned per `meta-fix-bug.md § Iron
129
+ * Laws`. The orchestrator composes the canonical event from runtime
130
+ * telemetry plus the subagent's SUMMARY and emits it; subagents that
131
+ * call emit themselves hallucinate runtime facts.
132
+ */
133
+ export function assertOrchestratorOnlyEmit(toolName) {
134
+ const caller = CallerContextStore.get();
135
+ if (caller.kind === "orchestrator")
136
+ return;
137
+ throw new PhaseOwnershipError(toolName, caller.phase, "emit (phase event)", "phase event emission is orchestrator-only — subagents write SUMMARY files and return");
138
+ }
139
+ //# sourceMappingURL=phase-guard.js.map