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.
- package/agents/gsd-codebase-mapper.md +29 -3
- package/agents/gsd-debugger.md +19 -21
- package/agents/gsd-executor.md +213 -528
- package/agents/gsd-integration-checker.md +20 -0
- package/agents/gsd-phase-researcher.md +189 -267
- package/agents/gsd-plan-checker.md +278 -279
- package/agents/gsd-planner.md +299 -490
- package/agents/gsd-project-researcher.md +103 -345
- package/agents/gsd-research-synthesizer.md +5 -22
- package/agents/gsd-roadmapper.md +43 -6
- package/agents/gsd-verifier.md +158 -377
- package/{lib → bin/dm/lib}/constants.js +10 -3
- package/{src → bin/dm/src}/commands/install.js +5 -4
- package/{src → bin/dm/src}/commands/uninstall.js +3 -1
- package/{src → bin/dm/src}/services/backup-manager.js +1 -1
- package/{src → bin/dm/src}/services/config.js +1 -1
- package/{src → bin/dm/src}/services/file-ops.js +20 -4
- package/{src → bin/dm/src}/services/health-checker.js +3 -1
- package/{src → bin/dm/src}/services/repair-service.js +3 -1
- package/{src → bin/dm/src}/services/settings.js +1 -1
- package/{src → bin/dm/src}/services/update-service.js +2 -2
- package/bin/gsd-install.js +0 -0
- package/bin/gsd.js +9 -9
- package/commands/gsd/gsd-add-phase.md +43 -0
- package/commands/gsd/gsd-add-todo.md +47 -0
- package/commands/gsd/gsd-audit-milestone.md +36 -0
- package/commands/gsd/gsd-check-todos.md +45 -0
- package/commands/gsd/gsd-cleanup.md +18 -0
- package/commands/gsd/{complete-milestone.md → gsd-complete-milestone.md} +1 -1
- package/commands/gsd/{debug.md → gsd-debug.md} +16 -21
- package/commands/gsd/{discuss-phase.md → gsd-discuss-phase.md} +6 -9
- package/commands/gsd/gsd-execute-phase.md +41 -0
- package/commands/gsd/gsd-health.md +22 -0
- package/commands/gsd/gsd-help.md +22 -0
- package/commands/gsd/gsd-insert-phase.md +32 -0
- package/commands/gsd/gsd-join-discord.md +18 -0
- package/commands/gsd/{list-phase-assumptions.md → gsd-list-phase-assumptions.md} +3 -7
- package/commands/gsd/{map-codebase.md → gsd-map-codebase.md} +3 -3
- package/commands/gsd/gsd-new-milestone.md +44 -0
- package/commands/gsd/gsd-new-project.md +42 -0
- package/commands/gsd/gsd-pause-work.md +38 -0
- package/commands/gsd/gsd-plan-milestone-gaps.md +34 -0
- package/commands/gsd/gsd-plan-phase.md +44 -0
- package/commands/gsd/gsd-progress.md +24 -0
- package/commands/gsd/gsd-quick.md +41 -0
- package/commands/gsd/gsd-reapply-patches.md +119 -0
- package/commands/gsd/gsd-remove-phase.md +31 -0
- package/commands/gsd/{research-phase.md → gsd-research-phase.md} +38 -49
- package/commands/gsd/{resume-work.md → gsd-resume-work.md} +2 -2
- package/commands/gsd/gsd-set-profile.md +34 -0
- package/commands/gsd/gsd-settings.md +36 -0
- package/commands/gsd/gsd-update.md +37 -0
- package/commands/gsd/gsd-verify-work.md +38 -0
- package/get-shit-done/bin/gsd-tools.cjs +553 -0
- package/get-shit-done/bin/gsd-tools.test.cjs +2346 -0
- package/get-shit-done/bin/lib/commands.cjs +556 -0
- package/get-shit-done/bin/lib/config.cjs +162 -0
- package/get-shit-done/bin/lib/core.cjs +377 -0
- package/get-shit-done/bin/lib/frontmatter.cjs +299 -0
- package/get-shit-done/bin/lib/init.cjs +694 -0
- package/get-shit-done/bin/lib/milestone.cjs +215 -0
- package/get-shit-done/bin/lib/phase.cjs +877 -0
- package/get-shit-done/bin/lib/roadmap.cjs +298 -0
- package/get-shit-done/bin/lib/state.cjs +490 -0
- package/get-shit-done/bin/lib/template.cjs +222 -0
- package/get-shit-done/bin/lib/verify.cjs +772 -0
- package/get-shit-done/references/checkpoints.md +62 -364
- package/get-shit-done/references/decimal-phase-calculation.md +65 -0
- package/get-shit-done/references/git-integration.md +10 -16
- package/get-shit-done/references/git-planning-commit.md +38 -0
- package/get-shit-done/references/model-profile-resolution.md +34 -0
- package/get-shit-done/references/model-profiles.md +54 -66
- package/get-shit-done/references/phase-argument-parsing.md +61 -0
- package/get-shit-done/references/planning-config.md +112 -10
- package/get-shit-done/references/questioning.md +4 -0
- package/get-shit-done/references/ui-brand.md +1 -1
- package/get-shit-done/templates/UAT.md +1 -1
- package/get-shit-done/templates/VALIDATION.md +104 -0
- package/get-shit-done/templates/codebase/structure.md +6 -6
- package/get-shit-done/templates/config.json +37 -0
- package/get-shit-done/templates/context.md +2 -10
- package/get-shit-done/templates/continue-here.md +6 -6
- package/get-shit-done/templates/debug-subagent-prompt.md +2 -2
- package/get-shit-done/templates/discovery.md +6 -6
- package/get-shit-done/templates/milestone-archive.md +3 -3
- package/get-shit-done/templates/phase-prompt.md +9 -7
- package/get-shit-done/templates/planner-subagent-prompt.md +6 -6
- package/get-shit-done/templates/research-project/ARCHITECTURE.md +1 -1
- package/get-shit-done/templates/research.md +29 -6
- package/get-shit-done/templates/roadmap.md +1 -1
- package/get-shit-done/templates/state.md +0 -30
- package/get-shit-done/templates/summary-complex.md +59 -0
- package/get-shit-done/templates/summary-minimal.md +41 -0
- package/get-shit-done/templates/summary-standard.md +48 -0
- package/get-shit-done/templates/summary.md +16 -37
- package/get-shit-done/templates/user-setup.md +1 -13
- package/get-shit-done/templates/verification-report.md +5 -5
- package/get-shit-done/workflows/add-phase.md +111 -0
- package/{commands/gsd → get-shit-done/workflows}/add-todo.md +24 -60
- package/{commands/gsd → get-shit-done/workflows}/audit-milestone.md +83 -63
- package/{commands/gsd → get-shit-done/workflows}/check-todos.md +21 -73
- package/get-shit-done/workflows/cleanup.md +152 -0
- package/get-shit-done/workflows/complete-milestone.md +251 -312
- package/get-shit-done/workflows/diagnose-issues.md +6 -31
- package/get-shit-done/workflows/discovery-phase.md +11 -11
- package/get-shit-done/workflows/discuss-phase.md +156 -49
- package/get-shit-done/workflows/execute-phase.md +238 -396
- package/get-shit-done/workflows/execute-plan.md +180 -1609
- package/get-shit-done/workflows/health.md +156 -0
- package/{commands/gsd → get-shit-done/workflows}/help.md +33 -35
- package/get-shit-done/workflows/insert-phase.md +129 -0
- package/get-shit-done/workflows/list-phase-assumptions.md +3 -3
- package/get-shit-done/workflows/map-codebase.md +73 -80
- package/get-shit-done/workflows/new-milestone.md +382 -0
- package/{commands/gsd → get-shit-done/workflows}/new-project.md +281 -234
- package/get-shit-done/workflows/oc-set-profile.md +320 -0
- package/{commands/gsd → get-shit-done/workflows}/pause-work.md +31 -43
- package/{commands/gsd → get-shit-done/workflows}/plan-milestone-gaps.md +29 -50
- package/get-shit-done/workflows/plan-phase.md +478 -0
- package/{commands/gsd → get-shit-done/workflows}/progress.md +64 -47
- package/get-shit-done/workflows/quick.md +453 -0
- package/get-shit-done/workflows/remove-phase.md +154 -0
- package/get-shit-done/workflows/research-phase.md +73 -0
- package/get-shit-done/workflows/resume-project.md +17 -26
- package/get-shit-done/workflows/set-profile.md +80 -0
- package/get-shit-done/workflows/settings.md +213 -0
- package/get-shit-done/workflows/transition.md +84 -104
- package/{commands/gsd → get-shit-done/workflows}/update.md +70 -28
- package/get-shit-done/workflows/verify-phase.md +106 -492
- package/get-shit-done/workflows/verify-work.md +26 -53
- package/package.json +7 -4
- package/rules/gsd-oc-work-hard.md +36 -0
- package/skills/gsd-oc-select-model/SKILL.md +348 -0
- package/skills/gsd-oc-select-model/scripts/select-models.cjs +268 -0
- package/agents/gsd-set-model.md +0 -287
- package/agents/gsd-set-profile.md +0 -239
- package/agents/gsd-settings.md +0 -749
- package/bin/install.js +0 -323
- package/commands/gsd/add-phase.md +0 -207
- package/commands/gsd/execute-phase.md +0 -339
- package/commands/gsd/insert-phase.md +0 -227
- package/commands/gsd/new-milestone.md +0 -721
- package/commands/gsd/plan-phase.md +0 -525
- package/commands/gsd/quick.md +0 -309
- package/commands/gsd/remove-phase.md +0 -349
- package/commands/gsd/set-model.md +0 -77
- package/commands/gsd/set-profile.md +0 -46
- package/commands/gsd/settings.md +0 -33
- package/commands/gsd/verify-work.md +0 -219
- package/commands/gsd/whats-new.md +0 -124
- /package/{src → bin/dm/src}/commands/check.js +0 -0
- /package/{src → bin/dm/src}/commands/config.js +0 -0
- /package/{src → bin/dm/src}/commands/list.js +0 -0
- /package/{src → bin/dm/src}/commands/repair.js +0 -0
- /package/{src → bin/dm/src}/commands/update.js +0 -0
- /package/{src → bin/dm/src}/services/manifest-manager.js +0 -0
- /package/{src → bin/dm/src}/services/migration-service.js +0 -0
- /package/{src → bin/dm/src}/services/scope-manager.js +0 -0
- /package/{src → bin/dm/src}/services/structure-detector.js +0 -0
- /package/{src → bin/dm/src}/utils/hash.js +0 -0
- /package/{src → bin/dm/src}/utils/interactive.js +0 -0
- /package/{src → bin/dm/src}/utils/logger.js +0 -0
- /package/{src → bin/dm/src}/utils/npm-registry.js +0 -0
- /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
|
+
}
|
package/agents/gsd-set-model.md
DELETED
|
@@ -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>
|