@wundr.io/cli 1.0.10 → 1.0.12

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 (269) hide show
  1. package/bin/wundr.js +8 -4
  2. package/package.json +23 -23
  3. package/src/ai/ai-service.ts +16 -17
  4. package/src/ai/claude-client.ts +16 -16
  5. package/src/ai/conversation-manager.ts +29 -29
  6. package/src/cli.ts +4 -4
  7. package/src/commands/ai.ts +246 -78
  8. package/src/commands/alignment.ts +74 -74
  9. package/src/commands/analyze-optimized.ts +111 -78
  10. package/src/commands/analyze.ts +14 -14
  11. package/src/commands/batch.ts +179 -42
  12. package/src/commands/chat.ts +37 -30
  13. package/src/commands/claude-init.ts +41 -45
  14. package/src/commands/claude-setup.ts +204 -119
  15. package/src/commands/computer-setup.ts +85 -43
  16. package/src/commands/create-command.ts +4 -4
  17. package/src/commands/create.ts +27 -27
  18. package/src/commands/dashboard.ts +24 -24
  19. package/src/commands/govern.ts +25 -25
  20. package/src/commands/governance.ts +34 -34
  21. package/src/commands/guardian.ts +56 -56
  22. package/src/commands/init.ts +25 -22
  23. package/src/commands/orchestrator.ts +68 -41
  24. package/src/commands/performance-optimizer.ts +34 -35
  25. package/src/commands/plugins.ts +27 -27
  26. package/src/commands/project-update.ts +175 -72
  27. package/src/commands/rag.ts +185 -78
  28. package/src/commands/session.ts +35 -35
  29. package/src/commands/setup.ts +40 -344
  30. package/src/commands/test-init.ts +3 -3
  31. package/src/commands/test.ts +4 -4
  32. package/src/commands/watch.ts +28 -29
  33. package/src/commands/worktree.ts +49 -49
  34. package/src/context/context-manager.ts +10 -10
  35. package/src/context/session-manager.ts +41 -41
  36. package/src/framework/command-interface.ts +520 -0
  37. package/src/framework/command-registry.ts +942 -0
  38. package/src/framework/completion-exporter.ts +383 -0
  39. package/src/framework/debug-logger.ts +519 -0
  40. package/src/framework/error-handler.ts +867 -0
  41. package/src/framework/help-generator.ts +540 -0
  42. package/src/framework/index.ts +169 -0
  43. package/src/framework/interactive-repl.ts +703 -0
  44. package/src/framework/output-formatter.ts +834 -0
  45. package/src/framework/progress-manager.ts +539 -0
  46. package/src/index.ts +4 -4
  47. package/src/interactive/interactive-mode.ts +16 -16
  48. package/src/lib/conflict-resolution.ts +799 -9
  49. package/src/lib/merge-strategy.ts +529 -7
  50. package/src/lib/safety-mechanisms.ts +422 -18
  51. package/src/lib/state-detection.ts +1015 -13
  52. package/src/nlp/command-mapper.ts +29 -29
  53. package/src/nlp/command-parser.ts +17 -17
  54. package/src/nlp/intent-classifier.ts +7 -7
  55. package/src/nlp/intent-parser.ts +54 -52
  56. package/src/plugins/plugin-manager.ts +61 -39
  57. package/src/tests/computer-setup-integration.test.ts +46 -15
  58. package/src/types/modules.d.ts +424 -1
  59. package/src/utils/backup-rollback-manager.ts +11 -8
  60. package/src/utils/config-manager.ts +3 -3
  61. package/src/utils/error-handler.ts +2 -2
  62. package/src/utils/logger.ts +22 -22
  63. package/templates/batch/ci-cd.yaml +7 -7
  64. package/test-suites/api/health.spec.ts +20 -23
  65. package/test-suites/helpers/test-config.ts +14 -13
  66. package/test-suites/ui/accessibility.spec.ts +27 -22
  67. package/test-suites/ui/smoke.spec.ts +26 -21
  68. package/LICENSE +0 -21
  69. package/dist/ai/ai-service.d.ts +0 -152
  70. package/dist/ai/ai-service.d.ts.map +0 -1
  71. package/dist/ai/ai-service.js +0 -430
  72. package/dist/ai/ai-service.js.map +0 -1
  73. package/dist/ai/claude-client.d.ts +0 -130
  74. package/dist/ai/claude-client.d.ts.map +0 -1
  75. package/dist/ai/claude-client.js +0 -340
  76. package/dist/ai/claude-client.js.map +0 -1
  77. package/dist/ai/conversation-manager.d.ts +0 -164
  78. package/dist/ai/conversation-manager.d.ts.map +0 -1
  79. package/dist/ai/conversation-manager.js +0 -614
  80. package/dist/ai/conversation-manager.js.map +0 -1
  81. package/dist/ai/index.d.ts +0 -5
  82. package/dist/ai/index.d.ts.map +0 -1
  83. package/dist/ai/index.js +0 -8
  84. package/dist/ai/index.js.map +0 -1
  85. package/dist/cli.d.ts +0 -36
  86. package/dist/cli.d.ts.map +0 -1
  87. package/dist/cli.js +0 -192
  88. package/dist/cli.js.map +0 -1
  89. package/dist/commands/ai.d.ts +0 -89
  90. package/dist/commands/ai.d.ts.map +0 -1
  91. package/dist/commands/ai.js +0 -799
  92. package/dist/commands/ai.js.map +0 -1
  93. package/dist/commands/alignment.d.ts +0 -78
  94. package/dist/commands/alignment.d.ts.map +0 -1
  95. package/dist/commands/alignment.js +0 -817
  96. package/dist/commands/alignment.js.map +0 -1
  97. package/dist/commands/analyze-optimized.d.ts +0 -14
  98. package/dist/commands/analyze-optimized.d.ts.map +0 -1
  99. package/dist/commands/analyze-optimized.js +0 -600
  100. package/dist/commands/analyze-optimized.js.map +0 -1
  101. package/dist/commands/analyze.d.ts +0 -65
  102. package/dist/commands/analyze.d.ts.map +0 -1
  103. package/dist/commands/analyze.js +0 -435
  104. package/dist/commands/analyze.js.map +0 -1
  105. package/dist/commands/batch.d.ts +0 -71
  106. package/dist/commands/batch.d.ts.map +0 -1
  107. package/dist/commands/batch.js +0 -738
  108. package/dist/commands/batch.js.map +0 -1
  109. package/dist/commands/chat.d.ts +0 -71
  110. package/dist/commands/chat.d.ts.map +0 -1
  111. package/dist/commands/chat.js +0 -674
  112. package/dist/commands/chat.js.map +0 -1
  113. package/dist/commands/claude-init.d.ts +0 -28
  114. package/dist/commands/claude-init.d.ts.map +0 -1
  115. package/dist/commands/claude-init.js +0 -591
  116. package/dist/commands/claude-init.js.map +0 -1
  117. package/dist/commands/claude-setup.d.ts +0 -119
  118. package/dist/commands/claude-setup.d.ts.map +0 -1
  119. package/dist/commands/claude-setup.js +0 -1073
  120. package/dist/commands/claude-setup.js.map +0 -1
  121. package/dist/commands/computer-setup-commands.d.ts +0 -53
  122. package/dist/commands/computer-setup-commands.d.ts.map +0 -1
  123. package/dist/commands/computer-setup-commands.js +0 -705
  124. package/dist/commands/computer-setup-commands.js.map +0 -1
  125. package/dist/commands/computer-setup.d.ts +0 -7
  126. package/dist/commands/computer-setup.d.ts.map +0 -1
  127. package/dist/commands/computer-setup.js +0 -849
  128. package/dist/commands/computer-setup.js.map +0 -1
  129. package/dist/commands/create-command.d.ts +0 -7
  130. package/dist/commands/create-command.d.ts.map +0 -1
  131. package/dist/commands/create-command.js +0 -158
  132. package/dist/commands/create-command.js.map +0 -1
  133. package/dist/commands/create.d.ts +0 -74
  134. package/dist/commands/create.d.ts.map +0 -1
  135. package/dist/commands/create.js +0 -556
  136. package/dist/commands/create.js.map +0 -1
  137. package/dist/commands/dashboard.d.ts +0 -91
  138. package/dist/commands/dashboard.d.ts.map +0 -1
  139. package/dist/commands/dashboard.js +0 -538
  140. package/dist/commands/dashboard.js.map +0 -1
  141. package/dist/commands/govern.d.ts +0 -70
  142. package/dist/commands/govern.d.ts.map +0 -1
  143. package/dist/commands/govern.js +0 -481
  144. package/dist/commands/govern.js.map +0 -1
  145. package/dist/commands/governance.d.ts +0 -17
  146. package/dist/commands/governance.d.ts.map +0 -1
  147. package/dist/commands/governance.js +0 -703
  148. package/dist/commands/governance.js.map +0 -1
  149. package/dist/commands/guardian.d.ts +0 -20
  150. package/dist/commands/guardian.d.ts.map +0 -1
  151. package/dist/commands/guardian.js +0 -597
  152. package/dist/commands/guardian.js.map +0 -1
  153. package/dist/commands/init.d.ts +0 -59
  154. package/dist/commands/init.d.ts.map +0 -1
  155. package/dist/commands/init.js +0 -650
  156. package/dist/commands/init.js.map +0 -1
  157. package/dist/commands/orchestrator.d.ts +0 -7
  158. package/dist/commands/orchestrator.d.ts.map +0 -1
  159. package/dist/commands/orchestrator.js +0 -571
  160. package/dist/commands/orchestrator.js.map +0 -1
  161. package/dist/commands/performance-optimizer.d.ts +0 -30
  162. package/dist/commands/performance-optimizer.d.ts.map +0 -1
  163. package/dist/commands/performance-optimizer.js +0 -650
  164. package/dist/commands/performance-optimizer.js.map +0 -1
  165. package/dist/commands/plugins.d.ts +0 -87
  166. package/dist/commands/plugins.d.ts.map +0 -1
  167. package/dist/commands/plugins.js +0 -685
  168. package/dist/commands/plugins.js.map +0 -1
  169. package/dist/commands/rag.d.ts +0 -7
  170. package/dist/commands/rag.d.ts.map +0 -1
  171. package/dist/commands/rag.js +0 -748
  172. package/dist/commands/rag.js.map +0 -1
  173. package/dist/commands/session.d.ts +0 -41
  174. package/dist/commands/session.d.ts.map +0 -1
  175. package/dist/commands/session.js +0 -441
  176. package/dist/commands/session.js.map +0 -1
  177. package/dist/commands/setup.d.ts +0 -29
  178. package/dist/commands/setup.d.ts.map +0 -1
  179. package/dist/commands/setup.js +0 -397
  180. package/dist/commands/setup.js.map +0 -1
  181. package/dist/commands/test-init.d.ts +0 -9
  182. package/dist/commands/test-init.d.ts.map +0 -1
  183. package/dist/commands/test-init.js +0 -222
  184. package/dist/commands/test-init.js.map +0 -1
  185. package/dist/commands/test.d.ts +0 -25
  186. package/dist/commands/test.d.ts.map +0 -1
  187. package/dist/commands/test.js +0 -217
  188. package/dist/commands/test.js.map +0 -1
  189. package/dist/commands/vp.d.ts +0 -7
  190. package/dist/commands/vp.d.ts.map +0 -1
  191. package/dist/commands/vp.js +0 -571
  192. package/dist/commands/vp.js.map +0 -1
  193. package/dist/commands/watch.d.ts +0 -76
  194. package/dist/commands/watch.d.ts.map +0 -1
  195. package/dist/commands/watch.js +0 -613
  196. package/dist/commands/watch.js.map +0 -1
  197. package/dist/commands/worktree.d.ts +0 -63
  198. package/dist/commands/worktree.d.ts.map +0 -1
  199. package/dist/commands/worktree.js +0 -774
  200. package/dist/commands/worktree.js.map +0 -1
  201. package/dist/context/context-manager.d.ts +0 -155
  202. package/dist/context/context-manager.d.ts.map +0 -1
  203. package/dist/context/context-manager.js +0 -383
  204. package/dist/context/context-manager.js.map +0 -1
  205. package/dist/context/index.d.ts +0 -3
  206. package/dist/context/index.d.ts.map +0 -1
  207. package/dist/context/index.js +0 -6
  208. package/dist/context/index.js.map +0 -1
  209. package/dist/context/session-manager.d.ts +0 -207
  210. package/dist/context/session-manager.d.ts.map +0 -1
  211. package/dist/context/session-manager.js +0 -686
  212. package/dist/context/session-manager.js.map +0 -1
  213. package/dist/index.d.ts +0 -8
  214. package/dist/index.d.ts.map +0 -1
  215. package/dist/index.js +0 -51
  216. package/dist/index.js.map +0 -1
  217. package/dist/interactive/interactive-mode.d.ts +0 -76
  218. package/dist/interactive/interactive-mode.d.ts.map +0 -1
  219. package/dist/interactive/interactive-mode.js +0 -732
  220. package/dist/interactive/interactive-mode.js.map +0 -1
  221. package/dist/nlp/command-mapper.d.ts +0 -174
  222. package/dist/nlp/command-mapper.d.ts.map +0 -1
  223. package/dist/nlp/command-mapper.js +0 -624
  224. package/dist/nlp/command-mapper.js.map +0 -1
  225. package/dist/nlp/command-parser.d.ts +0 -106
  226. package/dist/nlp/command-parser.d.ts.map +0 -1
  227. package/dist/nlp/command-parser.js +0 -417
  228. package/dist/nlp/command-parser.js.map +0 -1
  229. package/dist/nlp/index.d.ts +0 -5
  230. package/dist/nlp/index.d.ts.map +0 -1
  231. package/dist/nlp/index.js +0 -8
  232. package/dist/nlp/index.js.map +0 -1
  233. package/dist/nlp/intent-classifier.d.ts +0 -59
  234. package/dist/nlp/intent-classifier.d.ts.map +0 -1
  235. package/dist/nlp/intent-classifier.js +0 -384
  236. package/dist/nlp/intent-classifier.js.map +0 -1
  237. package/dist/nlp/intent-parser.d.ts +0 -152
  238. package/dist/nlp/intent-parser.d.ts.map +0 -1
  239. package/dist/nlp/intent-parser.js +0 -744
  240. package/dist/nlp/intent-parser.js.map +0 -1
  241. package/dist/plugins/plugin-manager.d.ts +0 -120
  242. package/dist/plugins/plugin-manager.d.ts.map +0 -1
  243. package/dist/plugins/plugin-manager.js +0 -595
  244. package/dist/plugins/plugin-manager.js.map +0 -1
  245. package/dist/types/index.d.ts +0 -224
  246. package/dist/types/index.d.ts.map +0 -1
  247. package/dist/types/index.js +0 -3
  248. package/dist/types/index.js.map +0 -1
  249. package/dist/utils/backup-rollback-manager.d.ts +0 -72
  250. package/dist/utils/backup-rollback-manager.d.ts.map +0 -1
  251. package/dist/utils/backup-rollback-manager.js +0 -289
  252. package/dist/utils/backup-rollback-manager.js.map +0 -1
  253. package/dist/utils/claude-config-installer.d.ts +0 -98
  254. package/dist/utils/claude-config-installer.d.ts.map +0 -1
  255. package/dist/utils/claude-config-installer.js +0 -678
  256. package/dist/utils/claude-config-installer.js.map +0 -1
  257. package/dist/utils/config-manager.d.ts +0 -73
  258. package/dist/utils/config-manager.d.ts.map +0 -1
  259. package/dist/utils/config-manager.js +0 -339
  260. package/dist/utils/config-manager.js.map +0 -1
  261. package/dist/utils/error-handler.d.ts +0 -46
  262. package/dist/utils/error-handler.d.ts.map +0 -1
  263. package/dist/utils/error-handler.js +0 -169
  264. package/dist/utils/error-handler.js.map +0 -1
  265. package/dist/utils/logger.d.ts +0 -25
  266. package/dist/utils/logger.d.ts.map +0 -1
  267. package/dist/utils/logger.js +0 -105
  268. package/dist/utils/logger.js.map +0 -1
  269. package/src/commands/computer-setup-commands.ts +0 -872
@@ -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
+ }