@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,593 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- // Forge tool: validate-store
5
- // Check store integrity: required fields, types, enums, and referential integrity.
6
- // Usage: validate-store [--dry-run] [--fix] [--json]
7
-
8
- let _store;
9
- function _getStore() { return _store || (_store = require('./store.cjs')); }
10
-
11
- let _schemas;
12
- function _getSchemas() {
13
- if (_schemas) return _schemas;
14
- const fs = require('fs');
15
- const path = require('path');
16
-
17
- const ENTITY_TYPES = ['sprint', 'task', 'bug', 'event', 'feature'];
18
-
19
- const MINIMAL_REQUIRED = {
20
- sprint: ['sprintId', 'title', 'status', 'taskIds', 'createdAt'],
21
- task: ['taskId', 'sprintId', 'title', 'status', 'path'],
22
- bug: ['bugId', 'title', 'severity', 'status', 'path', 'reportedAt'],
23
- event: ['eventId', 'taskId', 'sprintId', 'role', 'action', 'phase', 'iteration', 'startTimestamp', 'endTimestamp', 'durationMinutes', 'model'],
24
- feature: ['id', 'title', 'status', 'created_at']
25
- };
26
-
27
- const schemas = {};
28
- const projectDir = path.join('.forge', 'schemas');
29
- const inTreeDir = path.join('forge', 'schemas');
30
- const pluginDir = path.join(__dirname, '..', 'schemas');
31
-
32
- for (const type of ENTITY_TYPES) {
33
- const schemaFile = `${type}.schema.json`;
34
- let schema = null;
35
-
36
- // 1. Try project-installed schemas first
37
- const projectPath = path.join(projectDir, schemaFile);
38
- try {
39
- if (fs.existsSync(projectPath)) {
40
- schema = JSON.parse(fs.readFileSync(projectPath, 'utf8'));
41
- }
42
- } catch (e) {
43
- console.error(`WARN: schema file ${projectPath} exists but could not be parsed: ${e.message}`);
44
- }
45
-
46
- // 2. Fall back to in-tree source schemas (development mode)
47
- if (!schema) {
48
- const inTreePath = path.join(inTreeDir, schemaFile);
49
- try {
50
- if (fs.existsSync(inTreePath)) {
51
- schema = JSON.parse(fs.readFileSync(inTreePath, 'utf8'));
52
- }
53
- } catch (e) {
54
- console.error(`WARN: schema file ${inTreePath} exists but could not be parsed: ${e.message}`);
55
- }
56
- }
57
-
58
- // 3. Fall back to plugin-installed schemas (production mode)
59
- // validate-store.cjs lives at $FORGE_ROOT/tools/, so __dirname/../schemas/
60
- // resolves to $FORGE_ROOT/schemas/ — always correct for installed plugins.
61
- if (!schema) {
62
- const pluginPath = path.join(pluginDir, schemaFile);
63
- try {
64
- if (fs.existsSync(pluginPath)) {
65
- schema = JSON.parse(fs.readFileSync(pluginPath, 'utf8'));
66
- }
67
- } catch (e) {
68
- console.error(`WARN: schema file ${pluginPath} exists but could not be parsed: ${e.message}`);
69
- }
70
- }
71
-
72
- if (schema) {
73
- schemas[type] = schema;
74
- } else {
75
- console.error(`WARN: schema file ${schemaFile} not found in ${projectDir}, ${inTreeDir}, or ${pluginDir}, using minimal fallback`);
76
- schemas[type] = { type: 'object', required: MINIMAL_REQUIRED[type] || [], properties: {} };
77
- }
78
- }
79
-
80
- _schemas = schemas;
81
- return _schemas;
82
- }
83
-
84
- // ---------------------------------------------------------------------------
85
- // Constants (exported for testing)
86
- // ---------------------------------------------------------------------------
87
-
88
- const ENTITY_TYPES = ['sprint', 'task', 'bug', 'event', 'feature'];
89
-
90
- // Non-entity schemas: referenced and parsed for validity but not used for store record validation.
91
- const ANCILLARY_SCHEMAS = ['project-overlay', 'project-context', 'structure-versions'];
92
-
93
- const MINIMAL_REQUIRED = {
94
- sprint: ['sprintId', 'title', 'status', 'taskIds', 'createdAt'],
95
- task: ['taskId', 'sprintId', 'title', 'status', 'path'],
96
- bug: ['bugId', 'title', 'severity', 'status', 'path', 'reportedAt'],
97
- event: ['eventId', 'taskId', 'sprintId', 'role', 'action', 'phase', 'iteration', 'startTimestamp', 'endTimestamp', 'durationMinutes', 'model'],
98
- feature: ['id', 'title', 'status', 'created_at']
99
- };
100
-
101
- // Fields that are legitimately null:
102
- // sprintId / taskId — optional FK (e.g. standalone bug fix has no sprint)
103
- // endTimestamp / durationMinutes — not recorded on "start" events (phase opened but never closed)
104
- const NULLABLE_FK = new Set(['sprintId', 'taskId', 'endTimestamp', 'durationMinutes']);
105
-
106
- // --- Validation ---
107
- function validateRecord(record, schema) {
108
- const errors = [];
109
- const required = schema.required || [];
110
-
111
- for (const field of required) {
112
- if (record[field] === undefined || record[field] === '') {
113
- errors.push({ category: 'missing-required', field, message: `missing required field: "${field}"`, value: record[field], expected: null });
114
- } else if (record[field] === null && !NULLABLE_FK.has(field)) {
115
- errors.push({ category: 'missing-required', field, message: `missing required field: "${field}"`, value: null, expected: null });
116
- }
117
- }
118
-
119
- for (const [field, def] of Object.entries(schema.properties || {})) {
120
- const val = record[field];
121
- if (val === undefined) continue;
122
- if (val === null) continue;
123
-
124
- if (def.type) {
125
- const typeMatches = (expected, actualVal) => {
126
- return expected === 'integer' ? Number.isInteger(actualVal)
127
- : expected === 'number' ? typeof actualVal === 'number'
128
- : expected === 'array' ? Array.isArray(actualVal)
129
- : typeof actualVal === expected;
130
- };
131
- const ok = Array.isArray(def.type)
132
- ? def.type.some(t => typeMatches(t, val))
133
- : typeMatches(def.type, val);
134
- if (!ok) errors.push({ category: 'type-mismatch', field, message: `field "${field}": expected ${def.type}, got ${Array.isArray(val) ? 'array' : typeof val}`, value: val, expected: String(def.type) });
135
- }
136
- if (def.enum && !def.enum.includes(val)) {
137
- errors.push({ category: 'invalid-enum', field, message: `field "${field}": value "${val}" not in [${def.enum.join(', ')}]`, value: String(val), expected: def.enum });
138
- }
139
- if (def.minimum !== undefined && typeof val === 'number' && val < def.minimum) {
140
- errors.push({ category: 'minimum-violation', field, message: `field "${field}": value ${val} is below minimum ${def.minimum}`, value: val, expected: String(def.minimum) });
141
- }
142
- // FORGE-S20-T01 — minimal `pattern` interpreter for string fields. Strictly
143
- // additive: schemas without `pattern` see no behavior change. Used by the
144
- // friction `subkind` slot to encode "frozen enum OR ^x_[a-z_]+$" as a
145
- // single combined regex (neither validator supports `anyOf`).
146
- if (def.pattern && typeof val === 'string') {
147
- let re;
148
- try { re = new RegExp(def.pattern); }
149
- catch (_) {
150
- errors.push({
151
- category: 'pattern-invalid',
152
- field,
153
- message: `field "${field}": schema pattern "${def.pattern}" is not a valid regex`,
154
- value: String(val),
155
- expected: String(def.pattern),
156
- });
157
- re = null;
158
- }
159
- if (re && !re.test(val)) {
160
- errors.push({
161
- category: 'pattern-mismatch',
162
- field,
163
- message: `field "${field}": value "${val}" does not match pattern ${def.pattern}`,
164
- value: String(val),
165
- expected: String(def.pattern),
166
- });
167
- }
168
- }
169
- }
170
-
171
- // Check for undeclared fields when additionalProperties is false
172
- if (schema.additionalProperties === false) {
173
- const allowed = new Set([...required, ...Object.keys(schema.properties || {})]);
174
- for (const key of Object.keys(record)) {
175
- if (!allowed.has(key)) {
176
- errors.push({ category: 'undeclared-field', field: key, message: `undeclared field: "${key}"`, value: record[key], expected: null });
177
- }
178
- }
179
- }
180
-
181
- // Conditional required via JSON-Schema `allOf` with `if/then/required`.
182
- // FORGE-S20-T00 — minimal interpreter: each clause may carry an `if` whose
183
- // `properties.<field>.const` must equal `record[field]`, AND every field in
184
- // `if.required` must be present on the record. When the clause matches,
185
- // every name in `then.required` becomes an additional required field.
186
- // No other JSON-Schema constructs are honored — this is intentional; the
187
- // store schemas are thin and we don't want to drag in a full validator.
188
- if (Array.isArray(schema.allOf)) {
189
- for (const clause of schema.allOf) {
190
- if (!clause || typeof clause !== 'object' || !clause.if || !clause.then) continue;
191
- const condProps = (clause.if.properties && typeof clause.if.properties === 'object')
192
- ? clause.if.properties
193
- : {};
194
- const condRequired = Array.isArray(clause.if.required) ? clause.if.required : [];
195
-
196
- // All `if.required` fields must be present on the record.
197
- const allReqPresent = condRequired.every((f) => record[f] !== undefined && record[f] !== null && record[f] !== '');
198
- if (!allReqPresent) continue;
199
-
200
- // Every const predicate in `if.properties` must match the record.
201
- let condMatches = true;
202
- for (const [field, pred] of Object.entries(condProps)) {
203
- if (pred && Object.prototype.hasOwnProperty.call(pred, 'const')) {
204
- if (record[field] !== pred.const) { condMatches = false; break; }
205
- }
206
- }
207
- if (!condMatches) continue;
208
-
209
- // Clause fired — enforce `then.required`.
210
- const thenRequired = Array.isArray(clause.then.required) ? clause.then.required : [];
211
- for (const field of thenRequired) {
212
- if (record[field] === undefined || record[field] === null || record[field] === '') {
213
- errors.push({
214
- category: 'missing-required',
215
- field,
216
- message: `missing required field: "${field}"`,
217
- value: record[field],
218
- expected: null,
219
- });
220
- }
221
- }
222
- }
223
- }
224
-
225
- return errors;
226
- }
227
-
228
- // --- Backfill defaults for --fix mode ---
229
- const BACKFILL = {
230
- sprint: {
231
- createdAt: (rec) => rec.completedAt || rec.startDate || rec.endDate || new Date().toISOString(),
232
- },
233
- bug: {
234
- reportedAt: (rec) => rec.resolvedAt || new Date().toISOString(),
235
- },
236
- event: {
237
- eventId: (_rec, id) => id,
238
- role: (rec) => rec.agent || 'unknown',
239
- action: (rec) => rec.phase || 'unknown',
240
- phase: (rec) => rec.action || 'unknown',
241
- iteration: () => 1,
242
- startTimestamp: (rec) => rec.timestamp || new Date().toISOString(),
243
- endTimestamp: (rec) => rec.timestamp || null,
244
- durationMinutes: () => null,
245
- model: (rec) => {
246
- if (rec.actor && typeof rec.actor === 'string' && rec.actor.includes('claude')) return rec.actor;
247
- return 'unknown';
248
- },
249
- },
250
- };
251
-
252
- module.exports = { validateRecord, MINIMAL_REQUIRED, NULLABLE_FK, BACKFILL, ENTITY_TYPES, ANCILLARY_SCHEMAS };
253
-
254
- // ---------------------------------------------------------------------------
255
- // CLI
256
- // ---------------------------------------------------------------------------
257
- if (require.main === module) {
258
-
259
- process.on('uncaughtException', (error) => {
260
- console.error('Fatal validate-store error:', error);
261
- process.exit(1);
262
- });
263
-
264
- const fs = require('fs');
265
- const path = require('path');
266
- const store = _getStore();
267
- const schemas = _getSchemas();
268
-
269
- const DRY_RUN = process.argv.includes('--dry-run');
270
- const FIX_MODE = process.argv.includes('--fix');
271
- const JSON_MODE = process.argv.includes('--json');
272
-
273
- // Read engineering root and project prefix from config for filesystem consistency checks
274
- const CONFIG_PATH = '.forge/config.json';
275
- let engineeringRoot = 'engineering';
276
- let projectPrefix = '[A-Z]+';
277
- try {
278
- const cfg = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'));
279
- if (cfg.paths && cfg.paths.engineering) engineeringRoot = cfg.paths.engineering;
280
- if (cfg.project && cfg.project.prefix) projectPrefix = cfg.project.prefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
281
- } catch (_) {}
282
-
283
- // Slug-aware directory discovery regexes
284
- const SPRINT_DIR_RE = new RegExp(`^(${projectPrefix}-S\\d+)(-\\S+)?$`);
285
- const TASK_FULL_RE = new RegExp(`^(${projectPrefix}-S\\d+-T\\d+)(-\\S+)?$`);
286
- const TASK_SHORT_RE = /^(T\d+)(-\S+)?$/;
287
-
288
- let errorsCount = 0;
289
- let warningsCount = 0;
290
- let fixesCount = 0;
291
-
292
- // Structured collections for --json mode
293
- const jsonErrors = [];
294
- const jsonWarnings = [];
295
- const jsonFixes = [];
296
-
297
- function err(id, msg, category, field, value, expected) {
298
- errorsCount++;
299
- if (JSON_MODE) {
300
- jsonErrors.push({ entity: id.split('/')[0].split('-')[0] || 'unknown', id, category: category || 'unknown', field: field || null, message: msg, value: value || null, expected: expected || null });
301
- } else {
302
- console.error(`ERROR ${id}: ${msg}`);
303
- }
304
- }
305
-
306
- function warn(id, msg, category, field) {
307
- warningsCount++;
308
- if (JSON_MODE) {
309
- jsonWarnings.push({ entity: id.split('/')[0].split('-')[0] || 'unknown', id, category: category || 'unknown', field: field || null, message: msg });
310
- } else {
311
- console.log(`WARN ${id}: ${msg}`);
312
- }
313
- }
314
-
315
- function fixMsg(id, msg, category, field) {
316
- fixesCount++;
317
- if (JSON_MODE) {
318
- jsonFixes.push({ entity: id.split('/')[0].split('-')[0] || 'unknown', id, category: category || 'backfill', field: field || null, message: msg, applied: !DRY_RUN });
319
- } else {
320
- console.log(`FIXED ${id}: ${msg}`);
321
- }
322
- }
323
-
324
- function backfillRecord(id, rec, type) {
325
- const rules = BACKFILL[type];
326
- if (!rules) return false;
327
- let changed = false;
328
- for (const [field, derive] of Object.entries(rules)) {
329
- if (rec[field] === undefined || rec[field] === null || rec[field] === '') {
330
- const val = derive(rec, id);
331
- rec[field] = val;
332
- fixMsg(id, `backfilled "${field}" = "${val}"`, 'backfill', field);
333
- changed = true;
334
- }
335
- }
336
- if (changed) {
337
- // In dry-run mode, preview the fix without writing
338
- if (DRY_RUN) return changed;
339
- // Facade write uses the logic in FSImpl to maintain formatting
340
- if (type === 'sprint') store.writeSprint(rec);
341
- else if (type === 'task') store.writeTask(rec);
342
- else if (type === 'bug') store.writeBug(rec);
343
- else if (type === 'feature') store.writeFeature(rec);
344
- // Events are slightly different as they need sprintId
345
- else if (type === 'event') {
346
- // We'll handle event writing in the loop where sprintId is known
347
- }
348
- }
349
- return changed;
350
- }
351
-
352
- // Load all records up-front for referential integrity checks
353
- const sprintIds = new Set();
354
- const taskIds = new Set();
355
- const bugIds = new Set();
356
- const featureIds = new Set();
357
-
358
- // --- Pass 1: validate structure, collect IDs ---
359
- const sprints = store.listSprints();
360
- for (const rec of sprints) {
361
- if (!rec) continue;
362
- if (FIX_MODE) backfillRecord(rec.sprintId, rec, 'sprint');
363
- if (rec.sprintId) sprintIds.add(rec.sprintId);
364
- for (const e of validateRecord(rec, schemas.sprint)) err(rec.sprintId, e.message, e.category, e.field, e.value, e.expected);
365
- if (!rec.path) warn(rec.sprintId, 'missing optional field "path"', 'missing-optional', 'path');
366
- }
367
-
368
- const tasks = store.listTasks();
369
- for (const rec of tasks) {
370
- if (!rec) continue;
371
- if (rec.taskId) taskIds.add(rec.taskId);
372
- for (const e of validateRecord(rec, schemas.task)) err(rec.taskId, e.message, e.category, e.field, e.value, e.expected);
373
- }
374
-
375
- const bugs = store.listBugs();
376
- for (const rec of bugs) {
377
- if (!rec) continue;
378
- if (FIX_MODE) backfillRecord(rec.bugId, rec, 'bug');
379
- if (rec.bugId) bugIds.add(rec.bugId);
380
- for (const e of validateRecord(rec, schemas.bug)) err(rec.bugId, e.message, e.category, e.field, e.value, e.expected);
381
- }
382
-
383
- const features = store.listFeatures();
384
- for (const rec of features) {
385
- if (!rec) continue;
386
- const featureId = rec.id || 'unknown';
387
- featureIds.add(featureId);
388
- }
389
-
390
- // --- Pass 2: referential integrity ---
391
- for (const rec of sprints) {
392
- if (!rec) continue;
393
- if (rec.feature_id && !featureIds.has(rec.feature_id)) {
394
- if (FIX_MODE) {
395
- rec.feature_id = null;
396
- if (!DRY_RUN) store.writeSprint(rec);
397
- fixMsg(rec.sprintId, `nullified orphaned feature_id "${rec.feature_id}"`, 'orphaned-fk', 'feature_id');
398
- } else {
399
- err(rec.sprintId, `feature_id "${rec.feature_id}" references unknown feature`, 'orphaned-fk', 'feature_id', rec.feature_id);
400
- }
401
- }
402
- }
403
-
404
- for (const rec of tasks) {
405
- if (!rec) continue;
406
- if (rec.sprintId && !sprintIds.has(rec.sprintId))
407
- err(rec.taskId, `sprintId "${rec.sprintId}" references unknown sprint`, 'orphaned-fk', 'sprintId', rec.sprintId);
408
-
409
- if (rec.feature_id && !featureIds.has(rec.feature_id)) {
410
- if (FIX_MODE) {
411
- rec.feature_id = null;
412
- if (!DRY_RUN) store.writeTask(rec);
413
- fixMsg(rec.taskId, `nullified orphaned feature_id "${rec.feature_id}"`, 'orphaned-fk', 'feature_id');
414
- } else {
415
- err(rec.taskId, `feature_id "${rec.feature_id}" references unknown feature`, 'orphaned-fk', 'feature_id', rec.feature_id);
416
- }
417
- }
418
- }
419
-
420
- for (const rec of bugs) {
421
- if (!rec) continue;
422
- for (const ref of (rec.similarBugs || [])) {
423
- if (!bugIds.has(ref)) err(rec.bugId, `similarBugs references unknown bug "${ref}"`, 'orphaned-fk', 'similarBugs', ref);
424
- }
425
- }
426
-
427
- // --- Events ---
428
- const allSprints = store.listSprints();
429
- for (const sprint of allSprints) {
430
- if (!sprint) continue;
431
- const sprintId = sprint.sprintId;
432
- const eventFileEntries = store.listEventFilenames(sprintId)
433
- .filter(entry => !entry.id.startsWith('_'));
434
-
435
- for (const entry of eventFileEntries) {
436
- const filename = entry.id; // filename without .json extension
437
- const rec = store.getEvent(filename, sprintId);
438
- if (!rec) continue;
439
-
440
- const eventId = rec.eventId;
441
-
442
- if (FIX_MODE) {
443
- const rules = BACKFILL.event;
444
- let changed = false;
445
- for (const [field, derive] of Object.entries(rules)) {
446
- if (rec[field] === undefined || rec[field] === null || rec[field] === '') {
447
- const val = derive(rec, filename);
448
- rec[field] = val;
449
- fixMsg(`${sprintId}/${filename}`, `backfilled "${field}" = "${val}"`, 'backfill', field);
450
- changed = true;
451
- }
452
- }
453
-
454
- // If the filename doesn't match the canonical eventId, resolve the mismatch.
455
- // When the eventId is a valid filename, rename the file to match it.
456
- // When the eventId is invalid (contains /, is a placeholder like "temp",
457
- // or cannot be a filename), backfill eventId to the filename instead.
458
- if (filename !== rec.eventId) {
459
- const isValidFilename = (id) => id && !id.includes('/') && !id.includes('\\') && id !== '.';
460
- if (isValidFilename(rec.eventId)) {
461
- if (!DRY_RUN) {
462
- try {
463
- store.renameEvent(sprintId, filename, rec.eventId);
464
- } catch (renameErr) {
465
- err(`${sprintId}/${filename}`, `cannot rename to ${rec.eventId}.json: ${renameErr.message}`, 'filename-mismatch', 'eventId');
466
- }
467
- }
468
- fixMsg(`${sprintId}/${filename}`, `renamed to ${rec.eventId}.json`, 'filename-mismatch', 'eventId');
469
- } else {
470
- // eventId is invalid for a filename — backfill it to the current filename
471
- fixMsg(`${sprintId}/${filename}`, `eventId "${rec.eventId}" is not a valid filename, resetting to "${filename}"`, 'filename-mismatch', 'eventId');
472
- rec.eventId = filename;
473
- changed = true;
474
- }
475
- }
476
-
477
- // Write the updated record (writeEvent now handles ghost detection internally)
478
- if (changed && !DRY_RUN) store.writeEvent(sprintId, rec);
479
- }
480
-
481
- for (const e of validateRecord(rec, schemas.event)) err(`${sprintId}/${eventId}`, e.message, e.category, e.field, e.value, e.expected);
482
- if (rec.taskId && !taskIds.has(rec.taskId) && !bugIds.has(rec.taskId))
483
- err(`${sprintId}/${eventId}`, `taskId "${rec.taskId}" references unknown task or bug`, 'orphaned-fk', 'taskId', rec.taskId);
484
- if (rec.sprintId && !sprintIds.has(rec.sprintId) && rec.sprintId !== sprintId)
485
- err(`${sprintId}/${eventId}`, `sprintId "${rec.sprintId}" references unknown sprint`, 'orphaned-fk', 'sprintId', rec.sprintId);
486
- }
487
- }
488
-
489
- // --- Pass 3: Filesystem consistency ---
490
- // Walk engineering/sprints/ to detect orphaned directories and dangling path fields.
491
- // All checks here emit warnings (not errors) for backward compatibility.
492
- const sprintsDir = path.join(engineeringRoot, 'sprints');
493
- if (fs.existsSync(sprintsDir)) {
494
- let sprintEntries;
495
- try { sprintEntries = fs.readdirSync(sprintsDir); } catch (_) { sprintEntries = []; }
496
-
497
- for (const entry of sprintEntries) {
498
- const entryPath = path.join(sprintsDir, entry);
499
- let isDir = false;
500
- try { isDir = fs.statSync(entryPath).isDirectory(); } catch (_) {}
501
- if (!isDir) continue;
502
-
503
- const sprintMatch = SPRINT_DIR_RE.exec(entry);
504
- if (!sprintMatch) continue; // not a recognised sprint directory pattern — skip silently
505
- const dirSprintId = sprintMatch[1];
506
-
507
- if (!sprintIds.has(dirSprintId)) {
508
- warn(dirSprintId, `directory "${entry}" has no sprint record in store`, 'orphan-directory');
509
- continue; // no point walking tasks for an unregistered sprint
510
- }
511
-
512
- // Walk for task subdirectories
513
- let taskEntries;
514
- try { taskEntries = fs.readdirSync(entryPath); } catch (_) { taskEntries = []; }
515
-
516
- for (const taskEntry of taskEntries) {
517
- const taskEntryPath = path.join(entryPath, taskEntry);
518
- let isTaskDir = false;
519
- try { isTaskDir = fs.statSync(taskEntryPath).isDirectory(); } catch (_) {}
520
- if (!isTaskDir) continue;
521
-
522
- let dirTaskId = null;
523
-
524
- const taskFullMatch = TASK_FULL_RE.exec(taskEntry);
525
- if (taskFullMatch) {
526
- dirTaskId = taskFullMatch[1];
527
- } else {
528
- const taskShortMatch = TASK_SHORT_RE.exec(taskEntry);
529
- if (taskShortMatch) {
530
- // Construct full task ID from sprint ID + short task number (e.g. T09 → FORGE-S06-T09)
531
- dirTaskId = `${dirSprintId}-${taskShortMatch[1]}`;
532
- }
533
- }
534
-
535
- if (!dirTaskId) continue; // not a recognised task directory pattern — skip silently
536
-
537
- if (!taskIds.has(dirTaskId)) {
538
- warn(dirTaskId, `directory "${entry}/${taskEntry}" has no task record in store`, 'orphan-directory');
539
- }
540
- }
541
- }
542
- }
543
-
544
- // path field cross-check for sprints
545
- for (const rec of sprints) {
546
- if (!rec || !rec.path) continue;
547
- if (!fs.existsSync(rec.path)) {
548
- warn(rec.sprintId, `path "${rec.path}" does not exist on disk`, 'stale-path', 'path');
549
- }
550
- }
551
-
552
- // path field cross-check for tasks
553
- for (const rec of tasks) {
554
- if (!rec || !rec.path) continue;
555
- if (!fs.existsSync(rec.path)) {
556
- warn(rec.taskId, `path "${rec.path}" does not exist on disk`, 'stale-path', 'path');
557
- }
558
- }
559
-
560
- // --- Result ---
561
- if (JSON_MODE) {
562
- const result = {
563
- ok: errorsCount === 0,
564
- errors: jsonErrors,
565
- warnings: jsonWarnings,
566
- fixes: jsonFixes,
567
- summary: {
568
- sprints: sprintIds.size,
569
- tasks: taskIds.size,
570
- bugs: bugIds.size,
571
- features: featureIds.size,
572
- errors: errorsCount,
573
- warnings: warningsCount,
574
- fixes: fixesCount
575
- }
576
- };
577
- console.log(JSON.stringify(result, null, 2));
578
- process.exit(errorsCount === 0 ? 0 : 1);
579
- } else {
580
- if (fixesCount > 0) {
581
- console.log(`${fixesCount} field(s) backfilled.`);
582
- }
583
- if (errorsCount === 0) {
584
- console.log(`Store validation passed (${sprintIds.size} sprint(s), ${taskIds.size} task(s), ${bugIds.size} bug(s)).`);
585
- if (warningsCount > 0) console.log(`${warningsCount} warning(s).`);
586
- process.exit(0);
587
- } else {
588
- console.error(`\n${errorsCount} error(s) found.`);
589
- process.exit(1);
590
- }
591
- }
592
-
593
- } // end if (require.main === module)
@@ -1,24 +0,0 @@
1
- {
2
- "name": "pi-extension-custom-provider",
3
- "version": "0.74.2",
4
- "lockfileVersion": 3,
5
- "requires": true,
6
- "packages": {
7
- "": {
8
- "name": "pi-extension-custom-provider",
9
- "version": "0.74.2",
10
- "dependencies": {
11
- "@anthropic-ai/sdk": "^0.52.0"
12
- }
13
- },
14
- "node_modules/@anthropic-ai/sdk": {
15
- "version": "0.52.0",
16
- "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.52.0.tgz",
17
- "integrity": "sha512-d4c+fg+xy9e46c8+YnrrgIQR45CZlAi7PwdzIfDXDM6ACxEZli1/fxhURsq30ZpMZy6LvSkr41jGq5aF5TD7rQ==",
18
- "license": "MIT",
19
- "bin": {
20
- "anthropic-ai-sdk": "bin/cli"
21
- }
22
- }
23
- }
24
- }