@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,290 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- /**
5
- * build-context-pack.cjs — build a compact architecture context pack from
6
- * engineering/architecture/*.md files. Writes:
7
- * .forge/cache/context-pack.md (human-readable summary)
8
- * .forge/cache/context-pack.json (machine-readable index)
9
- *
10
- * CLI:
11
- * node build-context-pack.cjs [--arch-dir <path>] [--out-md <path>] [--out-json <path>]
12
- *
13
- * Exported API:
14
- * extractDoc(filePath) → { title, firstPara, sections, lineCount, filePath }
15
- * buildContextPack({ archDir, existingPackPath? }) → pack object (or { skipped: true })
16
- * computeSourceHash(archDir) → "sha256:..."
17
- * writeContextPack(pack, outMd, outJson) → void (atomic)
18
- */
19
-
20
- const fs = require('fs');
21
- const path = require('path');
22
- const crypto = require('crypto');
23
-
24
- const PACK_LINE_LIMIT = 400;
25
-
26
- // ── Document extraction ──────────────────────────────────────────────────────
27
-
28
- /**
29
- * Extract H1 title, first paragraph, and ## Key / ## Summary sections from
30
- * a single markdown file.
31
- */
32
- function extractDoc(filePath) {
33
- const raw = fs.readFileSync(filePath, 'utf8');
34
- const lines = raw.split('\n');
35
- const lineCount = lines[lines.length - 1] === '' ? lines.length - 1 : lines.length;
36
-
37
- let title = '';
38
- let firstPara = '';
39
- const sections = {};
40
-
41
- let i = 0;
42
-
43
- // Find H1
44
- while (i < lines.length) {
45
- const m = lines[i].match(/^#\s+(.+)$/);
46
- if (m) {
47
- title = m[1].trim();
48
- i++;
49
- break;
50
- }
51
- i++;
52
- }
53
-
54
- // First paragraph: non-empty lines after H1, before next heading
55
- const firstParaLines = [];
56
- while (i < lines.length && !lines[i].startsWith('#')) {
57
- if (lines[i].trim()) firstParaLines.push(lines[i]);
58
- else if (firstParaLines.length) break; // blank line ends paragraph
59
- i++;
60
- }
61
- firstPara = firstParaLines.join(' ').trim();
62
-
63
- // Remaining: scan for ## Key * or ## Summary sections
64
- while (i < lines.length) {
65
- const hm = lines[i].match(/^##\s+(Key\s+\S.*|Summary)\s*$/i);
66
- if (hm) {
67
- const heading = hm[1].trim();
68
- i++;
69
- const sectionLines = [];
70
- while (i < lines.length && !lines[i].match(/^##/)) {
71
- sectionLines.push(lines[i]);
72
- i++;
73
- }
74
- // Trim leading/trailing blank lines
75
- while (sectionLines.length && !sectionLines[0].trim()) sectionLines.shift();
76
- while (sectionLines.length && !sectionLines[sectionLines.length - 1].trim()) sectionLines.pop();
77
- if (sectionLines.length) {
78
- sections[heading] = sectionLines.join('\n');
79
- }
80
- } else {
81
- i++;
82
- }
83
- }
84
-
85
- return { title, firstPara, sections, lineCount, filePath };
86
- }
87
-
88
- // ── Source hash ──────────────────────────────────────────────────────────────
89
-
90
- function listArchFiles(archDir) {
91
- if (!fs.existsSync(archDir)) {
92
- throw new Error(`Architecture directory not found: ${archDir}`);
93
- }
94
- return fs.readdirSync(archDir)
95
- .filter((f) => f.endsWith('.md') && !f.endsWith('.draft.md'))
96
- .sort()
97
- .map((f) => path.join(archDir, f));
98
- }
99
-
100
- function computeSourceHash(archDir) {
101
- const files = listArchFiles(archDir);
102
- const hash = crypto.createHash('sha256');
103
- // FR-012: Content-based hashing for reproducibility.
104
- // Old mtime-based hash was non-deterministic across runs after git checkout.
105
- // New pattern: filePath\0 + fileContents + \0 — null-byte separators prevent
106
- // concatenation ambiguity and make the hash a pure function of content.
107
- for (const f of files) {
108
- hash.update(`${f}\0`);
109
- hash.update(fs.readFileSync(f));
110
- hash.update('\0');
111
- }
112
- return `sha256:${hash.digest('hex')}`;
113
- }
114
-
115
- // ── Pack composition ─────────────────────────────────────────────────────────
116
-
117
- function composePack(docs, builtAt, sourceHash, archDir) {
118
- const lines = [];
119
-
120
- lines.push('# Architecture Context Pack', '');
121
- lines.push(`Built: ${builtAt}`);
122
- lines.push(`Source hash: ${sourceHash}`);
123
- lines.push('');
124
-
125
- // Aggregate Key/Summary sections from all docs, grouped by heading name
126
- const allHeadings = [];
127
- const headingDocs = {}; // heading → [{basename, content}]
128
- for (const doc of docs) {
129
- for (const [heading, content] of Object.entries(doc.sections)) {
130
- if (!headingDocs[heading]) {
131
- allHeadings.push(heading);
132
- headingDocs[heading] = [];
133
- }
134
- headingDocs[heading].push({ basename: path.basename(doc.filePath), content });
135
- }
136
- }
137
-
138
- if (allHeadings.length) {
139
- for (const heading of allHeadings) {
140
- lines.push(`## ${heading}`, '');
141
- for (const { basename, content } of headingDocs[heading]) {
142
- if (headingDocs[heading].length > 1) {
143
- lines.push(`*From ${basename}:*`, '');
144
- }
145
- lines.push(content, '');
146
- }
147
- }
148
- }
149
-
150
- // Document summaries
151
- lines.push('## Document summaries', '');
152
- for (const doc of docs) {
153
- const basename = path.basename(doc.filePath);
154
- lines.push(`### ${doc.title || basename}`);
155
- if (doc.firstPara) {
156
- lines.push('');
157
- lines.push(doc.firstPara);
158
- }
159
- lines.push('');
160
- }
161
-
162
- // File index
163
- lines.push('## File index', '');
164
- for (const doc of docs) {
165
- const relPath = path.relative(process.cwd(), doc.filePath);
166
- lines.push(`- ${relPath} — ${doc.title || path.basename(doc.filePath)} (${doc.lineCount} lines)`);
167
- }
168
-
169
- return lines;
170
- }
171
-
172
- // ── Build ────────────────────────────────────────────────────────────────────
173
-
174
- function buildContextPack({ archDir, existingPackPath }) {
175
- // Check for manual override
176
- if (existingPackPath && fs.existsSync(existingPackPath)) {
177
- const existing = fs.readFileSync(existingPackPath, 'utf8');
178
- if (/^---[\s\S]*?manual:\s*true[\s\S]*?---/m.test(existing)) {
179
- return { skipped: true };
180
- }
181
- }
182
-
183
- const files = listArchFiles(archDir);
184
- const docs = files.map((f) => extractDoc(f));
185
-
186
- const builtAt = new Date().toISOString();
187
- const sourceHash = computeSourceHash(archDir);
188
-
189
- const mdLines = composePack(docs, builtAt, sourceHash, archDir);
190
- let markdown = mdLines.join('\n') + '\n';
191
-
192
- // Enforce 400-line cap (count real lines, excluding trailing empty after final \n)
193
- const splitLines = markdown.split('\n');
194
- const realLineCount = splitLines[splitLines.length - 1] === '' ? splitLines.length - 1 : splitLines.length;
195
- if (realLineCount > PACK_LINE_LIMIT) {
196
- // Keep PACK_LINE_LIMIT - 1 lines so the marker fits within the cap
197
- const truncated = splitLines.slice(0, PACK_LINE_LIMIT - 1);
198
- truncated.push('<!-- TRUNCATED: pack exceeded 400 lines. Architecture KB has grown beyond summary capacity. Run /forge:regenerate after pruning docs. -->');
199
- markdown = truncated.join('\n') + '\n';
200
- }
201
-
202
- const sources = files.map((f) => {
203
- const stat = fs.statSync(f);
204
- return {
205
- path: path.relative(process.cwd(), f),
206
- size: stat.size,
207
- mtime: new Date(stat.mtimeMs).toISOString(),
208
- };
209
- });
210
-
211
- return {
212
- version: 1,
213
- built_at: builtAt,
214
- source_hash: sourceHash,
215
- sources,
216
- markdown,
217
- };
218
- }
219
-
220
- // ── Atomic write ─────────────────────────────────────────────────────────────
221
-
222
- function writeContextPack(pack, outMd, outJson) {
223
- fs.mkdirSync(path.dirname(outMd), { recursive: true });
224
- fs.mkdirSync(path.dirname(outJson), { recursive: true });
225
-
226
- // Write markdown
227
- const tmpMd = outMd + '.tmp';
228
- fs.writeFileSync(tmpMd, pack.markdown, 'utf8');
229
- fs.renameSync(tmpMd, outMd);
230
-
231
- // Write JSON index
232
- const jsonRecord = {
233
- version: pack.version,
234
- built_at: pack.built_at,
235
- source_hash: pack.source_hash,
236
- sources: pack.sources,
237
- summary_path: outMd,
238
- };
239
- const tmpJson = outJson + '.tmp';
240
- fs.writeFileSync(tmpJson, JSON.stringify(jsonRecord, null, 2) + '\n', 'utf8');
241
- fs.renameSync(tmpJson, outJson);
242
- }
243
-
244
- // ── CLI ──────────────────────────────────────────────────────────────────────
245
-
246
- function parseArgs(argv) {
247
- const out = {};
248
- for (let i = 0; i < argv.length; i++) {
249
- const a = argv[i];
250
- if (a === '--arch-dir') out.archDir = argv[++i];
251
- else if (a === '--out-md') out.outMd = argv[++i];
252
- else if (a === '--out-json') out.outJson = argv[++i];
253
- }
254
- return out;
255
- }
256
-
257
- function main() {
258
- const args = parseArgs(process.argv.slice(2));
259
- const archDir = args.archDir || path.resolve(process.cwd(), 'engineering/architecture');
260
- const outMd = args.outMd || path.resolve(process.cwd(), '.forge/cache/context-pack.md');
261
- const outJson = args.outJson || path.resolve(process.cwd(), '.forge/cache/context-pack.json');
262
-
263
- const pack = buildContextPack({ archDir, existingPackPath: outMd });
264
-
265
- if (pack.skipped) {
266
- process.stdout.write('context-pack: manual: true — skipping rebuild\n');
267
- return;
268
- }
269
-
270
- writeContextPack(pack, outMd, outJson);
271
- process.stdout.write(
272
- `context-pack: wrote ${pack.sources.length} sources → ${outMd}\n`,
273
- );
274
- }
275
-
276
- if (require.main === module) {
277
- try {
278
- main();
279
- } catch (err) {
280
- process.stderr.write(`build-context-pack: ${err.message}\n`);
281
- process.exit(1);
282
- }
283
- }
284
-
285
- module.exports = {
286
- extractDoc,
287
- buildContextPack,
288
- computeSourceHash,
289
- writeContextPack,
290
- };
@@ -1,322 +0,0 @@
1
- 'use strict';
2
- // build-init-context.cjs
3
- // Deterministic project brief builder for /forge:init Phase 7 fan-out.
4
- // Reads: .forge/config.json, .forge/personas/, .forge/templates/, {kb}/
5
- // Writes: .forge/init-context.md (markdown — for LLM prompts)
6
- // .forge/init-context.json (same data — for deterministic consumers)
7
- //
8
- // Uses only Node.js built-ins — no npm dependencies.
9
- // Exports: buildBrief, extractPersonaSymbol, parseEntities (for testing)
10
-
11
- 'use strict';
12
- const fs = require('fs');
13
- const path = require('path');
14
-
15
- // ── Skill → persona wiring (mirrors meta-skill-recommendations.md) ─────────
16
- // Maps installed skill name to the persona roles it wires into.
17
- const SKILL_PERSONA_MAP = {
18
- 'vue-best-practices': ['engineer', 'supervisor'],
19
- 'stripe-integration': ['engineer', 'bug-fixer'],
20
- 'frontend-design': ['engineer', 'supervisor'],
21
- 'typescript-lsp': ['engineer', 'supervisor'],
22
- 'pyright-lsp': ['engineer', 'supervisor'],
23
- 'ruby-lsp': ['engineer', 'supervisor'],
24
- 'gopls-lsp': ['engineer', 'supervisor'],
25
- 'rust-analyzer-lsp': ['engineer', 'supervisor'],
26
- 'jdtls-lsp': ['engineer', 'supervisor'],
27
- 'kotlin-lsp': ['engineer', 'supervisor'],
28
- 'csharp-lsp': ['engineer', 'supervisor'],
29
- 'clangd-lsp': ['engineer', 'supervisor'],
30
- 'php-lsp': ['engineer', 'supervisor'],
31
- 'swift-lsp': ['engineer', 'supervisor'],
32
- 'lua-lsp': ['engineer', 'supervisor'],
33
- 'security-guidance': ['supervisor', 'engineer'],
34
- 'mcp-server-dev': ['engineer'],
35
- 'agent-sdk-dev': ['engineer'],
36
- 'threejs-skills': ['engineer'],
37
- 'meta-webxr-skills': ['engineer'],
38
- 'freshdesk-api': ['engineer'],
39
- };
40
-
41
- // ── extractPersonaSymbol ──────────────────────────────────────────────────────
42
- // Reads the first 15 lines of a persona file and extracts the emoji symbol.
43
- // Handles two formats:
44
- // 1. First-line emoji (generated persona style):
45
- // 🗻 **emberglow Architect** — tagline
46
- // 2. YAML frontmatter "symbol:" line:
47
- // ---
48
- // symbol: 🏛
49
- // ---
50
- // Returns '·' if no symbol is found.
51
- function extractPersonaSymbol(content) {
52
- const lines = content.split('\n').slice(0, 15);
53
-
54
- // Format 1: first non-blank line starts with an emoji character
55
- // Unicode emoji range check — covers most common emoji blocks
56
- const firstNonBlank = lines.find(l => l.trim().length > 0);
57
- if (firstNonBlank) {
58
- // Match a leading emoji (one or more emoji codepoints before a space or end)
59
- const emojiMatch = firstNonBlank.match(/^(\p{Emoji_Presentation}|\p{Extended_Pictographic})/u);
60
- if (emojiMatch) return emojiMatch[0];
61
- }
62
-
63
- // Format 2: "symbol: <value>" in YAML frontmatter
64
- for (const line of lines) {
65
- const m = line.match(/^symbol:\s*(\S.*?)\s*$/i);
66
- if (m) return m[1].trim();
67
- }
68
-
69
- return '·';
70
- }
71
-
72
- // ── parseEntities ─────────────────────────────────────────────────────────────
73
- // Extracts domain entity names from MASTER_INDEX.md content.
74
- // Looks for a heading containing "Entities" or "Domain"; reads the first
75
- // non-empty content line(s) below it as either comma-separated names or
76
- // markdown list items. Returns a sorted, deduplicated array.
77
- function parseEntities(content) {
78
- const lines = content.split('\n');
79
- let inSection = false;
80
- const found = [];
81
-
82
- for (let i = 0; i < lines.length; i++) {
83
- const line = lines[i];
84
-
85
- if (/^#{1,4}\s.*(entities|domain)/i.test(line)) {
86
- inSection = true;
87
- continue;
88
- }
89
-
90
- if (inSection) {
91
- // Stop at the next heading
92
- if (/^#{1,4}\s/.test(line)) break;
93
-
94
- const trimmed = line.trim();
95
- if (!trimmed) continue;
96
-
97
- // List items: "- Entity" or "* Entity"
98
- if (/^[-*]\s+/.test(trimmed)) {
99
- const name = trimmed.replace(/^[-*]\s+/, '').trim();
100
- if (name) found.push(name);
101
- continue;
102
- }
103
-
104
- // Comma-separated line
105
- if (trimmed.includes(',')) {
106
- for (const part of trimmed.split(',')) {
107
- const name = part.trim();
108
- if (name) found.push(name);
109
- }
110
- break; // Only read one comma-separated line
111
- }
112
-
113
- // Single name on its own line
114
- if (trimmed && !trimmed.startsWith('#')) {
115
- found.push(trimmed);
116
- }
117
- }
118
- }
119
-
120
- // Deduplicate and sort
121
- return [...new Set(found)].sort();
122
- }
123
-
124
- // ── buildBrief ────────────────────────────────────────────────────────────────
125
- // Main builder. Takes options object:
126
- // { configPath, personasDir, templatesDir, kbPath }
127
- // Returns: { markdown: string, json: object }
128
- function buildBrief({ configPath, personasDir, templatesDir, kbPath }) {
129
- // 1. Read config
130
- const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
131
- const projectName = (config.project && config.project.name) || '';
132
- const projectPrefix = (config.project && config.project.prefix) || '';
133
- const commands = config.commands || {};
134
- const paths = config.paths || {};
135
- const installedSkills = Array.isArray(config.installedSkills) ? config.installedSkills : [];
136
-
137
- const syntaxCheck = commands.syntaxCheck || '';
138
- const testCmd = commands.test || '';
139
- const buildCmd = commands.build || '';
140
- const lintCmd = commands.lint || '';
141
-
142
- // 2. Personas — exclude README.md, sort by role name
143
- const personas = [];
144
- if (fs.existsSync(personasDir)) {
145
- const files = fs.readdirSync(personasDir)
146
- .filter(f => f.endsWith('.md') && f.toLowerCase() !== 'readme.md')
147
- .sort();
148
-
149
- for (const file of files) {
150
- const role = path.basename(file, '.md');
151
- const filePath = path.join(personasDir, file);
152
- const content = fs.readFileSync(filePath, 'utf8');
153
- const symbol = extractPersonaSymbol(content);
154
- // One-liner: first non-blank, non-YAML, non-heading line after the opening block
155
- const bodyLines = content.split('\n').filter(l => {
156
- const t = l.trim();
157
- return t && !t.startsWith('#') && !t.startsWith('---') && !t.match(/^\w+:/);
158
- });
159
- const oneLiner = bodyLines[0] ? bodyLines[0].trim() : '';
160
- personas.push({ role, file: path.join(personasDir, file), symbol, oneLiner });
161
- }
162
- }
163
-
164
- // 3. Templates — stems only, exclude README.md, sort
165
- const templates = [];
166
- if (fs.existsSync(templatesDir)) {
167
- const files = fs.readdirSync(templatesDir)
168
- .filter(f => f.endsWith('.md') && f.toLowerCase() !== 'readme.md')
169
- .sort();
170
- for (const f of files) {
171
- templates.push(path.basename(f, '.md'));
172
- }
173
- }
174
-
175
- // 4. Architecture docs — filenames only, sorted
176
- const archDir = path.join(kbPath, 'architecture');
177
- const architectureDocs = [];
178
- if (fs.existsSync(archDir)) {
179
- const files = fs.readdirSync(archDir)
180
- .filter(f => f.endsWith('.md'))
181
- .sort();
182
- architectureDocs.push(...files);
183
- }
184
-
185
- // 5. Domain entities — from MASTER_INDEX.md
186
- const masterIndexPath = path.join(kbPath, 'MASTER_INDEX.md');
187
- let entities = [];
188
- if (fs.existsSync(masterIndexPath)) {
189
- entities = parseEntities(fs.readFileSync(masterIndexPath, 'utf8'));
190
- }
191
-
192
- // 6. Skill wiring
193
- const skillWiring = installedSkills
194
- .filter(s => SKILL_PERSONA_MAP[s])
195
- .map(s => ({ skill: s, personas: SKILL_PERSONA_MAP[s] }))
196
- .sort((a, b) => a.skill.localeCompare(b.skill));
197
-
198
- // ── Build JSON ──────────────────────────────────────────────────────────────
199
- const json = {
200
- project: { name: projectName, prefix: projectPrefix },
201
- commands: { syntaxCheck, test: testCmd, build: buildCmd, lint: lintCmd },
202
- paths,
203
- personas,
204
- templates,
205
- architectureDocs,
206
- entities,
207
- skillWiring,
208
- };
209
-
210
- // ── Build Markdown ──────────────────────────────────────────────────────────
211
- const lines = [];
212
-
213
- lines.push(`# ${projectName || 'Project'} — Init Context`);
214
- lines.push('');
215
-
216
- // Commands
217
- lines.push('## Commands');
218
- lines.push(`{SYNTAX_CHECK} = ${syntaxCheck}`);
219
- lines.push(`{TEST_COMMAND} = ${testCmd}`);
220
- lines.push(`{BUILD_COMMAND} = ${buildCmd}`);
221
- lines.push(`{LINT_COMMAND} = ${lintCmd}`);
222
- lines.push('');
223
-
224
- // Paths
225
- lines.push('## Paths');
226
- for (const [key, val] of Object.entries(paths).sort(([a], [b]) => a.localeCompare(b))) {
227
- lines.push(`${key.padEnd(12)} = ${val}`);
228
- }
229
- lines.push('');
230
-
231
- // Personas
232
- lines.push('## Personas');
233
- for (const p of personas) {
234
- lines.push(`${p.role} | ${p.file} | ${p.symbol} | ${p.oneLiner}`);
235
- }
236
- lines.push('');
237
-
238
- // Templates
239
- lines.push('## Templates');
240
- lines.push(templates.join(', '));
241
- lines.push('');
242
-
243
- // Architecture Docs
244
- lines.push('## Architecture Docs');
245
- lines.push(architectureDocs.join(', '));
246
- lines.push('');
247
-
248
- // Domain Entities
249
- lines.push('## Domain Entities');
250
- lines.push(entities.join(', '));
251
- lines.push('');
252
-
253
- // Installed Skill Wiring
254
- lines.push('## Installed Skill Wiring');
255
- if (skillWiring.length === 0) {
256
- lines.push('(none)');
257
- } else {
258
- for (const { skill, personas: ps } of skillWiring) {
259
- lines.push(`${skill} → ${ps.join(', ')}`);
260
- }
261
- }
262
- lines.push('');
263
-
264
- const markdown = lines.join('\n');
265
-
266
- return { markdown, json };
267
- }
268
-
269
- // ── CLI entry point ───────────────────────────────────────────────────────────
270
-
271
- function parseCliArgs(argv) {
272
- const args = {};
273
- for (let i = 2; i < argv.length; i++) {
274
- if (argv[i].startsWith('--') && argv[i + 1] && !argv[i + 1].startsWith('--')) {
275
- args[argv[i].slice(2)] = argv[i + 1];
276
- i++;
277
- }
278
- }
279
- return args;
280
- }
281
-
282
- if (require.main === module) {
283
- const args = parseCliArgs(process.argv);
284
-
285
- const configPath = args['config'];
286
- const personasDir = args['personas'];
287
- const templatesDir = args['templates'];
288
- const kbPath = args['kb'];
289
- const outMd = args['out'];
290
- const outJson = args['json-out'];
291
-
292
- if (!configPath || !personasDir || !templatesDir || !kbPath || !outMd) {
293
- process.stderr.write(
294
- 'Usage: node build-init-context.cjs ' +
295
- '--config <path> --personas <dir> --templates <dir> --kb <dir> --out <md-path> ' +
296
- '[--json-out <json-path>]\n'
297
- );
298
- process.exit(1);
299
- }
300
-
301
- try {
302
- const { markdown, json } = buildBrief({ configPath, personasDir, templatesDir, kbPath });
303
- fs.mkdirSync(path.dirname(path.resolve(outMd)), { recursive: true });
304
- fs.writeFileSync(outMd, markdown, 'utf8');
305
-
306
- const jsonPath = outJson || outMd.replace(/\.md$/, '.json');
307
- fs.writeFileSync(jsonPath, JSON.stringify(json, null, 2) + '\n', 'utf8');
308
-
309
- // Print summary line to stdout (consumed by Phase 7 orchestrator)
310
- const nPersonas = json.personas.length;
311
- const nTemplates = json.templates.length;
312
- const nDocs = json.architectureDocs.length;
313
- process.stdout.write(
314
- `\u25CB Brief written \u2014 ${nPersonas} personas, ${nTemplates} templates, ${nDocs} architecture docs\n`
315
- );
316
- } catch (err) {
317
- process.stderr.write(`build-init-context: ${err.message}\n`);
318
- process.exit(1);
319
- }
320
- }
321
-
322
- module.exports = { buildBrief, extractPersonaSymbol, parseEntities };