gsd-opencode 1.9.2 → 1.10.2

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 (59) hide show
  1. package/agents/gsd-debugger.md +5 -5
  2. package/agents/gsd-settings.md +476 -30
  3. package/bin/gsd-install.js +105 -0
  4. package/bin/gsd.js +352 -0
  5. package/{command → commands}/gsd/add-phase.md +1 -1
  6. package/{command → commands}/gsd/audit-milestone.md +1 -1
  7. package/{command → commands}/gsd/debug.md +3 -3
  8. package/{command → commands}/gsd/discuss-phase.md +1 -1
  9. package/{command → commands}/gsd/execute-phase.md +1 -1
  10. package/{command → commands}/gsd/list-phase-assumptions.md +1 -1
  11. package/{command → commands}/gsd/map-codebase.md +1 -1
  12. package/{command → commands}/gsd/new-milestone.md +1 -1
  13. package/{command → commands}/gsd/new-project.md +3 -3
  14. package/{command → commands}/gsd/plan-phase.md +2 -2
  15. package/{command → commands}/gsd/research-phase.md +1 -1
  16. package/{command → commands}/gsd/verify-work.md +1 -1
  17. package/get-shit-done/workflows/list-phase-assumptions.md +1 -1
  18. package/get-shit-done/workflows/verify-work.md +5 -5
  19. package/lib/constants.js +199 -0
  20. package/package.json +34 -20
  21. package/src/commands/check.js +329 -0
  22. package/src/commands/config.js +337 -0
  23. package/src/commands/install.js +608 -0
  24. package/src/commands/list.js +256 -0
  25. package/src/commands/repair.js +519 -0
  26. package/src/commands/uninstall.js +732 -0
  27. package/src/commands/update.js +444 -0
  28. package/src/services/backup-manager.js +585 -0
  29. package/src/services/config.js +262 -0
  30. package/src/services/file-ops.js +855 -0
  31. package/src/services/health-checker.js +475 -0
  32. package/src/services/manifest-manager.js +301 -0
  33. package/src/services/migration-service.js +831 -0
  34. package/src/services/repair-service.js +846 -0
  35. package/src/services/scope-manager.js +303 -0
  36. package/src/services/settings.js +553 -0
  37. package/src/services/structure-detector.js +240 -0
  38. package/src/services/update-service.js +863 -0
  39. package/src/utils/hash.js +71 -0
  40. package/src/utils/interactive.js +222 -0
  41. package/src/utils/logger.js +128 -0
  42. package/src/utils/npm-registry.js +255 -0
  43. package/src/utils/path-resolver.js +226 -0
  44. /package/{command → commands}/gsd/add-todo.md +0 -0
  45. /package/{command → commands}/gsd/check-todos.md +0 -0
  46. /package/{command → commands}/gsd/complete-milestone.md +0 -0
  47. /package/{command → commands}/gsd/help.md +0 -0
  48. /package/{command → commands}/gsd/insert-phase.md +0 -0
  49. /package/{command → commands}/gsd/pause-work.md +0 -0
  50. /package/{command → commands}/gsd/plan-milestone-gaps.md +0 -0
  51. /package/{command → commands}/gsd/progress.md +0 -0
  52. /package/{command → commands}/gsd/quick.md +0 -0
  53. /package/{command → commands}/gsd/remove-phase.md +0 -0
  54. /package/{command → commands}/gsd/resume-work.md +0 -0
  55. /package/{command → commands}/gsd/set-model.md +0 -0
  56. /package/{command → commands}/gsd/set-profile.md +0 -0
  57. /package/{command → commands}/gsd/settings.md +0 -0
  58. /package/{command → commands}/gsd/update.md +0 -0
  59. /package/{command → commands}/gsd/whats-new.md +0 -0
@@ -836,17 +836,17 @@ The file IS the debugging brain.
836
836
  ls .planning/debug/*.md 2>/dev/null | grep -v resolved
837
837
  ```
838
838
 
839
- **If active sessions exist AND no $ARGUMENTS:**
839
+ **If active sessions exist AND no `$ARGUMENTS`:**
840
840
  - Display sessions with status, hypothesis, next action
841
841
  - Wait for user to select (number) or describe new issue (text)
842
842
 
843
- **If active sessions exist AND $ARGUMENTS:**
843
+ **If active sessions exist AND `$ARGUMENTS`:**
844
844
  - Start new session (continue to create_debug_file)
845
845
 
846
- **If no active sessions AND no $ARGUMENTS:**
846
+ **If no active sessions AND no `$ARGUMENTS`:**
847
847
  - Prompt: "No active sessions. Describe the issue to start."
848
848
 
849
- **If no active sessions AND $ARGUMENTS:**
849
+ **If no active sessions AND `$ARGUMENTS`:**
850
850
  - Continue to create_debug_file
851
851
  </step>
852
852
 
@@ -857,7 +857,7 @@ ls .planning/debug/*.md 2>/dev/null | grep -v resolved
857
857
  2. `mkdir -p .planning/debug`
858
858
  3. Create file with initial state:
859
859
  - status: gathering
860
- - trigger: verbatim $ARGUMENTS
860
+ - trigger: verbatim `$ARGUMENTS`
861
861
  - Current Focus: next_action = "gather symptoms"
862
862
  - Symptoms: empty
863
863
  4. Proceed to symptom_gathering
@@ -27,6 +27,12 @@ Do NOT modify agent .md files.
27
27
  - **Verification:** gsd-verifier, gsd-integration-checker, gsd-set-profile, gsd-settings, gsd-set-model
28
28
 
29
29
  **Model discovery:** Presets are user-defined, not hardcoded. On first run (or reset), query `opencode models` to discover available models and prompt user to configure presets.
30
+
31
+ **Model ID structure:** Models use 2-level (provider/model) or 3-level (provider/subprovider/model) format:
32
+ - 2-level: `opencode/glm-4.7-free`, `xai/grok-3`
33
+ - 3-level: `openrouter/anthropic/claude-3.5-haiku`, `synthetic/hf:deepseek-ai/DeepSeek-R1`
34
+
35
+ **Provider hierarchy:** Some providers (openrouter, synthetic) have subproviders; others (opencode, xai) are flat. Always use hierarchical selection: provider → subprovider (if applicable) → model.
30
36
  </context>
31
37
 
32
38
  <rules>
@@ -42,10 +48,43 @@ Do NOT modify agent .md files.
42
48
  - Never overwrite existing presets — only create defaults for new/migrated projects
43
49
  - Keep `model_profile` in sync with `profiles.active_profile`
44
50
  - Merge into existing `opencode.json` (preserve non-agent keys)
45
- </rules>
51
+ </rules>
46
52
 
47
53
  <behavior>
48
54
 
55
+ ## Helper Discovery Functions
56
+
57
+ These bash commands use the cached MODELS_DATA for hierarchical model discovery:
58
+
59
+ ```bash
60
+ # Initialize cache at wizard start (run once)
61
+ MODELS_DATA=$(opencode models 2>/dev/null)
62
+
63
+ # Get all unique providers (from cache)
64
+ echo "$MODELS_DATA" | cut -d'/' -f1 | sort -u
65
+
66
+ # Get model count for a provider (from cache)
67
+ echo "$MODELS_DATA" | grep "^${provider}/" | wc -l
68
+
69
+ # Check if provider has subproviders (returns "true" or "false", from cache)
70
+ echo "$MODELS_DATA" | grep "^${provider}/" | awk -F'/' '{print NF}' | head -1 | grep -q '^3$' && echo "true" || echo "false"
71
+
72
+ # Get unique subproviders for a provider (from cache)
73
+ echo "$MODELS_DATA" | grep "^${provider}/" | cut -d'/' -f2 | sort -u
74
+
75
+ # Get model count for a subprovider (from cache)
76
+ echo "$MODELS_DATA" | grep "^${provider}/${subprovider}/" | wc -l
77
+
78
+ # Get models for provider/subprovider (3-level, from cache)
79
+ echo "$MODELS_DATA" | grep "^${provider}/${subprovider}/" | cut -d'/' -f3- | sort
80
+
81
+ # Get models for 2-level provider (from cache)
82
+ echo "$MODELS_DATA" | grep "^${provider}/" | cut -d'/' -f2- | sort
83
+
84
+ # Verify a model ID exists (from cache)
85
+ echo "$MODELS_DATA" | grep -q "^${model_id}$" && echo "valid" || echo "invalid"
86
+ ```
87
+
49
88
  ## Step 1: Load Config
50
89
 
51
90
  ```bash
@@ -68,29 +107,286 @@ Ensure `workflow` section exists (defaults: `research: true`, `plan_check: true`
68
107
 
69
108
  ### Preset Setup Wizard
70
109
 
71
- This wizard runs on first use or when "Reset presets" is selected. It queries available models and lets the user configure all three profiles.
110
+ This wizard runs on first use or when "Reset presets" is selected. It queries available models and lets the user configure all three profiles using hierarchical selection (provider → subprovider → model).
72
111
 
73
- **Step W1: Discover models**
112
+ **Step W1: Discover models and initialize cache**
74
113
 
75
114
  ```bash
76
- opencode models 2>/dev/null
115
+ MODELS_DATA=$(opencode models 2>/dev/null)
77
116
  ```
78
117
 
79
- Parse the output to extract model IDs. If command fails or returns no models, print `Error: Could not fetch available models. Check your OpenCode installation.` and stop.
118
+ Cache the models output in `MODELS_DATA` variable. All subsequent operations use this cache instead of calling `opencode models` repeatedly.
80
119
 
81
- **Step W2: Configure each profile**
120
+ If command fails or returns no models, print `Error: Could not fetch available models. Check your OpenCode installation.` and stop.
82
121
 
83
- For each profile (quality, balanced, budget), use a multi-question call:
122
+ **Cache Statistics (for internal use):**
123
+ ```bash
124
+ # Pre-compute provider counts for all menus
125
+ PROVIDER_COUNTS=$(echo "$MODELS_DATA" | awk -F'/' '{count[$1]++} END {for(p in count) print p ":" count[p]}')
126
+
127
+ # Pre-compute subprovider structure for 3-level providers
128
+ SUBPROVIDER_MAP=$(echo "$MODELS_DATA" | awk -F'/' 'NF==3 {print $1 "/" $2}' | sort -u)
129
+ ```
130
+
131
+ **Step W2: Configure Quality Profile**
132
+
133
+ Configure all 3 stages for the quality profile with full hierarchical selection.
134
+
135
+ **W2.1: Quality Profile - Planning Stage**
136
+
137
+ 1. **Build Provider Menu (using cached data)**
138
+
139
+ ```bash
140
+ # Get providers with counts from cache
141
+ echo "$PROVIDER_COUNTS" | while IFS=':' read -r provider count; do
142
+ echo "- label: \"$provider\""
143
+ echo " description: \"$count models\""
144
+ done
145
+ ```
146
+
147
+ Use Question tool:
148
+
149
+ ```
150
+ header: "Quality Profile - Planning"
151
+ question: "Which provider for planning agents (Quality profile)?"
152
+ options:
153
+ [providers from above with counts]
154
+ ```
155
+
156
+ Store selected provider as `quality_planning_provider`.
157
+
158
+ 2. **Check for Subproviders (using cache)**
159
+
160
+ ```bash
161
+ # Check if provider has subproviders using cached data
162
+ HAS_SUBPROVIDERS=$(echo "$MODELS_DATA" | grep "^${quality_planning_provider}/" | awk -F'/' '{print NF}' | head -1 | grep -q '^3$' && echo "true" || echo "false")
163
+ ```
164
+
165
+ If result is "true" (provider has subproviders):
166
+
167
+ **Build Subprovider Menu (lazy-load examples only when selected):**
168
+
169
+ ```bash
170
+ # Get subproviders with counts from cache
171
+ echo "$MODELS_DATA" | grep "^${quality_planning_provider}/" | awk -F'/' '{print $2}' | sort | uniq -c | while read count subprovider; do
172
+ echo "- label: \"$subprovider\""
173
+ echo " description: \"$count models\""
174
+ done
175
+ ```
176
+
177
+ Use Question tool:
178
+
179
+ ```
180
+ header: "Quality Profile - {quality_planning_provider} Subprovider (Planning Stage)"
181
+ question: "Which subprovider for planning agents?"
182
+ options:
183
+ - label: "{subprovider1}"
184
+ description: "{model_count} models (e.g., {model1}, {model2}, {model3}, ...)"
185
+ - label: "{subprovider2}"
186
+ description: "{model_count} models (e.g., {model1}, {model2}, {model3}, ...)"
187
+ [all unique subproviders for this provider with 3 example models each]
188
+ ```
189
+
190
+ Store selected subprovider as `quality_planning_subprovider`.
191
+
192
+ 3. **Choose Model (using cache)**
193
+
194
+ For 3-level structure (provider/subprovider/model):
195
+ ```bash
196
+ MODELS=$(echo "$MODELS_DATA" | grep "^${quality_planning_provider}/${quality_planning_subprovider}/" | cut -d'/' -f3- | sort)
197
+ ```
198
+
199
+ For 2-level structure (provider/model):
200
+ ```bash
201
+ MODELS=$(echo "$MODELS_DATA" | grep "^${quality_planning_provider}/" | cut -d'/' -f2- | sort)
202
+ ```
203
+
204
+ Use Question tool:
205
+
206
+ ```
207
+ header: "{quality_planning_provider} {quality_planning_subprovider} Models"
208
+ question: "Which model for planning?"
209
+ options:
210
+ [models from filtered list]
211
+ ```
212
+
213
+ Store full model ID as `quality_planning_model`.
214
+
215
+ **W2.2: Quality Profile - Execution Stage**
216
+
217
+ 1. **Choose Provider (using cached data)**
218
+
219
+ Use Question tool with smart proposal:
220
+
221
+ ```
222
+ header: "Quality Profile - Execution"
223
+ question: "Which provider for execution agents (Quality profile)?"
224
+ options:
225
+ - label: "Same as planning"
226
+ description: "Use {quality_planning_model}"
227
+ [providers from cache with counts]
228
+ ```
229
+
230
+ If "Same as planning" selected: Set `quality_execution_model = quality_planning_model`, skip to W2.3.
231
+
232
+ Otherwise: Repeat W2.1 steps 2-3 (subprovider → model) for execution, store as `quality_execution_model`.
233
+
234
+ **W2.3: Quality Profile - Verification Stage**
235
+
236
+ Use Question tool with smart proposals (using cached data):
237
+
238
+ ```
239
+ header: "Quality Profile - Verification"
240
+ question: "Which provider for verification agents (Quality profile)?"
241
+ options:
242
+ - label: "Same as planning"
243
+ description: "Use {quality_planning_model}"
244
+ - label: "Same as execution"
245
+ description: "Use {quality_execution_model}"
246
+ [providers from cache with counts]
247
+ ```
248
+
249
+ If "Same as planning" selected: Set `quality_verification_model = quality_planning_model`, skip to W2.4.
250
+
251
+ If "Same as execution" selected: Set `quality_verification_model = quality_execution_model`, skip to W2.4.
252
+
253
+ Otherwise: Repeat W2.1 steps 2-3 (subprovider → model) for verification, store as `quality_verification_model`.
254
+
255
+ **Step W3: Configure Balanced Profile**
256
+
257
+ Configure all 3 stages for balanced profile with smart proposals from quality profile.
258
+
259
+ **W3.1: Balanced Profile - Planning**
260
+
261
+ Use Question tool (using cached data):
262
+
263
+ ```
264
+ header: "Balanced Profile - Planning"
265
+ question: "Which provider for planning agents (Balanced profile)?"
266
+ options:
267
+ - label: "Same as quality profile"
268
+ description: "Use {quality_planning_model}"
269
+ [providers from cache with counts]
270
+ ```
271
+
272
+ If "Same as quality profile" selected: Set `balanced_planning_model = quality_planning_model`, skip to W3.2.
273
+
274
+ Otherwise: Repeat hierarchical selection (provider → subprovider → model), store as `balanced_planning_model`.
275
+
276
+ **W3.2: Balanced Profile - Execution**
277
+
278
+ Use Question tool (using cached data):
279
+
280
+ ```
281
+ header: "Balanced Profile - Execution"
282
+ question: "Which provider for execution agents (Balanced profile)?"
283
+ options:
284
+ - label: "Same as planning"
285
+ description: "Use {balanced_planning_model}"
286
+ - label: "Same as quality execution"
287
+ description: "Use {quality_execution_model}"
288
+ [providers from cache with counts]
289
+ ```
290
+
291
+ If "Same as planning" selected: Set `balanced_execution_model = balanced_planning_model`, skip to W3.3.
292
+
293
+ If "Same as quality execution" selected: Set `balanced_execution_model = quality_execution_model`, skip to W3.3.
294
+
295
+ Otherwise: Repeat hierarchical selection, store as `balanced_execution_model`.
296
+
297
+ **W3.3: Balanced Profile - Verification**
298
+
299
+ Use Question tool (using cached data):
84
300
 
85
- ```json
86
- [
87
- { "header": "{Profile} Profile - Planning", "question": "Which model for planning agents?", "options": ["{model1}", "{model2}", ...] },
88
- { "header": "{Profile} Profile - Execution", "question": "Which model for execution agents?", "options": ["{model1}", "{model2}", ...] },
89
- { "header": "{Profile} Profile - Verification", "question": "Which model for verification agents?", "options": ["{model1}", "{model2}", ...] }
90
- ]
91
301
  ```
302
+ header: "Balanced Profile - Verification"
303
+ question: "Which provider for verification agents (Balanced profile)?"
304
+ options:
305
+ - label: "Same as planning"
306
+ description: "Use {balanced_planning_model}"
307
+ - label: "Same as quality verification"
308
+ description: "Use {quality_verification_model}"
309
+ [providers from cache with counts]
310
+ ```
311
+
312
+ If "Same as planning" selected: Set `balanced_verification_model = balanced_planning_model`, skip to W4.
313
+
314
+ If "Same as quality verification" selected: Set `balanced_verification_model = quality_verification_model`, skip to W4.
315
+
316
+ Otherwise: Repeat hierarchical selection, store as `balanced_verification_model`.
317
+
318
+ **Step W4: Configure Budget Profile**
319
+
320
+ Configure all 3 stages for budget profile with smart proposals from balanced and quality profiles.
321
+
322
+ **W4.1: Budget Profile - Planning**
323
+
324
+ Use Question tool (using cached data):
92
325
 
93
- **Step W3: Save config**
326
+ ```
327
+ header: "Budget Profile - Planning"
328
+ question: "Which provider for planning agents (Budget profile)?"
329
+ options:
330
+ - label: "Same as balanced profile"
331
+ description: "Use {balanced_planning_model}"
332
+ - label: "Same as quality profile"
333
+ description: "Use {quality_planning_model}"
334
+ [providers from cache with counts]
335
+ ```
336
+
337
+ If "Same as balanced profile" selected: Set `budget_planning_model = balanced_planning_model`, skip to W4.2.
338
+
339
+ If "Same as quality profile" selected: Set `budget_planning_model = quality_planning_model`, skip to W4.2.
340
+
341
+ Otherwise: Repeat hierarchical selection, store as `budget_planning_model`.
342
+
343
+ **W4.2: Budget Profile - Execution**
344
+
345
+ Use Question tool (using cached data):
346
+
347
+ ```
348
+ header: "Budget Profile - Execution"
349
+ question: "Which provider for execution agents (Budget profile)?"
350
+ options:
351
+ - label: "Same as planning"
352
+ description: "Use {budget_planning_model}"
353
+ - label: "Same as balanced execution"
354
+ description: "Use {balanced_execution_model}"
355
+ - label: "Same as quality execution"
356
+ description: "Use {quality_execution_model}"
357
+ [providers from cache with counts]
358
+ ```
359
+
360
+ If "Same as planning" selected: Set `budget_execution_model = budget_planning_model`, skip to W4.3.
361
+
362
+ Otherwise if other "Same as" option selected: Set accordingly and skip to W4.3.
363
+
364
+ Otherwise: Repeat hierarchical selection, store as `budget_execution_model`.
365
+
366
+ **W4.3: Budget Profile - Verification**
367
+
368
+ Use Question tool (using cached data):
369
+
370
+ ```
371
+ header: "Budget Profile - Verification"
372
+ question: "Which provider for verification agents (Budget profile)?"
373
+ options:
374
+ - label: "Same as planning"
375
+ description: "Use {budget_planning_model}"
376
+ - label: "Same as balanced verification"
377
+ description: "Use {balanced_verification_model}"
378
+ - label: "Same as quality verification"
379
+ description: "Use {quality_verification_model}"
380
+ [providers from cache with counts]
381
+ ```
382
+
383
+ If "Same as planning" selected: Set `budget_verification_model = budget_planning_model`, skip to W5.
384
+
385
+ Otherwise if other "Same as" option selected: Set accordingly and skip to W5.
386
+
387
+ Otherwise: Repeat hierarchical selection, store as `budget_verification_model`.
388
+
389
+ **Step W5: Save config**
94
390
 
95
391
  Create config with user selections:
96
392
 
@@ -99,9 +395,21 @@ Create config with user selections:
99
395
  "profiles": {
100
396
  "active_profile": "balanced",
101
397
  "presets": {
102
- "quality": { "planning": "{user_selection}", "execution": "{user_selection}", "verification": "{user_selection}" },
103
- "balanced": { "planning": "{user_selection}", "execution": "{user_selection}", "verification": "{user_selection}" },
104
- "budget": { "planning": "{user_selection}", "execution": "{user_selection}", "verification": "{user_selection}" }
398
+ "quality": {
399
+ "planning": "{user_selection}",
400
+ "execution": "{user_selection}",
401
+ "verification": "{user_selection}"
402
+ },
403
+ "balanced": {
404
+ "planning": "{user_selection}",
405
+ "execution": "{user_selection}",
406
+ "verification": "{user_selection}"
407
+ },
408
+ "budget": {
409
+ "planning": "{user_selection}",
410
+ "execution": "{user_selection}",
411
+ "verification": "{user_selection}"
412
+ }
105
413
  },
106
414
  "custom_overrides": { "quality": {}, "balanced": {}, "budget": {} }
107
415
  },
@@ -116,7 +424,7 @@ Print:
116
424
  GSD ► PRESETS CONFIGURED
117
425
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
118
426
 
119
- Your model presets have been saved. Use "Reset presets"
427
+ Your model presets have been saved. Use "Reset presets"
120
428
  from the settings menu if available models change.
121
429
 
122
430
  Note: Quit and relaunch OpenCode to apply model changes.
@@ -187,10 +495,26 @@ Use multi-question call with pre-selected current values:
187
495
 
188
496
  ```json
189
497
  [
190
- { "header": "Model", "question": "Which model profile?", "options": ["Quality", "Balanced", "Budget"] },
191
- { "header": "Research", "question": "Spawn Plan Researcher?", "options": ["Yes", "No"] },
192
- { "header": "Plan Check", "question": "Spawn Plan Checker?", "options": ["Yes", "No"] },
193
- { "header": "Verifier", "question": "Spawn Execution Verifier?", "options": ["Yes", "No"] }
498
+ {
499
+ "header": "Model",
500
+ "question": "Which model profile?",
501
+ "options": ["Quality", "Balanced", "Budget"]
502
+ },
503
+ {
504
+ "header": "Research",
505
+ "question": "Spawn Plan Researcher?",
506
+ "options": ["Yes", "No"]
507
+ },
508
+ {
509
+ "header": "Plan Check",
510
+ "question": "Spawn Plan Checker?",
511
+ "options": ["Yes", "No"]
512
+ },
513
+ {
514
+ "header": "Verifier",
515
+ "question": "Spawn Execution Verifier?",
516
+ "options": ["Yes", "No"]
517
+ }
194
518
  ]
195
519
  ```
196
520
 
@@ -223,13 +547,128 @@ Quick commands:
223
547
 
224
548
  ### Set stage override
225
549
 
226
- 1. Pick stage: Planning / Execution / Verification / Cancel
227
- 2. If Cancel, return to menu
228
- 3. Fetch models via `opencode models` command
229
- 4. If command fails: print error and stop
230
- 5. Pick model from list (include Cancel option)
231
- 6. Set `custom_overrides[activeProfile][stage]` = model
232
- 7. Save, print "Saved", return to menu
550
+ 1. **Pick stage**
551
+
552
+ Use Question tool:
553
+
554
+ ```
555
+ header: "Select Stage"
556
+ question: "Which stage to override?"
557
+ options:
558
+ - label: "Planning"
559
+ description: "Override planning model"
560
+ - label: "Execution"
561
+ description: "Override execution model"
562
+ - label: "Verification"
563
+ description: "Override verification model"
564
+ - label: "Cancel"
565
+ description: "Return to menu"
566
+ ```
567
+
568
+ If Cancel selected, return to menu.
569
+
570
+ Store selected stage as `targetStage`.
571
+
572
+ 2. **Choose Provider (using cache)**
573
+
574
+ Initialize cache if not already available:
575
+ ```bash
576
+ [ -z "$MODELS_DATA" ] && MODELS_DATA=$(opencode models 2>/dev/null)
577
+ PROVIDER_COUNTS=$(echo "$MODELS_DATA" | awk -F'/' '{count[$1]++} END {for(p in count) print p ":" count[p]}')
578
+ ```
579
+
580
+ Build provider menu from cache:
581
+ ```bash
582
+ echo "$PROVIDER_COUNTS" | while IFS=':' read -r provider count; do
583
+ echo "- label: \"$provider\""
584
+ echo " description: \"$count models\""
585
+ done
586
+ ```
587
+
588
+ Use Question tool:
589
+
590
+ ```
591
+ header: "Choose LLM Provider ({activeProfile} profile)"
592
+ question: "Which provider for {targetStage} stage?"
593
+ options:
594
+ [providers from cache with counts]
595
+ - label: "Cancel"
596
+ description: "Return to menu"
597
+ ```
598
+
599
+ If Cancel selected, return to menu.
600
+
601
+ Store selected provider as `overrideProvider`.
602
+
603
+ 3. **Check for Subproviders (using cache)**
604
+
605
+ ```bash
606
+ HAS_SUBPROVIDERS=$(echo "$MODELS_DATA" | grep "^${overrideProvider}/" | awk -F'/' '{print NF}' | head -1 | grep -q '^3$' && echo "true" || echo "false")
607
+ ```
608
+
609
+ If result is "true" (provider has subproviders):
610
+
611
+ Build subprovider menu from cache:
612
+ ```bash
613
+ echo "$MODELS_DATA" | grep "^${overrideProvider}/" | awk -F'/' '{print $2}' | sort | uniq -c | while read count subprovider; do
614
+ echo "- label: \"$subprovider\""
615
+ echo " description: \"$count models\""
616
+ done
617
+ ```
618
+
619
+ Use Question tool:
620
+
621
+ ```
622
+ header: "{activeProfile} Profile - {overrideProvider} Subprovider ({targetStage} Stage)"
623
+ question: "Which subprovider for {targetStage}?"
624
+ options:
625
+ [subproviders from cache with counts]
626
+ - label: "Cancel"
627
+ description: "Back to provider selection"
628
+ ```
629
+
630
+ If Cancel selected, return to step 2.
631
+
632
+ Store selected subprovider as `overrideSubprovider`.
633
+
634
+ 4. **Choose Model**
635
+
636
+ For 3-level structure (provider/subprovider/model):
637
+ ```bash
638
+ MODELS=$(echo "$MODELS_DATA" | grep "^${overrideProvider}/${overrideSubprovider}/" | cut -d'/' -f3- | sort)
639
+ ```
640
+
641
+ For 2-level structure (provider/model):
642
+ ```bash
643
+ MODELS=$(echo "$MODELS_DATA" | grep "^${overrideProvider}/" | cut -d'/' -f2- | sort)
644
+ ```
645
+
646
+ Use Question tool:
647
+
648
+ ```
649
+ header: "{overrideProvider} {overrideSubprovider} Models"
650
+ question: "Which model for {targetStage} stage?"
651
+ options:
652
+ [models from cache]
653
+ - label: "Cancel"
654
+ description: "Back to provider selection"
655
+ ```
656
+
657
+ If Cancel selected, return to step 2.
658
+
659
+ Store selected model and construct full model ID:
660
+ - 3-level: `{overrideProvider}/{overrideSubprovider}/{model}`
661
+ - 2-level: `{overrideProvider}/{model}`
662
+
663
+ 5. **Save Override**
664
+
665
+ Set `config.profiles.custom_overrides[activeProfile][targetStage] = model_id`
666
+
667
+ 6. **Save and Return**
668
+
669
+ Save both files and print: `Saved {targetStage} override: {model_id}`
670
+
671
+ Return to main menu (Step 4).
233
672
 
234
673
  ### Clear stage override
235
674
 
@@ -253,7 +692,7 @@ Current overrides for {activeProfile} profile:
253
692
 
254
693
  ### Reset presets
255
694
 
256
- Run the **Preset Setup Wizard** (see Step 1). This re-queries available models and lets the user reconfigure all three profiles from scratch. Existing `custom_overrides` are cleared. After completion, return to menu.
695
+ Run the **Preset Setup Wizard** (see Step 1, W1-W5). This re-queries available models and lets the user reconfigure all three profiles from scratch using hierarchical selection. Existing `custom_overrides` are cleared. After completion, return to menu.
257
696
 
258
697
  ### Exit
259
698
 
@@ -299,5 +738,12 @@ Preserve existing non-agent keys in `opencode.json`.
299
738
  - Overrides are profile-scoped: `custom_overrides.{profile}.{stage}`
300
739
  - Source of truth: `config.json`; `opencode.json` is derived
301
740
  - OpenCode does not hot-reload model assignments; user must quit and relaunch to apply changes
741
+ - Model IDs support 2-level (provider/model) and 3-level (provider/subprovider/model) structures
742
+ - Hierarchical selection is used by default: provider → subprovider (if applicable) → model
743
+ - Providers with subproviders: openrouter (anthropic, meta-llama, google, etc.), synthetic (hf:deepseek-ai, hf:meta-llama, etc.)
744
+ - Providers without subproviders: opencode, xai, back, ollama, kimi-for-coding, zai-coding-plan
745
+ - Smart proposals allow reusing previous selections across profiles and stages to reduce user input
746
+ - All model selections are validated against `opencode models` output
747
+ - **Performance Optimization:** All model discovery uses a single cached `MODELS_DATA` variable instead of repeated `opencode models` calls. Provider counts are pre-computed with awk for O(n) efficiency. Lazy loading: model examples are not fetched until user selects a subprovider.
302
748
 
303
749
  </notes>