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.
- package/agents/gsd-debugger.md +5 -5
- package/agents/gsd-settings.md +476 -30
- package/bin/gsd-install.js +105 -0
- package/bin/gsd.js +352 -0
- 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 +3 -3
- package/{command → commands}/gsd/plan-phase.md +2 -2
- package/{command → commands}/gsd/research-phase.md +1 -1
- package/{command → commands}/gsd/verify-work.md +1 -1
- 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 +199 -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 +855 -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 → 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/set-model.md +0 -0
- /package/{command → commands}/gsd/set-profile.md +0 -0
- /package/{command → commands}/gsd/settings.md +0 -0
- /package/{command → commands}/gsd/update.md +0 -0
- /package/{command → commands}/gsd/whats-new.md +0 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structure detector for identifying GSD-OpenCode directory layout.
|
|
3
|
+
*
|
|
4
|
+
* This module provides detection and analysis of the command directory structure,
|
|
5
|
+
* supporting both legacy (command/gsd/) and new (commands/gsd/) layouts.
|
|
6
|
+
* Used during installation, update, and health checks to determine the correct
|
|
7
|
+
* structure and handle migration scenarios.
|
|
8
|
+
*
|
|
9
|
+
* @module structure-detector
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import fs from 'fs/promises';
|
|
13
|
+
import path from 'path';
|
|
14
|
+
import { OLD_COMMAND_DIR, NEW_COMMAND_DIR, STRUCTURE_TYPES } from '../../lib/constants.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Detects and analyzes GSD-OpenCode directory structure.
|
|
18
|
+
*
|
|
19
|
+
* This class provides methods to determine which command directory structure
|
|
20
|
+
* exists at a given installation path: legacy (command/gsd/), new (commands/gsd/),
|
|
21
|
+
* both (dual/migration state), or neither (fresh install).
|
|
22
|
+
*
|
|
23
|
+
* @class StructureDetector
|
|
24
|
+
* @example
|
|
25
|
+
* const detector = new StructureDetector('/home/user/.config/opencode');
|
|
26
|
+
* const structure = await detector.detect();
|
|
27
|
+
* console.log(structure); // 'old', 'new', 'dual', or 'none'
|
|
28
|
+
*/
|
|
29
|
+
export class StructureDetector {
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new StructureDetector instance.
|
|
32
|
+
*
|
|
33
|
+
* @param {string} installPath - Path to the GSD-OpenCode installation directory
|
|
34
|
+
* @throws {Error} If installPath is not provided
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* // Detect structure in global installation
|
|
38
|
+
* const detector = new StructureDetector('/home/user/.config/opencode');
|
|
39
|
+
*
|
|
40
|
+
* // Detect structure in local installation
|
|
41
|
+
* const detector = new StructureDetector('/project/.opencode');
|
|
42
|
+
*/
|
|
43
|
+
constructor(installPath) {
|
|
44
|
+
if (!installPath) {
|
|
45
|
+
throw new Error('installPath is required');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
this.installPath = installPath;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Detects the directory structure at the installation path.
|
|
53
|
+
*
|
|
54
|
+
* Checks for the existence of both old (command/gsd/) and new (commands/gsd/)
|
|
55
|
+
* directory structures and returns the appropriate STRUCTURE_TYPES value.
|
|
56
|
+
*
|
|
57
|
+
* @returns {Promise<string>} One of STRUCTURE_TYPES values:
|
|
58
|
+
* - 'old': Only legacy structure exists (command/gsd/)
|
|
59
|
+
* - 'new': Only new structure exists (commands/gsd/)
|
|
60
|
+
* - 'dual': Both structures exist (migration in progress)
|
|
61
|
+
* - 'none': Neither structure exists (fresh install or not installed)
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* const detector = new StructureDetector('/home/user/.config/opencode');
|
|
65
|
+
*
|
|
66
|
+
* // Returns 'old' if only command/gsd/ exists
|
|
67
|
+
* // Returns 'new' if only commands/gsd/ exists
|
|
68
|
+
* // Returns 'dual' if both exist
|
|
69
|
+
* // Returns 'none' if neither exists
|
|
70
|
+
* const structure = await detector.detect();
|
|
71
|
+
*/
|
|
72
|
+
async detect() {
|
|
73
|
+
const oldPath = path.join(this.installPath, OLD_COMMAND_DIR, 'gsd');
|
|
74
|
+
const newPath = path.join(this.installPath, NEW_COMMAND_DIR, 'gsd');
|
|
75
|
+
|
|
76
|
+
const [oldExists, newExists] = await Promise.all([
|
|
77
|
+
this._pathExists(oldPath),
|
|
78
|
+
this._pathExists(newPath)
|
|
79
|
+
]);
|
|
80
|
+
|
|
81
|
+
if (oldExists && newExists) return STRUCTURE_TYPES.DUAL;
|
|
82
|
+
if (newExists) return STRUCTURE_TYPES.NEW;
|
|
83
|
+
if (oldExists) return STRUCTURE_TYPES.OLD;
|
|
84
|
+
return STRUCTURE_TYPES.NONE;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Checks if a path exists on the filesystem.
|
|
89
|
+
*
|
|
90
|
+
* Uses fs.access() for existence checking with proper error handling.
|
|
91
|
+
*
|
|
92
|
+
* @private
|
|
93
|
+
* @param {string} checkPath - Path to check for existence
|
|
94
|
+
* @returns {Promise<boolean>} True if path exists, false otherwise
|
|
95
|
+
*/
|
|
96
|
+
async _pathExists(checkPath) {
|
|
97
|
+
try {
|
|
98
|
+
await fs.access(checkPath);
|
|
99
|
+
return true;
|
|
100
|
+
} catch {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Gets the appropriate command directory name for a structure type.
|
|
107
|
+
*
|
|
108
|
+
* Returns the command directory name to use based on the detected structure.
|
|
109
|
+
* For fresh installs (NONE), defaults to the new structure.
|
|
110
|
+
*
|
|
111
|
+
* @param {string} structureType - One of STRUCTURE_TYPES values
|
|
112
|
+
* @returns {string} The command directory name:
|
|
113
|
+
* - 'commands' for NEW, DUAL, or NONE
|
|
114
|
+
* - 'command' for OLD
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* const detector = new StructureDetector('/home/user/.config/opencode');
|
|
118
|
+
*
|
|
119
|
+
* detector.getCommandDir('new'); // returns 'commands'
|
|
120
|
+
* detector.getCommandDir('old'); // returns 'command'
|
|
121
|
+
* detector.getCommandDir('dual'); // returns 'commands' (prefer new)
|
|
122
|
+
* detector.getCommandDir('none'); // returns 'commands' (default for fresh)
|
|
123
|
+
*/
|
|
124
|
+
getCommandDir(structureType) {
|
|
125
|
+
switch (structureType) {
|
|
126
|
+
case STRUCTURE_TYPES.NEW:
|
|
127
|
+
case STRUCTURE_TYPES.DUAL:
|
|
128
|
+
case STRUCTURE_TYPES.NONE:
|
|
129
|
+
return NEW_COMMAND_DIR;
|
|
130
|
+
case STRUCTURE_TYPES.OLD:
|
|
131
|
+
return OLD_COMMAND_DIR;
|
|
132
|
+
default:
|
|
133
|
+
return NEW_COMMAND_DIR; // Default to new for unknown types
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Gets detailed information about the structure state.
|
|
139
|
+
*
|
|
140
|
+
* Returns an object with detailed information about both structures,
|
|
141
|
+
* useful for health checks and diagnostic output.
|
|
142
|
+
*
|
|
143
|
+
* @returns {Promise<Object>} Structure state details:
|
|
144
|
+
* - type: The detected structure type
|
|
145
|
+
* - oldPath: Full path to old structure
|
|
146
|
+
* - newPath: Full path to new structure
|
|
147
|
+
* - oldExists: Whether old structure exists
|
|
148
|
+
* - newExists: Whether new structure exists
|
|
149
|
+
* - recommendedAction: Suggested action based on state
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* const detector = new StructureDetector('/home/user/.config/opencode');
|
|
153
|
+
* const details = await detector.getDetails();
|
|
154
|
+
* // {
|
|
155
|
+
* // type: 'dual',
|
|
156
|
+
* // oldPath: '/home/user/.config/opencode/command/gsd',
|
|
157
|
+
* // newPath: '/home/user/.config/opencode/commands/gsd',
|
|
158
|
+
* // oldExists: true,
|
|
159
|
+
* // newExists: true,
|
|
160
|
+
* // recommendedAction: 'Run update to complete migration'
|
|
161
|
+
* // }
|
|
162
|
+
*/
|
|
163
|
+
async getDetails() {
|
|
164
|
+
const oldPath = path.join(this.installPath, OLD_COMMAND_DIR, 'gsd');
|
|
165
|
+
const newPath = path.join(this.installPath, NEW_COMMAND_DIR, 'gsd');
|
|
166
|
+
|
|
167
|
+
const [oldExists, newExists] = await Promise.all([
|
|
168
|
+
this._pathExists(oldPath),
|
|
169
|
+
this._pathExists(newPath)
|
|
170
|
+
]);
|
|
171
|
+
|
|
172
|
+
let type;
|
|
173
|
+
let recommendedAction;
|
|
174
|
+
|
|
175
|
+
if (oldExists && newExists) {
|
|
176
|
+
type = STRUCTURE_TYPES.DUAL;
|
|
177
|
+
recommendedAction = 'Run update to complete migration from old to new structure';
|
|
178
|
+
} else if (newExists) {
|
|
179
|
+
type = STRUCTURE_TYPES.NEW;
|
|
180
|
+
recommendedAction = 'Structure is up to date';
|
|
181
|
+
} else if (oldExists) {
|
|
182
|
+
type = STRUCTURE_TYPES.OLD;
|
|
183
|
+
recommendedAction = 'Run update to migrate to new structure';
|
|
184
|
+
} else {
|
|
185
|
+
type = STRUCTURE_TYPES.NONE;
|
|
186
|
+
recommendedAction = 'Fresh installation recommended';
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
type,
|
|
191
|
+
oldPath,
|
|
192
|
+
newPath,
|
|
193
|
+
oldExists,
|
|
194
|
+
newExists,
|
|
195
|
+
recommendedAction
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Convenience function for one-off structure detection.
|
|
202
|
+
*
|
|
203
|
+
* Creates a temporary StructureDetector instance and returns the detected type.
|
|
204
|
+
* Use this for simple detection without needing the full class instance.
|
|
205
|
+
*
|
|
206
|
+
* @param {string} installPath - Path to the installation directory
|
|
207
|
+
* @returns {Promise<string>} The detected structure type
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* // Quick detection without instantiating a class
|
|
211
|
+
* const type = await detectStructure('/home/user/.config/opencode');
|
|
212
|
+
* if (type === 'old') {
|
|
213
|
+
* console.log('Legacy structure detected, migration needed');
|
|
214
|
+
* }
|
|
215
|
+
*/
|
|
216
|
+
export async function detectStructure(installPath) {
|
|
217
|
+
const detector = new StructureDetector(installPath);
|
|
218
|
+
return await detector.detect();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Re-export of STRUCTURE_TYPES from constants for convenience.
|
|
223
|
+
*
|
|
224
|
+
* @type {Object.<string, string>}
|
|
225
|
+
*/
|
|
226
|
+
export { STRUCTURE_TYPES } from '../../lib/constants.js';
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Default export for the structure-detector module.
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* import { StructureDetector, detectStructure, STRUCTURE_TYPES } from './services/structure-detector.js';
|
|
233
|
+
* const detector = new StructureDetector('/path/to/opencode');
|
|
234
|
+
* const type = await detector.detect();
|
|
235
|
+
*/
|
|
236
|
+
export default {
|
|
237
|
+
StructureDetector,
|
|
238
|
+
detectStructure,
|
|
239
|
+
STRUCTURE_TYPES
|
|
240
|
+
};
|