@entelligentsia/forgecli 0.19.0 → 0.20.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/dist/bin/config.js +9 -9
  3. package/dist/bin/config.js.map +1 -1
  4. package/dist/bin/forge.js +3 -3
  5. package/dist/bin/forge.js.map +1 -1
  6. package/dist/bin/update-cli.js +2 -1
  7. package/dist/bin/update-cli.js.map +1 -1
  8. package/dist/extensions/forgecli/add-pipeline.js.map +1 -1
  9. package/dist/extensions/forgecli/add-task.js.map +1 -1
  10. package/dist/extensions/forgecli/approve.d.ts +2 -2
  11. package/dist/extensions/forgecli/approve.js +2 -2
  12. package/dist/extensions/forgecli/approve.js.map +1 -1
  13. package/dist/extensions/forgecli/ask-user-tool.js.map +1 -1
  14. package/dist/extensions/forgecli/audience-gate.js.map +1 -1
  15. package/dist/extensions/forgecli/calibrate.d.ts +1 -1
  16. package/dist/extensions/forgecli/calibrate.js +8 -10
  17. package/dist/extensions/forgecli/calibrate.js.map +1 -1
  18. package/dist/extensions/forgecli/collate.d.ts +2 -2
  19. package/dist/extensions/forgecli/collate.js +2 -2
  20. package/dist/extensions/forgecli/collate.js.map +1 -1
  21. package/dist/extensions/forgecli/commit.d.ts +2 -2
  22. package/dist/extensions/forgecli/commit.js +2 -2
  23. package/dist/extensions/forgecli/commit.js.map +1 -1
  24. package/dist/extensions/forgecli/config-command.js.map +1 -1
  25. package/dist/extensions/forgecli/config-layer.js +4 -2
  26. package/dist/extensions/forgecli/config-layer.js.map +1 -1
  27. package/dist/extensions/forgecli/config-tui/component.d.ts +1 -1
  28. package/dist/extensions/forgecli/config-tui/component.js +25 -21
  29. package/dist/extensions/forgecli/config-tui/component.js.map +1 -1
  30. package/dist/extensions/forgecli/config-tui/handler.js +2 -6
  31. package/dist/extensions/forgecli/config-tui/handler.js.map +1 -1
  32. package/dist/extensions/forgecli/config-tui/keys.js.map +1 -1
  33. package/dist/extensions/forgecli/config-tui/plugin-config-reader.js.map +1 -1
  34. package/dist/extensions/forgecli/config-tui/screens/advanced-menu.d.ts +2 -2
  35. package/dist/extensions/forgecli/config-tui/screens/advanced-menu.js +10 -8
  36. package/dist/extensions/forgecli/config-tui/screens/advanced-menu.js.map +1 -1
  37. package/dist/extensions/forgecli/config-tui/screens/confirm-quit.d.ts +2 -2
  38. package/dist/extensions/forgecli/config-tui/screens/confirm-quit.js +2 -5
  39. package/dist/extensions/forgecli/config-tui/screens/confirm-quit.js.map +1 -1
  40. package/dist/extensions/forgecli/config-tui/screens/override-editor.d.ts +2 -2
  41. package/dist/extensions/forgecli/config-tui/screens/override-editor.js +15 -11
  42. package/dist/extensions/forgecli/config-tui/screens/override-editor.js.map +1 -1
  43. package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.d.ts +2 -2
  44. package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.js +15 -11
  45. package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.js.map +1 -1
  46. package/dist/extensions/forgecli/config-tui/screens/overrides-list.d.ts +2 -2
  47. package/dist/extensions/forgecli/config-tui/screens/overrides-list.js +7 -4
  48. package/dist/extensions/forgecli/config-tui/screens/overrides-list.js.map +1 -1
  49. package/dist/extensions/forgecli/config-tui/screens/persona-editor.d.ts +2 -2
  50. package/dist/extensions/forgecli/config-tui/screens/persona-editor.js +6 -12
  51. package/dist/extensions/forgecli/config-tui/screens/persona-editor.js.map +1 -1
  52. package/dist/extensions/forgecli/config-tui/screens/persona-picker.d.ts +2 -2
  53. package/dist/extensions/forgecli/config-tui/screens/persona-picker.js +3 -6
  54. package/dist/extensions/forgecli/config-tui/screens/persona-picker.js.map +1 -1
  55. package/dist/extensions/forgecli/config-tui/screens/personas-list.d.ts +2 -2
  56. package/dist/extensions/forgecli/config-tui/screens/personas-list.js +2 -2
  57. package/dist/extensions/forgecli/config-tui/screens/personas-list.js.map +1 -1
  58. package/dist/extensions/forgecli/config-tui/screens/shared.d.ts +1 -1
  59. package/dist/extensions/forgecli/config-tui/screens/shared.js +4 -5
  60. package/dist/extensions/forgecli/config-tui/screens/shared.js.map +1 -1
  61. package/dist/extensions/forgecli/config-tui/screens/show-resolved.d.ts +2 -2
  62. package/dist/extensions/forgecli/config-tui/screens/show-resolved.js +9 -11
  63. package/dist/extensions/forgecli/config-tui/screens/show-resolved.js.map +1 -1
  64. package/dist/extensions/forgecli/config-tui/screens/tier-menu.d.ts +2 -2
  65. package/dist/extensions/forgecli/config-tui/screens/tier-menu.js +2 -2
  66. package/dist/extensions/forgecli/config-tui/screens/tier-menu.js.map +1 -1
  67. package/dist/extensions/forgecli/config-tui/screens/tier-picker.d.ts +2 -2
  68. package/dist/extensions/forgecli/config-tui/screens/tier-picker.js +12 -3
  69. package/dist/extensions/forgecli/config-tui/screens/tier-picker.js.map +1 -1
  70. package/dist/extensions/forgecli/config-tui/screens/types.d.ts +1 -1
  71. package/dist/extensions/forgecli/config-tui/screens.d.ts +10 -10
  72. package/dist/extensions/forgecli/config-tui/screens.js +16 -16
  73. package/dist/extensions/forgecli/config-tui/screens.js.map +1 -1
  74. package/dist/extensions/forgecli/config-tui/state/buffer.d.ts +2 -2
  75. package/dist/extensions/forgecli/config-tui/state/buffer.js +1 -2
  76. package/dist/extensions/forgecli/config-tui/state/buffer.js.map +1 -1
  77. package/dist/extensions/forgecli/config-tui/state/constants.js.map +1 -1
  78. package/dist/extensions/forgecli/config-tui/state/index.d.ts +3 -3
  79. package/dist/extensions/forgecli/config-tui/state/index.js +2 -2
  80. package/dist/extensions/forgecli/config-tui/state/index.js.map +1 -1
  81. package/dist/extensions/forgecli/config-tui/state/init.js.map +1 -1
  82. package/dist/extensions/forgecli/config-tui/state/reducer.js +2 -4
  83. package/dist/extensions/forgecli/config-tui/state/reducer.js.map +1 -1
  84. package/dist/extensions/forgecli/config-tui/state/selectors.d.ts +1 -1
  85. package/dist/extensions/forgecli/config-tui/state/selectors.js +7 -6
  86. package/dist/extensions/forgecli/config-tui/state/selectors.js.map +1 -1
  87. package/dist/extensions/forgecli/config-tui/state.d.ts +3 -3
  88. package/dist/extensions/forgecli/config-tui/state.js +2 -2
  89. package/dist/extensions/forgecli/config-tui/state.js.map +1 -1
  90. package/dist/extensions/forgecli/config-tui/theme.js +1 -1
  91. package/dist/extensions/forgecli/config-tui/theme.js.map +1 -1
  92. package/dist/extensions/forgecli/config-tui/tier-meta.js.map +1 -1
  93. package/dist/extensions/forgecli/config-writer.js +4 -2
  94. package/dist/extensions/forgecli/config-writer.js.map +1 -1
  95. package/dist/extensions/forgecli/enhance.d.ts +2 -2
  96. package/dist/extensions/forgecli/enhance.js +3 -3
  97. package/dist/extensions/forgecli/enhance.js.map +1 -1
  98. package/dist/extensions/forgecli/fix-bug.d.ts +1 -1
  99. package/dist/extensions/forgecli/fix-bug.js +148 -58
  100. package/dist/extensions/forgecli/fix-bug.js.map +1 -1
  101. package/dist/extensions/forgecli/forge-artifact-tool.d.ts +8 -1
  102. package/dist/extensions/forgecli/forge-artifact-tool.js +85 -15
  103. package/dist/extensions/forgecli/forge-artifact-tool.js.map +1 -1
  104. package/dist/extensions/forgecli/forge-commands.js.map +1 -1
  105. package/dist/extensions/forgecli/forge-header.d.ts +1 -1
  106. package/dist/extensions/forgecli/forge-header.js +1 -1
  107. package/dist/extensions/forgecli/forge-header.js.map +1 -1
  108. package/dist/extensions/forgecli/forge-init/phase-descriptors.js +14 -5
  109. package/dist/extensions/forgecli/forge-init/phase-descriptors.js.map +1 -1
  110. package/dist/extensions/forgecli/forge-init/phase4-register.js +20 -1
  111. package/dist/extensions/forgecli/forge-init/phase4-register.js.map +1 -1
  112. package/dist/extensions/forgecli/forge-init.js +5 -7
  113. package/dist/extensions/forgecli/forge-init.js.map +1 -1
  114. package/dist/extensions/forgecli/forge-subagent.d.ts +1 -1
  115. package/dist/extensions/forgecli/forge-subagent.js +4 -2
  116. package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
  117. package/dist/extensions/forgecli/forge-tools.js +10 -4
  118. package/dist/extensions/forgecli/forge-tools.js.map +1 -1
  119. package/dist/extensions/forgecli/forge-update-command.d.ts +32 -11
  120. package/dist/extensions/forgecli/forge-update-command.js +207 -155
  121. package/dist/extensions/forgecli/forge-update-command.js.map +1 -1
  122. package/dist/extensions/forgecli/friction-emit.js +3 -5
  123. package/dist/extensions/forgecli/friction-emit.js.map +1 -1
  124. package/dist/extensions/forgecli/health-check.js +10 -6
  125. package/dist/extensions/forgecli/health-check.js.map +1 -1
  126. package/dist/extensions/forgecli/hook-dispatcher.js +2 -2
  127. package/dist/extensions/forgecli/hook-dispatcher.js.map +1 -1
  128. package/dist/extensions/forgecli/hooks/check-update.js.map +1 -1
  129. package/dist/extensions/forgecli/hooks/forge-permissions.js.map +1 -1
  130. package/dist/extensions/forgecli/hooks/post-init-hook.js +1 -1
  131. package/dist/extensions/forgecli/hooks/post-init-hook.js.map +1 -1
  132. package/dist/extensions/forgecli/hooks/post-sprint-hook.js +1 -1
  133. package/dist/extensions/forgecli/hooks/post-sprint-hook.js.map +1 -1
  134. package/dist/extensions/forgecli/hooks/write-guard.js +5 -3
  135. package/dist/extensions/forgecli/hooks/write-guard.js.map +1 -1
  136. package/dist/extensions/forgecli/implement.d.ts +2 -2
  137. package/dist/extensions/forgecli/implement.js +2 -2
  138. package/dist/extensions/forgecli/implement.js.map +1 -1
  139. package/dist/extensions/forgecli/index.js +47 -41
  140. package/dist/extensions/forgecli/index.js.map +1 -1
  141. package/dist/extensions/forgecli/input-router.js +4 -1
  142. package/dist/extensions/forgecli/input-router.js.map +1 -1
  143. package/dist/extensions/forgecli/lib/catalog-helpers.js +2 -1
  144. package/dist/extensions/forgecli/lib/catalog-helpers.js.map +1 -1
  145. package/dist/extensions/forgecli/lib/catalog-loader.js.map +1 -1
  146. package/dist/extensions/forgecli/lib/catalog-types.js +1 -6
  147. package/dist/extensions/forgecli/lib/catalog-types.js.map +1 -1
  148. package/dist/extensions/forgecli/lib/exec-helpers.js +1 -1
  149. package/dist/extensions/forgecli/lib/exec-helpers.js.map +1 -1
  150. package/dist/extensions/forgecli/lib/forge-config.js.map +1 -1
  151. package/dist/extensions/forgecli/lib/orchestrator-preflight.js.map +1 -1
  152. package/dist/extensions/forgecli/lib/parsers.js.map +1 -1
  153. package/dist/extensions/forgecli/lib/spawn-store-cli.js +17 -7
  154. package/dist/extensions/forgecli/lib/spawn-store-cli.js.map +1 -1
  155. package/dist/extensions/forgecli/materialize.js.map +1 -1
  156. package/dist/extensions/forgecli/migrate.js +1 -1
  157. package/dist/extensions/forgecli/migrate.js.map +1 -1
  158. package/dist/extensions/forgecli/migration-engine.js +3 -6
  159. package/dist/extensions/forgecli/migration-engine.js.map +1 -1
  160. package/dist/extensions/forgecli/model-resolver.js.map +1 -1
  161. package/dist/extensions/forgecli/model-validator.js.map +1 -1
  162. package/dist/extensions/forgecli/parsers/persona-skill-loader.js +1 -1
  163. package/dist/extensions/forgecli/parsers/workflow-loader.js +2 -6
  164. package/dist/extensions/forgecli/parsers/workflow-loader.js.map +1 -1
  165. package/dist/extensions/forgecli/paths/migrator.js +2 -7
  166. package/dist/extensions/forgecli/paths/migrator.js.map +1 -1
  167. package/dist/extensions/forgecli/plan.d.ts +2 -2
  168. package/dist/extensions/forgecli/plan.js +2 -2
  169. package/dist/extensions/forgecli/plan.js.map +1 -1
  170. package/dist/extensions/forgecli/quiz-agent.js.map +1 -1
  171. package/dist/extensions/forgecli/read-command.js +1 -1
  172. package/dist/extensions/forgecli/read-command.js.map +1 -1
  173. package/dist/extensions/forgecli/regenerate.js +1 -3
  174. package/dist/extensions/forgecli/regenerate.js.map +1 -1
  175. package/dist/extensions/forgecli/remove-command.js.map +1 -1
  176. package/dist/extensions/forgecli/report-bug.js +2 -2
  177. package/dist/extensions/forgecli/report-bug.js.map +1 -1
  178. package/dist/extensions/forgecli/retrospective.js +2 -2
  179. package/dist/extensions/forgecli/retrospective.js.map +1 -1
  180. package/dist/extensions/forgecli/review-code.d.ts +2 -2
  181. package/dist/extensions/forgecli/review-code.js +2 -2
  182. package/dist/extensions/forgecli/review-code.js.map +1 -1
  183. package/dist/extensions/forgecli/review-plan.d.ts +2 -2
  184. package/dist/extensions/forgecli/review-plan.js +2 -2
  185. package/dist/extensions/forgecli/review-plan.js.map +1 -1
  186. package/dist/extensions/forgecli/review-server.js +3 -5
  187. package/dist/extensions/forgecli/review-server.js.map +1 -1
  188. package/dist/extensions/forgecli/run-sprint.d.ts +1 -1
  189. package/dist/extensions/forgecli/run-sprint.js +27 -21
  190. package/dist/extensions/forgecli/run-sprint.js.map +1 -1
  191. package/dist/extensions/forgecli/run-task.js +102 -42
  192. package/dist/extensions/forgecli/run-task.js.map +1 -1
  193. package/dist/extensions/forgecli/session-registry.js.map +1 -1
  194. package/dist/extensions/forgecli/skill-curator-subagent.js +4 -8
  195. package/dist/extensions/forgecli/skill-curator-subagent.js.map +1 -1
  196. package/dist/extensions/forgecli/skill-retriever.js +1 -1
  197. package/dist/extensions/forgecli/skill-retriever.js.map +1 -1
  198. package/dist/extensions/forgecli/skill-usage-tracker.js +1 -1
  199. package/dist/extensions/forgecli/skill-usage-tracker.js.map +1 -1
  200. package/dist/extensions/forgecli/status-command.js.map +1 -1
  201. package/dist/extensions/forgecli/store-error-remediation.js +16 -8
  202. package/dist/extensions/forgecli/store-error-remediation.js.map +1 -1
  203. package/dist/extensions/forgecli/store-query.js.map +1 -1
  204. package/dist/extensions/forgecli/store-repair.js.map +1 -1
  205. package/dist/extensions/forgecli/store-resolver.js +1 -1
  206. package/dist/extensions/forgecli/store-resolver.js.map +1 -1
  207. package/dist/extensions/forgecli/store-validator.js +1 -1
  208. package/dist/extensions/forgecli/store-validator.js.map +1 -1
  209. package/dist/extensions/forgecli/subagent/agents.js +1 -1
  210. package/dist/extensions/forgecli/subagent/agents.js.map +1 -1
  211. package/dist/extensions/forgecli/subagent/index.js +1 -1
  212. package/dist/extensions/forgecli/subagent/index.js.map +1 -1
  213. package/dist/extensions/forgecli/test-orchestrate.js +1 -1
  214. package/dist/extensions/forgecli/test-orchestrate.js.map +1 -1
  215. package/dist/extensions/forgecli/thread-switcher.js +8 -18
  216. package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
  217. package/dist/extensions/forgecli/transition-guard.js +1 -1
  218. package/dist/extensions/forgecli/transition-guard.js.map +1 -1
  219. package/dist/extensions/forgecli/update-tools.js +1 -2
  220. package/dist/extensions/forgecli/update-tools.js.map +1 -1
  221. package/dist/extensions/forgecli/validate.d.ts +2 -2
  222. package/dist/extensions/forgecli/validate.js +2 -2
  223. package/dist/extensions/forgecli/validate.js.map +1 -1
  224. package/dist/extensions/forgecli/viewport-events.js +2 -2
  225. package/dist/extensions/forgecli/viewport-events.js.map +1 -1
  226. package/dist/extensions/forgecli/wf-engine/engine.d.ts +1 -1
  227. package/dist/extensions/forgecli/wf-engine/engine.js +51 -31
  228. package/dist/extensions/forgecli/wf-engine/engine.js.map +1 -1
  229. package/dist/extensions/forgecli/wf-engine/event-parser.js.map +1 -1
  230. package/dist/extensions/forgecli/wf-engine/id-gen.js +4 -1
  231. package/dist/extensions/forgecli/wf-engine/id-gen.js.map +1 -1
  232. package/dist/extensions/forgecli/wf-engine/loader.js +7 -7
  233. package/dist/extensions/forgecli/wf-engine/loader.js.map +1 -1
  234. package/dist/extensions/forgecli/wf-engine/predicate.js +14 -7
  235. package/dist/extensions/forgecli/wf-engine/predicate.js.map +1 -1
  236. package/dist/extensions/forgecli/wf-engine/prompt-compiler.js.map +1 -1
  237. package/dist/extensions/forgecli/wf-engine/register.js +1 -1
  238. package/dist/extensions/forgecli/wf-engine/register.js.map +1 -1
  239. package/dist/extensions/forgecli/wf-engine/remit-check.js +3 -3
  240. package/dist/extensions/forgecli/wf-engine/remit-check.js.map +1 -1
  241. package/dist/extensions/forgecli/wf-engine/state-store.js +7 -3
  242. package/dist/extensions/forgecli/wf-engine/state-store.js.map +1 -1
  243. package/dist/extensions/forgecli/wf-engine/worker.js +3 -3
  244. package/dist/extensions/forgecli/wf-engine/worker.js.map +1 -1
  245. package/dist/extensions/forgecli/whats-new-widget.js +8 -6
  246. package/dist/extensions/forgecli/whats-new-widget.js.map +1 -1
  247. package/dist/extensions/forgecli/whats-new.js +1 -2
  248. package/dist/extensions/forgecli/whats-new.js.map +1 -1
  249. package/dist/forge-payload/commands/update.md +23 -1
  250. package/dist/forge-payload/schemas/_defs/phaseSummary.schema.json +18 -0
  251. package/dist/forge-payload/schemas/bug.schema.json +40 -0
  252. package/dist/forge-payload/schemas/collation-state.schema.json +16 -0
  253. package/dist/forge-payload/schemas/config.schema.json +215 -0
  254. package/dist/forge-payload/schemas/enum-catalog.json +71 -0
  255. package/dist/forge-payload/schemas/event-sidecar.schema.json +22 -0
  256. package/dist/forge-payload/schemas/event.schema.json +184 -0
  257. package/dist/forge-payload/schemas/feature.schema.json +22 -0
  258. package/dist/forge-payload/schemas/progress-entry.schema.json +16 -0
  259. package/dist/forge-payload/schemas/project-context.schema.json +167 -0
  260. package/dist/forge-payload/schemas/project-overlay.schema.json +25 -0
  261. package/dist/forge-payload/schemas/proposal.schema.json +40 -0
  262. package/dist/forge-payload/schemas/sprint.schema.json +27 -0
  263. package/dist/forge-payload/schemas/structure-versions.schema.json +57 -0
  264. package/dist/forge-payload/schemas/task.schema.json +43 -0
  265. package/dist/forge-payload/schemas/transitions/bug.json +31 -0
  266. package/dist/forge-payload/schemas/transitions/sprint.json +46 -0
  267. package/dist/forge-payload/schemas/transitions/task.json +109 -0
  268. package/dist/forge-payload/tools/manage-config.cjs +120 -2
  269. package/package.json +3 -3
@@ -8,6 +8,7 @@
8
8
  // manage-config pipeline add <name> --description <text> --phases <json>
9
9
  // manage-config pipeline get <name>
10
10
  // manage-config pipeline remove <name>
11
+ // manage-config backfill [--forge-root <path>] [--dry-run]
11
12
  // manage-config resolve-forge-root
12
13
  // manage-config set <key.path> <json-value>
13
14
 
@@ -106,8 +107,13 @@ function validatePhases(phases) {
106
107
  function parseArgs(argv) {
107
108
  const result = {};
108
109
  for (let i = 0; i < argv.length; i++) {
109
- if (argv[i].startsWith('--') && i + 1 < argv.length) {
110
- result[argv[i].slice(2)] = argv[++i];
110
+ if (argv[i].startsWith('--')) {
111
+ const key = argv[i].slice(2);
112
+ if (i + 1 < argv.length && !argv[i + 1].startsWith('--')) {
113
+ result[key] = argv[++i];
114
+ } else {
115
+ result[key] = 'true'; // boolean flag
116
+ }
111
117
  }
112
118
  }
113
119
  return result;
@@ -129,6 +135,7 @@ if (!subcmd) {
129
135
  ' pipeline get <name> Print a pipeline in full',
130
136
  ' pipeline remove <name>',
131
137
  ' pipeline backfill-models Backfill model fields from role defaults',
138
+ ' backfill [--forge-root <path>] [--dry-run] Backfill missing config fields from schema defaults',
132
139
  ' resolve-forge-root Resolve Forge plugin root path',
133
140
  ' set <key.path> <json-value> Set an arbitrary value',
134
141
  ].join('\n'));
@@ -279,6 +286,117 @@ if (subcmd === 'set') {
279
286
  // FR-010: resolve-forge-root — resolve the Forge plugin root path using
280
287
  // three-tier priority: (1) CLAUDE_PLUGIN_ROOT env var, (2) cache/marketplace
281
288
  // scan by forgeRef, (3) paths.forgeRoot fallback.
289
+ if (subcmd === 'backfill') {
290
+ // backfill-schema: write defaults for missing config fields per the config schema.
291
+ // Reads $FORGE_ROOT/schemas/config.schema.json (or .schemas/ fallback).
292
+ // Writes schema-defined defaults for any missing required or optional path fields.
293
+ // Also writes the top-level `version` field from the bundled plugin version.
294
+ // Usage: manage-config backfill [--forge-root <path>] [--dry-run]
295
+ const flags = parseArgs(args);
296
+ const forgeRoot = flags['forge-root'] || process.env.FORGE_ROOT || path.resolve(__dirname, '..');
297
+ const dryRun = !!flags['dry-run'];
298
+
299
+ // Locate config schema
300
+ let schemaPath = path.join(forgeRoot, 'schemas', 'config.schema.json');
301
+ if (!fs.existsSync(schemaPath)) {
302
+ schemaPath = path.join(forgeRoot, '.schemas', 'config.schema.json');
303
+ }
304
+ if (!fs.existsSync(schemaPath)) {
305
+ console.error('× config.schema.json not found in schemas/ or .schemas/ under forge-root:', forgeRoot);
306
+ process.exit(1);
307
+ }
308
+
309
+ let schema;
310
+ try { schema = JSON.parse(fs.readFileSync(schemaPath, 'utf8')); } catch (e) {
311
+ console.error(`× reading config schema: ${e.message}`); process.exit(1);
312
+ }
313
+
314
+ if (!fs.existsSync(CONFIG_PATH)) {
315
+ console.error('× .forge/config.json not found. Run /forge:init first.');
316
+ process.exit(1);
317
+ }
318
+ const { config, raw } = readConfig();
319
+
320
+ const backfilled = [];
321
+ const still = [];
322
+
323
+ // 1. Top-level `version` — write bundled plugin version if absent
324
+ if (!config.version) {
325
+ const pluginJsonPath = path.join(forgeRoot, '.claude-plugin', 'plugin.json');
326
+ if (fs.existsSync(pluginJsonPath)) {
327
+ try {
328
+ const plugin = JSON.parse(fs.readFileSync(pluginJsonPath, 'utf8'));
329
+ if (plugin.version) {
330
+ config.version = plugin.version;
331
+ backfilled.push('version = ' + plugin.version);
332
+ }
333
+ } catch { /* skip */ }
334
+ }
335
+ if (!config.version) {
336
+ still.push('version (no plugin.json found)');
337
+ }
338
+ }
339
+
340
+ // 2. Walk schema properties, apply defaults for any missing nested fields
341
+ // Covers: paths.*, commands.*
342
+ const walkDefaults = (obj, schemaProps, prefix) => {
343
+ if (!schemaProps || typeof schemaProps !== 'object') return;
344
+ for (const [key, spec] of Object.entries(schemaProps)) {
345
+ const dotPath = prefix ? prefix + '.' + key : key;
346
+ if (spec.type === 'object' && spec.properties) {
347
+ // Nested object — ensure container exists, then recurse
348
+ if (obj[key] == null || typeof obj[key] !== 'object') obj[key] = {};
349
+ walkDefaults(obj[key], spec.properties, dotPath);
350
+ } else if (obj[key] === undefined && spec.default !== undefined) {
351
+ obj[key] = spec.default;
352
+ backfilled.push(dotPath + ' = ' + JSON.stringify(spec.default));
353
+ } else if (obj[key] === undefined && spec.default === undefined) {
354
+ // Track that it's still missing (informational only)
355
+ const isRequired = Array.isArray(schema.required) && schema.required.includes(key);
356
+ if (isRequired || (prefix === 'paths' && spec.description)) {
357
+ still.push(dotPath + ' (no default in schema)');
358
+ }
359
+ }
360
+ }
361
+ };
362
+
363
+ // Walk top-level properties
364
+ for (const [key, spec] of Object.entries(schema.properties || {})) {
365
+ if (key === 'version') continue; // handled above
366
+ if (spec.type === 'object' && spec.properties) {
367
+ if (config[key] == null || typeof config[key] !== 'object') config[key] = {};
368
+ walkDefaults(config[key], spec.properties, key);
369
+ } else if (config[key] === undefined && spec.default !== undefined) {
370
+ config[key] = spec.default;
371
+ backfilled.push(key + ' = ' + JSON.stringify(spec.default));
372
+ } else if (config[key] === undefined && spec.default === undefined) {
373
+ if (Array.isArray(schema.required) && schema.required.includes(key)) {
374
+ still.push(key + ' (required, no default)');
375
+ }
376
+ }
377
+ }
378
+
379
+ if (backfilled.length > 0) {
380
+ if (dryRun) {
381
+ console.log('Would backfill:');
382
+ for (const b of backfilled) console.log(' + ' + b);
383
+ } else {
384
+ writeConfig(config, detectIndent(raw));
385
+ console.log('〇 Backfilled ' + backfilled.length + ' field(s):');
386
+ for (const b of backfilled) console.log(' + ' + b);
387
+ }
388
+ } else {
389
+ console.log('〇 No missing fields to backfill.');
390
+ }
391
+
392
+ if (still.length > 0) {
393
+ console.log('△ Still missing (no schema default):');
394
+ for (const s of still) console.log(' - ' + s);
395
+ }
396
+
397
+ process.exit(0);
398
+ }
399
+
282
400
  if (subcmd === 'resolve-forge-root') {
283
401
  // Priority 1: CLAUDE_PLUGIN_ROOT env var (if set and directory exists)
284
402
  const envRoot = process.env.CLAUDE_PLUGIN_ROOT;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@entelligentsia/forgecli",
3
- "version": "0.19.0",
4
- "description": "Forge SDLC ported onto @earendil-works/pi-coding-agent production launcher with three bin aliases (forge/forgecli/4ge). Bundles a curated fork of pi-coding-agent vendored under earendil-works names.",
3
+ "version": "0.20.3",
4
+ "description": "Forge SDLC ported onto @earendil-works/pi-coding-agent \u2014 production launcher with three bin aliases (forge/forgecli/4ge). Bundles a curated fork of pi-coding-agent vendored under earendil-works names.",
5
5
  "license": "MIT",
6
6
  "author": "Entelligentsia",
7
7
  "homepage": "https://github.com/Entelligentsia/forge-cli#readme",
@@ -105,4 +105,4 @@
105
105
  "@earendil-works/pi-tui",
106
106
  "js-yaml"
107
107
  ]
108
- }
108
+ }