@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
@@ -103,7 +103,7 @@ export class IntentParser extends EventEmitter {
103
103
 
104
104
  constructor(
105
105
  claudeClient: ClaudeClient,
106
- config: Partial<IntentParserConfig> = {},
106
+ config: Partial<IntentParserConfig> = {}
107
107
  ) {
108
108
  super();
109
109
 
@@ -131,13 +131,13 @@ export class IntentParser extends EventEmitter {
131
131
  async parseIntent(
132
132
  input: string,
133
133
  availableCommands: string[],
134
- context: IntentContext = {},
134
+ context: IntentContext = {}
135
135
  ): Promise<IntentResult> {
136
136
  const normalizedInput = this.normalizeInput(input);
137
137
  const cacheKey = this.getCacheKey(
138
138
  normalizedInput,
139
139
  availableCommands,
140
- context,
140
+ context
141
141
  );
142
142
 
143
143
  // Check cache first
@@ -151,7 +151,7 @@ export class IntentParser extends EventEmitter {
151
151
  // Step 1: Quick pattern matching for common commands
152
152
  const patternResult = await this.patternMatching(
153
153
  normalizedInput,
154
- availableCommands,
154
+ availableCommands
155
155
  );
156
156
  if (patternResult.confidence >= 0.9) {
157
157
  this.cacheResult(cacheKey, patternResult);
@@ -168,21 +168,21 @@ export class IntentParser extends EventEmitter {
168
168
  normalizedInput,
169
169
  availableCommands,
170
170
  context,
171
- entities,
171
+ entities
172
172
  );
173
173
 
174
174
  // Step 4: Combine results and validate
175
175
  const finalResult = this.combineResults(
176
176
  patternResult,
177
177
  aiResult,
178
- entities,
178
+ entities
179
179
  );
180
180
 
181
181
  // Step 5: Post-processing and validation
182
182
  const validatedResult = await this.validateAndEnrich(
183
183
  finalResult,
184
184
  availableCommands,
185
- context,
185
+ context
186
186
  );
187
187
 
188
188
  this.cacheResult(cacheKey, validatedResult);
@@ -197,7 +197,7 @@ export class IntentParser extends EventEmitter {
197
197
  return this.fallbackIntentParsing(
198
198
  normalizedInput,
199
199
  availableCommands,
200
- context,
200
+ context
201
201
  );
202
202
  }
203
203
  }
@@ -208,7 +208,7 @@ export class IntentParser extends EventEmitter {
208
208
  async extractParameters(
209
209
  input: string,
210
210
  command: string,
211
- commandPattern?: CommandPattern,
211
+ commandPattern?: CommandPattern
212
212
  ): Promise<Record<string, any>> {
213
213
  const parameters: Record<string, any> = {};
214
214
 
@@ -242,7 +242,7 @@ Extract parameters from the user input and respond with JSON only:
242
242
  {
243
243
  temperature: 0.1,
244
244
  maxTokens: 1024,
245
- },
245
+ }
246
246
  );
247
247
 
248
248
  const result = JSON.parse(response.trim());
@@ -256,7 +256,7 @@ Extract parameters from the user input and respond with JSON only:
256
256
  if (result.parameters[param.name] && param.validation) {
257
257
  if (!param.validation.test(result.parameters[param.name])) {
258
258
  logger.warn(
259
- `Parameter validation failed for ${param.name}: ${result.parameters[param.name]}`,
259
+ `Parameter validation failed for ${param.name}: ${result.parameters[param.name]}`
260
260
  );
261
261
  delete result.parameters[param.name];
262
262
  }
@@ -285,7 +285,7 @@ Extract parameters from the user input and respond with JSON only:
285
285
  partialInput: string,
286
286
  availableCommands: string[],
287
287
  context: IntentContext = {},
288
- limit: number = 5,
288
+ limit: number = 5
289
289
  ): Promise<
290
290
  Array<{
291
291
  command: string;
@@ -304,7 +304,7 @@ Extract parameters from the user input and respond with JSON only:
304
304
  // Pattern-based suggestions
305
305
  const patternSuggestions = this.getPatternSuggestions(
306
306
  partialInput,
307
- availableCommands,
307
+ availableCommands
308
308
  );
309
309
  suggestions.push(...patternSuggestions);
310
310
 
@@ -315,7 +315,7 @@ Extract parameters from the user input and respond with JSON only:
315
315
  partialInput,
316
316
  availableCommands,
317
317
  context,
318
- limit - suggestions.length,
318
+ limit - suggestions.length
319
319
  );
320
320
  suggestions.push(...aiSuggestions);
321
321
  } catch (error) {
@@ -368,7 +368,7 @@ Extract parameters from the user input and respond with JSON only:
368
368
  } {
369
369
  const now = Date.now();
370
370
  const validEntries = Array.from(this.intentCache.values()).filter(
371
- entry => now - entry.timestamp < this.config.cacheDuration,
371
+ entry => now - entry.timestamp < this.config.cacheDuration
372
372
  );
373
373
 
374
374
  const oldestEntry =
@@ -515,16 +515,16 @@ Extract parameters from the user input and respond with JSON only:
515
515
  this.entityPatterns.set('file_path', /(?:\.\/|\/|~\/)[^\s]+/g);
516
516
  this.entityPatterns.set(
517
517
  'package_name',
518
- /(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*/g,
518
+ /(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*/g
519
519
  );
520
520
  this.entityPatterns.set(
521
521
  'command',
522
- /(?:wundr\s+)?(?:analyze|create|init|help|dashboard|batch|watch)\b/g,
522
+ /(?:wundr\s+)?(?:analyze|create|init|help|dashboard|batch|watch)\b/g
523
523
  );
524
524
  this.entityPatterns.set('option', /--?[a-zA-Z][a-zA-Z0-9-]*/g);
525
525
  this.entityPatterns.set(
526
526
  'technology',
527
- /\b(?:react|angular|vue|nodejs|typescript|javascript|python|java|docker|kubernetes)\b/gi,
527
+ /\b(?:react|angular|vue|nodejs|typescript|javascript|python|java|docker|kubernetes)\b/gi
528
528
  );
529
529
  }
530
530
 
@@ -539,7 +539,7 @@ Extract parameters from the user input and respond with JSON only:
539
539
  private getCacheKey(
540
540
  input: string,
541
541
  commands: string[],
542
- context: IntentContext,
542
+ context: IntentContext
543
543
  ): string {
544
544
  const contextKey = JSON.stringify({
545
545
  projectType: context.projectType,
@@ -552,7 +552,7 @@ Extract parameters from the user input and respond with JSON only:
552
552
 
553
553
  private async patternMatching(
554
554
  input: string,
555
- availableCommands: string[],
555
+ availableCommands: string[]
556
556
  ): Promise<IntentResult> {
557
557
  let bestMatch: IntentResult = {
558
558
  intent: 'unknown',
@@ -562,8 +562,8 @@ Extract parameters from the user input and respond with JSON only:
562
562
 
563
563
  for (const [intent, pattern] of this.commandPatterns) {
564
564
  if (!availableCommands.includes(intent)) {
565
- continue;
566
- }
565
+ continue;
566
+ }
567
567
 
568
568
  const confidence = this.calculatePatternScore(input, pattern);
569
569
 
@@ -584,7 +584,7 @@ continue;
584
584
 
585
585
  private calculatePatternScore(
586
586
  input: string,
587
- pattern: CommandPattern,
587
+ pattern: CommandPattern
588
588
  ): number {
589
589
  let score = 0;
590
590
  let totalWeight = 0;
@@ -597,8 +597,8 @@ continue;
597
597
  let matchCount = 0;
598
598
  for (const word of patternWords) {
599
599
  if (word.startsWith('{') && word.endsWith('}')) {
600
- continue;
601
- } // Skip parameters
600
+ continue;
601
+ } // Skip parameters
602
602
  if (inputWords.includes(word)) {
603
603
  matchCount++;
604
604
  }
@@ -616,7 +616,7 @@ continue;
616
616
  for (const example of pattern.examples) {
617
617
  const similarity = this.calculateStringSimilarity(
618
618
  input,
619
- example.toLowerCase(),
619
+ example.toLowerCase()
620
620
  );
621
621
  exampleScore = Math.max(exampleScore, similarity);
622
622
  }
@@ -667,7 +667,7 @@ continue;
667
667
  input: string,
668
668
  availableCommands: string[],
669
669
  context: IntentContext,
670
- entities: Entity[],
670
+ entities: Entity[]
671
671
  ): Promise<IntentResult> {
672
672
  const contextInfo = this.buildContextInfo(context);
673
673
  const entityInfo =
@@ -702,7 +702,7 @@ Analyze and respond with JSON only:
702
702
  {
703
703
  temperature: 0.1,
704
704
  maxTokens: 1536,
705
- },
705
+ }
706
706
  );
707
707
 
708
708
  const cleanResponse = response.trim();
@@ -737,7 +737,7 @@ Analyze and respond with JSON only:
737
737
 
738
738
  if (context.recentCommands?.length) {
739
739
  parts.push(
740
- `Recent commands: ${context.recentCommands.slice(0, 3).join(', ')}`,
740
+ `Recent commands: ${context.recentCommands.slice(0, 3).join(', ')}`
741
741
  );
742
742
  }
743
743
 
@@ -751,7 +751,7 @@ Analyze and respond with JSON only:
751
751
  private combineResults(
752
752
  patternResult: IntentResult,
753
753
  aiResult: IntentResult,
754
- entities: Entity[],
754
+ entities: Entity[]
755
755
  ): IntentResult {
756
756
  // Use AI result as base, but boost confidence if pattern matching agrees
757
757
  let finalResult = { ...aiResult };
@@ -763,7 +763,8 @@ Analyze and respond with JSON only:
763
763
  // High-confidence pattern match might override AI
764
764
  if (patternResult.confidence > aiResult.confidence) {
765
765
  finalResult = patternResult;
766
- finalResult.reasoning += ' (overridden by high-confidence pattern match)';
766
+ finalResult.reasoning +=
767
+ ' (overridden by high-confidence pattern match)';
767
768
  }
768
769
  }
769
770
 
@@ -778,7 +779,7 @@ Analyze and respond with JSON only:
778
779
  private async validateAndEnrich(
779
780
  result: IntentResult,
780
781
  availableCommands: string[],
781
- context: IntentContext,
782
+ context: IntentContext
782
783
  ): Promise<IntentResult> {
783
784
  // Validate that the intent command is available
784
785
  if (!availableCommands.includes(result.intent)) {
@@ -790,7 +791,8 @@ Analyze and respond with JSON only:
790
791
  // Add safety warnings for destructive commands
791
792
  const commandPattern = this.commandPatterns.get(result.intent);
792
793
  if (commandPattern?.destructive) {
793
- result.clarification = 'This is a destructive operation. Are you sure you want to proceed?';
794
+ result.clarification =
795
+ 'This is a destructive operation. Are you sure you want to proceed?';
794
796
  }
795
797
 
796
798
  // Enrich with context-aware suggestions
@@ -798,7 +800,7 @@ Analyze and respond with JSON only:
798
800
  result.alternatives = await this.getContextualAlternatives(
799
801
  result,
800
802
  availableCommands,
801
- context,
803
+ context
802
804
  );
803
805
  }
804
806
 
@@ -808,7 +810,7 @@ Analyze and respond with JSON only:
808
810
  private async getContextualAlternatives(
809
811
  result: IntentResult,
810
812
  availableCommands: string[],
811
- context: IntentContext,
813
+ context: IntentContext
812
814
  ): Promise<IntentResult['alternatives']> {
813
815
  const alternatives: NonNullable<IntentResult['alternatives']> = [];
814
816
 
@@ -819,7 +821,7 @@ Analyze and respond with JSON only:
819
821
  if (pattern) {
820
822
  const confidence = this.calculatePatternScore(
821
823
  result.command || '',
822
- pattern,
824
+ pattern
823
825
  );
824
826
  if (confidence > 0.3) {
825
827
  alternatives.push({
@@ -840,7 +842,7 @@ Analyze and respond with JSON only:
840
842
  private fallbackIntentParsing(
841
843
  input: string,
842
844
  availableCommands: string[],
843
- context: IntentContext,
845
+ context: IntentContext
844
846
  ): IntentResult {
845
847
  // Simple keyword matching as last resort
846
848
  const keywords = input.split(/\s+/);
@@ -873,7 +875,7 @@ Analyze and respond with JSON only:
873
875
 
874
876
  private fallbackParameterExtraction(
875
877
  input: string,
876
- pattern: CommandPattern,
878
+ pattern: CommandPattern
877
879
  ): Record<string, any> {
878
880
  const parameters: Record<string, any> = {};
879
881
  const words = input.split(/\s+/);
@@ -888,13 +890,13 @@ Analyze and respond with JSON only:
888
890
  } else if (param.type === 'boolean') {
889
891
  if (
890
892
  words.some(word =>
891
- ['yes', 'true', 'on', 'enable'].includes(word.toLowerCase()),
893
+ ['yes', 'true', 'on', 'enable'].includes(word.toLowerCase())
892
894
  )
893
895
  ) {
894
896
  parameters[param.name] = true;
895
897
  } else if (
896
898
  words.some(word =>
897
- ['no', 'false', 'off', 'disable'].includes(word.toLowerCase()),
899
+ ['no', 'false', 'off', 'disable'].includes(word.toLowerCase())
898
900
  )
899
901
  ) {
900
902
  parameters[param.name] = false;
@@ -912,7 +914,7 @@ Analyze and respond with JSON only:
912
914
 
913
915
  private getPatternSuggestions(
914
916
  partialInput: string,
915
- availableCommands: string[],
917
+ availableCommands: string[]
916
918
  ): Array<{
917
919
  command: string;
918
920
  description: string;
@@ -929,15 +931,15 @@ Analyze and respond with JSON only:
929
931
  for (const command of availableCommands) {
930
932
  const pattern = this.commandPatterns.get(command);
931
933
  if (!pattern) {
932
- continue;
933
- }
934
+ continue;
935
+ }
934
936
 
935
937
  // Check if partial input matches command or examples
936
938
  const confidence = Math.max(
937
939
  this.calculateStringSimilarity(partialInput, command),
938
940
  ...pattern.examples.map(ex =>
939
- this.calculateStringSimilarity(partialInput, ex),
940
- ),
941
+ this.calculateStringSimilarity(partialInput, ex)
942
+ )
941
943
  );
942
944
 
943
945
  if (confidence > 0.3) {
@@ -957,7 +959,7 @@ continue;
957
959
  partialInput: string,
958
960
  availableCommands: string[],
959
961
  context: IntentContext,
960
- limit: number,
962
+ limit: number
961
963
  ): Promise<
962
964
  Array<{
963
965
  command: string;
@@ -1065,18 +1067,18 @@ Provide ${limit} suggestions in JSON format:
1065
1067
 
1066
1068
  const words = input.toLowerCase().split(/\s+/);
1067
1069
  const positiveCount = words.filter(word =>
1068
- positiveWords.includes(word),
1070
+ positiveWords.includes(word)
1069
1071
  ).length;
1070
1072
  const negativeCount = words.filter(word =>
1071
- negativeWords.includes(word),
1073
+ negativeWords.includes(word)
1072
1074
  ).length;
1073
1075
 
1074
1076
  if (positiveCount > negativeCount) {
1075
- return 'positive';
1076
- }
1077
+ return 'positive';
1078
+ }
1077
1079
  if (negativeCount > positiveCount) {
1078
- return 'negative';
1079
- }
1080
+ return 'negative';
1081
+ }
1080
1082
  return 'neutral';
1081
1083
  }
1082
1084
 
@@ -4,11 +4,15 @@ import path from 'path';
4
4
  import chalk from 'chalk';
5
5
  import fs from 'fs-extra';
6
6
 
7
-
8
7
  import { errorHandler } from '../utils/error-handler';
9
8
  import { logger } from '../utils/logger';
10
9
 
11
- import type { Plugin, PluginContext, PluginCommand, PluginHook } from '../types';
10
+ import type {
11
+ Plugin,
12
+ PluginContext,
13
+ PluginCommand,
14
+ PluginHook,
15
+ } from '../types';
12
16
  import type { ConfigManager } from '../utils/config-manager';
13
17
 
14
18
  /**
@@ -36,7 +40,7 @@ export class PluginManager {
36
40
  'WUNDR_PLUGIN_INIT_FAILED',
37
41
  'Failed to initialize plugin system',
38
42
  {},
39
- true,
43
+ true
40
44
  );
41
45
  }
42
46
  }
@@ -65,7 +69,7 @@ export class PluginManager {
65
69
  'WUNDR_PLUGIN_LOAD_FAILED',
66
70
  'Failed to load plugins',
67
71
  {},
68
- true,
72
+ true
69
73
  );
70
74
  }
71
75
  }
@@ -104,7 +108,7 @@ export class PluginManager {
104
108
  'WUNDR_PLUGIN_LOAD_SINGLE_FAILED',
105
109
  `Failed to load plugin: ${pluginName}`,
106
110
  { pluginName },
107
- true,
111
+ true
108
112
  );
109
113
  }
110
114
  }
@@ -136,7 +140,7 @@ export class PluginManager {
136
140
  'WUNDR_PLUGIN_UNLOAD_FAILED',
137
141
  `Failed to unload plugin: ${pluginName}`,
138
142
  { pluginName },
139
- true,
143
+ true
140
144
  );
141
145
  }
142
146
  }
@@ -166,7 +170,7 @@ export class PluginManager {
166
170
  'WUNDR_PLUGIN_INSTALL_FAILED',
167
171
  `Failed to install plugin: ${pluginName}`,
168
172
  { pluginName, options },
169
- true,
173
+ true
170
174
  );
171
175
  }
172
176
  }
@@ -196,7 +200,7 @@ export class PluginManager {
196
200
  'WUNDR_PLUGIN_UNINSTALL_FAILED',
197
201
  `Failed to uninstall plugin: ${pluginName}`,
198
202
  { pluginName },
199
- true,
203
+ true
200
204
  );
201
205
  }
202
206
  }
@@ -219,7 +223,7 @@ export class PluginManager {
219
223
  'WUNDR_PLUGIN_ENABLE_FAILED',
220
224
  `Failed to enable plugin: ${pluginName}`,
221
225
  { pluginName },
222
- true,
226
+ true
223
227
  );
224
228
  }
225
229
  }
@@ -238,7 +242,7 @@ export class PluginManager {
238
242
  'WUNDR_PLUGIN_DISABLE_FAILED',
239
243
  `Failed to disable plugin: ${pluginName}`,
240
244
  { pluginName },
241
- true,
245
+ true
242
246
  );
243
247
  }
244
248
  }
@@ -310,28 +314,46 @@ export class PluginManager {
310
314
  }
311
315
 
312
316
  /**
313
- * Get available plugins from registry
317
+ * Get available plugins by scanning the plugins directory on the filesystem.
318
+ * Returns an empty array if the directory does not exist or contains no valid plugins.
314
319
  */
315
320
  async getAvailablePlugins(): Promise<any[]> {
316
321
  try {
317
- // This would query a plugin registry
318
- // For now, return mock data
319
- return [
320
- {
321
- name: '@wundr/plugin-git',
322
- version: '1.0.0',
323
- description: 'Git integration plugin',
324
- downloads: 1000,
325
- updated: new Date().toISOString(),
326
- },
327
- {
328
- name: '@wundr/plugin-docker',
329
- version: '1.2.0',
330
- description: 'Docker integration plugin',
331
- downloads: 800,
332
- updated: new Date().toISOString(),
333
- },
334
- ];
322
+ if (!(await fs.pathExists(this.pluginsDir))) {
323
+ logger.debug(`Plugin directory not found: ${this.pluginsDir}`);
324
+ return [];
325
+ }
326
+
327
+ const entries = await fs.readdir(this.pluginsDir);
328
+ const plugins: any[] = [];
329
+
330
+ for (const entry of entries) {
331
+ const entryPath = path.join(this.pluginsDir, entry);
332
+ const packageJsonPath = path.join(entryPath, 'package.json');
333
+
334
+ if (!(await fs.pathExists(packageJsonPath))) {
335
+ continue;
336
+ }
337
+
338
+ try {
339
+ const packageJson = await fs.readJson(packageJsonPath);
340
+ const stat = await fs.stat(entryPath);
341
+ plugins.push({
342
+ name: packageJson.name || entry,
343
+ version: packageJson.version || 'unknown',
344
+ description: packageJson.description || '',
345
+ author: packageJson.author || '',
346
+ updated: stat.mtime.toISOString(),
347
+ });
348
+ } catch (parseError) {
349
+ logger.debug(
350
+ `Failed to read package.json for plugin ${entry}:`,
351
+ parseError
352
+ );
353
+ }
354
+ }
355
+
356
+ return plugins;
335
357
  } catch (error) {
336
358
  logger.debug('Failed to get available plugins:', error);
337
359
  return [];
@@ -348,7 +370,7 @@ export class PluginManager {
348
370
  .filter(
349
371
  plugin =>
350
372
  plugin.name.toLowerCase().includes(query.toLowerCase()) ||
351
- plugin.description.toLowerCase().includes(query.toLowerCase()),
373
+ plugin.description.toLowerCase().includes(query.toLowerCase())
352
374
  )
353
375
  .slice(0, options.limit || 20);
354
376
  } catch (error) {
@@ -375,7 +397,7 @@ export class PluginManager {
375
397
  'WUNDR_PLUGIN_UPDATE_FAILED',
376
398
  `Failed to update plugin: ${pluginName}`,
377
399
  { pluginName },
378
- true,
400
+ true
379
401
  );
380
402
  }
381
403
  }
@@ -426,7 +448,7 @@ export class PluginManager {
426
448
  'WUNDR_PLUGIN_LINK_FAILED',
427
449
  'Failed to link plugin',
428
450
  { pluginPath },
429
- true,
451
+ true
430
452
  );
431
453
  }
432
454
  }
@@ -454,7 +476,7 @@ export class PluginManager {
454
476
  'WUNDR_PLUGIN_UNLINK_FAILED',
455
477
  'Failed to unlink plugin',
456
478
  { pluginName },
457
- true,
479
+ true
458
480
  );
459
481
  }
460
482
  }
@@ -476,7 +498,7 @@ export class PluginManager {
476
498
  'WUNDR_PLUGIN_TEST_FAILED',
477
499
  `Failed to test plugin: ${pluginName}`,
478
500
  { pluginName, options },
479
- true,
501
+ true
480
502
  );
481
503
  }
482
504
  }
@@ -498,7 +520,7 @@ export class PluginManager {
498
520
  'WUNDR_PLUGIN_PUBLISH_FAILED',
499
521
  'Failed to publish plugin',
500
522
  { options },
501
- true,
523
+ true
502
524
  );
503
525
  }
504
526
  }
@@ -509,7 +531,7 @@ export class PluginManager {
509
531
  async setPluginConfig(
510
532
  pluginName: string,
511
533
  key: string,
512
- value: string,
534
+ value: string
513
535
  ): Promise<void> {
514
536
  this.configManager.set(`plugins.${pluginName}.${key}`, value);
515
537
  await this.configManager.saveConfig();
@@ -630,7 +652,7 @@ export class PluginManager {
630
652
  private removePluginHooks(pluginName: string): void {
631
653
  for (const [event, hooks] of this.pluginHooks) {
632
654
  const filteredHooks = hooks.filter(
633
- hook => !hook.event.startsWith(pluginName),
655
+ hook => !hook.event.startsWith(pluginName)
634
656
  );
635
657
  this.pluginHooks.set(event, filteredHooks);
636
658
  }
@@ -690,7 +712,7 @@ export class PluginManager {
690
712
 
691
713
  private async installNpmPlugin(
692
714
  pluginName: string,
693
- options: any,
715
+ options: any
694
716
  ): Promise<void> {
695
717
  const versionSpec = options.version ? `@${options.version}` : '';
696
718
  const targetPath = path.join(this.pluginsDir, pluginName);
@@ -737,7 +759,7 @@ export class PluginManager {
737
759
  resolve();
738
760
  } else {
739
761
  reject(
740
- new Error(`Command failed with exit code ${code}: ${command}`),
762
+ new Error(`Command failed with exit code ${code}: ${command}`)
741
763
  );
742
764
  }
743
765
  });