gsd-opencode 1.9.2 → 1.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/agents/gsd-debugger.md +5 -5
  2. package/agents/gsd-settings.md +476 -30
  3. package/bin/gsd-install.js +105 -0
  4. package/bin/gsd.js +352 -0
  5. package/{command → commands}/gsd/add-phase.md +1 -1
  6. package/{command → commands}/gsd/audit-milestone.md +1 -1
  7. package/{command → commands}/gsd/debug.md +3 -3
  8. package/{command → commands}/gsd/discuss-phase.md +1 -1
  9. package/{command → commands}/gsd/execute-phase.md +1 -1
  10. package/{command → commands}/gsd/list-phase-assumptions.md +1 -1
  11. package/{command → commands}/gsd/map-codebase.md +1 -1
  12. package/{command → commands}/gsd/new-milestone.md +1 -1
  13. package/{command → commands}/gsd/new-project.md +3 -3
  14. package/{command → commands}/gsd/plan-phase.md +2 -2
  15. package/{command → commands}/gsd/research-phase.md +1 -1
  16. package/{command → commands}/gsd/verify-work.md +1 -1
  17. package/get-shit-done/workflows/list-phase-assumptions.md +1 -1
  18. package/get-shit-done/workflows/verify-work.md +5 -5
  19. package/lib/constants.js +199 -0
  20. package/package.json +34 -20
  21. package/src/commands/check.js +329 -0
  22. package/src/commands/config.js +337 -0
  23. package/src/commands/install.js +608 -0
  24. package/src/commands/list.js +256 -0
  25. package/src/commands/repair.js +519 -0
  26. package/src/commands/uninstall.js +732 -0
  27. package/src/commands/update.js +444 -0
  28. package/src/services/backup-manager.js +585 -0
  29. package/src/services/config.js +262 -0
  30. package/src/services/file-ops.js +855 -0
  31. package/src/services/health-checker.js +475 -0
  32. package/src/services/manifest-manager.js +301 -0
  33. package/src/services/migration-service.js +831 -0
  34. package/src/services/repair-service.js +846 -0
  35. package/src/services/scope-manager.js +303 -0
  36. package/src/services/settings.js +553 -0
  37. package/src/services/structure-detector.js +240 -0
  38. package/src/services/update-service.js +863 -0
  39. package/src/utils/hash.js +71 -0
  40. package/src/utils/interactive.js +222 -0
  41. package/src/utils/logger.js +128 -0
  42. package/src/utils/npm-registry.js +255 -0
  43. package/src/utils/path-resolver.js +226 -0
  44. /package/{command → commands}/gsd/add-todo.md +0 -0
  45. /package/{command → commands}/gsd/check-todos.md +0 -0
  46. /package/{command → commands}/gsd/complete-milestone.md +0 -0
  47. /package/{command → commands}/gsd/help.md +0 -0
  48. /package/{command → commands}/gsd/insert-phase.md +0 -0
  49. /package/{command → commands}/gsd/pause-work.md +0 -0
  50. /package/{command → commands}/gsd/plan-milestone-gaps.md +0 -0
  51. /package/{command → commands}/gsd/progress.md +0 -0
  52. /package/{command → commands}/gsd/quick.md +0 -0
  53. /package/{command → commands}/gsd/remove-phase.md +0 -0
  54. /package/{command → commands}/gsd/resume-work.md +0 -0
  55. /package/{command → commands}/gsd/set-model.md +0 -0
  56. /package/{command → commands}/gsd/set-profile.md +0 -0
  57. /package/{command → commands}/gsd/settings.md +0 -0
  58. /package/{command → commands}/gsd/update.md +0 -0
  59. /package/{command → commands}/gsd/whats-new.md +0 -0
@@ -0,0 +1,256 @@
1
+ /**
2
+ * List command for GSD-OpenCode CLI.
3
+ *
4
+ * This module provides the list functionality to display installation status,
5
+ * showing version, location, and scope for global and/or local installations.
6
+ *
7
+ * Implements requirements:
8
+ * - CLI-06: User can run gsd-opencode list to show installed version and location
9
+ * - LIST-01: List shows currently installed version
10
+ * - LIST-02: List shows installation location (global or local path)
11
+ * - LIST-03: List shows installation scope (global vs local)
12
+ * - LIST-04: List handles case when not installed with appropriate message
13
+ * - ERROR-03: All commands support --verbose flag for detailed debugging output
14
+ * - ERROR-06: CLI shows consistent branding and formatted output using colors
15
+ *
16
+ * @module list
17
+ */
18
+
19
+ import { ScopeManager } from '../services/scope-manager.js';
20
+ import { ConfigManager } from '../services/config.js';
21
+ import { logger, setVerbose } from '../utils/logger.js';
22
+ import { ERROR_CODES } from '../../lib/constants.js';
23
+
24
+ /**
25
+ * Displays installation information for a single scope.
26
+ *
27
+ * @param {Object} info - Installation information object
28
+ * @param {boolean} info.installed - Whether GSD-OpenCode is installed
29
+ * @param {string|null} info.version - The installed version
30
+ * @param {string} info.location - Absolute path to installation directory
31
+ * @param {string} info.scope - 'global' or 'local'
32
+ * @param {string} info.pathPrefix - Display-friendly path
33
+ * @private
34
+ */
35
+ function displayInstallationInfo(info) {
36
+ if (info.installed) {
37
+ logger.info(`Scope: ${info.scope}`);
38
+ logger.info(`Location: ${info.pathPrefix}`);
39
+ logger.info(`Version: ${info.version || 'unknown'}`);
40
+ } else {
41
+ logger.info('Not installed');
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Displays a separator line.
47
+ *
48
+ * @private
49
+ */
50
+ function displaySeparator() {
51
+ logger.dim('================================');
52
+ }
53
+
54
+ /**
55
+ * Checks and displays installation status for a single scope.
56
+ *
57
+ * @param {string} scope - 'global' or 'local'
58
+ * @param {Object} options - Options
59
+ * @param {boolean} options.verbose - Enable verbose output
60
+ * @returns {Promise<Object>} Installation info object
61
+ * @private
62
+ */
63
+ async function checkScope(scope, options = {}) {
64
+ const scopeManager = new ScopeManager({ scope });
65
+ const config = new ConfigManager(scopeManager);
66
+
67
+ logger.debug(`Checking ${scope} installation...`);
68
+
69
+ try {
70
+ const info = await config.getInstallationInfo();
71
+
72
+ if (options.verbose) {
73
+ logger.debug(` Full path: ${info.location}`);
74
+ logger.debug(` VERSION file: ${info.location}/VERSION`);
75
+ }
76
+
77
+ return info;
78
+ } catch (error) {
79
+ logger.debug(`Error checking ${scope} scope: ${error.message}`);
80
+
81
+ // Return not installed on error
82
+ return {
83
+ installed: false,
84
+ version: null,
85
+ location: scopeManager.getTargetDir(),
86
+ scope: scope,
87
+ pathPrefix: scopeManager.getPathPrefix(),
88
+ error: error.message
89
+ };
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Lists installation status for all scopes.
95
+ *
96
+ * @param {Object} options - Command options
97
+ * @param {boolean} [options.global] - Check global installation only
98
+ * @param {boolean} [options.local] - Check local installation only
99
+ * @param {boolean} [options.verbose] - Enable verbose output
100
+ * @returns {Promise<Object>} Result with exit code
101
+ * @private
102
+ */
103
+ async function listAllScopes(options = {}) {
104
+ logger.heading('GSD-OpenCode Installation Status');
105
+ displaySeparator();
106
+
107
+ const scopesToCheck = [];
108
+
109
+ if (options.global) {
110
+ scopesToCheck.push('global');
111
+ } else if (options.local) {
112
+ scopesToCheck.push('local');
113
+ } else {
114
+ scopesToCheck.push('global', 'local');
115
+ }
116
+
117
+ const results = [];
118
+ let anyInstalled = false;
119
+ let hasError = false;
120
+
121
+ for (const scope of scopesToCheck) {
122
+ try {
123
+ const info = await checkScope(scope, options);
124
+ results.push(info);
125
+
126
+ if (info.installed) {
127
+ anyInstalled = true;
128
+ }
129
+
130
+ // Display this scope's status
131
+ if (scopesToCheck.length > 1) {
132
+ logger.dim('');
133
+ logger.heading(`${scope.charAt(0).toUpperCase() + scope.slice(1)} Installation`);
134
+ }
135
+
136
+ displayInstallationInfo(info);
137
+
138
+ if (options.verbose && info.error) {
139
+ logger.debug(`Error checking ${scope}: ${info.error}`);
140
+ }
141
+ } catch (error) {
142
+ hasError = true;
143
+ logger.error(`Failed to check ${scope} installation: ${error.message}`);
144
+
145
+ if (options.verbose) {
146
+ logger.debug(error.stack);
147
+ }
148
+ }
149
+ }
150
+
151
+ // Show "not installed anywhere" message if nothing found
152
+ if (!anyInstalled && !hasError) {
153
+ logger.dim('');
154
+ logger.dim('Not installed anywhere');
155
+ logger.dim('');
156
+ logger.info("Run 'gsd-opencode install' to install");
157
+ }
158
+
159
+ return {
160
+ exitCode: hasError ? ERROR_CODES.GENERAL_ERROR : ERROR_CODES.SUCCESS,
161
+ results,
162
+ anyInstalled
163
+ };
164
+ }
165
+
166
+ /**
167
+ * Handles errors with helpful messages.
168
+ *
169
+ * @param {Error} error - The error to handle
170
+ * @param {boolean} verbose - Whether verbose mode is enabled
171
+ * @returns {number} Exit code for the error
172
+ * @private
173
+ */
174
+ function handleError(error, verbose) {
175
+ if (verbose) {
176
+ logger.debug(`Error details: ${error.stack || error.message}`);
177
+ logger.debug(`Error code: ${error.code}`);
178
+ }
179
+
180
+ // Check for permission errors
181
+ if (error.code === 'EACCES') {
182
+ logger.error('Permission denied: Cannot access installation directory');
183
+ logger.dim('');
184
+ logger.dim('Suggestion: Check directory permissions or run with appropriate privileges.');
185
+ return ERROR_CODES.PERMISSION_ERROR;
186
+ }
187
+
188
+ // Generic error
189
+ logger.error(`Failed to list installation status: ${error.message}`);
190
+
191
+ if (!verbose) {
192
+ logger.dim('');
193
+ logger.dim('Suggestion: Run with --verbose for detailed error information');
194
+ }
195
+
196
+ return ERROR_CODES.GENERAL_ERROR;
197
+ }
198
+
199
+ /**
200
+ * Main list command function.
201
+ *
202
+ * Displays installation status for GSD-OpenCode. Shows version, location,
203
+ * and scope information for installed instances, or "Not installed" message
204
+ * when nothing is found.
205
+ *
206
+ * @param {Object} options - Command options
207
+ * @param {boolean} [options.global] - Show global installation only
208
+ * @param {boolean} [options.local] - Show local installation only
209
+ * @param {boolean} [options.verbose] - Enable verbose output
210
+ * @returns {Promise<number>} Exit code (0 for success, non-zero for errors)
211
+ *
212
+ * @example
213
+ * // List all installations
214
+ * await listCommand({});
215
+ *
216
+ * // List global installation only
217
+ * await listCommand({ global: true });
218
+ *
219
+ * // List local installation only
220
+ * await listCommand({ local: true });
221
+ *
222
+ * // List with verbose output
223
+ * await listCommand({ verbose: true });
224
+ */
225
+ export async function listCommand(options = {}) {
226
+ // Set verbose mode early
227
+ const verbose = options.verbose || false;
228
+ setVerbose(verbose);
229
+
230
+ logger.debug('Starting list command');
231
+ logger.debug(`Options: global=${options.global}, local=${options.local}, verbose=${verbose}`);
232
+
233
+ try {
234
+ const result = await listAllScopes(options);
235
+ return result.exitCode;
236
+
237
+ } catch (error) {
238
+ // Handle Ctrl+C
239
+ if (error.name === 'AbortPromptError' || error.message?.includes('cancel')) {
240
+ logger.info('\nCommand cancelled by user');
241
+ return ERROR_CODES.INTERRUPTED;
242
+ }
243
+
244
+ // Handle all other errors
245
+ return handleError(error, verbose);
246
+ }
247
+ }
248
+
249
+ /**
250
+ * Default export for the list command.
251
+ *
252
+ * @example
253
+ * import listCommand from './commands/list.js';
254
+ * await listCommand({ global: true });
255
+ */
256
+ export default listCommand;