@entelligentsia/forgecli 0.8.4 → 0.9.1

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 (170) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +165 -2
  3. package/dist/bin/argv.d.ts +2 -2
  4. package/dist/bin/argv.js +17 -0
  5. package/dist/bin/argv.js.map +1 -1
  6. package/dist/bin/config.d.ts +69 -0
  7. package/dist/bin/config.js +315 -0
  8. package/dist/bin/config.js.map +1 -0
  9. package/dist/bin/doctor.d.ts +1 -0
  10. package/dist/bin/doctor.js +12 -0
  11. package/dist/bin/doctor.js.map +1 -1
  12. package/dist/bin/forge.js +7 -0
  13. package/dist/bin/forge.js.map +1 -1
  14. package/dist/extensions/forgecli/config-command.d.ts +8 -0
  15. package/dist/extensions/forgecli/config-command.js +66 -0
  16. package/dist/extensions/forgecli/config-command.js.map +1 -0
  17. package/dist/extensions/forgecli/config-layer.d.ts +38 -0
  18. package/dist/extensions/forgecli/config-layer.js +68 -0
  19. package/dist/extensions/forgecli/config-layer.js.map +1 -0
  20. package/dist/extensions/forgecli/config-tui/component.d.ts +35 -0
  21. package/dist/extensions/forgecli/config-tui/component.js +236 -0
  22. package/dist/extensions/forgecli/config-tui/component.js.map +1 -0
  23. package/dist/extensions/forgecli/config-tui/handler.d.ts +40 -0
  24. package/dist/extensions/forgecli/config-tui/handler.js +240 -0
  25. package/dist/extensions/forgecli/config-tui/handler.js.map +1 -0
  26. package/dist/extensions/forgecli/config-tui/index.d.ts +5 -0
  27. package/dist/extensions/forgecli/config-tui/index.js +5 -0
  28. package/dist/extensions/forgecli/config-tui/index.js.map +1 -0
  29. package/dist/extensions/forgecli/config-tui/keys.d.ts +26 -0
  30. package/dist/extensions/forgecli/config-tui/keys.js +33 -0
  31. package/dist/extensions/forgecli/config-tui/keys.js.map +1 -0
  32. package/dist/extensions/forgecli/config-tui/plugin-config-reader.d.ts +23 -0
  33. package/dist/extensions/forgecli/config-tui/plugin-config-reader.js +58 -0
  34. package/dist/extensions/forgecli/config-tui/plugin-config-reader.js.map +1 -0
  35. package/dist/extensions/forgecli/config-tui/screens/advanced-menu.d.ts +7 -0
  36. package/dist/extensions/forgecli/config-tui/screens/advanced-menu.js +83 -0
  37. package/dist/extensions/forgecli/config-tui/screens/advanced-menu.js.map +1 -0
  38. package/dist/extensions/forgecli/config-tui/screens/confirm-quit.d.ts +11 -0
  39. package/dist/extensions/forgecli/config-tui/screens/confirm-quit.js +54 -0
  40. package/dist/extensions/forgecli/config-tui/screens/confirm-quit.js.map +1 -0
  41. package/dist/extensions/forgecli/config-tui/screens/override-editor.d.ts +11 -0
  42. package/dist/extensions/forgecli/config-tui/screens/override-editor.js +233 -0
  43. package/dist/extensions/forgecli/config-tui/screens/override-editor.js.map +1 -0
  44. package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.d.ts +7 -0
  45. package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.js +91 -0
  46. package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.js.map +1 -0
  47. package/dist/extensions/forgecli/config-tui/screens/overrides-list.d.ts +7 -0
  48. package/dist/extensions/forgecli/config-tui/screens/overrides-list.js +71 -0
  49. package/dist/extensions/forgecli/config-tui/screens/overrides-list.js.map +1 -0
  50. package/dist/extensions/forgecli/config-tui/screens/persona-editor.d.ts +10 -0
  51. package/dist/extensions/forgecli/config-tui/screens/persona-editor.js +182 -0
  52. package/dist/extensions/forgecli/config-tui/screens/persona-editor.js.map +1 -0
  53. package/dist/extensions/forgecli/config-tui/screens/persona-picker.d.ts +7 -0
  54. package/dist/extensions/forgecli/config-tui/screens/persona-picker.js +76 -0
  55. package/dist/extensions/forgecli/config-tui/screens/persona-picker.js.map +1 -0
  56. package/dist/extensions/forgecli/config-tui/screens/personas-list.d.ts +7 -0
  57. package/dist/extensions/forgecli/config-tui/screens/personas-list.js +98 -0
  58. package/dist/extensions/forgecli/config-tui/screens/personas-list.js.map +1 -0
  59. package/dist/extensions/forgecli/config-tui/screens/shared.d.ts +29 -0
  60. package/dist/extensions/forgecli/config-tui/screens/shared.js +100 -0
  61. package/dist/extensions/forgecli/config-tui/screens/shared.js.map +1 -0
  62. package/dist/extensions/forgecli/config-tui/screens/show-resolved.d.ts +23 -0
  63. package/dist/extensions/forgecli/config-tui/screens/show-resolved.js +128 -0
  64. package/dist/extensions/forgecli/config-tui/screens/show-resolved.js.map +1 -0
  65. package/dist/extensions/forgecli/config-tui/screens/tier-menu.d.ts +7 -0
  66. package/dist/extensions/forgecli/config-tui/screens/tier-menu.js +135 -0
  67. package/dist/extensions/forgecli/config-tui/screens/tier-menu.js.map +1 -0
  68. package/dist/extensions/forgecli/config-tui/screens/tier-picker.d.ts +9 -0
  69. package/dist/extensions/forgecli/config-tui/screens/tier-picker.js +122 -0
  70. package/dist/extensions/forgecli/config-tui/screens/tier-picker.js.map +1 -0
  71. package/dist/extensions/forgecli/config-tui/screens/types.d.ts +24 -0
  72. package/dist/extensions/forgecli/config-tui/screens/types.js +5 -0
  73. package/dist/extensions/forgecli/config-tui/screens/types.js.map +1 -0
  74. package/dist/extensions/forgecli/config-tui/screens.d.ts +24 -0
  75. package/dist/extensions/forgecli/config-tui/screens.js +78 -0
  76. package/dist/extensions/forgecli/config-tui/screens.js.map +1 -0
  77. package/dist/extensions/forgecli/config-tui/state/buffer.d.ts +11 -0
  78. package/dist/extensions/forgecli/config-tui/state/buffer.js +91 -0
  79. package/dist/extensions/forgecli/config-tui/state/buffer.js.map +1 -0
  80. package/dist/extensions/forgecli/config-tui/state/constants.d.ts +4 -0
  81. package/dist/extensions/forgecli/config-tui/state/constants.js +14 -0
  82. package/dist/extensions/forgecli/config-tui/state/constants.js.map +1 -0
  83. package/dist/extensions/forgecli/config-tui/state/index.d.ts +6 -0
  84. package/dist/extensions/forgecli/config-tui/state/index.js +9 -0
  85. package/dist/extensions/forgecli/config-tui/state/index.js.map +1 -0
  86. package/dist/extensions/forgecli/config-tui/state/init.d.ts +2 -0
  87. package/dist/extensions/forgecli/config-tui/state/init.js +30 -0
  88. package/dist/extensions/forgecli/config-tui/state/init.js.map +1 -0
  89. package/dist/extensions/forgecli/config-tui/state/model.d.ts +192 -0
  90. package/dist/extensions/forgecli/config-tui/state/model.js +4 -0
  91. package/dist/extensions/forgecli/config-tui/state/model.js.map +1 -0
  92. package/dist/extensions/forgecli/config-tui/state/reducer.d.ts +2 -0
  93. package/dist/extensions/forgecli/config-tui/state/reducer.js +212 -0
  94. package/dist/extensions/forgecli/config-tui/state/reducer.js.map +1 -0
  95. package/dist/extensions/forgecli/config-tui/state/selectors.d.ts +91 -0
  96. package/dist/extensions/forgecli/config-tui/state/selectors.js +231 -0
  97. package/dist/extensions/forgecli/config-tui/state/selectors.js.map +1 -0
  98. package/dist/extensions/forgecli/config-tui/state.d.ts +6 -0
  99. package/dist/extensions/forgecli/config-tui/state.js +11 -0
  100. package/dist/extensions/forgecli/config-tui/state.js.map +1 -0
  101. package/dist/extensions/forgecli/config-tui/theme.d.ts +37 -0
  102. package/dist/extensions/forgecli/config-tui/theme.js +88 -0
  103. package/dist/extensions/forgecli/config-tui/theme.js.map +1 -0
  104. package/dist/extensions/forgecli/config-tui/tier-meta.d.ts +28 -0
  105. package/dist/extensions/forgecli/config-tui/tier-meta.js +69 -0
  106. package/dist/extensions/forgecli/config-tui/tier-meta.js.map +1 -0
  107. package/dist/extensions/forgecli/config-writer.d.ts +16 -0
  108. package/dist/extensions/forgecli/config-writer.js +63 -0
  109. package/dist/extensions/forgecli/config-writer.js.map +1 -0
  110. package/dist/extensions/forgecli/fix-bug.js +85 -1
  111. package/dist/extensions/forgecli/fix-bug.js.map +1 -1
  112. package/dist/extensions/forgecli/forge-cli-schema.json +54 -0
  113. package/dist/extensions/forgecli/forge-commands.js +3 -8
  114. package/dist/extensions/forgecli/forge-commands.js.map +1 -1
  115. package/dist/extensions/forgecli/forge-subagent.d.ts +13 -0
  116. package/dist/extensions/forgecli/forge-subagent.js +19 -0
  117. package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
  118. package/dist/extensions/forgecli/index.js +16 -0
  119. package/dist/extensions/forgecli/index.js.map +1 -1
  120. package/dist/extensions/forgecli/input-router.d.ts +33 -0
  121. package/dist/extensions/forgecli/input-router.js +133 -0
  122. package/dist/extensions/forgecli/input-router.js.map +1 -0
  123. package/dist/extensions/forgecli/model-resolver.d.ts +32 -0
  124. package/dist/extensions/forgecli/model-resolver.js +65 -0
  125. package/dist/extensions/forgecli/model-resolver.js.map +1 -0
  126. package/dist/extensions/forgecli/model-validator.d.ts +29 -0
  127. package/dist/extensions/forgecli/model-validator.js +107 -0
  128. package/dist/extensions/forgecli/model-validator.js.map +1 -0
  129. package/dist/extensions/forgecli/run-sprint.js +59 -0
  130. package/dist/extensions/forgecli/run-sprint.js.map +1 -1
  131. package/dist/extensions/forgecli/run-task.js +93 -1
  132. package/dist/extensions/forgecli/run-task.js.map +1 -1
  133. package/dist/extensions/forgecli/thread-switcher.js +5 -2
  134. package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
  135. package/dist/extensions/forgecli/whats-new-widget.js +5 -2
  136. package/dist/extensions/forgecli/whats-new-widget.js.map +1 -1
  137. package/package.json +11 -3
  138. package/dist/extensions/forgecli/review-command.d.ts +0 -2
  139. package/dist/extensions/forgecli/review-command.js +0 -184
  140. package/dist/extensions/forgecli/review-command.js.map +0 -1
  141. package/dist/forge-payload/.tools/banners.cjs +0 -435
  142. package/dist/forge-payload/.tools/build-context-pack.cjs +0 -290
  143. package/dist/forge-payload/.tools/build-init-context.cjs +0 -322
  144. package/dist/forge-payload/.tools/build-overlay.cjs +0 -326
  145. package/dist/forge-payload/.tools/build-persona-pack.cjs +0 -226
  146. package/dist/forge-payload/.tools/collate.cjs +0 -1041
  147. package/dist/forge-payload/.tools/generation-manifest.cjs +0 -311
  148. package/dist/forge-payload/.tools/lib/forge-root.cjs +0 -59
  149. package/dist/forge-payload/.tools/lib/paths.cjs +0 -29
  150. package/dist/forge-payload/.tools/lib/pricing.cjs +0 -165
  151. package/dist/forge-payload/.tools/lib/project-root.cjs +0 -32
  152. package/dist/forge-payload/.tools/lib/result.js +0 -40
  153. package/dist/forge-payload/.tools/lib/store-facade.cjs +0 -162
  154. package/dist/forge-payload/.tools/lib/store-nlp.cjs +0 -250
  155. package/dist/forge-payload/.tools/lib/store-query-exec.cjs +0 -272
  156. package/dist/forge-payload/.tools/lib/validate.js +0 -141
  157. package/dist/forge-payload/.tools/manage-config.cjs +0 -340
  158. package/dist/forge-payload/.tools/manage-versions.cjs +0 -365
  159. package/dist/forge-payload/.tools/package.json +0 -3
  160. package/dist/forge-payload/.tools/parse-gates.cjs +0 -151
  161. package/dist/forge-payload/.tools/parse-verdict.cjs +0 -67
  162. package/dist/forge-payload/.tools/preflight-gate.cjs +0 -350
  163. package/dist/forge-payload/.tools/prompts/sprint-plan-prompt.md +0 -70
  164. package/dist/forge-payload/.tools/schemas/task-list.schema.json +0 -53
  165. package/dist/forge-payload/.tools/seed-store.cjs +0 -237
  166. package/dist/forge-payload/.tools/store-cli.cjs +0 -1226
  167. package/dist/forge-payload/.tools/store-query.cjs +0 -319
  168. package/dist/forge-payload/.tools/store.cjs +0 -315
  169. package/dist/forge-payload/.tools/substitute-placeholders.cjs +0 -625
  170. package/dist/forge-payload/.tools/validate-store.cjs +0 -593
package/CHANGELOG.md CHANGED
@@ -7,6 +7,67 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.9.1] — 2026-05-18
11
+
12
+ ### Changed
13
+ - **README: Model setup documentation** — new section walks users through
14
+ the three-knob tier setup (Heavy / Standard / Light) with screen-by-screen
15
+ examples, scope toggle, verification, advanced overrides, and
16
+ non-interactive CLI alternatives.
17
+
18
+ ## [0.9.0] — 2026-05-18
19
+
20
+ ### Added
21
+ - **Per-persona model routing** — Forge now routes each pipeline phase
22
+ (plan, review-plan, implement, review-code, validate, approve, writeback,
23
+ commit) to a specific AI model via persona-model assignments resolved
24
+ through a four-level cascade: per-step override → per-persona override →
25
+ tier baseline → pi current. The cascade is invisible to the user;
26
+ plain-English labels ("Heavy tier (global)", "Step override") replace
27
+ internal L1/L2/L3/L4 jargon everywhere it appears.
28
+ - **Tiered-baseline config TUI** — `/forge:config` (and `forge config`)
29
+ now opens a three-knob landing screen: pick **Heavy** (architect,
30
+ supervisor), **Standard** (engineer, bug-fixer, qa-engineer,
31
+ product-manager), or **Light** (collator, librarian, orchestrator) —
32
+ one model per tier and all nine personas are configured in under 30
33
+ seconds. Tier selections commit immediately (no separate save step).
34
+ Scope toggles between project and global per tier-pick.
35
+ - **`forge config show --resolved`** — prints a phase-by-phase table
36
+ showing which model runs each step, which persona handles it, and where
37
+ the assignment comes from (tier baseline, persona override, step
38
+ override, or pi-current fallback).
39
+ - **`forge config dispatch [--pipeline=<name>] [--json]`** — per-phase
40
+ dispatch trace without making an LLM call. Shows the resolved model
41
+ and source for every phase of the chosen pipeline.
42
+ - **`forge config show --strict-models`** — validates that every
43
+ resolved model exists in the authenticated provider catalog. Exits
44
+ non-zero if any persona or step resolves to an unavailable model.
45
+ - **Advanced menu** — per-persona and per-step overrides are reachable
46
+ from a dedicated "Advanced" screen, clearly separated from the
47
+ primary tier knobs. Explanation banners explain that most users
48
+ don't need these.
49
+ - **Observability** — each phase now logs `requested_model` and
50
+ `model_observed` so users can verify that the intended model ran.
51
+
52
+ ### Changed
53
+ - **Bug-fix pipeline uses same persona routing** — `runBugPipeline`
54
+ now dispatches via `resolveModelForPhase` for every phase, consistent
55
+ with the task pipeline.
56
+ - **Config TUI theming + width safety** — all screens use the pi TUI
57
+ theme (accent, muted, warning, border, etc.) and truncate to
58
+ terminal width via `safeLines`. Adaptive-width confirm-quit dialog.
59
+ - **Config TUI `top-menu` removed** — replaced entirely by the tier-menu
60
+ landing screen. The `isEmpty` state snapshot is now a selector
61
+ (`isConfigEmpty`) derived from the buffer.
62
+
63
+ ### Fixed
64
+ - **Forge-project detection** — `forge config` detects a Forge project
65
+ by the presence of `.forge/config.json` (not `.pi/`).
66
+ - **Dirty tracking + confirm-quit** — save clears dirty; quit while
67
+ dirty opens a themed modal instead of exiting immediately.
68
+ - **Scroll for long pickers** — provider and model pickers window
69
+ around the cursor when lists exceed the viewport.
70
+
10
71
  ## [0.8.4] — 2026-05-18
11
72
 
12
73
  ### Changed
package/README.md CHANGED
@@ -95,11 +95,172 @@ CHAIN /forge:plan plan
95
95
  ASK /forge:health KB freshness + store integrity
96
96
  /forge:status Sprint + task status
97
97
  /forge:ask <q> Ask the Tomoshibi concierge
98
- /forge:config Inspect or change project config
98
+ /forge:config Set up AI models for your workflow
99
99
  ```
100
100
 
101
101
  → [Full reference](docs/cli-reference.md) · [Non-interactive mode](docs/non-interactive.md) · [Hook safety net](docs/hook-safety-net.md) · [Custom tools](docs/custom-tools.md) · [Publishing](docs/publishing.md)
102
102
 
103
+ ## Model setup
104
+
105
+ Forge routes each step of your pipeline — plan, review, implement, validate, approve, writeback, commit — to a **specific AI model** via a persona. Out of the box, every step inherits whatever model pi is currently running. The `/forge:config` screen lets you assign models in about 30 seconds.
106
+
107
+ ### The three-knob setup
108
+
109
+ Forge groups its nine personas into three workload tiers:
110
+
111
+ | Tier | Personas | What this model does |
112
+ |------|----------|---------------------|
113
+ | **Heavy** | 🗻 architect · 🌿 supervisor | Review, sign-off, gates |
114
+ | **Standard** | 🌱 engineer · 🐛 bug-fixer · 🍵 qa-engineer · 📋 product-manager | Planning, implementation, validation |
115
+ | **Light** | 🍃 collator · 📚 librarian · 🌊 orchestrator | Writeback, indexing, task flow |
116
+
117
+ Pick one model per tier and you're done — all nine personas are configured.
118
+
119
+ ### Step by step
120
+
121
+ **1. Open the config screen**
122
+
123
+ ```
124
+ /forge:config
125
+ ```
126
+
127
+ You'll see three tier rows — Heavy, Standard, Light — each showing "not set":
128
+
129
+ ```
130
+ forge config
131
+ ────────────────────────────────────────────────────────────
132
+ Active right now
133
+ ────────────────
134
+ Heavy not set — falls back to pi current (ollama:qwen2.5:0.5b)
135
+ Standard not set — falls back to pi current (ollama:qwen2.5:0.5b)
136
+ Light not set — falls back to pi current (ollama:qwen2.5:0.5b)
137
+ Scope ▸ project ( ~/src/hello ) global
138
+
139
+ Choose models for your AI workflow
140
+ ──────────────────────────────────
141
+ ▸ Heavy (review, sign-off) not set
142
+ Standard (planning, implementation) not set
143
+ Light (writeback, indexing) not set
144
+
145
+ Show what runs at each step
146
+ Advanced — per-persona / per-step overrides
147
+
148
+ enter pick model tab toggle scope q quit
149
+ ```
150
+
151
+ **2. Pick a model for each tier**
152
+
153
+ Press `enter` on Heavy (or press `1`), pick a provider, then a model:
154
+
155
+ ```
156
+ forge config › Heavy › pick provider
157
+ ────────────────────────────────────
158
+ This will run for: 🗻 architect, 🌿 supervisor
159
+
160
+ ▸ anthropic ✓ authenticated 12 models
161
+ ollama ✓ authenticated 24 models
162
+ openai ✓ authenticated 18 models
163
+
164
+ ↑↓ select enter advance esc back
165
+ ```
166
+
167
+ ```
168
+ forge config › Heavy › pick model (provider: anthropic)
169
+ ──────────────────────────────────────────────────────────
170
+ This will run for: 🗻 architect, 🌿 supervisor
171
+
172
+ ▸ claude-opus-4-5-20250514
173
+ claude-sonnet-4-20250514
174
+ claude-haiku-4-20250514
175
+
176
+ ↑↓ select enter save esc back
177
+ ```
178
+
179
+ Pressing `enter` on a model commits it immediately — both personas in that tier are now configured. Repeat for Standard and Light.
180
+
181
+ **3. Done**
182
+
183
+ After all three tiers are set, the landing screen shows your assignments:
184
+
185
+ ```
186
+ Active right now
187
+ ────────────────
188
+ Heavy anthropic:claude-opus-4-5-20250514 (project)
189
+ Standard anthropic:claude-sonnet-4-20250514 (project)
190
+ Light ollama:qwen2.5:0.5b (project)
191
+ Scope project ▸ global
192
+
193
+ Choose models for your AI workflow
194
+ ──────────────────────────────────
195
+ ▸ Heavy (review, sign-off) anthropic:claude-opus-4-5-20250514
196
+ Standard (planning, implementation) anthropic:claude-sonnet-4-20250514
197
+ Light (writeback, indexing) ollama:qwen2.5:0.5b
198
+
199
+ Show what runs at each step
200
+ Advanced — per-persona / per-step overrides
201
+ ```
202
+
203
+ No separate save step — each tier pick writes through instantly.
204
+
205
+ ### Scope: project vs global
206
+
207
+ Press `tab` to toggle scope before picking a tier:
208
+
209
+ - **project** — writes to `.pi/forge-cli/config.json` in the current project. Different projects can use different models.
210
+ - **global** — writes to `~/.pi/agent/forge-cli/config.json`. Applies to every project that doesn't have a project-level override.
211
+
212
+ ### Verify your setup
213
+
214
+ Select **"Show what runs at each step"** (or press `s`) to see which model runs each pipeline step:
215
+
216
+ ```
217
+ forge config › current setup
218
+ ────────────────────────────
219
+ Step Persona Model Source
220
+ ───── ───────── ────── ──────
221
+ plan 🌱 engineer anthropic:claude-sonnet… Standard tier (project)
222
+ review-plan 🌿 supervisor anthropic:claude-opus-… Heavy tier (project)
223
+ implement 🌱 engineer anthropic:claude-sonnet… Standard tier (project)
224
+ review-code 🌿 supervisor anthropic:claude-opus-… Heavy tier (project)
225
+ validate 🍵 qa-engineer anthropic:claude-sonnet… Standard tier (project)
226
+ approve 🗻 architect anthropic:claude-opus-… Heavy tier (project)
227
+ writeback 🍃 collator ollama:qwen2.5:0.5b Light tier (project)
228
+ commit 🌱 engineer anthropic:claude-sonnet… Standard tier (project)
229
+
230
+ How models get picked
231
+ ─────────────────────
232
+ Each step's persona looks for an override at four levels (most specific wins):
233
+ 1. A model set just for this step (Step override)
234
+ 2. A model set just for this persona (Per-persona override)
235
+ 3. The tier baseline you set above (Heavy / Standard / Light)
236
+ 4. Whatever model pi is currently running on (falls back automatically)
237
+ ```
238
+
239
+ ### Advanced overrides
240
+
241
+ Select **"Advanced"** (or press `a`) for fine-grained control:
242
+
243
+ - **Override one persona's model** — change the model for a single persona without affecting the rest of its tier.
244
+ - **Override one step's model** — change the model for a single pipeline step (e.g. always use a specific model for the commit step).
245
+ - **Edit raw persona-models entries** — direct editor for the full persona list.
246
+
247
+ Most users never need these — the three tier knobs cover the 80% path.
248
+
249
+ ### Non-interactive model setup
250
+
251
+ Use the CLI directly (no TUI required):
252
+
253
+ ```sh
254
+ # Print the resolved routing table
255
+ forge config show --resolved
256
+
257
+ # Per-phase dispatch trace (no LLM call)
258
+ forge config dispatch
259
+
260
+ # Validate all resolved models are authenticated
261
+ forge config show --strict-models
262
+ ```
263
+
103
264
  ## Where to go next
104
265
 
105
266
  - **[docs/](docs/)** — CLI flags, non-interactive mode, hook dispatcher, custom tools, publishing
@@ -110,6 +271,7 @@ ASK /forge:health KB freshness + store integrity
110
271
 
111
272
  | Up next | Status |
112
273
  |----------------------------------------------------|---------------------|
274
+ | Per-persona model routing + tiered config TUI | Shipped (0.9.0) |
113
275
  | 4ge brand wordmark in CLI banner + 3 themes | Shipped (0.7.7) |
114
276
  | Slim README + docs/ split | Shipped (0.7.7) |
115
277
  | Subagent audience relaxed to advisory | Shipped (0.7.6) |
@@ -147,6 +309,7 @@ MIT © Entelligentsia
147
309
  Shipped: 0.2.0 · 0.2.1 · 0.3.0 · 0.4.0 ·
148
310
  0.5.0 · 0.5.1 · 0.5.2 · 0.5.3 · 0.5.4 · 0.5.5 · 0.5.6 · 0.5.7 ·
149
311
  0.6.1 · 0.6.2 · 0.6.3 · 0.6.4 · 0.6.5 · 0.6.6 ·
150
- 0.7.0 · 0.7.1 · 0.7.2 · 0.7.3 · 0.7.4 · 0.7.5 · 0.7.6 · 0.7.7
312
+ 0.7.0 · 0.7.1 · 0.7.2 · 0.7.3 · 0.7.4 · 0.7.5 · 0.7.6 · 0.7.7 ·
313
+ 0.8.0 · 0.8.1 · 0.8.2 · 0.8.3 · 0.8.4 · 0.9.0
151
314
  -->
152
315
 
@@ -1,5 +1,5 @@
1
- /** Parsed result when `--version`, `--help`, `doctor`, `update`, or a fast-path subcommand is requested. */
2
- export type ForgeAction = "version" | "help" | "doctor" | "update" | "subcommand" | null;
1
+ /** Parsed result when `--version`, `--help`, `doctor`, `update`, `config`, or a fast-path subcommand is requested. */
2
+ export type ForgeAction = "version" | "help" | "doctor" | "update" | "config" | "subcommand" | null;
3
3
  /**
4
4
  * Whitelist of bare subcommands that bypass pi and exec a bundled cjs tool
5
5
  * directly. Each entry maps the user-typed subcommand to the cjs filename
package/dist/bin/argv.js CHANGED
@@ -88,6 +88,11 @@ export function parseForgeArgv(argv) {
88
88
  i++;
89
89
  continue;
90
90
  }
91
+ if (token === "--strict-models") {
92
+ env.FORGE_STRICT_MODELS = "1";
93
+ i++;
94
+ continue;
95
+ }
91
96
  if (token === "--registry") {
92
97
  if (i + 1 >= argv.length) {
93
98
  return { error: "forge: --registry requires a path argument. Run `forge --help` for usage." };
@@ -136,6 +141,18 @@ export function parseForgeArgv(argv) {
136
141
  subcommandArgs: argv.slice(i + 1),
137
142
  };
138
143
  }
144
+ // ── `forge config` — routing config subcommand (Plan 16) ────────────
145
+ // Intercepts `config show [--resolved] [--json]`. Bare `config` with no
146
+ // args is also handled (prints usage). Anything else falls through to pi.
147
+ // Only matches the first bare token, no flags collected yet.
148
+ if (token === "config" && piArgv.length === 0) {
149
+ return {
150
+ forgeAction: "config",
151
+ piArgv: [],
152
+ env,
153
+ subcommandArgs: argv.slice(i + 1),
154
+ };
155
+ }
139
156
  // ── Fast-path subcommand (forge store, forge collate, etc.) ──────────
140
157
  // Only matches the FIRST bare token, and only when no flags have
141
158
  // been collected yet (so `forge --cwd /tmp store ...` still treats
@@ -1 +1 @@
1
- {"version":3,"file":"argv.js","sourceRoot":"","sources":["../../src/bin/argv.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,EAAE;AACF,0EAA0E;AAC1E,sEAAsE;AACtE,EAAE;AACF,8CAA8C;AAC9C,EAAE;AACF,qBAAqB;AACrB,yDAAyD;AACzD,sDAAsD;AACtD,iEAAiE;AACjE,mEAAmE;AACnE,EAAE;AACF,wCAAwC;AACxC,mEAAmE;AACnE,mEAAmE;AACnE,EAAE;AACF,6CAA6C;AAC7C,oEAAoE;AACpE,sEAAsE;AACtE,gDAAgD;AAKhD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAqC,MAAM,CAAC,MAAM,CAAC;IACpF,KAAK,EAAE,eAAe;IACtB,OAAO,EAAE,aAAa;IACtB,gBAAgB,EAAE,oBAAoB;IACtC,aAAa,EAAE,iBAAiB;CAChC,CAAC,CAAC;AAqBH,MAAM,UAAU,YAAY,CAAC,CAAqB;IACjD,OAAO,OAAO,IAAI,CAAC,CAAC;AACrB,CAAC;AAED,kFAAkF;AAClF,4DAA4D;AAC5D,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IACjC,YAAY;IACZ,QAAQ;IACR,cAAc;IACd,YAAY;IACZ,YAAY;IACZ,eAAe;CACf,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IACnC,OAAO;IACP,WAAW;IACX,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,SAAS;IACT,SAAS;IACT,wBAAwB;CACxB,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,IAAc;IAC5C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,IAAI,WAAW,GAAgB,IAAI,CAAC;IAEpC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEtB,wEAAwE;QACxE,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;YAC3B,WAAW,GAAG,SAAS,CAAC;YACxB,CAAC,EAAE,CAAC;YACJ,SAAS;QACV,CAAC;QAED,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC1C,WAAW,GAAG,MAAM,CAAC;YACrB,CAAC,EAAE,CAAC;YACJ,SAAS;QACV,CAAC;QAED,IAAI,KAAK,KAAK,mBAAmB,EAAE,CAAC;YACnC,GAAG,CAAC,qBAAqB,GAAG,GAAG,CAAC;YAChC,CAAC,EAAE,CAAC;YACJ,SAAS;QACV,CAAC;QAED,IAAI,KAAK,KAAK,mBAAmB,EAAE,CAAC;YACnC,GAAG,CAAC,qBAAqB,GAAG,GAAG,CAAC;YAChC,CAAC,EAAE,CAAC;YACJ,SAAS;QACV,CAAC;QAED,IAAI,KAAK,KAAK,YAAY,EAAE,CAAC;YAC5B,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC1B,OAAO,EAAE,KAAK,EAAE,2EAA2E,EAAE,CAAC;YAC/F,CAAC;YACD,GAAG,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACvC,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACV,CAAC;QAED,wEAAwE;QACxE,IAAI,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnB,CAAC,EAAE,CAAC;YACJ,SAAS;QACV,CAAC;QAED,wEAAwE;QACxE,IAAI,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACpC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1D,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBACzB,CAAC,IAAI,CAAC,CAAC;YACR,CAAC;iBAAM,CAAC;gBACP,sDAAsD;gBACtD,CAAC,EAAE,CAAC;YACL,CAAC;YACD,SAAS;QACV,CAAC;QAED,uEAAuE;QACvE,qEAAqE;QACrE,4CAA4C;QAC5C,IAAI,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/C,OAAO;gBACN,WAAW,EAAE,QAAQ;gBACrB,MAAM,EAAE,EAAE;gBACV,GAAG;gBACH,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;aACjC,CAAC;QACH,CAAC;QAED,uEAAuE;QACvE,6DAA6D;QAC7D,IAAI,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/C,OAAO;gBACN,WAAW,EAAE,QAAQ;gBACrB,MAAM,EAAE,EAAE;gBACV,GAAG;gBACH,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;aACjC,CAAC;QACH,CAAC;QAED,wEAAwE;QACxE,iEAAiE;QACjE,mEAAmE;QACnE,sEAAsE;QACtE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,qBAAqB,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClG,OAAO;gBACN,WAAW,EAAE,YAAY;gBACzB,MAAM,EAAE,EAAE;gBACV,GAAG;gBACH,cAAc,EAAE,qBAAqB,CAAC,KAAK,CAAC;gBAC5C,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;aACjC,CAAC;QACH,CAAC;QAED,wEAAwE;QACxE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnB,CAAC,EAAE,CAAC;YACJ,SAAS;QACV,CAAC;QAED,wEAAwE;QACxE,2BAA2B;QAC3B,OAAO;YACN,KAAK,EAAE,uBAAuB,KAAK,mCAAmC;SACtE,CAAC;IACH,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACrC,CAAC"}
1
+ {"version":3,"file":"argv.js","sourceRoot":"","sources":["../../src/bin/argv.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ export interface ConfigArgs {
2
+ subcommand: "show" | "dispatch" | "usage";
3
+ resolved: boolean;
4
+ json: boolean;
5
+ /** dispatch-only: pipeline name override (defaults to "default" for task, "fix-bug" for bug). */
6
+ pipeline?: string;
7
+ }
8
+ export interface ConfigArgsError {
9
+ error: string;
10
+ }
11
+ export type ParseConfigResult = ConfigArgs | ConfigArgsError;
12
+ export declare function parseConfigArgs(args: string[]): ParseConfigResult;
13
+ export interface PersonaModelEntry {
14
+ persona: string;
15
+ provider: string;
16
+ model: string;
17
+ available: boolean;
18
+ source: string;
19
+ }
20
+ export interface ConfigShowOutput {
21
+ personaModels: Record<string, PersonaModelEntry>;
22
+ pipelines: Record<string, PipelineShowOutput>;
23
+ }
24
+ export interface PipelineShowOutput {
25
+ personaModels: Record<string, PersonaModelEntry>;
26
+ phases: Array<{
27
+ role: string;
28
+ override: string | null;
29
+ available: boolean;
30
+ source: string;
31
+ }>;
32
+ }
33
+ type WriteFn = (line: string) => void;
34
+ export declare function runConfigShow(opts: ConfigArgs, cwd: string, write: WriteFn): Promise<number>;
35
+ export interface DispatchPhaseRow {
36
+ pipeline: "default" | "fix-bug";
37
+ phaseRole: string;
38
+ persona: string;
39
+ requested: {
40
+ provider: string;
41
+ model: string;
42
+ } | null;
43
+ source: string;
44
+ /** True if pi.modelRegistry.find(provider, model) returns a Model — i.e. setModel
45
+ * will actually take effect at dispatch time. False = will silently fall through
46
+ * to pi's current model.
47
+ */
48
+ registered: boolean | null;
49
+ /** When registered === true, the exact id the registry returned. May differ from
50
+ * `requested.model` if pi aliases (e.g. "claude-haiku-4-5" → "claude-haiku-4-5-20251001").
51
+ */
52
+ registryId: string | null;
53
+ }
54
+ export interface DispatchOutput {
55
+ cwd: string;
56
+ taskPipeline: string;
57
+ taskPhases: DispatchPhaseRow[];
58
+ bugPhases: DispatchPhaseRow[];
59
+ }
60
+ /**
61
+ * Walk run-task's PHASES and fix-bug's BUG_PHASES; for each, compute the requested
62
+ * model via the same resolveModelForPhase the orchestrator uses, and verify that
63
+ * pi's ModelRegistry can resolve the requested id. Prints a table or JSON.
64
+ *
65
+ * No LLM call. No pi session. Pure inspection.
66
+ */
67
+ export declare function runConfigDispatch(args: ConfigArgs, cwd: string, write: (line: string) => void): number;
68
+ export declare function runConfig(args: string[], cwd?: string): Promise<number>;
69
+ export {};