@wundr.io/cli 1.0.0 → 1.0.2-dev.20260530174250.ef0ec927

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 (230) hide show
  1. package/README.md +696 -280
  2. package/bin/wundr.js +13 -5
  3. package/package.json +30 -9
  4. package/src/ai/ai-service.ts +6 -4
  5. package/src/ai/claude-client.ts +6 -2
  6. package/src/ai/conversation-manager.ts +12 -5
  7. package/src/cli.ts +42 -13
  8. package/src/commands/ai.ts +340 -64
  9. package/src/commands/alignment.ts +1212 -0
  10. package/src/commands/analyze-optimized.ts +371 -33
  11. package/src/commands/analyze.ts +8 -6
  12. package/src/commands/batch.ts +166 -26
  13. package/src/commands/chat.ts +20 -10
  14. package/src/commands/claude-init.ts +31 -27
  15. package/src/commands/claude-setup.ts +761 -81
  16. package/src/commands/computer-setup.ts +524 -12
  17. package/src/commands/create-command.ts +3 -3
  18. package/src/commands/create.ts +9 -6
  19. package/src/commands/dashboard.ts +11 -6
  20. package/src/commands/govern.ts +11 -6
  21. package/src/commands/governance.ts +1005 -0
  22. package/src/commands/guardian.ts +887 -0
  23. package/src/commands/init.ts +104 -11
  24. package/src/commands/orchestrator.ts +789 -0
  25. package/src/commands/performance-optimizer.ts +15 -10
  26. package/src/commands/plugins.ts +8 -5
  27. package/src/commands/project-update.ts +1156 -0
  28. package/src/commands/rag.ts +1011 -0
  29. package/src/commands/session.ts +631 -0
  30. package/src/commands/setup.ts +42 -344
  31. package/src/commands/test-init.ts +3 -2
  32. package/src/commands/test.ts +3 -2
  33. package/src/commands/watch.ts +21 -11
  34. package/src/commands/worktree.ts +1057 -0
  35. package/src/context/context-manager.ts +5 -2
  36. package/src/context/session-manager.ts +18 -7
  37. package/src/framework/command-interface.ts +520 -0
  38. package/src/framework/command-registry.ts +942 -0
  39. package/src/framework/completion-exporter.ts +383 -0
  40. package/src/framework/debug-logger.ts +519 -0
  41. package/src/framework/error-handler.ts +867 -0
  42. package/src/framework/help-generator.ts +540 -0
  43. package/src/framework/index.ts +169 -0
  44. package/src/framework/interactive-repl.ts +703 -0
  45. package/src/framework/output-formatter.ts +834 -0
  46. package/src/framework/progress-manager.ts +539 -0
  47. package/src/index.ts +3 -2
  48. package/src/interactive/interactive-mode.ts +14 -7
  49. package/src/lib/conflict-resolution.ts +818 -0
  50. package/src/lib/merge-strategy.ts +550 -0
  51. package/src/lib/safety-mechanisms.ts +451 -0
  52. package/src/lib/state-detection.ts +1030 -0
  53. package/src/nlp/command-mapper.ts +8 -3
  54. package/src/nlp/command-parser.ts +5 -2
  55. package/src/nlp/intent-parser.ts +23 -9
  56. package/src/plugins/plugin-manager.ts +50 -24
  57. package/src/tests/computer-setup-integration.test.ts +470 -0
  58. package/src/types/index.ts +1 -1
  59. package/src/types/modules.d.ts +425 -1
  60. package/src/utils/backup-rollback-manager.ts +366 -0
  61. package/src/utils/claude-config-installer.ts +823 -0
  62. package/src/utils/config-manager.ts +9 -6
  63. package/src/utils/error-handler.ts +3 -1
  64. package/src/utils/logger.ts +35 -12
  65. package/templates/batch/ci-cd.yaml +7 -7
  66. package/test-suites/api/health.spec.ts +20 -23
  67. package/test-suites/helpers/test-config.ts +14 -13
  68. package/test-suites/ui/accessibility.spec.ts +27 -22
  69. package/test-suites/ui/smoke.spec.ts +26 -21
  70. package/dist/ai/ai-service.d.ts +0 -152
  71. package/dist/ai/ai-service.d.ts.map +0 -1
  72. package/dist/ai/ai-service.js +0 -430
  73. package/dist/ai/ai-service.js.map +0 -1
  74. package/dist/ai/claude-client.d.ts +0 -130
  75. package/dist/ai/claude-client.d.ts.map +0 -1
  76. package/dist/ai/claude-client.js +0 -339
  77. package/dist/ai/claude-client.js.map +0 -1
  78. package/dist/ai/conversation-manager.d.ts +0 -164
  79. package/dist/ai/conversation-manager.d.ts.map +0 -1
  80. package/dist/ai/conversation-manager.js +0 -612
  81. package/dist/ai/conversation-manager.js.map +0 -1
  82. package/dist/ai/index.d.ts +0 -5
  83. package/dist/ai/index.d.ts.map +0 -1
  84. package/dist/ai/index.js +0 -8
  85. package/dist/ai/index.js.map +0 -1
  86. package/dist/cli.d.ts +0 -36
  87. package/dist/cli.d.ts.map +0 -1
  88. package/dist/cli.js +0 -173
  89. package/dist/cli.js.map +0 -1
  90. package/dist/commands/ai.d.ts +0 -89
  91. package/dist/commands/ai.d.ts.map +0 -1
  92. package/dist/commands/ai.js +0 -735
  93. package/dist/commands/ai.js.map +0 -1
  94. package/dist/commands/analyze-optimized.d.ts +0 -14
  95. package/dist/commands/analyze-optimized.d.ts.map +0 -1
  96. package/dist/commands/analyze-optimized.js +0 -437
  97. package/dist/commands/analyze-optimized.js.map +0 -1
  98. package/dist/commands/analyze.d.ts +0 -65
  99. package/dist/commands/analyze.d.ts.map +0 -1
  100. package/dist/commands/analyze.js +0 -435
  101. package/dist/commands/analyze.js.map +0 -1
  102. package/dist/commands/batch.d.ts +0 -71
  103. package/dist/commands/batch.d.ts.map +0 -1
  104. package/dist/commands/batch.js +0 -738
  105. package/dist/commands/batch.js.map +0 -1
  106. package/dist/commands/chat.d.ts +0 -71
  107. package/dist/commands/chat.d.ts.map +0 -1
  108. package/dist/commands/chat.js +0 -674
  109. package/dist/commands/chat.js.map +0 -1
  110. package/dist/commands/claude-init.d.ts +0 -28
  111. package/dist/commands/claude-init.d.ts.map +0 -1
  112. package/dist/commands/claude-init.js +0 -587
  113. package/dist/commands/claude-init.js.map +0 -1
  114. package/dist/commands/claude-setup.d.ts +0 -32
  115. package/dist/commands/claude-setup.d.ts.map +0 -1
  116. package/dist/commands/claude-setup.js +0 -570
  117. package/dist/commands/claude-setup.js.map +0 -1
  118. package/dist/commands/computer-setup-commands.d.ts +0 -39
  119. package/dist/commands/computer-setup-commands.d.ts.map +0 -1
  120. package/dist/commands/computer-setup-commands.js +0 -563
  121. package/dist/commands/computer-setup-commands.js.map +0 -1
  122. package/dist/commands/computer-setup.d.ts +0 -7
  123. package/dist/commands/computer-setup.d.ts.map +0 -1
  124. package/dist/commands/computer-setup.js +0 -481
  125. package/dist/commands/computer-setup.js.map +0 -1
  126. package/dist/commands/create-command.d.ts +0 -7
  127. package/dist/commands/create-command.d.ts.map +0 -1
  128. package/dist/commands/create-command.js +0 -158
  129. package/dist/commands/create-command.js.map +0 -1
  130. package/dist/commands/create.d.ts +0 -74
  131. package/dist/commands/create.d.ts.map +0 -1
  132. package/dist/commands/create.js +0 -556
  133. package/dist/commands/create.js.map +0 -1
  134. package/dist/commands/dashboard.d.ts +0 -91
  135. package/dist/commands/dashboard.d.ts.map +0 -1
  136. package/dist/commands/dashboard.js +0 -537
  137. package/dist/commands/dashboard.js.map +0 -1
  138. package/dist/commands/govern.d.ts +0 -70
  139. package/dist/commands/govern.d.ts.map +0 -1
  140. package/dist/commands/govern.js +0 -480
  141. package/dist/commands/govern.js.map +0 -1
  142. package/dist/commands/init.d.ts +0 -55
  143. package/dist/commands/init.d.ts.map +0 -1
  144. package/dist/commands/init.js +0 -584
  145. package/dist/commands/init.js.map +0 -1
  146. package/dist/commands/performance-optimizer.d.ts +0 -30
  147. package/dist/commands/performance-optimizer.d.ts.map +0 -1
  148. package/dist/commands/performance-optimizer.js +0 -649
  149. package/dist/commands/performance-optimizer.js.map +0 -1
  150. package/dist/commands/plugins.d.ts +0 -87
  151. package/dist/commands/plugins.d.ts.map +0 -1
  152. package/dist/commands/plugins.js +0 -685
  153. package/dist/commands/plugins.js.map +0 -1
  154. package/dist/commands/setup.d.ts +0 -29
  155. package/dist/commands/setup.d.ts.map +0 -1
  156. package/dist/commands/setup.js +0 -399
  157. package/dist/commands/setup.js.map +0 -1
  158. package/dist/commands/test-init.d.ts +0 -9
  159. package/dist/commands/test-init.d.ts.map +0 -1
  160. package/dist/commands/test-init.js +0 -222
  161. package/dist/commands/test-init.js.map +0 -1
  162. package/dist/commands/test.d.ts +0 -25
  163. package/dist/commands/test.d.ts.map +0 -1
  164. package/dist/commands/test.js +0 -217
  165. package/dist/commands/test.js.map +0 -1
  166. package/dist/commands/watch.d.ts +0 -76
  167. package/dist/commands/watch.d.ts.map +0 -1
  168. package/dist/commands/watch.js +0 -610
  169. package/dist/commands/watch.js.map +0 -1
  170. package/dist/context/context-manager.d.ts +0 -155
  171. package/dist/context/context-manager.d.ts.map +0 -1
  172. package/dist/context/context-manager.js +0 -383
  173. package/dist/context/context-manager.js.map +0 -1
  174. package/dist/context/index.d.ts +0 -3
  175. package/dist/context/index.d.ts.map +0 -1
  176. package/dist/context/index.js +0 -6
  177. package/dist/context/index.js.map +0 -1
  178. package/dist/context/session-manager.d.ts +0 -207
  179. package/dist/context/session-manager.d.ts.map +0 -1
  180. package/dist/context/session-manager.js +0 -682
  181. package/dist/context/session-manager.js.map +0 -1
  182. package/dist/index.d.ts +0 -8
  183. package/dist/index.d.ts.map +0 -1
  184. package/dist/index.js +0 -51
  185. package/dist/index.js.map +0 -1
  186. package/dist/interactive/interactive-mode.d.ts +0 -76
  187. package/dist/interactive/interactive-mode.d.ts.map +0 -1
  188. package/dist/interactive/interactive-mode.js +0 -730
  189. package/dist/interactive/interactive-mode.js.map +0 -1
  190. package/dist/nlp/command-mapper.d.ts +0 -174
  191. package/dist/nlp/command-mapper.d.ts.map +0 -1
  192. package/dist/nlp/command-mapper.js +0 -623
  193. package/dist/nlp/command-mapper.js.map +0 -1
  194. package/dist/nlp/command-parser.d.ts +0 -106
  195. package/dist/nlp/command-parser.d.ts.map +0 -1
  196. package/dist/nlp/command-parser.js +0 -416
  197. package/dist/nlp/command-parser.js.map +0 -1
  198. package/dist/nlp/index.d.ts +0 -5
  199. package/dist/nlp/index.d.ts.map +0 -1
  200. package/dist/nlp/index.js +0 -8
  201. package/dist/nlp/index.js.map +0 -1
  202. package/dist/nlp/intent-classifier.d.ts +0 -59
  203. package/dist/nlp/intent-classifier.d.ts.map +0 -1
  204. package/dist/nlp/intent-classifier.js +0 -384
  205. package/dist/nlp/intent-classifier.js.map +0 -1
  206. package/dist/nlp/intent-parser.d.ts +0 -152
  207. package/dist/nlp/intent-parser.d.ts.map +0 -1
  208. package/dist/nlp/intent-parser.js +0 -739
  209. package/dist/nlp/intent-parser.js.map +0 -1
  210. package/dist/plugins/plugin-manager.d.ts +0 -120
  211. package/dist/plugins/plugin-manager.d.ts.map +0 -1
  212. package/dist/plugins/plugin-manager.js +0 -595
  213. package/dist/plugins/plugin-manager.js.map +0 -1
  214. package/dist/types/index.d.ts +0 -224
  215. package/dist/types/index.d.ts.map +0 -1
  216. package/dist/types/index.js +0 -3
  217. package/dist/types/index.js.map +0 -1
  218. package/dist/utils/config-manager.d.ts +0 -73
  219. package/dist/utils/config-manager.d.ts.map +0 -1
  220. package/dist/utils/config-manager.js +0 -339
  221. package/dist/utils/config-manager.js.map +0 -1
  222. package/dist/utils/error-handler.d.ts +0 -46
  223. package/dist/utils/error-handler.d.ts.map +0 -1
  224. package/dist/utils/error-handler.js +0 -169
  225. package/dist/utils/error-handler.js.map +0 -1
  226. package/dist/utils/logger.d.ts +0 -25
  227. package/dist/utils/logger.d.ts.map +0 -1
  228. package/dist/utils/logger.js +0 -94
  229. package/dist/utils/logger.js.map +0 -1
  230. package/src/commands/computer-setup-commands.ts +0 -709
@@ -0,0 +1,383 @@
1
+ /**
2
+ * Completion Exporter - Tab completion data export for shells.
3
+ *
4
+ * Generates shell-specific completion scripts from the command registry.
5
+ * Supports bash, zsh, fish, and PowerShell.
6
+ * Also exports raw completion data as JSON for custom integrations.
7
+ *
8
+ * @module framework/completion-exporter
9
+ */
10
+
11
+ import type { CommandDefinition, CommandCategory } from './command-interface';
12
+ import { CATEGORY_LABELS } from './command-interface';
13
+ import type { CommandRegistry } from './command-registry';
14
+
15
+ // ---------------------------------------------------------------------------
16
+ // Types
17
+ // ---------------------------------------------------------------------------
18
+
19
+ /**
20
+ * Shell types supported for completion export.
21
+ */
22
+ export type ShellType = 'bash' | 'zsh' | 'fish' | 'powershell';
23
+
24
+ /**
25
+ * Raw completion data structure for custom integrations.
26
+ */
27
+ export interface CompletionData {
28
+ programName: string;
29
+ version: string;
30
+ commands: CompletionCommand[];
31
+ globalOptions: CompletionOption[];
32
+ }
33
+
34
+ /**
35
+ * Completion data for a single command.
36
+ */
37
+ export interface CompletionCommand {
38
+ name: string;
39
+ description: string;
40
+ aliases: string[];
41
+ category?: string;
42
+ hidden: boolean;
43
+ arguments: CompletionArgument[];
44
+ options: CompletionOption[];
45
+ subcommands: CompletionCommand[];
46
+ }
47
+
48
+ /**
49
+ * Completion data for an argument.
50
+ */
51
+ export interface CompletionArgument {
52
+ name: string;
53
+ description: string;
54
+ required: boolean;
55
+ variadic: boolean;
56
+ }
57
+
58
+ /**
59
+ * Completion data for an option.
60
+ */
61
+ export interface CompletionOption {
62
+ long: string;
63
+ short?: string;
64
+ description: string;
65
+ required: boolean;
66
+ choices?: string[];
67
+ takesValue: boolean;
68
+ }
69
+
70
+ // ---------------------------------------------------------------------------
71
+ // Completion Exporter
72
+ // ---------------------------------------------------------------------------
73
+
74
+ export class CompletionExporter {
75
+ private programName: string;
76
+
77
+ constructor(
78
+ private registry: CommandRegistry,
79
+ programName: string = 'wundr'
80
+ ) {
81
+ this.programName = programName;
82
+ }
83
+
84
+ // -------------------------------------------------------------------------
85
+ // Shell Script Generation
86
+ // -------------------------------------------------------------------------
87
+
88
+ /**
89
+ * Generate a completion script for the specified shell.
90
+ */
91
+ generate(shell: ShellType): string {
92
+ switch (shell) {
93
+ case 'bash':
94
+ return this.registry.generateBashCompletion(this.programName);
95
+ case 'zsh':
96
+ return this.registry.generateZshCompletion(this.programName);
97
+ case 'fish':
98
+ return this.generateFishCompletion();
99
+ case 'powershell':
100
+ return this.generatePowerShellCompletion();
101
+ }
102
+ }
103
+
104
+ // -------------------------------------------------------------------------
105
+ // Raw Data Export
106
+ // -------------------------------------------------------------------------
107
+
108
+ /**
109
+ * Export completion data as a JSON-serializable structure.
110
+ * Useful for custom completion integrations or IDE plugins.
111
+ */
112
+ exportData(version: string = '1.0.0'): CompletionData {
113
+ const commands = this.registry
114
+ .list()
115
+ .filter(cmd => !cmd.name.includes(':'))
116
+ .map(cmd => this.commandToCompletionData(cmd));
117
+
118
+ return {
119
+ programName: this.programName,
120
+ version,
121
+ commands,
122
+ globalOptions: [
123
+ {
124
+ long: '--verbose',
125
+ description: 'Enable verbose logging',
126
+ required: false,
127
+ takesValue: false,
128
+ },
129
+ {
130
+ long: '--quiet',
131
+ description: 'Suppress output',
132
+ required: false,
133
+ takesValue: false,
134
+ },
135
+ {
136
+ long: '--json',
137
+ description: 'Output as JSON',
138
+ required: false,
139
+ takesValue: false,
140
+ },
141
+ {
142
+ long: '--no-color',
143
+ description: 'Disable colored output',
144
+ required: false,
145
+ takesValue: false,
146
+ },
147
+ {
148
+ long: '--dry-run',
149
+ description: 'Show what would be done',
150
+ required: false,
151
+ takesValue: false,
152
+ },
153
+ {
154
+ long: '--config',
155
+ description: 'Specify config file',
156
+ required: false,
157
+ takesValue: true,
158
+ },
159
+ {
160
+ long: '--help',
161
+ short: '-h',
162
+ description: 'Show help',
163
+ required: false,
164
+ takesValue: false,
165
+ },
166
+ {
167
+ long: '--version',
168
+ short: '-v',
169
+ description: 'Show version',
170
+ required: false,
171
+ takesValue: false,
172
+ },
173
+ ],
174
+ };
175
+ }
176
+
177
+ /**
178
+ * Export completion data as JSON string.
179
+ */
180
+ exportJson(version: string = '1.0.0', pretty: boolean = true): string {
181
+ const data = this.exportData(version);
182
+ return pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
183
+ }
184
+
185
+ // -------------------------------------------------------------------------
186
+ // Fish Completion
187
+ // -------------------------------------------------------------------------
188
+
189
+ private generateFishCompletion(): string {
190
+ const lines: string[] = [];
191
+
192
+ lines.push(`# Fish completion for ${this.programName}`);
193
+ lines.push(`# Generated by @wundr/cli framework`);
194
+ lines.push('');
195
+
196
+ // Disable file completion by default
197
+ lines.push(`complete -c ${this.programName} -f`);
198
+ lines.push('');
199
+
200
+ // Global options
201
+ lines.push('# Global options');
202
+ lines.push(
203
+ `complete -c ${this.programName} -l verbose -d 'Enable verbose logging'`
204
+ );
205
+ lines.push(`complete -c ${this.programName} -l quiet -d 'Suppress output'`);
206
+ lines.push(`complete -c ${this.programName} -l json -d 'Output as JSON'`);
207
+ lines.push(
208
+ `complete -c ${this.programName} -l no-color -d 'Disable colored output'`
209
+ );
210
+ lines.push(
211
+ `complete -c ${this.programName} -l dry-run -d 'Show what would be done'`
212
+ );
213
+ lines.push(
214
+ `complete -c ${this.programName} -l config -d 'Specify config file' -r`
215
+ );
216
+ lines.push(`complete -c ${this.programName} -s h -l help -d 'Show help'`);
217
+ lines.push(
218
+ `complete -c ${this.programName} -s v -l version -d 'Show version'`
219
+ );
220
+ lines.push('');
221
+
222
+ // Commands
223
+ lines.push('# Commands');
224
+ for (const cmd of this.registry.list()) {
225
+ if (cmd.hidden || cmd.name.includes(':')) continue;
226
+
227
+ const desc = cmd.description.replace(/'/g, "\\'");
228
+ lines.push(
229
+ `complete -c ${this.programName} -n '__fish_use_subcommand' -a '${cmd.name}' -d '${desc}'`
230
+ );
231
+
232
+ // Aliases
233
+ if (cmd.aliases) {
234
+ for (const alias of cmd.aliases) {
235
+ lines.push(
236
+ `complete -c ${this.programName} -n '__fish_use_subcommand' -a '${alias}' -d '${desc}'`
237
+ );
238
+ }
239
+ }
240
+
241
+ // Command-specific options
242
+ if (cmd.options) {
243
+ for (const opt of cmd.options) {
244
+ const longMatch = opt.flags.match(/--([a-z-]+)/);
245
+ const shortMatch = opt.flags.match(/-([a-z]),/);
246
+ const optDesc = opt.description.replace(/'/g, "\\'");
247
+
248
+ let line = `complete -c ${this.programName} -n '__fish_seen_subcommand_from ${cmd.name}'`;
249
+ if (longMatch) line += ` -l '${longMatch[1]}'`;
250
+ if (shortMatch) line += ` -s '${shortMatch[1]}'`;
251
+ line += ` -d '${optDesc}'`;
252
+
253
+ if (opt.choices) {
254
+ line += ` -xa '${opt.choices.join(' ')}'`;
255
+ } else if (opt.flags.includes('<')) {
256
+ line += ' -r';
257
+ }
258
+
259
+ lines.push(line);
260
+ }
261
+ }
262
+
263
+ // Subcommands
264
+ if (cmd.subcommands) {
265
+ for (const sub of cmd.subcommands) {
266
+ const subDesc = sub.description.replace(/'/g, "\\'");
267
+ lines.push(
268
+ `complete -c ${this.programName} -n '__fish_seen_subcommand_from ${cmd.name}' ` +
269
+ `-a '${sub.name}' -d '${subDesc}'`
270
+ );
271
+ }
272
+ }
273
+ }
274
+
275
+ return lines.join('\n');
276
+ }
277
+
278
+ // -------------------------------------------------------------------------
279
+ // PowerShell Completion
280
+ // -------------------------------------------------------------------------
281
+
282
+ private generatePowerShellCompletion(): string {
283
+ const lines: string[] = [];
284
+
285
+ lines.push(`# PowerShell completion for ${this.programName}`);
286
+ lines.push(`# Generated by @wundr/cli framework`);
287
+ lines.push('');
288
+ lines.push(
289
+ `Register-ArgumentCompleter -CommandName '${this.programName}' -ScriptBlock {`
290
+ );
291
+ lines.push(' param($wordToComplete, $commandAst, $cursorPosition)');
292
+ lines.push('');
293
+ lines.push(' $commands = @(');
294
+
295
+ for (const cmd of this.registry.list()) {
296
+ if (cmd.hidden || cmd.name.includes(':')) continue;
297
+ const desc = cmd.description.replace(/'/g, "''");
298
+ lines.push(` @{ Name = '${cmd.name}'; Description = '${desc}' }`);
299
+ }
300
+
301
+ lines.push(' )');
302
+ lines.push('');
303
+ lines.push(' $globalOptions = @(');
304
+ lines.push(
305
+ " @{ Name = '--verbose'; Description = 'Enable verbose logging' }"
306
+ );
307
+ lines.push(
308
+ " @{ Name = '--quiet'; Description = 'Suppress output' }"
309
+ );
310
+ lines.push(" @{ Name = '--json'; Description = 'Output as JSON' }");
311
+ lines.push(
312
+ " @{ Name = '--no-color'; Description = 'Disable colored output' }"
313
+ );
314
+ lines.push(
315
+ " @{ Name = '--dry-run'; Description = 'Show what would be done' }"
316
+ );
317
+ lines.push(
318
+ " @{ Name = '--config'; Description = 'Specify config file' }"
319
+ );
320
+ lines.push(' )');
321
+ lines.push('');
322
+ lines.push(' $elements = $commandAst.CommandElements');
323
+ lines.push(' if ($elements.Count -le 2) {');
324
+ lines.push(
325
+ ' $items = if ($wordToComplete.StartsWith("-")) { $globalOptions } else { $commands }'
326
+ );
327
+ lines.push(
328
+ ' $items | Where-Object { $_.Name -like "$wordToComplete*" } | ForEach-Object {'
329
+ );
330
+ lines.push(
331
+ " [System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Description)"
332
+ );
333
+ lines.push(' }');
334
+ lines.push(' }');
335
+ lines.push('}');
336
+
337
+ return lines.join('\n');
338
+ }
339
+
340
+ // -------------------------------------------------------------------------
341
+ // Private Helpers
342
+ // -------------------------------------------------------------------------
343
+
344
+ private commandToCompletionData(cmd: CommandDefinition): CompletionCommand {
345
+ return {
346
+ name: cmd.name,
347
+ description: cmd.description,
348
+ aliases: cmd.aliases ?? [],
349
+ category: cmd.category,
350
+ hidden: cmd.hidden ?? false,
351
+ arguments: (cmd.arguments ?? []).map(arg => ({
352
+ name: arg.name,
353
+ description: arg.description,
354
+ required: arg.required ?? false,
355
+ variadic: arg.variadic ?? false,
356
+ })),
357
+ options: (cmd.options ?? []).map(opt => this.parseOptionFlags(opt)),
358
+ subcommands: (cmd.subcommands ?? []).map(sub =>
359
+ this.commandToCompletionData(sub)
360
+ ),
361
+ };
362
+ }
363
+
364
+ private parseOptionFlags(opt: {
365
+ flags: string;
366
+ description: string;
367
+ required?: boolean;
368
+ choices?: string[];
369
+ }): CompletionOption {
370
+ const longMatch = opt.flags.match(/--([a-z-]+)/);
371
+ const shortMatch = opt.flags.match(/-([a-z]),/);
372
+ const takesValue = opt.flags.includes('<') || opt.flags.includes('[');
373
+
374
+ return {
375
+ long: longMatch ? `--${longMatch[1]}` : opt.flags,
376
+ short: shortMatch ? `-${shortMatch[1]}` : undefined,
377
+ description: opt.description,
378
+ required: opt.required ?? false,
379
+ choices: opt.choices,
380
+ takesValue,
381
+ };
382
+ }
383
+ }