gsd-opencode 1.10.2 → 1.20.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 (164) hide show
  1. package/agents/gsd-codebase-mapper.md +29 -3
  2. package/agents/gsd-debugger.md +19 -21
  3. package/agents/gsd-executor.md +213 -528
  4. package/agents/gsd-integration-checker.md +20 -0
  5. package/agents/gsd-phase-researcher.md +189 -267
  6. package/agents/gsd-plan-checker.md +278 -279
  7. package/agents/gsd-planner.md +299 -490
  8. package/agents/gsd-project-researcher.md +103 -345
  9. package/agents/gsd-research-synthesizer.md +5 -22
  10. package/agents/gsd-roadmapper.md +43 -6
  11. package/agents/gsd-verifier.md +158 -377
  12. package/{lib → bin/dm/lib}/constants.js +10 -3
  13. package/{src → bin/dm/src}/commands/install.js +5 -4
  14. package/{src → bin/dm/src}/commands/uninstall.js +3 -1
  15. package/{src → bin/dm/src}/services/backup-manager.js +1 -1
  16. package/{src → bin/dm/src}/services/config.js +1 -1
  17. package/{src → bin/dm/src}/services/file-ops.js +20 -4
  18. package/{src → bin/dm/src}/services/health-checker.js +3 -1
  19. package/{src → bin/dm/src}/services/repair-service.js +3 -1
  20. package/{src → bin/dm/src}/services/settings.js +1 -1
  21. package/{src → bin/dm/src}/services/update-service.js +2 -2
  22. package/bin/gsd-install.js +0 -0
  23. package/bin/gsd.js +9 -9
  24. package/commands/gsd/gsd-add-phase.md +43 -0
  25. package/commands/gsd/gsd-add-todo.md +47 -0
  26. package/commands/gsd/gsd-audit-milestone.md +36 -0
  27. package/commands/gsd/gsd-check-todos.md +45 -0
  28. package/commands/gsd/gsd-cleanup.md +18 -0
  29. package/commands/gsd/{complete-milestone.md → gsd-complete-milestone.md} +1 -1
  30. package/commands/gsd/{debug.md → gsd-debug.md} +16 -21
  31. package/commands/gsd/{discuss-phase.md → gsd-discuss-phase.md} +6 -9
  32. package/commands/gsd/gsd-execute-phase.md +41 -0
  33. package/commands/gsd/gsd-health.md +22 -0
  34. package/commands/gsd/gsd-help.md +22 -0
  35. package/commands/gsd/gsd-insert-phase.md +32 -0
  36. package/commands/gsd/gsd-join-discord.md +18 -0
  37. package/commands/gsd/{list-phase-assumptions.md → gsd-list-phase-assumptions.md} +3 -7
  38. package/commands/gsd/{map-codebase.md → gsd-map-codebase.md} +3 -3
  39. package/commands/gsd/gsd-new-milestone.md +44 -0
  40. package/commands/gsd/gsd-new-project.md +42 -0
  41. package/commands/gsd/gsd-pause-work.md +38 -0
  42. package/commands/gsd/gsd-plan-milestone-gaps.md +34 -0
  43. package/commands/gsd/gsd-plan-phase.md +44 -0
  44. package/commands/gsd/gsd-progress.md +24 -0
  45. package/commands/gsd/gsd-quick.md +41 -0
  46. package/commands/gsd/gsd-reapply-patches.md +119 -0
  47. package/commands/gsd/gsd-remove-phase.md +31 -0
  48. package/commands/gsd/{research-phase.md → gsd-research-phase.md} +38 -49
  49. package/commands/gsd/{resume-work.md → gsd-resume-work.md} +2 -2
  50. package/commands/gsd/gsd-set-profile.md +34 -0
  51. package/commands/gsd/gsd-settings.md +36 -0
  52. package/commands/gsd/gsd-update.md +37 -0
  53. package/commands/gsd/gsd-verify-work.md +38 -0
  54. package/get-shit-done/bin/gsd-tools.cjs +553 -0
  55. package/get-shit-done/bin/gsd-tools.test.cjs +2346 -0
  56. package/get-shit-done/bin/lib/commands.cjs +556 -0
  57. package/get-shit-done/bin/lib/config.cjs +162 -0
  58. package/get-shit-done/bin/lib/core.cjs +377 -0
  59. package/get-shit-done/bin/lib/frontmatter.cjs +299 -0
  60. package/get-shit-done/bin/lib/init.cjs +694 -0
  61. package/get-shit-done/bin/lib/milestone.cjs +215 -0
  62. package/get-shit-done/bin/lib/phase.cjs +877 -0
  63. package/get-shit-done/bin/lib/roadmap.cjs +298 -0
  64. package/get-shit-done/bin/lib/state.cjs +490 -0
  65. package/get-shit-done/bin/lib/template.cjs +222 -0
  66. package/get-shit-done/bin/lib/verify.cjs +772 -0
  67. package/get-shit-done/references/checkpoints.md +62 -364
  68. package/get-shit-done/references/decimal-phase-calculation.md +65 -0
  69. package/get-shit-done/references/git-integration.md +10 -16
  70. package/get-shit-done/references/git-planning-commit.md +38 -0
  71. package/get-shit-done/references/model-profile-resolution.md +34 -0
  72. package/get-shit-done/references/model-profiles.md +54 -66
  73. package/get-shit-done/references/phase-argument-parsing.md +61 -0
  74. package/get-shit-done/references/planning-config.md +112 -10
  75. package/get-shit-done/references/questioning.md +4 -0
  76. package/get-shit-done/references/ui-brand.md +1 -1
  77. package/get-shit-done/templates/UAT.md +1 -1
  78. package/get-shit-done/templates/VALIDATION.md +104 -0
  79. package/get-shit-done/templates/codebase/structure.md +6 -6
  80. package/get-shit-done/templates/config.json +37 -0
  81. package/get-shit-done/templates/context.md +2 -10
  82. package/get-shit-done/templates/continue-here.md +6 -6
  83. package/get-shit-done/templates/debug-subagent-prompt.md +2 -2
  84. package/get-shit-done/templates/discovery.md +6 -6
  85. package/get-shit-done/templates/milestone-archive.md +3 -3
  86. package/get-shit-done/templates/phase-prompt.md +9 -7
  87. package/get-shit-done/templates/planner-subagent-prompt.md +6 -6
  88. package/get-shit-done/templates/research-project/ARCHITECTURE.md +1 -1
  89. package/get-shit-done/templates/research.md +29 -6
  90. package/get-shit-done/templates/roadmap.md +1 -1
  91. package/get-shit-done/templates/state.md +0 -30
  92. package/get-shit-done/templates/summary-complex.md +59 -0
  93. package/get-shit-done/templates/summary-minimal.md +41 -0
  94. package/get-shit-done/templates/summary-standard.md +48 -0
  95. package/get-shit-done/templates/summary.md +16 -37
  96. package/get-shit-done/templates/user-setup.md +1 -13
  97. package/get-shit-done/templates/verification-report.md +5 -5
  98. package/get-shit-done/workflows/add-phase.md +111 -0
  99. package/{commands/gsd → get-shit-done/workflows}/add-todo.md +24 -60
  100. package/{commands/gsd → get-shit-done/workflows}/audit-milestone.md +83 -63
  101. package/{commands/gsd → get-shit-done/workflows}/check-todos.md +21 -73
  102. package/get-shit-done/workflows/cleanup.md +152 -0
  103. package/get-shit-done/workflows/complete-milestone.md +251 -312
  104. package/get-shit-done/workflows/diagnose-issues.md +6 -31
  105. package/get-shit-done/workflows/discovery-phase.md +11 -11
  106. package/get-shit-done/workflows/discuss-phase.md +156 -49
  107. package/get-shit-done/workflows/execute-phase.md +238 -396
  108. package/get-shit-done/workflows/execute-plan.md +180 -1609
  109. package/get-shit-done/workflows/health.md +156 -0
  110. package/{commands/gsd → get-shit-done/workflows}/help.md +33 -35
  111. package/get-shit-done/workflows/insert-phase.md +129 -0
  112. package/get-shit-done/workflows/list-phase-assumptions.md +3 -3
  113. package/get-shit-done/workflows/map-codebase.md +73 -80
  114. package/get-shit-done/workflows/new-milestone.md +382 -0
  115. package/{commands/gsd → get-shit-done/workflows}/new-project.md +281 -234
  116. package/get-shit-done/workflows/oc-set-profile.md +320 -0
  117. package/{commands/gsd → get-shit-done/workflows}/pause-work.md +31 -43
  118. package/{commands/gsd → get-shit-done/workflows}/plan-milestone-gaps.md +29 -50
  119. package/get-shit-done/workflows/plan-phase.md +478 -0
  120. package/{commands/gsd → get-shit-done/workflows}/progress.md +64 -47
  121. package/get-shit-done/workflows/quick.md +453 -0
  122. package/get-shit-done/workflows/remove-phase.md +154 -0
  123. package/get-shit-done/workflows/research-phase.md +73 -0
  124. package/get-shit-done/workflows/resume-project.md +17 -26
  125. package/get-shit-done/workflows/set-profile.md +80 -0
  126. package/get-shit-done/workflows/settings.md +213 -0
  127. package/get-shit-done/workflows/transition.md +84 -104
  128. package/{commands/gsd → get-shit-done/workflows}/update.md +70 -28
  129. package/get-shit-done/workflows/verify-phase.md +106 -492
  130. package/get-shit-done/workflows/verify-work.md +26 -53
  131. package/package.json +7 -4
  132. package/rules/gsd-oc-work-hard.md +36 -0
  133. package/skills/gsd-oc-select-model/SKILL.md +348 -0
  134. package/skills/gsd-oc-select-model/scripts/select-models.cjs +268 -0
  135. package/agents/gsd-set-model.md +0 -287
  136. package/agents/gsd-set-profile.md +0 -239
  137. package/agents/gsd-settings.md +0 -749
  138. package/bin/install.js +0 -323
  139. package/commands/gsd/add-phase.md +0 -207
  140. package/commands/gsd/execute-phase.md +0 -339
  141. package/commands/gsd/insert-phase.md +0 -227
  142. package/commands/gsd/new-milestone.md +0 -721
  143. package/commands/gsd/plan-phase.md +0 -525
  144. package/commands/gsd/quick.md +0 -309
  145. package/commands/gsd/remove-phase.md +0 -349
  146. package/commands/gsd/set-model.md +0 -77
  147. package/commands/gsd/set-profile.md +0 -46
  148. package/commands/gsd/settings.md +0 -33
  149. package/commands/gsd/verify-work.md +0 -219
  150. package/commands/gsd/whats-new.md +0 -124
  151. /package/{src → bin/dm/src}/commands/check.js +0 -0
  152. /package/{src → bin/dm/src}/commands/config.js +0 -0
  153. /package/{src → bin/dm/src}/commands/list.js +0 -0
  154. /package/{src → bin/dm/src}/commands/repair.js +0 -0
  155. /package/{src → bin/dm/src}/commands/update.js +0 -0
  156. /package/{src → bin/dm/src}/services/manifest-manager.js +0 -0
  157. /package/{src → bin/dm/src}/services/migration-service.js +0 -0
  158. /package/{src → bin/dm/src}/services/scope-manager.js +0 -0
  159. /package/{src → bin/dm/src}/services/structure-detector.js +0 -0
  160. /package/{src → bin/dm/src}/utils/hash.js +0 -0
  161. /package/{src → bin/dm/src}/utils/interactive.js +0 -0
  162. /package/{src → bin/dm/src}/utils/logger.js +0 -0
  163. /package/{src → bin/dm/src}/utils/npm-registry.js +0 -0
  164. /package/{src → bin/dm/src}/utils/path-resolver.js +0 -0
@@ -0,0 +1,268 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { execSync } = require('child_process');
4
+
5
+ function checkOpenCodeAvailable() {
6
+ try {
7
+ execSync('which opencode', { stdio: 'pipe' });
8
+ return true;
9
+ } catch {
10
+ console.error('Error: opencode CLI not found.');
11
+ console.error('Please install opencode first.');
12
+ console.error('');
13
+ console.error('See: https://opencode.ai for installation instructions.');
14
+ process.exit(1);
15
+ }
16
+ }
17
+
18
+ function getModels(provider = null) {
19
+ const cmd = provider
20
+ ? `opencode models "${provider}"`
21
+ : `opencode models`;
22
+
23
+ try {
24
+ const output = execSync(cmd, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
25
+ return output.trim().split('\n').filter(Boolean);
26
+ } catch (error) {
27
+ const stderr = error.stderr ? error.stderr.toString().trim() : '';
28
+ console.error(`Error: Failed to run opencode models: ${stderr || error.message}`);
29
+ process.exit(1);
30
+ }
31
+ }
32
+
33
+ function groupByProviders(models) {
34
+ const providers = {};
35
+ for (const model of models) {
36
+ const slashIndex = model.indexOf('/');
37
+ if (slashIndex === -1) continue;
38
+ const provider = model.substring(0, slashIndex);
39
+ const rest = model.substring(slashIndex + 1);
40
+ if (!providers[provider]) {
41
+ providers[provider] = [];
42
+ }
43
+ providers[provider].push(rest);
44
+ }
45
+ return providers;
46
+ }
47
+
48
+ function hasSubProviders(modelNames) {
49
+ // Check if any model name contains a slash (indicating sub-provider structure)
50
+ return modelNames.some(name => name.includes('/'));
51
+ }
52
+
53
+ function groupBySubProviders(modelNames) {
54
+ const subProviders = {};
55
+ const directModels = [];
56
+
57
+ for (const name of modelNames) {
58
+ const slashIndex = name.indexOf('/');
59
+ if (slashIndex === -1) {
60
+ // Direct model (no sub-provider)
61
+ directModels.push(name);
62
+ } else {
63
+ // Has sub-provider
64
+ const subProvider = name.substring(0, slashIndex);
65
+ const modelName = name.substring(slashIndex + 1);
66
+ if (!subProviders[subProvider]) {
67
+ subProviders[subProvider] = [];
68
+ }
69
+ subProviders[subProvider].push(modelName);
70
+ }
71
+ }
72
+
73
+ return { subProviders, directModels };
74
+ }
75
+
76
+ function truncateSample(models, maxLen = 30) {
77
+ const samples = models.slice(0, 3);
78
+ let result = samples.map(m => {
79
+ if (m.length <= maxLen) return m;
80
+ return m.substring(0, maxLen - 3) + '...';
81
+ }).join(', ');
82
+
83
+ if (result.length > maxLen) {
84
+ result = result.substring(0, maxLen - 3) + '...';
85
+ }
86
+ return result;
87
+ }
88
+
89
+ function outputProviders() {
90
+ const models = getModels();
91
+ const providers = groupByProviders(models);
92
+
93
+ const providerList = Object.entries(providers)
94
+ .sort(([a], [b]) => a.localeCompare(b))
95
+ .map(([name, modelList]) => {
96
+ const subProviderInfo = groupBySubProviders(modelList);
97
+ const hasSubProvidersFlag = Object.keys(subProviderInfo.subProviders).length > 0;
98
+ const subProviderCount = Object.keys(subProviderInfo.subProviders).length;
99
+
100
+ // For sample_models, show both direct models and sub-provider examples
101
+ let sampleModels;
102
+ if (hasSubProvidersFlag) {
103
+ const subNames = Object.keys(subProviderInfo.subProviders).slice(0, 2);
104
+ sampleModels = subNames.map(s => `${s}/...`).join(', ');
105
+ } else {
106
+ sampleModels = truncateSample(modelList);
107
+ }
108
+
109
+ return {
110
+ name,
111
+ model_count: modelList.length,
112
+ sample_models: sampleModels,
113
+ has_sub_providers: hasSubProvidersFlag,
114
+ sub_provider_count: subProviderCount
115
+ };
116
+ });
117
+
118
+ const output = {
119
+ provider_count: providerList.length,
120
+ providers: providerList
121
+ };
122
+
123
+ console.log(JSON.stringify(output, null, 2));
124
+ }
125
+
126
+ function outputProviderModels(provider) {
127
+ const models = getModels(provider);
128
+ const filtered = models.filter(m => m.startsWith(provider + '/'));
129
+
130
+ if (filtered.length === 0) {
131
+ console.error(`Error: No models found for provider "${provider}".`);
132
+ console.error('Run with --providers-only to see available providers.');
133
+ process.exit(1);
134
+ }
135
+
136
+ // Extract model names after provider prefix
137
+ const modelNames = filtered.map(m => m.substring(provider.length + 1));
138
+
139
+ // Check if this provider has sub-providers
140
+ const subProviderInfo = groupBySubProviders(modelNames);
141
+ const hasSubProvidersFlag = Object.keys(subProviderInfo.subProviders).length > 0;
142
+
143
+ if (hasSubProvidersFlag) {
144
+ // Build sub-providers list
145
+ const subProvidersList = Object.entries(subProviderInfo.subProviders)
146
+ .sort(([a], [b]) => a.localeCompare(b))
147
+ .map(([subName, subModels]) => ({
148
+ name: subName,
149
+ model_count: subModels.length,
150
+ sample_models: truncateSample(subModels)
151
+ }));
152
+
153
+ const output = {
154
+ provider,
155
+ has_sub_providers: true,
156
+ sub_provider_count: subProvidersList.length,
157
+ sub_providers: subProvidersList
158
+ };
159
+
160
+ // Include direct models if any
161
+ if (subProviderInfo.directModels.length > 0) {
162
+ output.direct_models = subProviderInfo.directModels.sort();
163
+ output.direct_model_count = subProviderInfo.directModels.length;
164
+ }
165
+
166
+ console.log(JSON.stringify(output, null, 2));
167
+ } else {
168
+ // Flat structure
169
+ const output = {
170
+ provider,
171
+ has_sub_providers: false,
172
+ model_count: modelNames.length,
173
+ models: modelNames.sort()
174
+ };
175
+
176
+ console.log(JSON.stringify(output, null, 2));
177
+ }
178
+ }
179
+
180
+ function outputSubProviderModels(provider, subProvider) {
181
+ const models = getModels(provider);
182
+ const prefix = `${provider}/${subProvider}/`;
183
+ const filtered = models.filter(m => m.startsWith(prefix));
184
+
185
+ if (filtered.length === 0) {
186
+ console.error(`Error: No models found for sub-provider "${subProvider}" in provider "${provider}".`);
187
+ console.error(`Run with --provider "${provider}" to see available sub-providers.`);
188
+ process.exit(1);
189
+ }
190
+
191
+ // Extract model names after provider/sub-provider prefix
192
+ const modelNames = filtered.map(m => m.substring(prefix.length));
193
+
194
+ const output = {
195
+ provider,
196
+ sub_provider: subProvider,
197
+ model_count: modelNames.length,
198
+ models: modelNames.sort()
199
+ };
200
+
201
+ console.log(JSON.stringify(output, null, 2));
202
+ }
203
+
204
+ function printHelp() {
205
+ console.log(`
206
+ Usage: select-models [options]
207
+
208
+ Options:
209
+ --providers-only List providers with sample models
210
+ --provider <name> List all models/sub-providers for a provider
211
+ --provider <name> --sub-provider * List models for a specific sub-provider
212
+ -h, --help Show this help message
213
+
214
+ Examples:
215
+ select-models --providers-only
216
+ select-models --provider nvidia
217
+ select-models --provider nvidia --sub-provider deepseek-ai
218
+ `);
219
+ }
220
+
221
+ const args = process.argv.slice(2);
222
+
223
+ if (args.includes('-h') || args.includes('--help')) {
224
+ printHelp();
225
+ process.exit(0);
226
+ }
227
+
228
+ checkOpenCodeAvailable();
229
+
230
+ const providersOnlyIndex = args.indexOf('--providers-only');
231
+ const providerIndex = args.indexOf('--provider');
232
+ const subProviderIndex = args.indexOf('--sub-provider');
233
+
234
+ // Validate argument combinations
235
+ if (providersOnlyIndex !== -1 && providerIndex !== -1) {
236
+ console.error('Error: --providers-only and --provider cannot be used together.');
237
+ console.error('Use --providers-only to discover providers, then --provider "name" to see models.');
238
+ process.exit(1);
239
+ }
240
+
241
+ if (subProviderIndex !== -1 && providerIndex === -1) {
242
+ console.error('Error: --sub-provider requires --provider to be specified.');
243
+ process.exit(1);
244
+ }
245
+
246
+ if (providersOnlyIndex !== -1) {
247
+ outputProviders();
248
+ } else if (providerIndex !== -1) {
249
+ const providerName = args[providerIndex + 1];
250
+ if (!providerName) {
251
+ console.error('Error: --provider requires a provider name.');
252
+ process.exit(1);
253
+ }
254
+
255
+ if (subProviderIndex !== -1) {
256
+ const subProviderName = args[subProviderIndex + 1];
257
+ if (!subProviderName) {
258
+ console.error('Error: --sub-provider requires a sub-provider name.');
259
+ process.exit(1);
260
+ }
261
+ outputSubProviderModels(providerName, subProviderName);
262
+ } else {
263
+ outputProviderModels(providerName);
264
+ }
265
+ } else {
266
+ printHelp();
267
+ process.exit(1);
268
+ }
@@ -1,287 +0,0 @@
1
- ---
2
- name: gsd-set-model
3
- description: Configure models for a specific profile's stages
4
- tools:
5
- read: true
6
- write: true
7
- bash: true
8
- question: true
9
- ---
10
-
11
- <role>
12
- You are executing the `/gsd-set-model` command. Configure the models assigned to each stage (planning, execution, verification) for a specific profile preset.
13
-
14
- This command reads/writes two files:
15
- - `.planning/config.json` — profile state (active_profile, presets, custom_overrides)
16
- - `opencode.json` — agent model assignments (OpenCode's native config)
17
-
18
- Do NOT modify agent .md files. This command updates profile presets, not overrides.
19
- </role>
20
-
21
- <context>
22
- **Invocation styles:**
23
-
24
- 1. No args (interactive): `/gsd-set-model`
25
- 2. Positional: `/gsd-set-model quality` or `balanced` or `budget`
26
-
27
- **Stage-to-agent mapping (11 agents):**
28
-
29
- | Stage | Agents |
30
- |--------------|--------|
31
- | Planning | gsd-planner, gsd-plan-checker, gsd-phase-researcher, gsd-roadmapper, gsd-project-researcher, gsd-research-synthesizer, gsd-codebase-mapper |
32
- | Execution | gsd-executor, gsd-debugger |
33
- | Verification | gsd-verifier, gsd-integration-checker, gsd-set-profile, gsd-settings, gsd-set-model |
34
-
35
- **Profile presets:** Stored in `.planning/config.json` under `profiles.presets.{profile}`. Each profile has three keys: `planning`, `execution`, `verification`.
36
- </context>
37
-
38
- <behavior>
39
-
40
- ## Step 1: Read config file
41
-
42
- Read `.planning/config.json`. Handle these cases:
43
-
44
- **Case A: File missing or no `.planning/` directory**
45
- - Print: `Error: No GSD project found. Run /gsd-new-project first.`
46
- - Stop.
47
-
48
- **Case B: File exists but no `profiles.presets` key**
49
- - Print: `Error: No model presets configured. Run /gsd-settings first to initialize your profiles.`
50
- - Stop.
51
-
52
- **Case C: File exists with `profiles.presets` key**
53
- - Use as-is
54
-
55
- ## Step 2: Determine target profile
56
-
57
- **A) Check for positional argument:**
58
- - If user typed `/gsd-set-model quality` (or balanced/budget), use that as `targetProfile`
59
-
60
- **B) Interactive picker (no args):**
61
-
62
- Use Question tool:
63
-
64
- ```
65
- header: "Configure Profile"
66
- question: "Which profile do you want to configure?"
67
- options:
68
- - label: "Quality"
69
- description: "Configure models for the quality profile"
70
- - label: "Balanced"
71
- description: "Configure models for the balanced profile"
72
- - label: "Budget"
73
- description: "Configure models for the budget profile"
74
- - label: "Cancel"
75
- description: "Exit without changes"
76
- ```
77
-
78
- Input rules:
79
- - For this command, custom/freeform answers are NOT allowed.
80
- - If the user's selection is not exactly one of the option labels, print an error and re-run the same Question prompt.
81
-
82
- If user selects Cancel:
83
- ```
84
- Configuration cancelled.
85
- ```
86
- Stop.
87
-
88
- **C) Invalid profile handling:**
89
-
90
- If an invalid profile name is provided:
91
- - Print: `Unknown profile '{name}'. Valid options: quality, balanced, budget`
92
- - Fall back to interactive picker
93
-
94
- ## Step 3: Display information BEFORE prompting
95
-
96
- **IMPORTANT: Complete ALL display output in this step before asking any questions.**
97
-
98
- ### 3a. Show current configuration
99
-
100
- Get current preset from `config.profiles.presets[targetProfile]` and print:
101
-
102
- ```text
103
- Configuring models for: {targetProfile}
104
-
105
- Current configuration:
106
- | Stage | Model |
107
- |-------|-------|
108
- | planning | {preset.planning} |
109
- | execution | {preset.execution} |
110
- | verification | {preset.verification} |
111
- ```
112
-
113
- ### 3b. Discover and display available models
114
-
115
- Run:
116
-
117
- ```bash
118
- opencode models 2>/dev/null
119
- ```
120
-
121
- Parse the output to extract model IDs in `provider/model` format. Store these in a list for validation.
122
-
123
- If command fails or returns no models:
124
- ```text
125
- Error: Could not fetch available models. Check your OpenCode installation.
126
- ```
127
- Stop.
128
-
129
- **Print** the tip below after running opencode models:
130
-
131
- ```text
132
- Tip: Models prefixed with "opencode/" require an OpenCode Zen subscription.
133
- To see only one provider's models: opencode models <provider>
134
- ```
135
-
136
- ### 3c. Print input instructions
137
-
138
- ```text
139
- Enter model selection for each stage (you may press Enter to keep the current value).
140
- ```
141
-
142
- **Do NOT proceed to Step 4 until all of the above is printed.**
143
-
144
- ## Step 4: Prompt for model selection
145
-
146
- Now prompt the user for each stage. Ask one question at a time.
147
-
148
- ### Planning Stage
149
-
150
- Use Question tool with free-form input allowed:
151
-
152
- ```
153
- header: "{targetProfile} Profile - Planning"
154
- question: "Enter model ID for planning agents (or press Enter to keep current)"
155
- placeholder: "{preset.planning}"
156
- allowFreeform: true
157
- options:
158
- - label: "Keep current"
159
- description: "{preset.planning}"
160
- ```
161
-
162
- ### Execution Stage
163
-
164
- ```
165
- header: "{targetProfile} Profile - Execution"
166
- question: "Enter model ID for execution agents (or press Enter to keep current)"
167
- placeholder: "{preset.execution}"
168
- allowFreeform: true
169
- options:
170
- - label: "Keep current"
171
- description: "{preset.execution}"
172
- ```
173
-
174
- ### Verification Stage
175
-
176
- ```
177
- header: "{targetProfile} Profile - Verification"
178
- question: "Enter model ID for verification agents (or press Enter to keep current)"
179
- placeholder: "{preset.verification}"
180
- allowFreeform: true
181
- options:
182
- - label: "Keep current"
183
- description: "{preset.verification}"
184
- ```
185
-
186
- **Input handling for each stage:**
187
-
188
- 1. If user selects "Keep current" or enters empty/blank input, retain the existing value
189
- 2. If user enters a model ID:
190
- - Validate it exists in the available models list
191
- - If invalid, print error and re-prompt:
192
- ```
193
- Invalid model ID: '{input}'. Please enter a valid model from the list above.
194
- ```
195
- - If valid, use the entered model ID
196
-
197
- ## Step 5: Check for changes
198
-
199
- If no changes were made (all stages selected "Keep current"):
200
- ```
201
- No changes made to {targetProfile} profile.
202
- ```
203
- Stop.
204
-
205
- ## Step 6: Save changes
206
-
207
- Use the **write tool directly** to update files. Do NOT use bash, python, or other scripts—use native file writing.
208
-
209
- 1. **Update .planning/config.json:**
210
-
211
- - Set `config.profiles.presets[targetProfile].planning` to selected value
212
- - Set `config.profiles.presets[targetProfile].execution` to selected value
213
- - Set `config.profiles.presets[targetProfile].verification` to selected value
214
- - Write the config file (preserve all other keys)
215
-
216
- 2. **Update opencode.json (only if targetProfile is active):**
217
-
218
- Check if `config.profiles.active_profile === targetProfile`. If so, regenerate `opencode.json` with the new effective models.
219
-
220
- Compute effective models (preset + overrides):
221
- ```
222
- overrides = config.profiles.custom_overrides[targetProfile] || {}
223
- effective.planning = overrides.planning || newPreset.planning
224
- effective.execution = overrides.execution || newPreset.execution
225
- effective.verification = overrides.verification || newPreset.verification
226
- ```
227
-
228
- Build agent config:
229
-
230
- ```json
231
- {
232
- "$schema": "https://opencode.ai/config.json",
233
- "agent": {
234
- "gsd-planner": { "model": "{effective.planning}" },
235
- "gsd-plan-checker": { "model": "{effective.planning}" },
236
- "gsd-phase-researcher": { "model": "{effective.planning}" },
237
- "gsd-roadmapper": { "model": "{effective.planning}" },
238
- "gsd-project-researcher": { "model": "{effective.planning}" },
239
- "gsd-research-synthesizer": { "model": "{effective.planning}" },
240
- "gsd-codebase-mapper": { "model": "{effective.planning}" },
241
- "gsd-executor": { "model": "{effective.execution}" },
242
- "gsd-debugger": { "model": "{effective.execution}" },
243
- "gsd-verifier": { "model": "{effective.verification}" },
244
- "gsd-integration-checker": { "model": "{effective.verification}" },
245
- "gsd-set-profile": { "model": "{effective.verification}" },
246
- "gsd-settings": { "model": "{effective.verification}" },
247
- "gsd-set-model": { "model": "{effective.verification}" }
248
- }
249
- }
250
- ```
251
-
252
- If `opencode.json` already exists, merge the `agent` key (preserve other top-level keys).
253
-
254
- 3. **Report success:**
255
-
256
- ```text
257
- ✓ Updated {targetProfile} profile:
258
-
259
- | Stage | Model |
260
- |--------------|-------|
261
- | planning | {newPreset.planning} |
262
- | execution | {newPreset.execution} |
263
- | verification | {newPreset.verification} |
264
- ```
265
-
266
- If `targetProfile` is the active profile:
267
- ```text
268
- Note: This is your active profile. Quit and relaunch OpenCode to apply model changes.
269
- ```
270
-
271
- If `targetProfile` is NOT the active profile:
272
- ```text
273
- To use this profile, run: /gsd-set-profile {targetProfile}
274
- ```
275
-
276
- </behavior>
277
-
278
- <notes>
279
- - Display available models first, then accept free-form input for model selection
280
- - Validate entered model IDs against the available models list
281
- - Always show full model IDs (e.g., `opencode/claude-sonnet-4`)
282
- - Preserve all other config.json keys when writing (deep merge)
283
- - Do NOT rewrite agent .md files — only update config.json and opencode.json
284
- - This command modifies **presets**, not overrides. Use `/gsd-settings` for per-stage overrides.
285
- - **Source of truth:** `config.json` stores profiles/presets/overrides; `opencode.json` is **derived** from the effective models
286
- - OpenCode shows all available models regardless of subscription status. Users without Zen can filter with `opencode models github-copilot`
287
- </notes>