@fission-ai/openspec 0.16.0 → 0.17.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/README.md +21 -14
- package/dist/cli/index.js +67 -2
- package/dist/commands/change.js +4 -3
- package/dist/commands/completion.d.ts +72 -0
- package/dist/commands/completion.js +221 -0
- package/dist/commands/config.d.ts +8 -0
- package/dist/commands/config.js +198 -0
- package/dist/commands/show.js +3 -2
- package/dist/commands/spec.js +4 -3
- package/dist/commands/validate.js +21 -2
- package/dist/core/archive.js +4 -1
- package/dist/core/completions/command-registry.d.ts +7 -0
- package/dist/core/completions/command-registry.js +362 -0
- package/dist/core/completions/completion-provider.d.ts +60 -0
- package/dist/core/completions/completion-provider.js +102 -0
- package/dist/core/completions/factory.d.ts +51 -0
- package/dist/core/completions/factory.js +57 -0
- package/dist/core/completions/generators/zsh-generator.d.ts +58 -0
- package/dist/core/completions/generators/zsh-generator.js +319 -0
- package/dist/core/completions/installers/zsh-installer.d.ts +136 -0
- package/dist/core/completions/installers/zsh-installer.js +449 -0
- package/dist/core/completions/types.d.ts +78 -0
- package/dist/core/completions/types.js +2 -0
- package/dist/core/config-schema.d.ts +76 -0
- package/dist/core/config-schema.js +200 -0
- package/dist/core/configurators/slash/opencode.js +0 -3
- package/dist/core/global-config.d.ts +29 -0
- package/dist/core/global-config.js +87 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +2 -1
- package/dist/utils/file-system.js +19 -3
- package/dist/utils/interactive.d.ts +12 -1
- package/dist/utils/interactive.js +7 -2
- package/dist/utils/item-discovery.d.ts +1 -0
- package/dist/utils/item-discovery.js +23 -0
- package/dist/utils/shell-detection.d.ts +20 -0
- package/dist/utils/shell-detection.js +41 -0
- package/package.json +7 -1
- package/scripts/postinstall.js +147 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common flags used across multiple commands
|
|
3
|
+
*/
|
|
4
|
+
const COMMON_FLAGS = {
|
|
5
|
+
json: {
|
|
6
|
+
name: 'json',
|
|
7
|
+
description: 'Output as JSON',
|
|
8
|
+
},
|
|
9
|
+
jsonValidation: {
|
|
10
|
+
name: 'json',
|
|
11
|
+
description: 'Output validation results as JSON',
|
|
12
|
+
},
|
|
13
|
+
strict: {
|
|
14
|
+
name: 'strict',
|
|
15
|
+
description: 'Enable strict validation mode',
|
|
16
|
+
},
|
|
17
|
+
noInteractive: {
|
|
18
|
+
name: 'no-interactive',
|
|
19
|
+
description: 'Disable interactive prompts',
|
|
20
|
+
},
|
|
21
|
+
type: {
|
|
22
|
+
name: 'type',
|
|
23
|
+
description: 'Specify item type when ambiguous',
|
|
24
|
+
takesValue: true,
|
|
25
|
+
values: ['change', 'spec'],
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Registry of all OpenSpec CLI commands with their flags and metadata.
|
|
30
|
+
* This registry is used to generate shell completion scripts.
|
|
31
|
+
*/
|
|
32
|
+
export const COMMAND_REGISTRY = [
|
|
33
|
+
{
|
|
34
|
+
name: 'init',
|
|
35
|
+
description: 'Initialize OpenSpec in your project',
|
|
36
|
+
acceptsPositional: true,
|
|
37
|
+
positionalType: 'path',
|
|
38
|
+
flags: [
|
|
39
|
+
{
|
|
40
|
+
name: 'tools',
|
|
41
|
+
description: 'Configure AI tools non-interactively (e.g., "all", "none", or comma-separated tool IDs)',
|
|
42
|
+
takesValue: true,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'update',
|
|
48
|
+
description: 'Update OpenSpec instruction files',
|
|
49
|
+
acceptsPositional: true,
|
|
50
|
+
positionalType: 'path',
|
|
51
|
+
flags: [],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'list',
|
|
55
|
+
description: 'List items (changes by default, or specs with --specs)',
|
|
56
|
+
flags: [
|
|
57
|
+
{
|
|
58
|
+
name: 'specs',
|
|
59
|
+
description: 'List specs instead of changes',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'changes',
|
|
63
|
+
description: 'List changes explicitly (default)',
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'view',
|
|
69
|
+
description: 'Display an interactive dashboard of specs and changes',
|
|
70
|
+
flags: [],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'validate',
|
|
74
|
+
description: 'Validate changes and specs',
|
|
75
|
+
acceptsPositional: true,
|
|
76
|
+
positionalType: 'change-or-spec-id',
|
|
77
|
+
flags: [
|
|
78
|
+
{
|
|
79
|
+
name: 'all',
|
|
80
|
+
description: 'Validate all changes and specs',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: 'changes',
|
|
84
|
+
description: 'Validate all changes',
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'specs',
|
|
88
|
+
description: 'Validate all specs',
|
|
89
|
+
},
|
|
90
|
+
COMMON_FLAGS.type,
|
|
91
|
+
COMMON_FLAGS.strict,
|
|
92
|
+
COMMON_FLAGS.jsonValidation,
|
|
93
|
+
{
|
|
94
|
+
name: 'concurrency',
|
|
95
|
+
description: 'Max concurrent validations (defaults to env OPENSPEC_CONCURRENCY or 6)',
|
|
96
|
+
takesValue: true,
|
|
97
|
+
},
|
|
98
|
+
COMMON_FLAGS.noInteractive,
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: 'show',
|
|
103
|
+
description: 'Show a change or spec',
|
|
104
|
+
acceptsPositional: true,
|
|
105
|
+
positionalType: 'change-or-spec-id',
|
|
106
|
+
flags: [
|
|
107
|
+
COMMON_FLAGS.json,
|
|
108
|
+
COMMON_FLAGS.type,
|
|
109
|
+
COMMON_FLAGS.noInteractive,
|
|
110
|
+
{
|
|
111
|
+
name: 'deltas-only',
|
|
112
|
+
description: 'Show only deltas (JSON only, change-specific)',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: 'requirements-only',
|
|
116
|
+
description: 'Alias for --deltas-only (deprecated, change-specific)',
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: 'requirements',
|
|
120
|
+
description: 'Show only requirements, exclude scenarios (JSON only, spec-specific)',
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: 'no-scenarios',
|
|
124
|
+
description: 'Exclude scenario content (JSON only, spec-specific)',
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: 'requirement',
|
|
128
|
+
short: 'r',
|
|
129
|
+
description: 'Show specific requirement by ID (JSON only, spec-specific)',
|
|
130
|
+
takesValue: true,
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: 'archive',
|
|
136
|
+
description: 'Archive a completed change and update main specs',
|
|
137
|
+
acceptsPositional: true,
|
|
138
|
+
positionalType: 'change-id',
|
|
139
|
+
flags: [
|
|
140
|
+
{
|
|
141
|
+
name: 'yes',
|
|
142
|
+
short: 'y',
|
|
143
|
+
description: 'Skip confirmation prompts',
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: 'skip-specs',
|
|
147
|
+
description: 'Skip spec update operations',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: 'no-validate',
|
|
151
|
+
description: 'Skip validation (not recommended)',
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: 'change',
|
|
157
|
+
description: 'Manage OpenSpec change proposals (deprecated)',
|
|
158
|
+
flags: [],
|
|
159
|
+
subcommands: [
|
|
160
|
+
{
|
|
161
|
+
name: 'show',
|
|
162
|
+
description: 'Show a change proposal',
|
|
163
|
+
acceptsPositional: true,
|
|
164
|
+
positionalType: 'change-id',
|
|
165
|
+
flags: [
|
|
166
|
+
COMMON_FLAGS.json,
|
|
167
|
+
{
|
|
168
|
+
name: 'deltas-only',
|
|
169
|
+
description: 'Show only deltas (JSON only)',
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: 'requirements-only',
|
|
173
|
+
description: 'Alias for --deltas-only (deprecated)',
|
|
174
|
+
},
|
|
175
|
+
COMMON_FLAGS.noInteractive,
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
name: 'list',
|
|
180
|
+
description: 'List all active changes (deprecated)',
|
|
181
|
+
flags: [
|
|
182
|
+
COMMON_FLAGS.json,
|
|
183
|
+
{
|
|
184
|
+
name: 'long',
|
|
185
|
+
description: 'Show id and title with counts',
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: 'validate',
|
|
191
|
+
description: 'Validate a change proposal',
|
|
192
|
+
acceptsPositional: true,
|
|
193
|
+
positionalType: 'change-id',
|
|
194
|
+
flags: [
|
|
195
|
+
COMMON_FLAGS.strict,
|
|
196
|
+
COMMON_FLAGS.jsonValidation,
|
|
197
|
+
COMMON_FLAGS.noInteractive,
|
|
198
|
+
],
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: 'spec',
|
|
204
|
+
description: 'Manage OpenSpec specifications',
|
|
205
|
+
flags: [],
|
|
206
|
+
subcommands: [
|
|
207
|
+
{
|
|
208
|
+
name: 'show',
|
|
209
|
+
description: 'Show a specification',
|
|
210
|
+
acceptsPositional: true,
|
|
211
|
+
positionalType: 'spec-id',
|
|
212
|
+
flags: [
|
|
213
|
+
COMMON_FLAGS.json,
|
|
214
|
+
{
|
|
215
|
+
name: 'requirements',
|
|
216
|
+
description: 'Show only requirements, exclude scenarios (JSON only)',
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: 'no-scenarios',
|
|
220
|
+
description: 'Exclude scenario content (JSON only)',
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
name: 'requirement',
|
|
224
|
+
short: 'r',
|
|
225
|
+
description: 'Show specific requirement by ID (JSON only)',
|
|
226
|
+
takesValue: true,
|
|
227
|
+
},
|
|
228
|
+
COMMON_FLAGS.noInteractive,
|
|
229
|
+
],
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
name: 'list',
|
|
233
|
+
description: 'List all specifications',
|
|
234
|
+
flags: [
|
|
235
|
+
COMMON_FLAGS.json,
|
|
236
|
+
{
|
|
237
|
+
name: 'long',
|
|
238
|
+
description: 'Show id and title with counts',
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
name: 'validate',
|
|
244
|
+
description: 'Validate a specification',
|
|
245
|
+
acceptsPositional: true,
|
|
246
|
+
positionalType: 'spec-id',
|
|
247
|
+
flags: [
|
|
248
|
+
COMMON_FLAGS.strict,
|
|
249
|
+
COMMON_FLAGS.jsonValidation,
|
|
250
|
+
COMMON_FLAGS.noInteractive,
|
|
251
|
+
],
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
name: 'completion',
|
|
257
|
+
description: 'Manage shell completions for OpenSpec CLI',
|
|
258
|
+
flags: [],
|
|
259
|
+
subcommands: [
|
|
260
|
+
{
|
|
261
|
+
name: 'generate',
|
|
262
|
+
description: 'Generate completion script for a shell (outputs to stdout)',
|
|
263
|
+
acceptsPositional: true,
|
|
264
|
+
positionalType: 'shell',
|
|
265
|
+
flags: [],
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: 'install',
|
|
269
|
+
description: 'Install completion script for a shell',
|
|
270
|
+
acceptsPositional: true,
|
|
271
|
+
positionalType: 'shell',
|
|
272
|
+
flags: [
|
|
273
|
+
{
|
|
274
|
+
name: 'verbose',
|
|
275
|
+
description: 'Show detailed installation output',
|
|
276
|
+
},
|
|
277
|
+
],
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
name: 'uninstall',
|
|
281
|
+
description: 'Uninstall completion script for a shell',
|
|
282
|
+
acceptsPositional: true,
|
|
283
|
+
positionalType: 'shell',
|
|
284
|
+
flags: [],
|
|
285
|
+
},
|
|
286
|
+
],
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
name: 'config',
|
|
290
|
+
description: 'View and modify global OpenSpec configuration',
|
|
291
|
+
flags: [
|
|
292
|
+
{
|
|
293
|
+
name: 'scope',
|
|
294
|
+
description: 'Config scope (only "global" supported currently)',
|
|
295
|
+
takesValue: true,
|
|
296
|
+
values: ['global'],
|
|
297
|
+
},
|
|
298
|
+
],
|
|
299
|
+
subcommands: [
|
|
300
|
+
{
|
|
301
|
+
name: 'path',
|
|
302
|
+
description: 'Show config file location',
|
|
303
|
+
flags: [],
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
name: 'list',
|
|
307
|
+
description: 'Show all current settings',
|
|
308
|
+
flags: [
|
|
309
|
+
COMMON_FLAGS.json,
|
|
310
|
+
],
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
name: 'get',
|
|
314
|
+
description: 'Get a specific value (raw, scriptable)',
|
|
315
|
+
acceptsPositional: true,
|
|
316
|
+
flags: [],
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
name: 'set',
|
|
320
|
+
description: 'Set a value (auto-coerce types)',
|
|
321
|
+
acceptsPositional: true,
|
|
322
|
+
flags: [
|
|
323
|
+
{
|
|
324
|
+
name: 'string',
|
|
325
|
+
description: 'Force value to be stored as string',
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
name: 'allow-unknown',
|
|
329
|
+
description: 'Allow setting unknown keys',
|
|
330
|
+
},
|
|
331
|
+
],
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
name: 'unset',
|
|
335
|
+
description: 'Remove a key (revert to default)',
|
|
336
|
+
acceptsPositional: true,
|
|
337
|
+
flags: [],
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
name: 'reset',
|
|
341
|
+
description: 'Reset configuration to defaults',
|
|
342
|
+
flags: [
|
|
343
|
+
{
|
|
344
|
+
name: 'all',
|
|
345
|
+
description: 'Reset all configuration (required)',
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
name: 'yes',
|
|
349
|
+
short: 'y',
|
|
350
|
+
description: 'Skip confirmation prompts',
|
|
351
|
+
},
|
|
352
|
+
],
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
name: 'edit',
|
|
356
|
+
description: 'Open config in $EDITOR',
|
|
357
|
+
flags: [],
|
|
358
|
+
},
|
|
359
|
+
],
|
|
360
|
+
},
|
|
361
|
+
];
|
|
362
|
+
//# sourceMappingURL=command-registry.js.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provides dynamic completion suggestions for OpenSpec items (changes and specs).
|
|
3
|
+
* Implements a 2-second cache to avoid excessive file system operations during
|
|
4
|
+
* tab completion.
|
|
5
|
+
*/
|
|
6
|
+
export declare class CompletionProvider {
|
|
7
|
+
private readonly cacheTTLMs;
|
|
8
|
+
private readonly projectRoot;
|
|
9
|
+
private readonly cacheTTL;
|
|
10
|
+
private changeCache;
|
|
11
|
+
private specCache;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new completion provider
|
|
14
|
+
*
|
|
15
|
+
* @param cacheTTLMs - Cache time-to-live in milliseconds (default: 2000ms)
|
|
16
|
+
* @param projectRoot - Project root directory (default: process.cwd())
|
|
17
|
+
*/
|
|
18
|
+
constructor(cacheTTLMs?: number, projectRoot?: string);
|
|
19
|
+
/**
|
|
20
|
+
* Get all active change IDs for completion
|
|
21
|
+
*
|
|
22
|
+
* @returns Array of change IDs
|
|
23
|
+
*/
|
|
24
|
+
getChangeIds(): Promise<string[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Get all spec IDs for completion
|
|
27
|
+
*
|
|
28
|
+
* @returns Array of spec IDs
|
|
29
|
+
*/
|
|
30
|
+
getSpecIds(): Promise<string[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Get both change and spec IDs for completion
|
|
33
|
+
*
|
|
34
|
+
* @returns Object with changeIds and specIds arrays
|
|
35
|
+
*/
|
|
36
|
+
getAllIds(): Promise<{
|
|
37
|
+
changeIds: string[];
|
|
38
|
+
specIds: string[];
|
|
39
|
+
}>;
|
|
40
|
+
/**
|
|
41
|
+
* Clear all cached data
|
|
42
|
+
*/
|
|
43
|
+
clearCache(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Get cache statistics for debugging
|
|
46
|
+
*
|
|
47
|
+
* @returns Cache status information
|
|
48
|
+
*/
|
|
49
|
+
getCacheStats(): {
|
|
50
|
+
changeCache: {
|
|
51
|
+
valid: boolean;
|
|
52
|
+
age?: number;
|
|
53
|
+
};
|
|
54
|
+
specCache: {
|
|
55
|
+
valid: boolean;
|
|
56
|
+
age?: number;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=completion-provider.d.ts.map
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { getActiveChangeIds, getSpecIds } from '../../utils/item-discovery.js';
|
|
2
|
+
/**
|
|
3
|
+
* Provides dynamic completion suggestions for OpenSpec items (changes and specs).
|
|
4
|
+
* Implements a 2-second cache to avoid excessive file system operations during
|
|
5
|
+
* tab completion.
|
|
6
|
+
*/
|
|
7
|
+
export class CompletionProvider {
|
|
8
|
+
cacheTTLMs;
|
|
9
|
+
projectRoot;
|
|
10
|
+
cacheTTL;
|
|
11
|
+
changeCache = null;
|
|
12
|
+
specCache = null;
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new completion provider
|
|
15
|
+
*
|
|
16
|
+
* @param cacheTTLMs - Cache time-to-live in milliseconds (default: 2000ms)
|
|
17
|
+
* @param projectRoot - Project root directory (default: process.cwd())
|
|
18
|
+
*/
|
|
19
|
+
constructor(cacheTTLMs = 2000, projectRoot = process.cwd()) {
|
|
20
|
+
this.cacheTTLMs = cacheTTLMs;
|
|
21
|
+
this.projectRoot = projectRoot;
|
|
22
|
+
this.cacheTTL = cacheTTLMs;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get all active change IDs for completion
|
|
26
|
+
*
|
|
27
|
+
* @returns Array of change IDs
|
|
28
|
+
*/
|
|
29
|
+
async getChangeIds() {
|
|
30
|
+
const now = Date.now();
|
|
31
|
+
// Check if cache is valid
|
|
32
|
+
if (this.changeCache && now - this.changeCache.timestamp < this.cacheTTL) {
|
|
33
|
+
return this.changeCache.data;
|
|
34
|
+
}
|
|
35
|
+
// Fetch fresh data
|
|
36
|
+
const changeIds = await getActiveChangeIds(this.projectRoot);
|
|
37
|
+
// Update cache
|
|
38
|
+
this.changeCache = {
|
|
39
|
+
data: changeIds,
|
|
40
|
+
timestamp: now,
|
|
41
|
+
};
|
|
42
|
+
return changeIds;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get all spec IDs for completion
|
|
46
|
+
*
|
|
47
|
+
* @returns Array of spec IDs
|
|
48
|
+
*/
|
|
49
|
+
async getSpecIds() {
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
// Check if cache is valid
|
|
52
|
+
if (this.specCache && now - this.specCache.timestamp < this.cacheTTL) {
|
|
53
|
+
return this.specCache.data;
|
|
54
|
+
}
|
|
55
|
+
// Fetch fresh data
|
|
56
|
+
const specIds = await getSpecIds(this.projectRoot);
|
|
57
|
+
// Update cache
|
|
58
|
+
this.specCache = {
|
|
59
|
+
data: specIds,
|
|
60
|
+
timestamp: now,
|
|
61
|
+
};
|
|
62
|
+
return specIds;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get both change and spec IDs for completion
|
|
66
|
+
*
|
|
67
|
+
* @returns Object with changeIds and specIds arrays
|
|
68
|
+
*/
|
|
69
|
+
async getAllIds() {
|
|
70
|
+
const [changeIds, specIds] = await Promise.all([
|
|
71
|
+
this.getChangeIds(),
|
|
72
|
+
this.getSpecIds(),
|
|
73
|
+
]);
|
|
74
|
+
return { changeIds, specIds };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Clear all cached data
|
|
78
|
+
*/
|
|
79
|
+
clearCache() {
|
|
80
|
+
this.changeCache = null;
|
|
81
|
+
this.specCache = null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get cache statistics for debugging
|
|
85
|
+
*
|
|
86
|
+
* @returns Cache status information
|
|
87
|
+
*/
|
|
88
|
+
getCacheStats() {
|
|
89
|
+
const now = Date.now();
|
|
90
|
+
return {
|
|
91
|
+
changeCache: {
|
|
92
|
+
valid: this.changeCache !== null && now - this.changeCache.timestamp < this.cacheTTL,
|
|
93
|
+
age: this.changeCache ? now - this.changeCache.timestamp : undefined,
|
|
94
|
+
},
|
|
95
|
+
specCache: {
|
|
96
|
+
valid: this.specCache !== null && now - this.specCache.timestamp < this.cacheTTL,
|
|
97
|
+
age: this.specCache ? now - this.specCache.timestamp : undefined,
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=completion-provider.js.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { CompletionGenerator } from './types.js';
|
|
2
|
+
import { InstallationResult } from './installers/zsh-installer.js';
|
|
3
|
+
import { SupportedShell } from '../../utils/shell-detection.js';
|
|
4
|
+
/**
|
|
5
|
+
* Interface for completion installers
|
|
6
|
+
*/
|
|
7
|
+
export interface CompletionInstaller {
|
|
8
|
+
install(script: string): Promise<InstallationResult>;
|
|
9
|
+
uninstall(): Promise<{
|
|
10
|
+
success: boolean;
|
|
11
|
+
message: string;
|
|
12
|
+
}>;
|
|
13
|
+
}
|
|
14
|
+
export type { InstallationResult };
|
|
15
|
+
/**
|
|
16
|
+
* Factory for creating completion generators and installers
|
|
17
|
+
* This design makes it easy to add support for additional shells
|
|
18
|
+
*/
|
|
19
|
+
export declare class CompletionFactory {
|
|
20
|
+
private static readonly SUPPORTED_SHELLS;
|
|
21
|
+
/**
|
|
22
|
+
* Create a completion generator for the specified shell
|
|
23
|
+
*
|
|
24
|
+
* @param shell - The target shell
|
|
25
|
+
* @returns CompletionGenerator instance
|
|
26
|
+
* @throws Error if shell is not supported
|
|
27
|
+
*/
|
|
28
|
+
static createGenerator(shell: SupportedShell): CompletionGenerator;
|
|
29
|
+
/**
|
|
30
|
+
* Create a completion installer for the specified shell
|
|
31
|
+
*
|
|
32
|
+
* @param shell - The target shell
|
|
33
|
+
* @returns CompletionInstaller instance
|
|
34
|
+
* @throws Error if shell is not supported
|
|
35
|
+
*/
|
|
36
|
+
static createInstaller(shell: SupportedShell): CompletionInstaller;
|
|
37
|
+
/**
|
|
38
|
+
* Check if a shell is supported
|
|
39
|
+
*
|
|
40
|
+
* @param shell - The shell to check
|
|
41
|
+
* @returns true if the shell is supported
|
|
42
|
+
*/
|
|
43
|
+
static isSupported(shell: string): shell is SupportedShell;
|
|
44
|
+
/**
|
|
45
|
+
* Get list of all supported shells
|
|
46
|
+
*
|
|
47
|
+
* @returns Array of supported shell names
|
|
48
|
+
*/
|
|
49
|
+
static getSupportedShells(): SupportedShell[];
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ZshGenerator } from './generators/zsh-generator.js';
|
|
2
|
+
import { ZshInstaller } from './installers/zsh-installer.js';
|
|
3
|
+
/**
|
|
4
|
+
* Factory for creating completion generators and installers
|
|
5
|
+
* This design makes it easy to add support for additional shells
|
|
6
|
+
*/
|
|
7
|
+
export class CompletionFactory {
|
|
8
|
+
static SUPPORTED_SHELLS = ['zsh'];
|
|
9
|
+
/**
|
|
10
|
+
* Create a completion generator for the specified shell
|
|
11
|
+
*
|
|
12
|
+
* @param shell - The target shell
|
|
13
|
+
* @returns CompletionGenerator instance
|
|
14
|
+
* @throws Error if shell is not supported
|
|
15
|
+
*/
|
|
16
|
+
static createGenerator(shell) {
|
|
17
|
+
switch (shell) {
|
|
18
|
+
case 'zsh':
|
|
19
|
+
return new ZshGenerator();
|
|
20
|
+
default:
|
|
21
|
+
throw new Error(`Unsupported shell: ${shell}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Create a completion installer for the specified shell
|
|
26
|
+
*
|
|
27
|
+
* @param shell - The target shell
|
|
28
|
+
* @returns CompletionInstaller instance
|
|
29
|
+
* @throws Error if shell is not supported
|
|
30
|
+
*/
|
|
31
|
+
static createInstaller(shell) {
|
|
32
|
+
switch (shell) {
|
|
33
|
+
case 'zsh':
|
|
34
|
+
return new ZshInstaller();
|
|
35
|
+
default:
|
|
36
|
+
throw new Error(`Unsupported shell: ${shell}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Check if a shell is supported
|
|
41
|
+
*
|
|
42
|
+
* @param shell - The shell to check
|
|
43
|
+
* @returns true if the shell is supported
|
|
44
|
+
*/
|
|
45
|
+
static isSupported(shell) {
|
|
46
|
+
return this.SUPPORTED_SHELLS.includes(shell);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get list of all supported shells
|
|
50
|
+
*
|
|
51
|
+
* @returns Array of supported shell names
|
|
52
|
+
*/
|
|
53
|
+
static getSupportedShells() {
|
|
54
|
+
return [...this.SUPPORTED_SHELLS];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { CompletionGenerator, CommandDefinition } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates Zsh completion scripts for the OpenSpec CLI.
|
|
4
|
+
* Follows Zsh completion system conventions using the _openspec function.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ZshGenerator implements CompletionGenerator {
|
|
7
|
+
readonly shell: "zsh";
|
|
8
|
+
/**
|
|
9
|
+
* Generate a Zsh completion script
|
|
10
|
+
*
|
|
11
|
+
* @param commands - Command definitions to generate completions for
|
|
12
|
+
* @returns Zsh completion script as a string
|
|
13
|
+
*/
|
|
14
|
+
generate(commands: CommandDefinition[]): string;
|
|
15
|
+
/**
|
|
16
|
+
* Generate a single completion function
|
|
17
|
+
*
|
|
18
|
+
* @param functionName - Name of the completion function
|
|
19
|
+
* @param varName - Name of the local array variable
|
|
20
|
+
* @param varLabel - Label for the completion items
|
|
21
|
+
* @param commandLines - Command line(s) to populate the array
|
|
22
|
+
* @param comment - Optional comment describing the function
|
|
23
|
+
*/
|
|
24
|
+
private generateCompletionFunction;
|
|
25
|
+
/**
|
|
26
|
+
* Generate dynamic completion helper functions for change and spec IDs
|
|
27
|
+
*/
|
|
28
|
+
private generateDynamicCompletionHelpers;
|
|
29
|
+
/**
|
|
30
|
+
* Generate completion function for a specific command
|
|
31
|
+
*/
|
|
32
|
+
private generateCommandFunction;
|
|
33
|
+
/**
|
|
34
|
+
* Generate completion function for a subcommand
|
|
35
|
+
*/
|
|
36
|
+
private generateSubcommandFunction;
|
|
37
|
+
/**
|
|
38
|
+
* Generate flag specification for _arguments
|
|
39
|
+
*/
|
|
40
|
+
private generateFlagSpec;
|
|
41
|
+
/**
|
|
42
|
+
* Generate positional argument specification
|
|
43
|
+
*/
|
|
44
|
+
private generatePositionalSpec;
|
|
45
|
+
/**
|
|
46
|
+
* Escape special characters in descriptions
|
|
47
|
+
*/
|
|
48
|
+
private escapeDescription;
|
|
49
|
+
/**
|
|
50
|
+
* Escape special characters in values
|
|
51
|
+
*/
|
|
52
|
+
private escapeValue;
|
|
53
|
+
/**
|
|
54
|
+
* Sanitize command names for use in function names
|
|
55
|
+
*/
|
|
56
|
+
private sanitizeFunctionName;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=zsh-generator.d.ts.map
|