@entelligentsia/forgecli 0.7.10 → 0.9.0

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 (385) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/dist/CHANGELOG-forge-plugin.md +70 -0
  3. package/dist/CHANGELOG-pi.md +63 -0
  4. package/dist/bin/argv.d.ts +2 -2
  5. package/dist/bin/argv.js +27 -0
  6. package/dist/bin/argv.js.map +1 -1
  7. package/dist/bin/config.d.ts +69 -0
  8. package/dist/bin/config.js +315 -0
  9. package/dist/bin/config.js.map +1 -0
  10. package/dist/bin/doctor.d.ts +1 -0
  11. package/dist/bin/doctor.js +12 -0
  12. package/dist/bin/doctor.js.map +1 -1
  13. package/dist/bin/env-defaults.d.ts +1 -0
  14. package/dist/bin/env-defaults.js +13 -0
  15. package/dist/bin/env-defaults.js.map +1 -0
  16. package/dist/bin/forge.js +16 -0
  17. package/dist/bin/forge.js.map +1 -1
  18. package/dist/bin/update-cli.d.ts +9 -0
  19. package/dist/bin/update-cli.js +120 -0
  20. package/dist/bin/update-cli.js.map +1 -0
  21. package/dist/extensions/forgecli/config-command.d.ts +8 -0
  22. package/dist/extensions/forgecli/config-command.js +66 -0
  23. package/dist/extensions/forgecli/config-command.js.map +1 -0
  24. package/dist/extensions/forgecli/config-layer.d.ts +38 -0
  25. package/dist/extensions/forgecli/config-layer.js +68 -0
  26. package/dist/extensions/forgecli/config-layer.js.map +1 -0
  27. package/dist/extensions/forgecli/config-tui/component.d.ts +35 -0
  28. package/dist/extensions/forgecli/config-tui/component.js +236 -0
  29. package/dist/extensions/forgecli/config-tui/component.js.map +1 -0
  30. package/dist/extensions/forgecli/config-tui/handler.d.ts +40 -0
  31. package/dist/extensions/forgecli/config-tui/handler.js +240 -0
  32. package/dist/extensions/forgecli/config-tui/handler.js.map +1 -0
  33. package/dist/extensions/forgecli/config-tui/index.d.ts +5 -0
  34. package/dist/extensions/forgecli/config-tui/index.js +5 -0
  35. package/dist/extensions/forgecli/config-tui/index.js.map +1 -0
  36. package/dist/extensions/forgecli/config-tui/keys.d.ts +26 -0
  37. package/dist/extensions/forgecli/config-tui/keys.js +33 -0
  38. package/dist/extensions/forgecli/config-tui/keys.js.map +1 -0
  39. package/dist/extensions/forgecli/config-tui/plugin-config-reader.d.ts +23 -0
  40. package/dist/extensions/forgecli/config-tui/plugin-config-reader.js +58 -0
  41. package/dist/extensions/forgecli/config-tui/plugin-config-reader.js.map +1 -0
  42. package/dist/extensions/forgecli/config-tui/screens/advanced-menu.d.ts +7 -0
  43. package/dist/extensions/forgecli/config-tui/screens/advanced-menu.js +83 -0
  44. package/dist/extensions/forgecli/config-tui/screens/advanced-menu.js.map +1 -0
  45. package/dist/extensions/forgecli/config-tui/screens/confirm-quit.d.ts +11 -0
  46. package/dist/extensions/forgecli/config-tui/screens/confirm-quit.js +54 -0
  47. package/dist/extensions/forgecli/config-tui/screens/confirm-quit.js.map +1 -0
  48. package/dist/extensions/forgecli/config-tui/screens/override-editor.d.ts +11 -0
  49. package/dist/extensions/forgecli/config-tui/screens/override-editor.js +233 -0
  50. package/dist/extensions/forgecli/config-tui/screens/override-editor.js.map +1 -0
  51. package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.d.ts +7 -0
  52. package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.js +91 -0
  53. package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.js.map +1 -0
  54. package/dist/extensions/forgecli/config-tui/screens/overrides-list.d.ts +7 -0
  55. package/dist/extensions/forgecli/config-tui/screens/overrides-list.js +71 -0
  56. package/dist/extensions/forgecli/config-tui/screens/overrides-list.js.map +1 -0
  57. package/dist/extensions/forgecli/config-tui/screens/persona-editor.d.ts +10 -0
  58. package/dist/extensions/forgecli/config-tui/screens/persona-editor.js +182 -0
  59. package/dist/extensions/forgecli/config-tui/screens/persona-editor.js.map +1 -0
  60. package/dist/extensions/forgecli/config-tui/screens/persona-picker.d.ts +7 -0
  61. package/dist/extensions/forgecli/config-tui/screens/persona-picker.js +76 -0
  62. package/dist/extensions/forgecli/config-tui/screens/persona-picker.js.map +1 -0
  63. package/dist/extensions/forgecli/config-tui/screens/personas-list.d.ts +7 -0
  64. package/dist/extensions/forgecli/config-tui/screens/personas-list.js +98 -0
  65. package/dist/extensions/forgecli/config-tui/screens/personas-list.js.map +1 -0
  66. package/dist/extensions/forgecli/config-tui/screens/shared.d.ts +29 -0
  67. package/dist/extensions/forgecli/config-tui/screens/shared.js +100 -0
  68. package/dist/extensions/forgecli/config-tui/screens/shared.js.map +1 -0
  69. package/dist/extensions/forgecli/config-tui/screens/show-resolved.d.ts +23 -0
  70. package/dist/extensions/forgecli/config-tui/screens/show-resolved.js +128 -0
  71. package/dist/extensions/forgecli/config-tui/screens/show-resolved.js.map +1 -0
  72. package/dist/extensions/forgecli/config-tui/screens/tier-menu.d.ts +7 -0
  73. package/dist/extensions/forgecli/config-tui/screens/tier-menu.js +135 -0
  74. package/dist/extensions/forgecli/config-tui/screens/tier-menu.js.map +1 -0
  75. package/dist/extensions/forgecli/config-tui/screens/tier-picker.d.ts +9 -0
  76. package/dist/extensions/forgecli/config-tui/screens/tier-picker.js +122 -0
  77. package/dist/extensions/forgecli/config-tui/screens/tier-picker.js.map +1 -0
  78. package/dist/extensions/forgecli/config-tui/screens/types.d.ts +24 -0
  79. package/dist/extensions/forgecli/config-tui/screens/types.js +5 -0
  80. package/dist/extensions/forgecli/config-tui/screens/types.js.map +1 -0
  81. package/dist/extensions/forgecli/config-tui/screens.d.ts +24 -0
  82. package/dist/extensions/forgecli/config-tui/screens.js +78 -0
  83. package/dist/extensions/forgecli/config-tui/screens.js.map +1 -0
  84. package/dist/extensions/forgecli/config-tui/state/buffer.d.ts +11 -0
  85. package/dist/extensions/forgecli/config-tui/state/buffer.js +91 -0
  86. package/dist/extensions/forgecli/config-tui/state/buffer.js.map +1 -0
  87. package/dist/extensions/forgecli/config-tui/state/constants.d.ts +4 -0
  88. package/dist/extensions/forgecli/config-tui/state/constants.js +14 -0
  89. package/dist/extensions/forgecli/config-tui/state/constants.js.map +1 -0
  90. package/dist/extensions/forgecli/config-tui/state/index.d.ts +6 -0
  91. package/dist/extensions/forgecli/config-tui/state/index.js +9 -0
  92. package/dist/extensions/forgecli/config-tui/state/index.js.map +1 -0
  93. package/dist/extensions/forgecli/config-tui/state/init.d.ts +2 -0
  94. package/dist/extensions/forgecli/config-tui/state/init.js +30 -0
  95. package/dist/extensions/forgecli/config-tui/state/init.js.map +1 -0
  96. package/dist/extensions/forgecli/config-tui/state/model.d.ts +192 -0
  97. package/dist/extensions/forgecli/config-tui/state/model.js +4 -0
  98. package/dist/extensions/forgecli/config-tui/state/model.js.map +1 -0
  99. package/dist/extensions/forgecli/config-tui/state/reducer.d.ts +2 -0
  100. package/dist/extensions/forgecli/config-tui/state/reducer.js +212 -0
  101. package/dist/extensions/forgecli/config-tui/state/reducer.js.map +1 -0
  102. package/dist/extensions/forgecli/config-tui/state/selectors.d.ts +91 -0
  103. package/dist/extensions/forgecli/config-tui/state/selectors.js +231 -0
  104. package/dist/extensions/forgecli/config-tui/state/selectors.js.map +1 -0
  105. package/dist/extensions/forgecli/config-tui/state.d.ts +6 -0
  106. package/dist/extensions/forgecli/config-tui/state.js +11 -0
  107. package/dist/extensions/forgecli/config-tui/state.js.map +1 -0
  108. package/dist/extensions/forgecli/config-tui/theme.d.ts +37 -0
  109. package/dist/extensions/forgecli/config-tui/theme.js +88 -0
  110. package/dist/extensions/forgecli/config-tui/theme.js.map +1 -0
  111. package/dist/extensions/forgecli/config-tui/tier-meta.d.ts +28 -0
  112. package/dist/extensions/forgecli/config-tui/tier-meta.js +69 -0
  113. package/dist/extensions/forgecli/config-tui/tier-meta.js.map +1 -0
  114. package/dist/extensions/forgecli/config-writer.d.ts +16 -0
  115. package/dist/extensions/forgecli/config-writer.js +63 -0
  116. package/dist/extensions/forgecli/config-writer.js.map +1 -0
  117. package/dist/extensions/forgecli/fix-bug.js +85 -1
  118. package/dist/extensions/forgecli/fix-bug.js.map +1 -1
  119. package/dist/extensions/forgecli/forge-cli-schema.json +54 -0
  120. package/dist/extensions/forgecli/forge-commands.js +3 -8
  121. package/dist/extensions/forgecli/forge-commands.js.map +1 -1
  122. package/dist/extensions/forgecli/forge-subagent.d.ts +13 -0
  123. package/dist/extensions/forgecli/forge-subagent.js +19 -0
  124. package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
  125. package/dist/extensions/forgecli/index.js +19 -3
  126. package/dist/extensions/forgecli/index.js.map +1 -1
  127. package/dist/extensions/forgecli/input-router.d.ts +33 -0
  128. package/dist/extensions/forgecli/input-router.js +133 -0
  129. package/dist/extensions/forgecli/input-router.js.map +1 -0
  130. package/dist/extensions/forgecli/model-resolver.d.ts +32 -0
  131. package/dist/extensions/forgecli/model-resolver.js +65 -0
  132. package/dist/extensions/forgecli/model-resolver.js.map +1 -0
  133. package/dist/extensions/forgecli/model-validator.d.ts +29 -0
  134. package/dist/extensions/forgecli/model-validator.js +107 -0
  135. package/dist/extensions/forgecli/model-validator.js.map +1 -0
  136. package/dist/extensions/forgecli/run-sprint.js +59 -0
  137. package/dist/extensions/forgecli/run-sprint.js.map +1 -1
  138. package/dist/extensions/forgecli/run-task.js +93 -1
  139. package/dist/extensions/forgecli/run-task.js.map +1 -1
  140. package/dist/extensions/forgecli/thread-switcher.js +5 -2
  141. package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
  142. package/dist/extensions/forgecli/update-check.js +1 -1
  143. package/dist/extensions/forgecli/update-check.js.map +1 -1
  144. package/dist/extensions/forgecli/whats-new-widget.d.ts +5 -5
  145. package/dist/extensions/forgecli/whats-new-widget.js +16 -13
  146. package/dist/extensions/forgecli/whats-new-widget.js.map +1 -1
  147. package/dist/extensions/forgecli/whats-new.js +6 -5
  148. package/dist/extensions/forgecli/whats-new.js.map +1 -1
  149. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  150. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +27 -98
  151. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  152. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +62 -132
  153. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
  154. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  155. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +25 -15
  156. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  157. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  158. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +1 -0
  159. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
  160. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  161. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js +17 -1
  162. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  163. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  164. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +8 -2
  165. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js.map +1 -1
  166. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  167. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js +17 -1
  168. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js.map +1 -1
  169. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  170. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js +8 -1
  171. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js.map +1 -1
  172. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  173. package/node_modules/@earendil-works/pi-coding-agent/CHANGELOG.md +63 -0
  174. package/node_modules/@earendil-works/pi-coding-agent/README.md +1 -1
  175. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/config-selector.d.ts.map +1 -1
  176. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/config-selector.js +1 -1
  177. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/config-selector.js.map +1 -1
  178. package/node_modules/@earendil-works/pi-coding-agent/dist/cli.d.ts.map +1 -1
  179. package/node_modules/@earendil-works/pi-coding-agent/dist/cli.js +6 -10
  180. package/node_modules/@earendil-works/pi-coding-agent/dist/cli.js.map +1 -1
  181. package/node_modules/@earendil-works/pi-coding-agent/dist/config.d.ts.map +1 -1
  182. package/node_modules/@earendil-works/pi-coding-agent/dist/config.js +12 -3
  183. package/node_modules/@earendil-works/pi-coding-agent/dist/config.js.map +1 -1
  184. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.d.ts +1 -0
  185. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  186. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js +30 -15
  187. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  188. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.d.ts +3 -3
  189. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  190. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.js +23 -13
  191. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  192. package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.d.ts +4 -0
  193. package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  194. package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js +58 -38
  195. package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  196. package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  197. package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.js +0 -1
  198. package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  199. package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  200. package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js +3 -2
  201. package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  202. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts +2 -2
  203. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  204. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.js +7 -4
  205. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.js.map +1 -1
  206. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  207. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js +6 -2
  208. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  209. package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.d.ts.map +1 -1
  210. package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js +3 -4
  211. package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js.map +1 -1
  212. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.d.ts.map +1 -1
  213. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.js +2 -2
  214. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.js.map +1 -1
  215. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/child-process.d.ts +7 -1
  216. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/child-process.d.ts.map +1 -1
  217. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/child-process.js +60 -7
  218. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/child-process.js.map +1 -1
  219. package/node_modules/@earendil-works/pi-coding-agent/docs/packages.md +2 -2
  220. package/node_modules/@earendil-works/pi-coding-agent/docs/settings.md +1 -3
  221. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-anthropic/package.json +1 -1
  222. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  223. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/sandbox/package.json +1 -1
  224. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/with-deps/package.json +1 -1
  225. package/node_modules/@earendil-works/pi-coding-agent/package.json +6 -6
  226. package/node_modules/@earendil-works/pi-tui/package.json +2 -2
  227. package/node_modules/@protobufjs/fetch/CHANGELOG.md +8 -0
  228. package/node_modules/@protobufjs/fetch/index.d.ts +7 -7
  229. package/node_modules/@protobufjs/fetch/index.js +4 -7
  230. package/node_modules/@protobufjs/fetch/package.json +7 -5
  231. package/node_modules/@protobufjs/fetch/tests/data/file.txt +1 -0
  232. package/node_modules/@protobufjs/fetch/tests/index.js +150 -8
  233. package/node_modules/@protobufjs/fetch/util/fs.js +11 -0
  234. package/node_modules/@protobufjs/inquire/CHANGELOG.md +8 -0
  235. package/node_modules/@protobufjs/inquire/index.d.ts +1 -0
  236. package/node_modules/@protobufjs/inquire/index.js +1 -0
  237. package/node_modules/@protobufjs/inquire/package.json +1 -1
  238. package/node_modules/protobufjs/dist/light/protobuf.js +187 -153
  239. package/node_modules/protobufjs/dist/light/protobuf.js.map +1 -1
  240. package/node_modules/protobufjs/dist/light/protobuf.min.js +3 -3
  241. package/node_modules/protobufjs/dist/light/protobuf.min.js.map +1 -1
  242. package/node_modules/protobufjs/dist/minimal/protobuf.js +14 -5
  243. package/node_modules/protobufjs/dist/minimal/protobuf.js.map +1 -1
  244. package/node_modules/protobufjs/dist/minimal/protobuf.min.js +3 -3
  245. package/node_modules/protobufjs/dist/minimal/protobuf.min.js.map +1 -1
  246. package/node_modules/protobufjs/dist/protobuf.js +207 -173
  247. package/node_modules/protobufjs/dist/protobuf.js.map +1 -1
  248. package/node_modules/protobufjs/dist/protobuf.min.js +3 -3
  249. package/node_modules/protobufjs/dist/protobuf.min.js.map +1 -1
  250. package/node_modules/protobufjs/package.json +6 -3
  251. package/node_modules/protobufjs/src/util/fs.js +11 -0
  252. package/node_modules/protobufjs/src/util/minimal.js +10 -2
  253. package/node_modules/protobufjs/src/util.js +1 -1
  254. package/node_modules/undici/README.md +14 -5
  255. package/node_modules/undici/docs/docs/api/Client.md +4 -2
  256. package/node_modules/undici/docs/docs/api/Dispatcher.md +62 -27
  257. package/node_modules/undici/docs/docs/api/GlobalInstallation.md +7 -5
  258. package/node_modules/undici/docs/docs/api/H2CClient.md +1 -1
  259. package/node_modules/undici/docs/docs/api/RedirectHandler.md +14 -9
  260. package/node_modules/undici/docs/docs/api/RetryAgent.md +0 -1
  261. package/node_modules/undici/docs/docs/api/RetryHandler.md +12 -14
  262. package/node_modules/undici/docs/docs/api/SnapshotAgent.md +23 -0
  263. package/node_modules/undici/docs/docs/best-practices/migrating-from-v7-to-v8.md +231 -0
  264. package/node_modules/undici/index.js +4 -2
  265. package/node_modules/undici/lib/api/api-connect.js +13 -11
  266. package/node_modules/undici/lib/api/api-pipeline.js +26 -13
  267. package/node_modules/undici/lib/api/api-request.js +45 -21
  268. package/node_modules/undici/lib/api/api-stream.js +81 -20
  269. package/node_modules/undici/lib/api/api-upgrade.js +21 -11
  270. package/node_modules/undici/lib/api/readable.js +3 -2
  271. package/node_modules/undici/lib/cache/memory-cache-store.js +1 -1
  272. package/node_modules/undici/lib/cache/sqlite-cache-store.js +6 -4
  273. package/node_modules/undici/lib/core/connect.js +17 -1
  274. package/node_modules/undici/lib/core/constants.js +1 -24
  275. package/node_modules/undici/lib/core/errors.js +2 -2
  276. package/node_modules/undici/lib/core/request.js +115 -18
  277. package/node_modules/undici/lib/core/socks5-client.js +24 -9
  278. package/node_modules/undici/lib/core/socks5-utils.js +32 -23
  279. package/node_modules/undici/lib/core/symbols.js +1 -0
  280. package/node_modules/undici/lib/core/util.js +70 -43
  281. package/node_modules/undici/lib/dispatcher/agent.js +47 -33
  282. package/node_modules/undici/lib/dispatcher/balanced-pool.js +21 -26
  283. package/node_modules/undici/lib/dispatcher/client-h1.js +98 -39
  284. package/node_modules/undici/lib/dispatcher/client-h2.js +603 -272
  285. package/node_modules/undici/lib/dispatcher/client.js +12 -5
  286. package/node_modules/undici/lib/dispatcher/dispatcher-base.js +24 -5
  287. package/node_modules/undici/lib/dispatcher/dispatcher.js +0 -4
  288. package/node_modules/undici/lib/dispatcher/dispatcher1-wrapper.js +107 -0
  289. package/node_modules/undici/lib/dispatcher/h2c-client.js +5 -5
  290. package/node_modules/undici/lib/dispatcher/pool-base.js +28 -10
  291. package/node_modules/undici/lib/dispatcher/pool.js +31 -6
  292. package/node_modules/undici/lib/dispatcher/proxy-agent.js +38 -13
  293. package/node_modules/undici/lib/dispatcher/round-robin-pool.js +31 -9
  294. package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +95 -80
  295. package/node_modules/undici/lib/global.js +13 -1
  296. package/node_modules/undici/lib/handler/cache-handler.js +16 -8
  297. package/node_modules/undici/lib/handler/decorator-handler.js +1 -2
  298. package/node_modules/undici/lib/handler/redirect-handler.js +5 -51
  299. package/node_modules/undici/lib/handler/retry-handler.js +15 -2
  300. package/node_modules/undici/lib/interceptor/cache.js +30 -17
  301. package/node_modules/undici/lib/interceptor/decompress.js +28 -2
  302. package/node_modules/undici/lib/interceptor/dns.js +1 -1
  303. package/node_modules/undici/lib/interceptor/redirect.js +3 -3
  304. package/node_modules/undici/lib/llhttp/llhttp-wasm.js +1 -1
  305. package/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +1 -1
  306. package/node_modules/undici/lib/mock/mock-agent.js +8 -8
  307. package/node_modules/undici/lib/mock/mock-call-history.js +15 -15
  308. package/node_modules/undici/lib/mock/mock-utils.js +37 -22
  309. package/node_modules/undici/lib/mock/snapshot-agent.js +16 -6
  310. package/node_modules/undici/lib/mock/snapshot-recorder.js +38 -3
  311. package/node_modules/undici/lib/util/cache.js +8 -7
  312. package/node_modules/undici/lib/util/runtime-features.js +3 -34
  313. package/node_modules/undici/lib/web/cache/cache.js +6 -8
  314. package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +245 -150
  315. package/node_modules/undici/lib/web/fetch/body.js +3 -9
  316. package/node_modules/undici/lib/web/fetch/formdata-parser.js +17 -6
  317. package/node_modules/undici/lib/web/fetch/formdata.js +21 -2
  318. package/node_modules/undici/lib/web/fetch/index.js +214 -221
  319. package/node_modules/undici/lib/web/webidl/index.js +7 -9
  320. package/node_modules/undici/lib/web/websocket/frame.js +1 -7
  321. package/node_modules/undici/lib/web/websocket/permessage-deflate.js +13 -31
  322. package/node_modules/undici/lib/web/websocket/receiver.js +62 -22
  323. package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +11 -17
  324. package/node_modules/undici/lib/web/websocket/websocket.js +6 -1
  325. package/node_modules/undici/package.json +9 -9
  326. package/node_modules/undici/types/agent.d.ts +0 -2
  327. package/node_modules/undici/types/client.d.ts +25 -19
  328. package/node_modules/undici/types/dispatcher.d.ts +7 -27
  329. package/node_modules/undici/types/dispatcher1-wrapper.d.ts +7 -0
  330. package/node_modules/undici/types/formdata.d.ts +0 -6
  331. package/node_modules/undici/types/h2c-client.d.ts +6 -6
  332. package/node_modules/undici/types/header.d.ts +5 -0
  333. package/node_modules/undici/types/index.d.ts +3 -1
  334. package/node_modules/undici/types/interceptors.d.ts +1 -1
  335. package/node_modules/undici/types/pool.d.ts +0 -2
  336. package/node_modules/undici/types/proxy-agent.d.ts +2 -2
  337. package/node_modules/undici/types/round-robin-pool.d.ts +0 -2
  338. package/node_modules/undici/types/snapshot-agent.d.ts +4 -0
  339. package/node_modules/undici/types/socks5-proxy-agent.d.ts +2 -2
  340. package/node_modules/undici/types/webidl.d.ts +0 -1
  341. package/package.json +16 -9
  342. package/dist/extensions/forgecli/review-command.d.ts +0 -2
  343. package/dist/extensions/forgecli/review-command.js +0 -184
  344. package/dist/extensions/forgecli/review-command.js.map +0 -1
  345. package/dist/forge-payload/.tools/banners.cjs +0 -435
  346. package/dist/forge-payload/.tools/build-context-pack.cjs +0 -290
  347. package/dist/forge-payload/.tools/build-init-context.cjs +0 -322
  348. package/dist/forge-payload/.tools/build-overlay.cjs +0 -326
  349. package/dist/forge-payload/.tools/build-persona-pack.cjs +0 -226
  350. package/dist/forge-payload/.tools/collate.cjs +0 -1041
  351. package/dist/forge-payload/.tools/generation-manifest.cjs +0 -311
  352. package/dist/forge-payload/.tools/lib/forge-root.cjs +0 -59
  353. package/dist/forge-payload/.tools/lib/paths.cjs +0 -29
  354. package/dist/forge-payload/.tools/lib/pricing.cjs +0 -165
  355. package/dist/forge-payload/.tools/lib/project-root.cjs +0 -32
  356. package/dist/forge-payload/.tools/lib/result.js +0 -40
  357. package/dist/forge-payload/.tools/lib/store-facade.cjs +0 -162
  358. package/dist/forge-payload/.tools/lib/store-nlp.cjs +0 -250
  359. package/dist/forge-payload/.tools/lib/store-query-exec.cjs +0 -272
  360. package/dist/forge-payload/.tools/lib/validate.js +0 -141
  361. package/dist/forge-payload/.tools/manage-config.cjs +0 -340
  362. package/dist/forge-payload/.tools/manage-versions.cjs +0 -365
  363. package/dist/forge-payload/.tools/package.json +0 -3
  364. package/dist/forge-payload/.tools/parse-gates.cjs +0 -151
  365. package/dist/forge-payload/.tools/parse-verdict.cjs +0 -67
  366. package/dist/forge-payload/.tools/preflight-gate.cjs +0 -350
  367. package/dist/forge-payload/.tools/prompts/sprint-plan-prompt.md +0 -70
  368. package/dist/forge-payload/.tools/schemas/task-list.schema.json +0 -53
  369. package/dist/forge-payload/.tools/seed-store.cjs +0 -237
  370. package/dist/forge-payload/.tools/store-cli.cjs +0 -1226
  371. package/dist/forge-payload/.tools/store-query.cjs +0 -319
  372. package/dist/forge-payload/.tools/store.cjs +0 -315
  373. package/dist/forge-payload/.tools/substitute-placeholders.cjs +0 -625
  374. package/dist/forge-payload/.tools/validate-store.cjs +0 -593
  375. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-anthropic/package-lock.json +0 -24
  376. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/sandbox/package-lock.json +0 -92
  377. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/with-deps/package-lock.json +0 -31
  378. package/node_modules/undici/lib/handler/unwrap-handler.js +0 -100
  379. package/node_modules/undici/lib/handler/wrap-handler.js +0 -105
  380. package/node_modules/undici/lib/llhttp/.gitkeep +0 -0
  381. package/node_modules/undici/lib/util/promise.js +0 -28
  382. package/skills/refresh-kb-links/SKILL.md +0 -217
  383. package/skills/store-custodian/SKILL.md +0 -163
  384. package/skills/store-query-grammar/SKILL.md +0 -145
  385. package/skills/store-query-nlp/SKILL.md +0 -110
@@ -1,141 +0,0 @@
1
- 'use strict';
2
-
3
- // Shared JSON Schema validator for Forge.
4
- //
5
- // Minimal Draft-07 subset used by both store-cli.cjs (tool writes) and the
6
- // write-boundary hook (direct agent writes). Keeps Forge dependency-free.
7
- //
8
- // Supported keywords:
9
- // type (string|number|integer|boolean|array|object; union via array)
10
- // required, properties, additionalProperties: false
11
- // enum, minimum, maxLength, minLength, maxItems, items (type + maxLength)
12
- // pattern (ECMA regex against string values)
13
- // format: "date-time" (ISO 8601)
14
- //
15
- // Not supported (by design): $ref, allOf/anyOf/oneOf, propertyNames,
16
- // dependencies, const. Schemas can express what Forge needs without them.
17
-
18
- // Fields that may legitimately be null (nullable FKs / optional timing).
19
- // Mirrors store-cli.cjs — keep in sync.
20
- const NULLABLE_FIELDS = new Set([
21
- 'sprintId', 'taskId', 'endTimestamp', 'durationMinutes',
22
- 'feature_id', 'description', 'completedAt', 'resolvedAt'
23
- ]);
24
-
25
- function isDateTime(s) {
26
- if (typeof s !== 'string') return false;
27
- // Accept standard ISO 8601 / RFC 3339 date-time strings.
28
- // Require: YYYY-MM-DDTHH:MM:SS(.sss)?(Z|±HH:MM)
29
- return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,9})?(Z|[+-]\d{2}:?\d{2})$/.test(s);
30
- }
31
-
32
- function typeMatches(expected, val) {
33
- if (expected === 'integer') return Number.isInteger(val);
34
- if (expected === 'number') return typeof val === 'number' && !Number.isNaN(val);
35
- if (expected === 'array') return Array.isArray(val);
36
- if (expected === 'null') return val === null;
37
- if (expected === 'object') return val !== null && typeof val === 'object' && !Array.isArray(val);
38
- return typeof val === expected;
39
- }
40
-
41
- function validateRecord(record, schema, opts) {
42
- opts = opts || {};
43
- const errors = [];
44
-
45
- if (record === null || typeof record !== 'object' || Array.isArray(record)) {
46
- errors.push('record: expected object');
47
- return errors;
48
- }
49
-
50
- const required = schema.required || [];
51
- for (const field of required) {
52
- const v = record[field];
53
- if (v === undefined || v === '') {
54
- errors.push(`${field}: missing required field`);
55
- } else if (v === null && !NULLABLE_FIELDS.has(field)) {
56
- errors.push(`${field}: missing required field`);
57
- }
58
- }
59
-
60
- const properties = schema.properties || {};
61
-
62
- for (const [field, def] of Object.entries(properties)) {
63
- const val = record[field];
64
- if (val === undefined || val === null) continue;
65
-
66
- if (def.type) {
67
- const ok = Array.isArray(def.type)
68
- ? def.type.some(t => typeMatches(t, val))
69
- : typeMatches(def.type, val);
70
- if (!ok) {
71
- errors.push(`${field}: expected ${def.type}, got ${Array.isArray(val) ? 'array' : typeof val}`);
72
- continue;
73
- }
74
- }
75
-
76
- if (def.enum && !def.enum.includes(val)) {
77
- errors.push(`${field}: value "${val}" not in [${def.enum.join(', ')}]`);
78
- }
79
-
80
- if (def.minimum !== undefined && typeof val === 'number' && val < def.minimum) {
81
- errors.push(`${field}: value ${val} is below minimum ${def.minimum}`);
82
- }
83
-
84
- if (typeof val === 'string') {
85
- if (def.maxLength !== undefined && val.length > def.maxLength) {
86
- errors.push(`${field}: value length ${val.length} exceeds maxLength ${def.maxLength}`);
87
- }
88
- if (def.minLength !== undefined && val.length < def.minLength) {
89
- errors.push(`${field}: value length ${val.length} is below minLength ${def.minLength}`);
90
- }
91
- if (def.pattern) {
92
- let re;
93
- try { re = new RegExp(def.pattern); }
94
- catch (_) { errors.push(`${field}: invalid schema pattern`); re = null; }
95
- if (re && !re.test(val)) {
96
- errors.push(`${field}: value "${val}" does not match pattern ${def.pattern}`);
97
- }
98
- }
99
- if (def.format === 'date-time' && !isDateTime(val)) {
100
- errors.push(`${field}: value "${val}" is not a valid date-time`);
101
- }
102
- }
103
-
104
- if (Array.isArray(val)) {
105
- if (def.maxItems !== undefined && val.length > def.maxItems) {
106
- errors.push(`${field}: array has ${val.length} items, exceeds maxItems ${def.maxItems}`);
107
- }
108
- if (def.items) {
109
- val.forEach((item, idx) => {
110
- if (def.items.type && !typeMatches(def.items.type, item)) {
111
- errors.push(`${field}[${idx}]: expected ${def.items.type}, got ${typeof item}`);
112
- }
113
- if (def.items.maxLength !== undefined && typeof item === 'string' && item.length > def.items.maxLength) {
114
- errors.push(`${field}[${idx}]: item length ${item.length} exceeds maxLength ${def.items.maxLength}`);
115
- }
116
- });
117
- }
118
- }
119
- }
120
-
121
- if (schema.additionalProperties === false) {
122
- const allowed = new Set(Object.keys(properties));
123
- for (const key of Object.keys(record)) {
124
- if (!allowed.has(key)) errors.push(`${key}: undeclared field`);
125
- }
126
- }
127
-
128
- // Append a hint when validation fails so the LLM/user knows where to look
129
- // for a canonical sample. The opts.entity hint is set by callers that know
130
- // which entity they're validating (store-cli.cjs cmdWrite, cmdValidate).
131
- if (errors.length > 0 && opts.entity) {
132
- errors.push(
133
- `(hint: run 'node store-cli.cjs template ${opts.entity}' for a canonical sample, ` +
134
- `or 'node store-cli.cjs describe ${opts.entity}' for the raw JSON Schema)`
135
- );
136
- }
137
-
138
- return errors;
139
- }
140
-
141
- module.exports = { validateRecord, isDateTime, NULLABLE_FIELDS };
@@ -1,340 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- // Forge tool: manage-config
5
- // Read and write .forge/config.json safely.
6
- // Usage: manage-config get <key.path>
7
- // manage-config list-pipelines
8
- // manage-config pipeline add <name> --description <text> --phases <json>
9
- // manage-config pipeline get <name>
10
- // manage-config pipeline remove <name>
11
- // manage-config resolve-forge-root
12
- // manage-config set <key.path> <json-value>
13
-
14
- const fs = require('fs');
15
- const path = require('path');
16
- const os = require('os');
17
- const { findProjectRoot } = require('./lib/project-root.cjs');
18
-
19
- const _projectRoot = findProjectRoot();
20
- const CONFIG_PATH = _projectRoot
21
- ? path.join(_projectRoot, '.forge', 'config.json')
22
- : path.join(process.cwd(), '.forge', 'config.json');
23
-
24
- const VALID_ROLES = ['plan', 'review-plan', 'implement', 'review-code', 'validate', 'approve', 'commit'];
25
- const VALID_NAME = /^[a-z0-9_-]+$/;
26
-
27
- const ROLE_MODEL_DEFAULTS = {
28
- 'plan': 'sonnet',
29
- 'implement': 'sonnet',
30
- 'review-plan': 'opus',
31
- 'review-code': 'opus',
32
- 'validate': 'opus',
33
- 'approve': 'opus',
34
- 'commit': 'haiku'
35
- };
36
-
37
- function readConfig() {
38
- if (!fs.existsSync(CONFIG_PATH)) {
39
- console.error('× .forge/config.json not found. Run /forge:init first.');
40
- process.exit(1);
41
- }
42
- let raw;
43
- try { raw = fs.readFileSync(CONFIG_PATH, 'utf8'); } catch (e) {
44
- console.error(`× reading ${CONFIG_PATH}: ${e.message}`); process.exit(1);
45
- }
46
- try { return { config: JSON.parse(raw), raw }; } catch (e) {
47
- console.error(`× .forge/config.json is not valid JSON: ${e.message}`); process.exit(1);
48
- }
49
- }
50
-
51
- function detectIndent(raw) {
52
- const m = raw.match(/^([ \t]+)/m);
53
- return m ? m[1] : ' ';
54
- }
55
-
56
- function writeConfig(config, indent) {
57
- const json = JSON.stringify(config, null, indent) + '\n';
58
- const tmp = CONFIG_PATH + '.tmp.' + process.pid;
59
- try {
60
- fs.writeFileSync(tmp, json, 'utf8');
61
- fs.renameSync(tmp, CONFIG_PATH);
62
- } catch (e) {
63
- try { fs.unlinkSync(tmp); } catch {}
64
- console.error(`× writing config: ${e.message}`); process.exit(1);
65
- }
66
- }
67
-
68
- const DANGEROUS_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
69
-
70
- function assertSafeKeys(dotPath) {
71
- const keys = dotPath.split('.');
72
- for (const key of keys) {
73
- if (DANGEROUS_KEYS.has(key)) {
74
- throw new Error(`Unsafe key path '${key}' in '${dotPath}' — prototype traversal blocked`);
75
- }
76
- }
77
- }
78
-
79
- function getByPath(obj, dotPath) {
80
- assertSafeKeys(dotPath);
81
- return dotPath.split('.').reduce((cur, key) => (cur != null && typeof cur === 'object' ? cur[key] : undefined), obj);
82
- }
83
-
84
- function setByPath(obj, dotPath, value) {
85
- assertSafeKeys(dotPath);
86
- const keys = dotPath.split('.');
87
- let cur = obj;
88
- for (let i = 0; i < keys.length - 1; i++) {
89
- if (cur[keys[i]] == null || typeof cur[keys[i]] !== 'object') cur[keys[i]] = {};
90
- cur = cur[keys[i]];
91
- }
92
- cur[keys[keys.length - 1]] = value;
93
- }
94
-
95
- function validatePhases(phases) {
96
- if (!Array.isArray(phases) || phases.length === 0) return 'At least one phase is required';
97
- for (const [i, p] of phases.entries()) {
98
- if (!p.command || typeof p.command !== 'string') return `Phase ${i + 1}: command must be a non-empty string`;
99
- if (!VALID_ROLES.includes(p.role)) return `Phase ${i + 1}: role must be one of: ${VALID_ROLES.join(', ')}`;
100
- if (p.maxIterations !== undefined && (!Number.isInteger(p.maxIterations) || p.maxIterations < 1))
101
- return `Phase ${i + 1}: maxIterations must be a positive integer`;
102
- }
103
- return null;
104
- }
105
-
106
- function parseArgs(argv) {
107
- const result = {};
108
- for (let i = 0; i < argv.length; i++) {
109
- if (argv[i].startsWith('--') && i + 1 < argv.length) {
110
- result[argv[i].slice(2)] = argv[++i];
111
- }
112
- }
113
- return result;
114
- }
115
-
116
- module.exports = { getByPath, setByPath, assertSafeKeys, validatePhases, detectIndent, parseArgs, VALID_ROLES, VALID_NAME, ROLE_MODEL_DEFAULTS };
117
-
118
- if (require.main === module) {
119
- const [,, subcmd, ...args] = process.argv;
120
-
121
- if (!subcmd) {
122
- console.error([
123
- 'Usage: manage-config <subcommand> [options]',
124
- '',
125
- 'Subcommands:',
126
- ' get <key.path> Print a config value',
127
- ' list-pipelines List all pipelines',
128
- ' pipeline add <name> --description <t> --phases <json>',
129
- ' pipeline get <name> Print a pipeline in full',
130
- ' pipeline remove <name>',
131
- ' pipeline backfill-models Backfill model fields from role defaults',
132
- ' resolve-forge-root Resolve Forge plugin root path',
133
- ' set <key.path> <json-value> Set an arbitrary value',
134
- ].join('\n'));
135
- process.exit(2);
136
- }
137
-
138
- if (subcmd === 'get') {
139
- const keyPath = args[0];
140
- if (!keyPath) { console.error('Usage: manage-config get <key.path>'); process.exit(2); }
141
- const { config } = readConfig();
142
- const value = getByPath(config, keyPath);
143
- if (value === undefined) { console.error(`Key not found: ${keyPath}`); process.exit(1); }
144
- console.log(value !== null && typeof value === 'object' ? JSON.stringify(value, null, 2) : String(value));
145
- process.exit(0);
146
- }
147
-
148
- if (subcmd === 'list-pipelines') {
149
- const { config } = readConfig();
150
- const pipelines = config.pipelines;
151
- if (!pipelines || Object.keys(pipelines).length === 0) {
152
- console.log('── No pipelines configured.');
153
- process.exit(0);
154
- }
155
- console.log('| Name | Description | Phases |');
156
- console.log('|------|-------------|--------|');
157
- for (const [name, pl] of Object.entries(pipelines)) {
158
- const desc = pl.description || '(none)';
159
- const count = Array.isArray(pl.phases) ? pl.phases.length : 0;
160
- console.log(`| ${name} | ${desc} | ${count} |`);
161
- }
162
- process.exit(0);
163
- }
164
-
165
- if (subcmd === 'pipeline') {
166
- const action = args[0];
167
-
168
- if (action === 'get') {
169
- const name = args[1];
170
- if (!name) { console.error('Usage: manage-config pipeline get <name>'); process.exit(2); }
171
- const { config } = readConfig();
172
- if (!config.pipelines || !config.pipelines[name]) {
173
- console.error(`× Pipeline '${name}' not found`); process.exit(1);
174
- }
175
- const pl = config.pipelines[name];
176
- if (pl.description) console.log(`── ${pl.description}\n`);
177
- console.log('| # | Role | Command | Workflow | Model | maxIter |');
178
- console.log('|---|------|---------|----------|-------|---------|');
179
- (pl.phases || []).forEach((p, i) => {
180
- const wf = p.workflow || '(built-in)';
181
- const model = p.model || '(default)';
182
- const maxIter = p.maxIterations != null ? p.maxIterations : '—';
183
- console.log(`| ${i + 1} | ${p.role} | \`${p.command}\` | \`${wf}\` | ${model} | ${maxIter} |`);
184
- });
185
- process.exit(0);
186
- }
187
-
188
- if (action === 'add') {
189
- const name = args[1];
190
- if (!name) { console.error('Usage: manage-config pipeline add <name> --description <text> --phases <json>'); process.exit(2); }
191
- if (!VALID_NAME.test(name)) { console.error(`× pipeline name must match [a-z0-9_-], got: ${name}`); process.exit(1); }
192
-
193
- const flags = parseArgs(args.slice(2));
194
- if (!flags.phases) { console.error('Error: --phases <json> is required'); process.exit(2); }
195
-
196
- let phases;
197
- try { phases = JSON.parse(flags.phases); } catch (e) {
198
- console.error(`× --phases is not valid JSON: ${e.message}`); process.exit(2);
199
- }
200
-
201
- const err = validatePhases(phases);
202
- if (err) { console.error(`× ${err}`); process.exit(1); }
203
-
204
- const { config, raw } = readConfig();
205
- if (!config.pipelines) config.pipelines = {};
206
- config.pipelines[name] = flags.description
207
- ? { description: flags.description, phases }
208
- : { phases };
209
- writeConfig(config, detectIndent(raw));
210
- console.log(`〇 Pipeline '${name}' saved.`);
211
- process.exit(0);
212
- }
213
-
214
- if (action === 'backfill-models') {
215
- const { config, raw } = readConfig();
216
- if (!config.pipelines || Object.keys(config.pipelines).length === 0) {
217
- console.log('── No pipelines configured — nothing to backfill.');
218
- process.exit(0);
219
- }
220
- let updated = 0;
221
- for (const [name, pl] of Object.entries(config.pipelines)) {
222
- if (!Array.isArray(pl.phases)) continue;
223
- for (const phase of pl.phases) {
224
- if (!phase.model && ROLE_MODEL_DEFAULTS[phase.role]) {
225
- phase.model = ROLE_MODEL_DEFAULTS[phase.role];
226
- updated++;
227
- }
228
- }
229
- }
230
- if (updated === 0) {
231
- console.log('〇 All pipeline phases already have model fields.');
232
- process.exit(0);
233
- }
234
- writeConfig(config, detectIndent(raw));
235
- console.log(`〇 Backfilled model fields on ${updated} phase(s) across ${Object.keys(config.pipelines).length} pipeline(s).`);
236
- process.exit(0);
237
- }
238
-
239
- if (action === 'remove') {
240
- const name = args[1];
241
- if (!name) { console.error('Usage: manage-config pipeline remove <name>'); process.exit(2); }
242
- const { config, raw } = readConfig();
243
- if (!config.pipelines || !config.pipelines[name]) {
244
- console.error(`× Pipeline '${name}' not found`); process.exit(1);
245
- }
246
- delete config.pipelines[name];
247
- if (Object.keys(config.pipelines).length === 0) delete config.pipelines;
248
- writeConfig(config, detectIndent(raw));
249
- console.log(`〇 Pipeline '${name}' removed.`);
250
- process.exit(0);
251
- }
252
-
253
- console.error(`Unknown pipeline action: ${action}`);
254
- process.exit(2);
255
- }
256
-
257
- if (subcmd === 'set') {
258
- const keyPath = args[0];
259
- const valueStr = args[1];
260
- if (!keyPath || valueStr === undefined) { console.error('Usage: manage-config set <key.path> <json-value>'); process.exit(2); }
261
- // FR-005: If config.json does not exist, create a minimal {} config before reading.
262
- // This allows `set` to work on fresh projects that haven't run /forge:init yet.
263
- if (!fs.existsSync(CONFIG_PATH)) {
264
- const configDir = path.dirname(CONFIG_PATH);
265
- if (!fs.existsSync(configDir)) {
266
- fs.mkdirSync(configDir, { recursive: true });
267
- }
268
- fs.writeFileSync(CONFIG_PATH, '{}\n', 'utf8');
269
- }
270
- let value;
271
- try { value = JSON.parse(valueStr); } catch { value = valueStr; }
272
- const { config, raw } = readConfig();
273
- setByPath(config, keyPath, value);
274
- writeConfig(config, detectIndent(raw));
275
- console.log(`Set ${keyPath}.`);
276
- process.exit(0);
277
- }
278
-
279
- // FR-010: resolve-forge-root — resolve the Forge plugin root path using
280
- // three-tier priority: (1) CLAUDE_PLUGIN_ROOT env var, (2) cache/marketplace
281
- // scan by forgeRef, (3) paths.forgeRoot fallback.
282
- if (subcmd === 'resolve-forge-root') {
283
- // Priority 1: CLAUDE_PLUGIN_ROOT env var (if set and directory exists)
284
- const envRoot = process.env.CLAUDE_PLUGIN_ROOT;
285
- if (envRoot && envRoot.length > 0) {
286
- try {
287
- // Verify the directory exists and contains a valid plugin.json
288
- const pluginJsonPath = path.join(envRoot, '.claude-plugin', 'plugin.json');
289
- if (fs.existsSync(pluginJsonPath)) {
290
- console.log(envRoot);
291
- process.exit(0);
292
- }
293
- // Directory exists but no plugin.json — still use it if the directory itself exists
294
- if (fs.existsSync(envRoot)) {
295
- console.log(envRoot);
296
- process.exit(0);
297
- }
298
- } catch { /* fall through to next priority */ }
299
- }
300
-
301
- const { config } = readConfig();
302
- const forgeRef = getByPath(config, 'paths.forgeRef');
303
- const forgeRoot = getByPath(config, 'paths.forgeRoot');
304
-
305
- // Priority 2: Scan cache/marketplace directories by forgeRef
306
- if (forgeRef && typeof forgeRef === 'string') {
307
- const homeDir = os.homedir();
308
- const candidates = [
309
- path.join(homeDir, '.claude', 'plugins', 'cache', 'forge', 'forge', forgeRef),
310
- path.join(homeDir, '.claude', 'plugins', 'marketplaces', 'skillforge', 'forge', 'forge', forgeRef),
311
- ];
312
- for (const candidate of candidates) {
313
- try {
314
- const pluginJsonPath = path.join(candidate, '.claude-plugin', 'plugin.json');
315
- if (fs.existsSync(pluginJsonPath)) {
316
- // Validate that the plugin.json version matches forgeRef
317
- const manifest = JSON.parse(fs.readFileSync(pluginJsonPath, 'utf8'));
318
- if (manifest.version === forgeRef) {
319
- console.log(candidate);
320
- process.exit(0);
321
- }
322
- }
323
- } catch { /* try next candidate */ }
324
- }
325
- }
326
-
327
- // Priority 3: Fallback to paths.forgeRoot (deprecated but still read)
328
- if (forgeRoot && typeof forgeRoot === 'string') {
329
- console.log(forgeRoot);
330
- process.exit(0);
331
- }
332
-
333
- // No resolution possible
334
- console.error('× Cannot resolve Forge plugin root: no CLAUDE_PLUGIN_ROOT env var, no forgeRef cache match, and no forgeRoot in config.');
335
- process.exit(1);
336
- }
337
-
338
- console.error(`Unknown subcommand: ${subcmd}`);
339
- process.exit(2)
340
- } // end require.main === module;