@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.
- package/bin/wundr.js +8 -4
- package/package.json +23 -23
- package/src/ai/ai-service.ts +16 -17
- package/src/ai/claude-client.ts +16 -16
- package/src/ai/conversation-manager.ts +29 -29
- package/src/cli.ts +4 -4
- package/src/commands/ai.ts +246 -78
- package/src/commands/alignment.ts +74 -74
- package/src/commands/analyze-optimized.ts +111 -78
- package/src/commands/analyze.ts +14 -14
- package/src/commands/batch.ts +179 -42
- package/src/commands/chat.ts +37 -30
- package/src/commands/claude-init.ts +41 -45
- package/src/commands/claude-setup.ts +204 -119
- package/src/commands/computer-setup.ts +85 -43
- package/src/commands/create-command.ts +4 -4
- package/src/commands/create.ts +27 -27
- package/src/commands/dashboard.ts +24 -24
- package/src/commands/govern.ts +25 -25
- package/src/commands/governance.ts +34 -34
- package/src/commands/guardian.ts +56 -56
- package/src/commands/init.ts +25 -22
- package/src/commands/orchestrator.ts +68 -41
- package/src/commands/performance-optimizer.ts +34 -35
- package/src/commands/plugins.ts +27 -27
- package/src/commands/project-update.ts +175 -72
- package/src/commands/rag.ts +185 -78
- package/src/commands/session.ts +35 -35
- package/src/commands/setup.ts +40 -344
- package/src/commands/test-init.ts +3 -3
- package/src/commands/test.ts +4 -4
- package/src/commands/watch.ts +28 -29
- package/src/commands/worktree.ts +49 -49
- package/src/context/context-manager.ts +10 -10
- package/src/context/session-manager.ts +41 -41
- package/src/framework/command-interface.ts +520 -0
- package/src/framework/command-registry.ts +942 -0
- package/src/framework/completion-exporter.ts +383 -0
- package/src/framework/debug-logger.ts +519 -0
- package/src/framework/error-handler.ts +867 -0
- package/src/framework/help-generator.ts +540 -0
- package/src/framework/index.ts +169 -0
- package/src/framework/interactive-repl.ts +703 -0
- package/src/framework/output-formatter.ts +834 -0
- package/src/framework/progress-manager.ts +539 -0
- package/src/index.ts +4 -4
- package/src/interactive/interactive-mode.ts +16 -16
- package/src/lib/conflict-resolution.ts +799 -9
- package/src/lib/merge-strategy.ts +529 -7
- package/src/lib/safety-mechanisms.ts +422 -18
- package/src/lib/state-detection.ts +1015 -13
- package/src/nlp/command-mapper.ts +29 -29
- package/src/nlp/command-parser.ts +17 -17
- package/src/nlp/intent-classifier.ts +7 -7
- package/src/nlp/intent-parser.ts +54 -52
- package/src/plugins/plugin-manager.ts +61 -39
- package/src/tests/computer-setup-integration.test.ts +46 -15
- package/src/types/modules.d.ts +424 -1
- package/src/utils/backup-rollback-manager.ts +11 -8
- package/src/utils/config-manager.ts +3 -3
- package/src/utils/error-handler.ts +2 -2
- package/src/utils/logger.ts +22 -22
- package/templates/batch/ci-cd.yaml +7 -7
- package/test-suites/api/health.spec.ts +20 -23
- package/test-suites/helpers/test-config.ts +14 -13
- package/test-suites/ui/accessibility.spec.ts +27 -22
- package/test-suites/ui/smoke.spec.ts +26 -21
- package/LICENSE +0 -21
- package/dist/ai/ai-service.d.ts +0 -152
- package/dist/ai/ai-service.d.ts.map +0 -1
- package/dist/ai/ai-service.js +0 -430
- package/dist/ai/ai-service.js.map +0 -1
- package/dist/ai/claude-client.d.ts +0 -130
- package/dist/ai/claude-client.d.ts.map +0 -1
- package/dist/ai/claude-client.js +0 -340
- package/dist/ai/claude-client.js.map +0 -1
- package/dist/ai/conversation-manager.d.ts +0 -164
- package/dist/ai/conversation-manager.d.ts.map +0 -1
- package/dist/ai/conversation-manager.js +0 -614
- package/dist/ai/conversation-manager.js.map +0 -1
- package/dist/ai/index.d.ts +0 -5
- package/dist/ai/index.d.ts.map +0 -1
- package/dist/ai/index.js +0 -8
- package/dist/ai/index.js.map +0 -1
- package/dist/cli.d.ts +0 -36
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -192
- package/dist/cli.js.map +0 -1
- package/dist/commands/ai.d.ts +0 -89
- package/dist/commands/ai.d.ts.map +0 -1
- package/dist/commands/ai.js +0 -799
- package/dist/commands/ai.js.map +0 -1
- package/dist/commands/alignment.d.ts +0 -78
- package/dist/commands/alignment.d.ts.map +0 -1
- package/dist/commands/alignment.js +0 -817
- package/dist/commands/alignment.js.map +0 -1
- package/dist/commands/analyze-optimized.d.ts +0 -14
- package/dist/commands/analyze-optimized.d.ts.map +0 -1
- package/dist/commands/analyze-optimized.js +0 -600
- package/dist/commands/analyze-optimized.js.map +0 -1
- package/dist/commands/analyze.d.ts +0 -65
- package/dist/commands/analyze.d.ts.map +0 -1
- package/dist/commands/analyze.js +0 -435
- package/dist/commands/analyze.js.map +0 -1
- package/dist/commands/batch.d.ts +0 -71
- package/dist/commands/batch.d.ts.map +0 -1
- package/dist/commands/batch.js +0 -738
- package/dist/commands/batch.js.map +0 -1
- package/dist/commands/chat.d.ts +0 -71
- package/dist/commands/chat.d.ts.map +0 -1
- package/dist/commands/chat.js +0 -674
- package/dist/commands/chat.js.map +0 -1
- package/dist/commands/claude-init.d.ts +0 -28
- package/dist/commands/claude-init.d.ts.map +0 -1
- package/dist/commands/claude-init.js +0 -591
- package/dist/commands/claude-init.js.map +0 -1
- package/dist/commands/claude-setup.d.ts +0 -119
- package/dist/commands/claude-setup.d.ts.map +0 -1
- package/dist/commands/claude-setup.js +0 -1073
- package/dist/commands/claude-setup.js.map +0 -1
- package/dist/commands/computer-setup-commands.d.ts +0 -53
- package/dist/commands/computer-setup-commands.d.ts.map +0 -1
- package/dist/commands/computer-setup-commands.js +0 -705
- package/dist/commands/computer-setup-commands.js.map +0 -1
- package/dist/commands/computer-setup.d.ts +0 -7
- package/dist/commands/computer-setup.d.ts.map +0 -1
- package/dist/commands/computer-setup.js +0 -849
- package/dist/commands/computer-setup.js.map +0 -1
- package/dist/commands/create-command.d.ts +0 -7
- package/dist/commands/create-command.d.ts.map +0 -1
- package/dist/commands/create-command.js +0 -158
- package/dist/commands/create-command.js.map +0 -1
- package/dist/commands/create.d.ts +0 -74
- package/dist/commands/create.d.ts.map +0 -1
- package/dist/commands/create.js +0 -556
- package/dist/commands/create.js.map +0 -1
- package/dist/commands/dashboard.d.ts +0 -91
- package/dist/commands/dashboard.d.ts.map +0 -1
- package/dist/commands/dashboard.js +0 -538
- package/dist/commands/dashboard.js.map +0 -1
- package/dist/commands/govern.d.ts +0 -70
- package/dist/commands/govern.d.ts.map +0 -1
- package/dist/commands/govern.js +0 -481
- package/dist/commands/govern.js.map +0 -1
- package/dist/commands/governance.d.ts +0 -17
- package/dist/commands/governance.d.ts.map +0 -1
- package/dist/commands/governance.js +0 -703
- package/dist/commands/governance.js.map +0 -1
- package/dist/commands/guardian.d.ts +0 -20
- package/dist/commands/guardian.d.ts.map +0 -1
- package/dist/commands/guardian.js +0 -597
- package/dist/commands/guardian.js.map +0 -1
- package/dist/commands/init.d.ts +0 -59
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -650
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/orchestrator.d.ts +0 -7
- package/dist/commands/orchestrator.d.ts.map +0 -1
- package/dist/commands/orchestrator.js +0 -571
- package/dist/commands/orchestrator.js.map +0 -1
- package/dist/commands/performance-optimizer.d.ts +0 -30
- package/dist/commands/performance-optimizer.d.ts.map +0 -1
- package/dist/commands/performance-optimizer.js +0 -650
- package/dist/commands/performance-optimizer.js.map +0 -1
- package/dist/commands/plugins.d.ts +0 -87
- package/dist/commands/plugins.d.ts.map +0 -1
- package/dist/commands/plugins.js +0 -685
- package/dist/commands/plugins.js.map +0 -1
- package/dist/commands/rag.d.ts +0 -7
- package/dist/commands/rag.d.ts.map +0 -1
- package/dist/commands/rag.js +0 -748
- package/dist/commands/rag.js.map +0 -1
- package/dist/commands/session.d.ts +0 -41
- package/dist/commands/session.d.ts.map +0 -1
- package/dist/commands/session.js +0 -441
- package/dist/commands/session.js.map +0 -1
- package/dist/commands/setup.d.ts +0 -29
- package/dist/commands/setup.d.ts.map +0 -1
- package/dist/commands/setup.js +0 -397
- package/dist/commands/setup.js.map +0 -1
- package/dist/commands/test-init.d.ts +0 -9
- package/dist/commands/test-init.d.ts.map +0 -1
- package/dist/commands/test-init.js +0 -222
- package/dist/commands/test-init.js.map +0 -1
- package/dist/commands/test.d.ts +0 -25
- package/dist/commands/test.d.ts.map +0 -1
- package/dist/commands/test.js +0 -217
- package/dist/commands/test.js.map +0 -1
- package/dist/commands/vp.d.ts +0 -7
- package/dist/commands/vp.d.ts.map +0 -1
- package/dist/commands/vp.js +0 -571
- package/dist/commands/vp.js.map +0 -1
- package/dist/commands/watch.d.ts +0 -76
- package/dist/commands/watch.d.ts.map +0 -1
- package/dist/commands/watch.js +0 -613
- package/dist/commands/watch.js.map +0 -1
- package/dist/commands/worktree.d.ts +0 -63
- package/dist/commands/worktree.d.ts.map +0 -1
- package/dist/commands/worktree.js +0 -774
- package/dist/commands/worktree.js.map +0 -1
- package/dist/context/context-manager.d.ts +0 -155
- package/dist/context/context-manager.d.ts.map +0 -1
- package/dist/context/context-manager.js +0 -383
- package/dist/context/context-manager.js.map +0 -1
- package/dist/context/index.d.ts +0 -3
- package/dist/context/index.d.ts.map +0 -1
- package/dist/context/index.js +0 -6
- package/dist/context/index.js.map +0 -1
- package/dist/context/session-manager.d.ts +0 -207
- package/dist/context/session-manager.d.ts.map +0 -1
- package/dist/context/session-manager.js +0 -686
- package/dist/context/session-manager.js.map +0 -1
- package/dist/index.d.ts +0 -8
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -51
- package/dist/index.js.map +0 -1
- package/dist/interactive/interactive-mode.d.ts +0 -76
- package/dist/interactive/interactive-mode.d.ts.map +0 -1
- package/dist/interactive/interactive-mode.js +0 -732
- package/dist/interactive/interactive-mode.js.map +0 -1
- package/dist/nlp/command-mapper.d.ts +0 -174
- package/dist/nlp/command-mapper.d.ts.map +0 -1
- package/dist/nlp/command-mapper.js +0 -624
- package/dist/nlp/command-mapper.js.map +0 -1
- package/dist/nlp/command-parser.d.ts +0 -106
- package/dist/nlp/command-parser.d.ts.map +0 -1
- package/dist/nlp/command-parser.js +0 -417
- package/dist/nlp/command-parser.js.map +0 -1
- package/dist/nlp/index.d.ts +0 -5
- package/dist/nlp/index.d.ts.map +0 -1
- package/dist/nlp/index.js +0 -8
- package/dist/nlp/index.js.map +0 -1
- package/dist/nlp/intent-classifier.d.ts +0 -59
- package/dist/nlp/intent-classifier.d.ts.map +0 -1
- package/dist/nlp/intent-classifier.js +0 -384
- package/dist/nlp/intent-classifier.js.map +0 -1
- package/dist/nlp/intent-parser.d.ts +0 -152
- package/dist/nlp/intent-parser.d.ts.map +0 -1
- package/dist/nlp/intent-parser.js +0 -744
- package/dist/nlp/intent-parser.js.map +0 -1
- package/dist/plugins/plugin-manager.d.ts +0 -120
- package/dist/plugins/plugin-manager.d.ts.map +0 -1
- package/dist/plugins/plugin-manager.js +0 -595
- package/dist/plugins/plugin-manager.js.map +0 -1
- package/dist/types/index.d.ts +0 -224
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -3
- package/dist/types/index.js.map +0 -1
- package/dist/utils/backup-rollback-manager.d.ts +0 -72
- package/dist/utils/backup-rollback-manager.d.ts.map +0 -1
- package/dist/utils/backup-rollback-manager.js +0 -289
- package/dist/utils/backup-rollback-manager.js.map +0 -1
- package/dist/utils/claude-config-installer.d.ts +0 -98
- package/dist/utils/claude-config-installer.d.ts.map +0 -1
- package/dist/utils/claude-config-installer.js +0 -678
- package/dist/utils/claude-config-installer.js.map +0 -1
- package/dist/utils/config-manager.d.ts +0 -73
- package/dist/utils/config-manager.d.ts.map +0 -1
- package/dist/utils/config-manager.js +0 -339
- package/dist/utils/config-manager.js.map +0 -1
- package/dist/utils/error-handler.d.ts +0 -46
- package/dist/utils/error-handler.d.ts.map +0 -1
- package/dist/utils/error-handler.js +0 -169
- package/dist/utils/error-handler.js.map +0 -1
- package/dist/utils/logger.d.ts +0 -25
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js +0 -105
- package/dist/utils/logger.js.map +0 -1
- package/src/commands/computer-setup-commands.ts +0 -872
package/src/nlp/intent-parser.ts
CHANGED
|
@@ -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 +=
|
|
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 =
|
|
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 {
|
|
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
|
|
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
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
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
|
});
|