gsd-opencode 1.9.1 → 1.10.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-debugger.md +5 -5
- package/agents/gsd-set-model.md +287 -0
- package/agents/gsd-set-profile.md +239 -0
- package/agents/gsd-settings.md +303 -0
- package/bin/gsd-install.js +105 -0
- package/bin/gsd.js +352 -0
- package/bin/install.js +81 -1
- package/{command → commands}/gsd/add-phase.md +1 -1
- package/{command → commands}/gsd/audit-milestone.md +1 -1
- package/{command → commands}/gsd/debug.md +3 -3
- package/{command → commands}/gsd/discuss-phase.md +1 -1
- package/{command → commands}/gsd/execute-phase.md +1 -1
- package/{command → commands}/gsd/list-phase-assumptions.md +1 -1
- package/{command → commands}/gsd/map-codebase.md +1 -1
- package/{command → commands}/gsd/new-milestone.md +1 -1
- package/{command → commands}/gsd/new-project.md +71 -6
- package/{command → commands}/gsd/plan-phase.md +2 -2
- package/{command → commands}/gsd/research-phase.md +1 -1
- package/commands/gsd/set-model.md +77 -0
- package/commands/gsd/set-profile.md +46 -0
- package/commands/gsd/settings.md +33 -0
- package/{command → commands}/gsd/verify-work.md +1 -1
- package/get-shit-done/references/model-profiles.md +67 -36
- package/get-shit-done/workflows/list-phase-assumptions.md +1 -1
- package/get-shit-done/workflows/verify-work.md +5 -5
- package/lib/constants.js +193 -0
- package/package.json +34 -20
- package/src/commands/check.js +329 -0
- package/src/commands/config.js +337 -0
- package/src/commands/install.js +608 -0
- package/src/commands/list.js +256 -0
- package/src/commands/repair.js +519 -0
- package/src/commands/uninstall.js +732 -0
- package/src/commands/update.js +444 -0
- package/src/services/backup-manager.js +585 -0
- package/src/services/config.js +262 -0
- package/src/services/file-ops.js +830 -0
- package/src/services/health-checker.js +475 -0
- package/src/services/manifest-manager.js +301 -0
- package/src/services/migration-service.js +831 -0
- package/src/services/repair-service.js +846 -0
- package/src/services/scope-manager.js +303 -0
- package/src/services/settings.js +553 -0
- package/src/services/structure-detector.js +240 -0
- package/src/services/update-service.js +863 -0
- package/src/utils/hash.js +71 -0
- package/src/utils/interactive.js +222 -0
- package/src/utils/logger.js +128 -0
- package/src/utils/npm-registry.js +255 -0
- package/src/utils/path-resolver.js +226 -0
- package/command/gsd/set-profile.md +0 -111
- package/command/gsd/settings.md +0 -136
- /package/{command → commands}/gsd/add-todo.md +0 -0
- /package/{command → commands}/gsd/check-todos.md +0 -0
- /package/{command → commands}/gsd/complete-milestone.md +0 -0
- /package/{command → commands}/gsd/help.md +0 -0
- /package/{command → commands}/gsd/insert-phase.md +0 -0
- /package/{command → commands}/gsd/pause-work.md +0 -0
- /package/{command → commands}/gsd/plan-milestone-gaps.md +0 -0
- /package/{command → commands}/gsd/progress.md +0 -0
- /package/{command → commands}/gsd/quick.md +0 -0
- /package/{command → commands}/gsd/remove-phase.md +0 -0
- /package/{command → commands}/gsd/resume-work.md +0 -0
- /package/{command → commands}/gsd/update.md +0 -0
- /package/{command → commands}/gsd/whats-new.md +0 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path resolver utility with security-focused traversal protection.
|
|
3
|
+
*
|
|
4
|
+
* This module provides safe path resolution functions that prevent directory
|
|
5
|
+
* traversal attacks. All functions normalize paths and validate that resolved
|
|
6
|
+
* paths remain within allowed directory boundaries.
|
|
7
|
+
*
|
|
8
|
+
* SECURITY NOTE: Always validate paths before using them in file operations.
|
|
9
|
+
* The validatePath() function throws descriptive errors for traversal attempts.
|
|
10
|
+
*
|
|
11
|
+
* @module path-resolver
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import path from 'path';
|
|
15
|
+
import os from 'os';
|
|
16
|
+
import fs from 'fs';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Expand a path string, resolving ~ to home directory and relative paths.
|
|
20
|
+
*
|
|
21
|
+
* @param {string} pathStr - Path string to expand (may contain ~ or relative segments)
|
|
22
|
+
* @returns {string} Absolute, normalized path
|
|
23
|
+
* @throws {Error} If path contains null bytes (potential injection attack)
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* expandPath('~/.config/opencode')
|
|
27
|
+
* // Returns: '/Users/username/.config/opencode' (macOS)
|
|
28
|
+
*
|
|
29
|
+
* expandPath('./relative/path')
|
|
30
|
+
* // Returns: '/absolute/path/to/relative/path'
|
|
31
|
+
*/
|
|
32
|
+
export function expandPath(pathStr) {
|
|
33
|
+
if (typeof pathStr !== 'string') {
|
|
34
|
+
throw new Error('Path must be a string');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Security: Reject null bytes which could be used for injection attacks
|
|
38
|
+
if (pathStr.includes('\0')) {
|
|
39
|
+
throw new Error('Path contains null bytes');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let expanded = pathStr;
|
|
43
|
+
|
|
44
|
+
// Expand ~ to home directory
|
|
45
|
+
if (expanded.startsWith('~')) {
|
|
46
|
+
expanded = expanded.replace('~', os.homedir());
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Resolve to absolute path
|
|
50
|
+
const resolved = path.resolve(expanded);
|
|
51
|
+
|
|
52
|
+
// Normalize to handle .. and . segments consistently
|
|
53
|
+
return normalizePath(resolved);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Normalize a path consistently across platforms.
|
|
58
|
+
*
|
|
59
|
+
* @param {string} pathStr - Path to normalize
|
|
60
|
+
* @returns {string} Normalized path with consistent separators
|
|
61
|
+
*/
|
|
62
|
+
export function normalizePath(pathStr) {
|
|
63
|
+
if (typeof pathStr !== 'string') {
|
|
64
|
+
throw new Error('Path must be a string');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Use path.normalize() to resolve .. and . segments
|
|
68
|
+
// This ensures consistent path representation across platforms
|
|
69
|
+
return path.normalize(pathStr);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Check if a child path is within a parent path.
|
|
74
|
+
*
|
|
75
|
+
* @param {string} childPath - Path to check (child candidate)
|
|
76
|
+
* @param {string} parentPath - Parent directory path
|
|
77
|
+
* @returns {boolean} True if child is within or equal to parent
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* isSubPath('/home/user/.config', '/home/user') // true
|
|
81
|
+
* isSubPath('/home/user', '/home/user') // true
|
|
82
|
+
* isSubPath('/etc/passwd', '/home/user') // false
|
|
83
|
+
*/
|
|
84
|
+
export function isSubPath(childPath, parentPath) {
|
|
85
|
+
if (typeof childPath !== 'string' || typeof parentPath !== 'string') {
|
|
86
|
+
throw new Error('Paths must be strings');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Normalize both paths to ensure consistent comparison
|
|
90
|
+
const normalizedChild = normalizePath(childPath);
|
|
91
|
+
const normalizedParent = normalizePath(parentPath);
|
|
92
|
+
|
|
93
|
+
// Get relative path from parent to child
|
|
94
|
+
const relative = path.relative(normalizedParent, normalizedChild);
|
|
95
|
+
|
|
96
|
+
// If relative path starts with '..', child is outside parent
|
|
97
|
+
// Empty string means same path
|
|
98
|
+
// Path starting without '..' means child is inside or equal to parent
|
|
99
|
+
if (relative === '') {
|
|
100
|
+
return true; // Same path
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// On Windows, relative paths don't use .. for same-level directories
|
|
104
|
+
// Check if relative path contains '..' at the start
|
|
105
|
+
return !relative.startsWith('..');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Validate that a target path does not escape an allowed base directory.
|
|
110
|
+
*
|
|
111
|
+
* SECURITY CRITICAL: This function must be called before any file operation
|
|
112
|
+
* that uses user-provided paths. It prevents directory traversal attacks
|
|
113
|
+
* where malicious input like '../../../etc/passwd' attempts to access
|
|
114
|
+
* files outside the intended directory.
|
|
115
|
+
*
|
|
116
|
+
* @param {string} targetPath - Path to validate
|
|
117
|
+
* @param {string} allowedBasePath - Base directory the target must remain within
|
|
118
|
+
* @returns {string} The resolved, validated absolute path
|
|
119
|
+
* @throws {Error} If path escapes allowed base directory (traversal detected)
|
|
120
|
+
* @throws {Error} If path contains null bytes
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* validatePath('/home/user/.config/opencode', '/home/user') // OK
|
|
124
|
+
* validatePath('/etc/passwd', '/home/user') // Throws error
|
|
125
|
+
*
|
|
126
|
+
* // Handles symlink resolution
|
|
127
|
+
* const realTarget = fs.realpathSync(targetPath);
|
|
128
|
+
* validatePath(realTarget, allowedBasePath);
|
|
129
|
+
*/
|
|
130
|
+
export function validatePath(targetPath, allowedBasePath) {
|
|
131
|
+
if (typeof targetPath !== 'string' || typeof allowedBasePath !== 'string') {
|
|
132
|
+
throw new Error('Paths must be strings');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Security: Reject null bytes
|
|
136
|
+
if (targetPath.includes('\0')) {
|
|
137
|
+
throw new Error('Path contains null bytes');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Expand and normalize both paths
|
|
141
|
+
const resolvedTarget = expandPath(targetPath);
|
|
142
|
+
const resolvedBase = expandPath(allowedBasePath);
|
|
143
|
+
|
|
144
|
+
// Check if target is within allowed base
|
|
145
|
+
if (!isSubPath(resolvedTarget, resolvedBase)) {
|
|
146
|
+
throw new Error(
|
|
147
|
+
'Path traversal detected. Use absolute or relative paths within allowed directories.'
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return resolvedTarget;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Validate a path after resolving symlinks.
|
|
156
|
+
*
|
|
157
|
+
* Symlinks can be used to bypass directory restrictions by pointing to
|
|
158
|
+
* locations outside the allowed base. This function resolves symlinks
|
|
159
|
+
* before validation to ensure the actual file location is checked.
|
|
160
|
+
*
|
|
161
|
+
* @param {string} targetPath - Path to validate (may contain symlinks)
|
|
162
|
+
* @param {string} allowedBasePath - Base directory the target must remain within
|
|
163
|
+
* @returns {Promise<string>} The real, resolved absolute path
|
|
164
|
+
* @throws {Error} If path escapes allowed base directory after symlink resolution
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* // If ~/.config is a symlink to /etc/config:
|
|
168
|
+
* await validatePathSafe('~/.config/opencode', os.homedir());
|
|
169
|
+
* // Throws error because resolved path is outside homedir
|
|
170
|
+
*/
|
|
171
|
+
export async function validatePathSafe(targetPath, allowedBasePath) {
|
|
172
|
+
const expandedTarget = expandPath(targetPath);
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
// Resolve symlinks to get the real path
|
|
176
|
+
const realTarget = await fs.promises.realpath(expandedTarget);
|
|
177
|
+
|
|
178
|
+
// Now validate the resolved path
|
|
179
|
+
return validatePath(realTarget, allowedBasePath);
|
|
180
|
+
} catch (error) {
|
|
181
|
+
// If realpath fails (file doesn't exist), validate the non-resolved path
|
|
182
|
+
// This allows validation of paths that will be created
|
|
183
|
+
if (error.code === 'ENOENT') {
|
|
184
|
+
return validatePath(expandedTarget, allowedBasePath);
|
|
185
|
+
}
|
|
186
|
+
throw error;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Synchronous version of validatePathSafe.
|
|
192
|
+
*
|
|
193
|
+
* @param {string} targetPath - Path to validate (may contain symlinks)
|
|
194
|
+
* @param {string} allowedBasePath - Base directory the target must remain within
|
|
195
|
+
* @returns {string} The real, resolved absolute path
|
|
196
|
+
* @throws {Error} If path escapes allowed base directory after symlink resolution
|
|
197
|
+
*/
|
|
198
|
+
export function validatePathSafeSync(targetPath, allowedBasePath) {
|
|
199
|
+
const expandedTarget = expandPath(targetPath);
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
// Resolve symlinks synchronously
|
|
203
|
+
const realTarget = fs.realpathSync(expandedTarget);
|
|
204
|
+
|
|
205
|
+
// Now validate the resolved path
|
|
206
|
+
return validatePath(realTarget, allowedBasePath);
|
|
207
|
+
} catch (error) {
|
|
208
|
+
// If realpath fails (file doesn't exist), validate the non-resolved path
|
|
209
|
+
if (error.code === 'ENOENT') {
|
|
210
|
+
return validatePath(expandedTarget, allowedBasePath);
|
|
211
|
+
}
|
|
212
|
+
throw error;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Default export combining all path resolver functions.
|
|
218
|
+
*/
|
|
219
|
+
export default {
|
|
220
|
+
expandPath,
|
|
221
|
+
normalizePath,
|
|
222
|
+
isSubPath,
|
|
223
|
+
validatePath,
|
|
224
|
+
validatePathSafe,
|
|
225
|
+
validatePathSafeSync
|
|
226
|
+
};
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: gsd-set-profile
|
|
3
|
-
description: Switch model profile for GSD agents (quality/balanced/budget)
|
|
4
|
-
arguments:
|
|
5
|
-
- name: profile
|
|
6
|
-
description: "Profile name: quality, balanced, or budget"
|
|
7
|
-
required: true
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
<objective>
|
|
11
|
-
Switch the model profile used by GSD agents. This controls which OpenCode model each agent uses, balancing quality vs token spend.
|
|
12
|
-
</objective>
|
|
13
|
-
|
|
14
|
-
<profiles>
|
|
15
|
-
| Profile | Description |
|
|
16
|
-
|---------|-------------|
|
|
17
|
-
| **quality** | Opus everywhere except read-only verification |
|
|
18
|
-
| **balanced** | Opus for planning, Sonnet for execution/verification (default) |
|
|
19
|
-
| **budget** | Sonnet for writing, Haiku for research/verification |
|
|
20
|
-
</profiles>
|
|
21
|
-
|
|
22
|
-
<process>
|
|
23
|
-
|
|
24
|
-
## 1. Validate argument
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
if $ARGUMENTS.profile not in ["quality", "balanced", "budget"]:
|
|
28
|
-
Error: Invalid profile "$ARGUMENTS.profile"
|
|
29
|
-
Valid profiles: quality, balanced, budget
|
|
30
|
-
STOP
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## 2. Check for project
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
ls .planning/config.json 2>/dev/null
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
If no `.planning/` directory:
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
Error: No GSD project found.
|
|
43
|
-
Run /gsd-new-project first to initialize a project.
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## 3. Update config.json
|
|
47
|
-
|
|
48
|
-
read current config:
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
cat .planning/config.json
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Update `model_profile` field (or add if missing):
|
|
55
|
-
|
|
56
|
-
```json
|
|
57
|
-
{
|
|
58
|
-
"model_profile": "$ARGUMENTS.profile"
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
write updated config back to `.planning/config.json`.
|
|
63
|
-
|
|
64
|
-
## 4. Confirm
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
✓ Model profile set to: $ARGUMENTS.profile
|
|
68
|
-
|
|
69
|
-
Agents will now use:
|
|
70
|
-
[Show table from model-profiles.md for selected profile]
|
|
71
|
-
|
|
72
|
-
Next spawned agents will use the new profile.
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
</process>
|
|
76
|
-
|
|
77
|
-
<examples>
|
|
78
|
-
|
|
79
|
-
**Switch to budget mode:**
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
/gsd-set-profile budget
|
|
83
|
-
|
|
84
|
-
✓ Model profile set to: budget
|
|
85
|
-
|
|
86
|
-
Agents will now use:
|
|
87
|
-
| Agent | Model |
|
|
88
|
-
|-------|-------|
|
|
89
|
-
| gsd-planner | sonnet |
|
|
90
|
-
| gsd-executor | sonnet |
|
|
91
|
-
| gsd-verifier | haiku |
|
|
92
|
-
| ... | ... |
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
**Switch to quality mode:**
|
|
96
|
-
|
|
97
|
-
```
|
|
98
|
-
/gsd-set-profile quality
|
|
99
|
-
|
|
100
|
-
✓ Model profile set to: quality
|
|
101
|
-
|
|
102
|
-
Agents will now use:
|
|
103
|
-
| Agent | Model |
|
|
104
|
-
|-------|-------|
|
|
105
|
-
| gsd-planner | opus |
|
|
106
|
-
| gsd-executor | opus |
|
|
107
|
-
| gsd-verifier | sonnet |
|
|
108
|
-
| ... | ... |
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
</examples>
|
package/command/gsd/settings.md
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: gsd-settings
|
|
3
|
-
description: Configure GSD workflow toggles and model profile
|
|
4
|
-
tools:
|
|
5
|
-
- read
|
|
6
|
-
- write
|
|
7
|
-
- question
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
<objective>
|
|
11
|
-
Allow users to toggle workflow agents on/off and select model profile via interactive settings.
|
|
12
|
-
|
|
13
|
-
Updates `.planning/config.json` with workflow preferences and model profile selection.
|
|
14
|
-
</objective>
|
|
15
|
-
|
|
16
|
-
<process>
|
|
17
|
-
|
|
18
|
-
## 1. Validate Environment
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
ls .planning/config.json 2>/dev/null
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
**If not found:** Error - run `/gsd-new-project` first.
|
|
25
|
-
|
|
26
|
-
## 2. read Current Config
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
cat .planning/config.json
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Parse current values (default to `true` if not present):
|
|
33
|
-
- `workflow.research` — spawn researcher during plan-phase
|
|
34
|
-
- `workflow.plan_check` — spawn plan checker during plan-phase
|
|
35
|
-
- `workflow.verifier` — spawn verifier during execute-phase
|
|
36
|
-
- `model_profile` — which model each agent uses (default: `balanced`)
|
|
37
|
-
|
|
38
|
-
## 3. Present Settings
|
|
39
|
-
|
|
40
|
-
Use question with current values shown:
|
|
41
|
-
|
|
42
|
-
```
|
|
43
|
-
question([
|
|
44
|
-
{
|
|
45
|
-
question: "Which model profile for agents?",
|
|
46
|
-
header: "Model",
|
|
47
|
-
multiSelect: false,
|
|
48
|
-
options: [
|
|
49
|
-
{ label: "Quality", description: "Opus everywhere except verification (highest cost)" },
|
|
50
|
-
{ label: "Balanced (Recommended)", description: "Opus for planning, Sonnet for execution/verification" },
|
|
51
|
-
{ label: "Budget", description: "Sonnet for writing, Haiku for research/verification (lowest cost)" }
|
|
52
|
-
]
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
question: "Spawn Plan Researcher? (researches domain before planning)",
|
|
56
|
-
header: "Research",
|
|
57
|
-
multiSelect: false,
|
|
58
|
-
options: [
|
|
59
|
-
{ label: "Yes", description: "Research phase goals before planning" },
|
|
60
|
-
{ label: "No", description: "Skip research, plan directly" }
|
|
61
|
-
]
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
question: "Spawn Plan Checker? (verifies plans before execution)",
|
|
65
|
-
header: "Plan Check",
|
|
66
|
-
multiSelect: false,
|
|
67
|
-
options: [
|
|
68
|
-
{ label: "Yes", description: "Verify plans meet phase goals" },
|
|
69
|
-
{ label: "No", description: "Skip plan verification" }
|
|
70
|
-
]
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
question: "Spawn Execution Verifier? (verifies phase completion)",
|
|
74
|
-
header: "Verifier",
|
|
75
|
-
multiSelect: false,
|
|
76
|
-
options: [
|
|
77
|
-
{ label: "Yes", description: "Verify must-haves after execution" },
|
|
78
|
-
{ label: "No", description: "Skip post-execution verification" }
|
|
79
|
-
]
|
|
80
|
-
}
|
|
81
|
-
])
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
**Pre-select based on current config values.**
|
|
85
|
-
|
|
86
|
-
## 4. Update Config
|
|
87
|
-
|
|
88
|
-
Merge new settings into existing config.json:
|
|
89
|
-
|
|
90
|
-
```json
|
|
91
|
-
{
|
|
92
|
-
...existing_config,
|
|
93
|
-
"model_profile": "quality" | "balanced" | "budget",
|
|
94
|
-
"workflow": {
|
|
95
|
-
"research": true/false,
|
|
96
|
-
"plan_check": true/false,
|
|
97
|
-
"verifier": true/false
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
write updated config to `.planning/config.json`.
|
|
103
|
-
|
|
104
|
-
## 5. Confirm Changes
|
|
105
|
-
|
|
106
|
-
Display:
|
|
107
|
-
|
|
108
|
-
```
|
|
109
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
110
|
-
GSD ► SETTINGS UPDATED
|
|
111
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
112
|
-
|
|
113
|
-
| Setting | Value |
|
|
114
|
-
|----------------------|-------|
|
|
115
|
-
| Model Profile | {quality/balanced/budget} |
|
|
116
|
-
| Plan Researcher | {On/Off} |
|
|
117
|
-
| Plan Checker | {On/Off} |
|
|
118
|
-
| Execution Verifier | {On/Off} |
|
|
119
|
-
|
|
120
|
-
These settings apply to future /gsd-plan-phase and /gsd-execute-phase runs.
|
|
121
|
-
|
|
122
|
-
Quick commands:
|
|
123
|
-
- /gsd-set-profile <profile> — switch model profile
|
|
124
|
-
- /gsd-plan-phase --research — force research
|
|
125
|
-
- /gsd-plan-phase --skip-research — skip research
|
|
126
|
-
- /gsd-plan-phase --skip-verify — skip plan check
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
</process>
|
|
130
|
-
|
|
131
|
-
<success_criteria>
|
|
132
|
-
- [ ] Current config read
|
|
133
|
-
- [ ] User presented with 4 settings (profile + 3 toggles)
|
|
134
|
-
- [ ] Config updated with model_profile and workflow section
|
|
135
|
-
- [ ] Changes confirmed to user
|
|
136
|
-
</success_criteria>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|