agentic-qe 3.7.5 → 3.7.6
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/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +18 -0
- package/dist/cli/bundle.js +5199 -1335
- package/dist/cli/commands/security.d.ts.map +1 -1
- package/dist/cli/commands/security.js +66 -1
- package/dist/cli/commands/security.js.map +1 -1
- package/dist/cli/commands/test.d.ts.map +1 -1
- package/dist/cli/commands/test.js +86 -3
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/index.js +119 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/coordination/workflow-orchestrator.d.ts.map +1 -1
- package/dist/coordination/workflow-orchestrator.js +2 -6
- package/dist/coordination/workflow-orchestrator.js.map +1 -1
- package/dist/mcp/bundle.js +3977 -153
- package/dist/mcp/handlers/core-handlers.d.ts.map +1 -1
- package/dist/mcp/handlers/core-handlers.js +35 -0
- package/dist/mcp/handlers/core-handlers.js.map +1 -1
- package/dist/mcp/protocol-server.d.ts.map +1 -1
- package/dist/mcp/protocol-server.js +4 -1
- package/dist/mcp/protocol-server.js.map +1 -1
- package/dist/mcp/qe-tool-bridge.d.ts +27 -0
- package/dist/mcp/qe-tool-bridge.d.ts.map +1 -0
- package/dist/mcp/qe-tool-bridge.js +87 -0
- package/dist/mcp/qe-tool-bridge.js.map +1 -0
- package/dist/mcp/tools/registry.d.ts +4 -0
- package/dist/mcp/tools/registry.d.ts.map +1 -1
- package/dist/mcp/tools/registry.js +20 -0
- package/dist/mcp/tools/registry.js.map +1 -1
- package/dist/mcp/tools/security-compliance/visual-security.d.ts +45 -0
- package/dist/mcp/tools/security-compliance/visual-security.d.ts.map +1 -0
- package/dist/mcp/tools/security-compliance/visual-security.js +218 -0
- package/dist/mcp/tools/security-compliance/visual-security.js.map +1 -0
- package/dist/mcp/tools/test-execution/browser-workflow.d.ts +50 -0
- package/dist/mcp/tools/test-execution/browser-workflow.d.ts.map +1 -0
- package/dist/mcp/tools/test-execution/browser-workflow.js +145 -0
- package/dist/mcp/tools/test-execution/browser-workflow.js.map +1 -0
- package/dist/mcp/tools/test-execution/load-test.d.ts +37 -0
- package/dist/mcp/tools/test-execution/load-test.d.ts.map +1 -0
- package/dist/mcp/tools/test-execution/load-test.js +98 -0
- package/dist/mcp/tools/test-execution/load-test.js.map +1 -0
- package/dist/mcp/tools/test-execution/schedule.d.ts +44 -0
- package/dist/mcp/tools/test-execution/schedule.d.ts.map +1 -0
- package/dist/mcp/tools/test-execution/schedule.js +96 -0
- package/dist/mcp/tools/test-execution/schedule.js.map +1 -0
- package/dist/planning/goap-planner.d.ts.map +1 -1
- package/dist/planning/goap-planner.js +7 -28
- package/dist/planning/goap-planner.js.map +1 -1
- package/dist/planning/plan-executor.d.ts.map +1 -1
- package/dist/planning/plan-executor.js +7 -28
- package/dist/planning/plan-executor.js.map +1 -1
- package/package.json +3 -10
- package/dist/cli/commands/qe-tools.d.ts +0 -27
- package/dist/cli/commands/qe-tools.d.ts.map +0 -1
- package/dist/cli/commands/qe-tools.js +0 -771
- package/dist/cli/commands/qe-tools.js.map +0 -1
- package/dist/neural-optimizer/index.d.ts +0 -55
- package/dist/neural-optimizer/index.d.ts.map +0 -1
- package/dist/neural-optimizer/index.js +0 -57
- package/dist/neural-optimizer/index.js.map +0 -1
- package/dist/neural-optimizer/replay-buffer.d.ts +0 -126
- package/dist/neural-optimizer/replay-buffer.d.ts.map +0 -1
- package/dist/neural-optimizer/replay-buffer.js +0 -356
- package/dist/neural-optimizer/replay-buffer.js.map +0 -1
- package/dist/neural-optimizer/swarm-topology.d.ts +0 -157
- package/dist/neural-optimizer/swarm-topology.d.ts.map +0 -1
- package/dist/neural-optimizer/swarm-topology.js +0 -384
- package/dist/neural-optimizer/swarm-topology.js.map +0 -1
- package/dist/neural-optimizer/topology-optimizer.d.ts +0 -137
- package/dist/neural-optimizer/topology-optimizer.d.ts.map +0 -1
- package/dist/neural-optimizer/topology-optimizer.js +0 -657
- package/dist/neural-optimizer/topology-optimizer.js.map +0 -1
- package/dist/neural-optimizer/types.d.ts +0 -333
- package/dist/neural-optimizer/types.d.ts.map +0 -1
- package/dist/neural-optimizer/types.js +0 -57
- package/dist/neural-optimizer/types.js.map +0 -1
- package/dist/neural-optimizer/value-network.d.ts +0 -129
- package/dist/neural-optimizer/value-network.d.ts.map +0 -1
- package/dist/neural-optimizer/value-network.js +0 -279
- package/dist/neural-optimizer/value-network.js.map +0 -1
|
@@ -1,771 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Agentic QE v3 - CLI Commands for MCP Tools
|
|
4
|
-
*
|
|
5
|
-
* Thin CLI wrappers around MCP tools per ADR-010: MCP-First Tool Design.
|
|
6
|
-
* All QE functionality is exposed as MCP tools first, CLI wraps them.
|
|
7
|
-
*/
|
|
8
|
-
import chalk from 'chalk';
|
|
9
|
-
import { TestGenerateTool, TestExecuteTool, CoverageAnalyzeTool, CoverageGapsTool, QualityEvaluateTool, DefectPredictTool, RequirementsValidateTool, CodeAnalyzeTool, SecurityScanTool, ContractValidateTool, VisualCompareTool, A11yAuditTool, ChaosInjectTool, LearningOptimizeTool, } from '../../mcp/tools';
|
|
10
|
-
import { parseJsonOption } from '../../shared/safe-json.js';
|
|
11
|
-
import { runTestGenerationWizard } from '../wizards/test-wizard.js';
|
|
12
|
-
import { runCoverageAnalysisWizard, } from '../wizards/coverage-wizard.js';
|
|
13
|
-
import { runSecurityScanWizard, } from '../wizards/security-wizard.js';
|
|
14
|
-
import { createTestStreamHandler, createCoverageStreamHandler, } from '../utils/streaming.js';
|
|
15
|
-
function createStreamHandler() {
|
|
16
|
-
return {
|
|
17
|
-
onStream: (data) => {
|
|
18
|
-
const streamData = data;
|
|
19
|
-
printStreaming(streamData.message || JSON.stringify(data));
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Create an enhanced stream handler for test execution with real-time output
|
|
25
|
-
* per ADR-041 requirements for streaming test results.
|
|
26
|
-
*
|
|
27
|
-
* Output format:
|
|
28
|
-
* ```
|
|
29
|
-
* [checkmark] UserService.test.ts
|
|
30
|
-
* [checkmark] should create user (12ms)
|
|
31
|
-
* [checkmark] should validate email (3ms)
|
|
32
|
-
* [X] PaymentService.test.ts
|
|
33
|
-
* [checkmark] should process payment (23ms)
|
|
34
|
-
* [X] should handle declined card (45ms)
|
|
35
|
-
* Tests: 8 passed, 1 failed, 1 skipped
|
|
36
|
-
* Time: 1.234s
|
|
37
|
-
* ```
|
|
38
|
-
*/
|
|
39
|
-
function createEnhancedTestStreamHandler() {
|
|
40
|
-
const { onStream, streamer } = createTestStreamHandler({ colors: true });
|
|
41
|
-
return {
|
|
42
|
-
onStream: (data) => {
|
|
43
|
-
const streamData = data;
|
|
44
|
-
// Handle different stream data formats from MCP tools
|
|
45
|
-
if (streamData.suite) {
|
|
46
|
-
streamer.streamSuite(streamData.suite);
|
|
47
|
-
}
|
|
48
|
-
else if (streamData.test) {
|
|
49
|
-
streamer.streamTest(streamData.test);
|
|
50
|
-
}
|
|
51
|
-
else if (streamData.type === 'summary') {
|
|
52
|
-
streamer.streamSummary();
|
|
53
|
-
}
|
|
54
|
-
else if (streamData.message) {
|
|
55
|
-
// Fallback for simple messages
|
|
56
|
-
onStream(data);
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
streamer,
|
|
60
|
-
finish: () => {
|
|
61
|
-
streamer.streamSummary();
|
|
62
|
-
streamer.stop();
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Create an enhanced stream handler for coverage analysis with real-time output
|
|
68
|
-
* per ADR-041 requirements for streaming coverage analysis.
|
|
69
|
-
*/
|
|
70
|
-
function createEnhancedCoverageStreamHandler() {
|
|
71
|
-
const { onStream, streamer } = createCoverageStreamHandler({ colors: true });
|
|
72
|
-
return {
|
|
73
|
-
onStream: (data) => {
|
|
74
|
-
const streamData = data;
|
|
75
|
-
// Handle different stream data formats from MCP tools
|
|
76
|
-
if (streamData.type === 'start' && streamData.totalFiles) {
|
|
77
|
-
streamer.start(streamData.totalFiles);
|
|
78
|
-
}
|
|
79
|
-
else if (streamData.file) {
|
|
80
|
-
streamer.streamFileCoverage(streamData.file);
|
|
81
|
-
}
|
|
82
|
-
else if (streamData.gap) {
|
|
83
|
-
streamer.streamGap(streamData.gap);
|
|
84
|
-
}
|
|
85
|
-
else if (streamData.summary) {
|
|
86
|
-
streamer.streamSummary(streamData.summary);
|
|
87
|
-
}
|
|
88
|
-
else if (streamData.message) {
|
|
89
|
-
// Fallback for simple messages
|
|
90
|
-
onStream(data);
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
streamer,
|
|
94
|
-
finish: (summary) => {
|
|
95
|
-
streamer.streamSummary(summary);
|
|
96
|
-
streamer.stop();
|
|
97
|
-
},
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
function formatDuration(ms) {
|
|
101
|
-
if (ms < 1000)
|
|
102
|
-
return `${ms}ms`;
|
|
103
|
-
if (ms < 60000)
|
|
104
|
-
return `${(ms / 1000).toFixed(1)}s`;
|
|
105
|
-
return `${(ms / 60000).toFixed(1)}m`;
|
|
106
|
-
}
|
|
107
|
-
function printResult(result) {
|
|
108
|
-
if (result.success) {
|
|
109
|
-
console.log(chalk.green('\n Success!\n'));
|
|
110
|
-
if (result.data) {
|
|
111
|
-
console.log(JSON.stringify(result.data, null, 2));
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
console.log(chalk.red(`\n Error: ${result.error}\n`));
|
|
116
|
-
process.exit(1);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
function printStreaming(message) {
|
|
120
|
-
console.log(chalk.gray(` [stream] ${message}`));
|
|
121
|
-
}
|
|
122
|
-
// ============================================================================
|
|
123
|
-
// Test Generation Commands
|
|
124
|
-
// ============================================================================
|
|
125
|
-
export function registerTestCommands(program) {
|
|
126
|
-
const testCmd = program
|
|
127
|
-
.command('tests')
|
|
128
|
-
.description('Test generation and execution (MCP: qe/tests/*)');
|
|
129
|
-
// qe tests generate
|
|
130
|
-
testCmd
|
|
131
|
-
.command('generate')
|
|
132
|
-
.description('Generate tests for source files (MCP: qe/tests/generate)')
|
|
133
|
-
.argument('[files...]', 'Source files to generate tests for')
|
|
134
|
-
.option('-t, --type <type>', 'Test type (unit|integration|e2e|property|contract)', 'unit')
|
|
135
|
-
.option('-f, --framework <framework>', 'Test framework (jest|vitest|mocha|playwright)', 'vitest')
|
|
136
|
-
.option('-l, --language <lang>', 'Programming language (typescript|javascript|python)', 'typescript')
|
|
137
|
-
.option('-c, --coverage <target>', 'Coverage target percentage', '80')
|
|
138
|
-
.option('--patterns <patterns>', 'Include patterns (comma-separated)')
|
|
139
|
-
.option('--anti-patterns', 'Detect anti-patterns', false)
|
|
140
|
-
.option('--streaming', 'Enable streaming output', false)
|
|
141
|
-
.option('--wizard', 'Run interactive test generation wizard')
|
|
142
|
-
.option('--ai-level <level>', 'AI enhancement level (none|basic|standard|advanced)', 'standard')
|
|
143
|
-
.action(async (files, options) => {
|
|
144
|
-
let sourceFiles = files;
|
|
145
|
-
let testType = options.type;
|
|
146
|
-
let framework = options.framework;
|
|
147
|
-
let coverageTarget = parseInt(options.coverage, 10);
|
|
148
|
-
let detectAntiPatterns = options.antiPatterns;
|
|
149
|
-
let aiLevel = options.aiLevel;
|
|
150
|
-
// Run wizard if requested
|
|
151
|
-
if (options.wizard) {
|
|
152
|
-
try {
|
|
153
|
-
const wizardResult = await runTestGenerationWizard({
|
|
154
|
-
defaultSourceFiles: files.length > 0 ? files : undefined,
|
|
155
|
-
defaultTestType: options.type,
|
|
156
|
-
defaultCoverageTarget: parseInt(options.coverage, 10),
|
|
157
|
-
defaultFramework: options.framework,
|
|
158
|
-
defaultAILevel: options.aiLevel,
|
|
159
|
-
});
|
|
160
|
-
if (wizardResult.cancelled) {
|
|
161
|
-
console.log(chalk.yellow('\n Test generation cancelled.\n'));
|
|
162
|
-
process.exit(0);
|
|
163
|
-
}
|
|
164
|
-
// Use wizard results
|
|
165
|
-
sourceFiles = wizardResult.sourceFiles;
|
|
166
|
-
testType = wizardResult.testType;
|
|
167
|
-
framework = wizardResult.framework;
|
|
168
|
-
coverageTarget = wizardResult.coverageTarget;
|
|
169
|
-
detectAntiPatterns = wizardResult.detectAntiPatterns;
|
|
170
|
-
aiLevel = wizardResult.aiLevel;
|
|
171
|
-
console.log(chalk.green('\n Starting test generation...\n'));
|
|
172
|
-
}
|
|
173
|
-
catch (err) {
|
|
174
|
-
console.error(chalk.red('\n Wizard error:'), err);
|
|
175
|
-
process.exit(1);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
// Validate we have source files
|
|
179
|
-
if (!sourceFiles || sourceFiles.length === 0) {
|
|
180
|
-
console.log(chalk.red('\n Error: No source files specified.'));
|
|
181
|
-
console.log(chalk.gray(' Use --wizard for interactive mode or provide file paths.\n'));
|
|
182
|
-
console.log(chalk.gray(' Examples:'));
|
|
183
|
-
console.log(chalk.gray(' aqe tests generate src/services/*.ts'));
|
|
184
|
-
console.log(chalk.gray(' aqe tests generate --wizard\n'));
|
|
185
|
-
process.exit(1);
|
|
186
|
-
}
|
|
187
|
-
const tool = new TestGenerateTool();
|
|
188
|
-
console.log(chalk.blue(`\n Generating ${testType} tests for ${sourceFiles.length} file(s)...\n`));
|
|
189
|
-
console.log(chalk.gray(` Framework: ${framework} | Coverage: ${coverageTarget}% | AI: ${aiLevel}\n`));
|
|
190
|
-
const start = Date.now();
|
|
191
|
-
const result = await tool.invoke({
|
|
192
|
-
sourceFiles,
|
|
193
|
-
testType,
|
|
194
|
-
framework,
|
|
195
|
-
language: options.language,
|
|
196
|
-
coverageTarget,
|
|
197
|
-
includePatterns: options.patterns?.split(','),
|
|
198
|
-
detectAntiPatterns,
|
|
199
|
-
aiEnhanced: aiLevel !== 'none',
|
|
200
|
-
}, options.streaming ? createStreamHandler() : {});
|
|
201
|
-
console.log(chalk.gray(` Duration: ${formatDuration(Date.now() - start)}`));
|
|
202
|
-
printResult(result);
|
|
203
|
-
});
|
|
204
|
-
// qe tests execute
|
|
205
|
-
testCmd
|
|
206
|
-
.command('execute')
|
|
207
|
-
.description('Execute tests with parallel execution and flaky detection (MCP: qe/tests/execute)')
|
|
208
|
-
.argument('[pattern]', 'Test pattern to match', '**/*.test.ts')
|
|
209
|
-
.option('-f, --framework <framework>', 'Test framework', 'vitest')
|
|
210
|
-
.option('-p, --parallel <count>', 'Parallel execution count', '4')
|
|
211
|
-
.option('-r, --retries <count>', 'Retry count for failures', '2')
|
|
212
|
-
.option('--coverage', 'Collect coverage', true)
|
|
213
|
-
.option('--flaky-detection', 'Enable flaky test detection', true)
|
|
214
|
-
.option('--fail-fast', 'Stop on first failure', false)
|
|
215
|
-
.option('--streaming', 'Enable streaming output', false)
|
|
216
|
-
.option('--stream', 'Alias for --streaming (enhanced real-time output)', false)
|
|
217
|
-
.action(async (pattern, options) => {
|
|
218
|
-
const tool = new TestExecuteTool();
|
|
219
|
-
const useStreaming = options.streaming || options.stream;
|
|
220
|
-
console.log(chalk.blue(`\n Executing tests matching: ${pattern}...\n`));
|
|
221
|
-
const start = Date.now();
|
|
222
|
-
// Use enhanced streaming handler for real-time test output per ADR-041
|
|
223
|
-
let streamHandler = {};
|
|
224
|
-
let enhancedHandler = null;
|
|
225
|
-
if (useStreaming) {
|
|
226
|
-
enhancedHandler = createEnhancedTestStreamHandler();
|
|
227
|
-
streamHandler = { onStream: enhancedHandler.onStream };
|
|
228
|
-
}
|
|
229
|
-
const result = await tool.invoke({
|
|
230
|
-
testPattern: pattern,
|
|
231
|
-
framework: options.framework,
|
|
232
|
-
parallel: options.parallel ? true : false,
|
|
233
|
-
parallelWorkers: parseInt(options.parallel, 10) || undefined,
|
|
234
|
-
retries: parseInt(options.retries, 10),
|
|
235
|
-
collectCoverage: options.coverage,
|
|
236
|
-
flakyDetection: options.flakyDetection,
|
|
237
|
-
failFast: options.failFast,
|
|
238
|
-
}, streamHandler);
|
|
239
|
-
// Finalize streaming output with summary
|
|
240
|
-
if (enhancedHandler) {
|
|
241
|
-
enhancedHandler.finish();
|
|
242
|
-
}
|
|
243
|
-
console.log(chalk.gray(` Duration: ${formatDuration(Date.now() - start)}`));
|
|
244
|
-
// Only print result if not streaming (streaming already shows output)
|
|
245
|
-
if (!useStreaming) {
|
|
246
|
-
printResult(result);
|
|
247
|
-
}
|
|
248
|
-
else if (!result.success) {
|
|
249
|
-
console.log(chalk.red(`\n Error: ${result.error}\n`));
|
|
250
|
-
process.exit(1);
|
|
251
|
-
}
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
// ============================================================================
|
|
255
|
-
// Coverage Commands
|
|
256
|
-
// ============================================================================
|
|
257
|
-
export function registerCoverageCommands(program) {
|
|
258
|
-
const coverageCmd = program
|
|
259
|
-
.command('coverage')
|
|
260
|
-
.description('Coverage analysis with O(log n) gap detection (MCP: qe/coverage/*)');
|
|
261
|
-
// qe coverage analyze
|
|
262
|
-
coverageCmd
|
|
263
|
-
.command('analyze')
|
|
264
|
-
.description('Analyze code coverage (MCP: qe/coverage/analyze)')
|
|
265
|
-
.argument('[target]', 'Target directory or file', '.')
|
|
266
|
-
.option('--include <patterns>', 'Include patterns (comma-separated)')
|
|
267
|
-
.option('--exclude <patterns>', 'Exclude patterns (comma-separated)')
|
|
268
|
-
.option('--threshold <percent>', 'Coverage threshold', '80')
|
|
269
|
-
.option('--risk-scoring', 'Include risk scoring', true)
|
|
270
|
-
.option('--sensitivity <level>', 'Gap detection sensitivity (low|medium|high)', 'medium')
|
|
271
|
-
.option('--format <format>', 'Report format (json|html|markdown|text)', 'json')
|
|
272
|
-
.option('--streaming', 'Enable streaming output', false)
|
|
273
|
-
.option('--stream', 'Alias for --streaming (enhanced real-time output)', false)
|
|
274
|
-
.option('--wizard', 'Run interactive coverage analysis wizard')
|
|
275
|
-
.action(async (target, options) => {
|
|
276
|
-
let analyzeTarget = target;
|
|
277
|
-
let threshold = parseInt(options.threshold, 10);
|
|
278
|
-
let includeRiskScoring = options.riskScoring;
|
|
279
|
-
let includePatterns = options.include?.split(',');
|
|
280
|
-
let excludePatterns = options.exclude?.split(',');
|
|
281
|
-
let sensitivity = options.sensitivity;
|
|
282
|
-
const useStreaming = options.streaming || options.stream;
|
|
283
|
-
// Run wizard if requested
|
|
284
|
-
if (options.wizard) {
|
|
285
|
-
try {
|
|
286
|
-
const wizardResult = await runCoverageAnalysisWizard({
|
|
287
|
-
defaultTarget: target !== '.' ? target : undefined,
|
|
288
|
-
defaultThreshold: options.threshold !== '80' ? parseInt(options.threshold, 10) : undefined,
|
|
289
|
-
defaultRiskScoring: options.riskScoring,
|
|
290
|
-
defaultSensitivity: options.sensitivity !== 'medium' ? options.sensitivity : undefined,
|
|
291
|
-
defaultFormat: options.format !== 'json' ? options.format : undefined,
|
|
292
|
-
});
|
|
293
|
-
if (wizardResult.cancelled) {
|
|
294
|
-
console.log(chalk.yellow('\n Coverage analysis cancelled.\n'));
|
|
295
|
-
process.exit(0);
|
|
296
|
-
}
|
|
297
|
-
// Use wizard results
|
|
298
|
-
analyzeTarget = wizardResult.target;
|
|
299
|
-
threshold = wizardResult.threshold;
|
|
300
|
-
includeRiskScoring = wizardResult.riskScoring;
|
|
301
|
-
includePatterns = wizardResult.includePatterns;
|
|
302
|
-
excludePatterns = wizardResult.excludePatterns;
|
|
303
|
-
sensitivity = wizardResult.sensitivity;
|
|
304
|
-
console.log(chalk.green('\n Starting coverage analysis...\n'));
|
|
305
|
-
}
|
|
306
|
-
catch (err) {
|
|
307
|
-
console.error(chalk.red('\n Wizard error:'), err);
|
|
308
|
-
process.exit(1);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
const tool = new CoverageAnalyzeTool();
|
|
312
|
-
console.log(chalk.blue(`\n Analyzing coverage for: ${analyzeTarget}...\n`));
|
|
313
|
-
console.log(chalk.gray(` Threshold: ${threshold}% | Sensitivity: ${sensitivity} | Risk Scoring: ${includeRiskScoring ? 'enabled' : 'disabled'}\n`));
|
|
314
|
-
const start = Date.now();
|
|
315
|
-
// Use enhanced streaming handler for real-time coverage output per ADR-041
|
|
316
|
-
let streamHandler = {};
|
|
317
|
-
let enhancedHandler = null;
|
|
318
|
-
if (useStreaming) {
|
|
319
|
-
enhancedHandler = createEnhancedCoverageStreamHandler();
|
|
320
|
-
streamHandler = { onStream: enhancedHandler.onStream };
|
|
321
|
-
}
|
|
322
|
-
const result = await tool.invoke({
|
|
323
|
-
target: analyzeTarget,
|
|
324
|
-
includePatterns,
|
|
325
|
-
excludePatterns,
|
|
326
|
-
threshold,
|
|
327
|
-
includeRiskScoring,
|
|
328
|
-
}, streamHandler);
|
|
329
|
-
// Finalize streaming output with summary if we have data
|
|
330
|
-
if (enhancedHandler && result.success && result.data) {
|
|
331
|
-
const data = result.data;
|
|
332
|
-
enhancedHandler.finish({
|
|
333
|
-
overall: data.overall || 0,
|
|
334
|
-
files: data.files || [],
|
|
335
|
-
gaps: data.gaps || [],
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
console.log(chalk.gray(` Duration: ${formatDuration(Date.now() - start)}`));
|
|
339
|
-
// Only print result if not streaming (streaming already shows output)
|
|
340
|
-
if (!useStreaming) {
|
|
341
|
-
printResult(result);
|
|
342
|
-
}
|
|
343
|
-
else if (!result.success) {
|
|
344
|
-
console.log(chalk.red(`\n Error: ${result.error}\n`));
|
|
345
|
-
process.exit(1);
|
|
346
|
-
}
|
|
347
|
-
});
|
|
348
|
-
// qe coverage gaps
|
|
349
|
-
coverageCmd
|
|
350
|
-
.command('gaps')
|
|
351
|
-
.description('Detect coverage gaps using O(log n) HNSW (MCP: qe/coverage/gaps)')
|
|
352
|
-
.argument('[target]', 'Target directory or file', '.')
|
|
353
|
-
.option('--max-coverage <percent>', 'Maximum line coverage to consider a gap', '60')
|
|
354
|
-
.option('--min-risk <score>', 'Minimum risk score (0-1)', '0.5')
|
|
355
|
-
.option('--limit <count>', 'Maximum gaps to return', '20')
|
|
356
|
-
.option('--suggest-tests', 'Suggest test cases for gaps', true)
|
|
357
|
-
.option('--streaming', 'Enable streaming output', false)
|
|
358
|
-
.action(async (target, options) => {
|
|
359
|
-
const tool = new CoverageGapsTool();
|
|
360
|
-
console.log(chalk.blue(`\n Detecting coverage gaps in: ${target}...\n`));
|
|
361
|
-
const start = Date.now();
|
|
362
|
-
const result = await tool.invoke({
|
|
363
|
-
target,
|
|
364
|
-
maxLineCoverage: parseInt(options.maxCoverage, 10),
|
|
365
|
-
minRiskScore: parseFloat(options.minRisk),
|
|
366
|
-
limit: parseInt(options.limit, 10),
|
|
367
|
-
suggestTests: options.suggestTests,
|
|
368
|
-
}, options.streaming ? createStreamHandler() : {});
|
|
369
|
-
console.log(chalk.gray(` Duration: ${formatDuration(Date.now() - start)}`));
|
|
370
|
-
printResult(result);
|
|
371
|
-
});
|
|
372
|
-
}
|
|
373
|
-
// ============================================================================
|
|
374
|
-
// Quality Commands
|
|
375
|
-
// ============================================================================
|
|
376
|
-
export function registerQualityCommands(program) {
|
|
377
|
-
const qualityCmd = program
|
|
378
|
-
.command('quality')
|
|
379
|
-
.description('Quality assessment and gate evaluation (MCP: qe/quality/*)');
|
|
380
|
-
// qe quality evaluate
|
|
381
|
-
qualityCmd
|
|
382
|
-
.command('evaluate')
|
|
383
|
-
.description('Evaluate quality gates for deployment (MCP: qe/quality/evaluate)')
|
|
384
|
-
.option('--gate <name>', 'Quality gate name', 'default')
|
|
385
|
-
.option('--coverage-threshold <percent>', 'Coverage threshold', '80')
|
|
386
|
-
.option('--test-pass-threshold <percent>', 'Test pass rate threshold', '100')
|
|
387
|
-
.option('--security-threshold <level>', 'Max security severity (critical|high|medium|low)', 'high')
|
|
388
|
-
.option('--include-trends', 'Include trend analysis', true)
|
|
389
|
-
.option('--include-deployment-advice', 'Include deployment recommendation', true)
|
|
390
|
-
.option('--streaming', 'Enable streaming output', false)
|
|
391
|
-
.action(async (options) => {
|
|
392
|
-
const tool = new QualityEvaluateTool();
|
|
393
|
-
console.log(chalk.blue(`\n Evaluating quality gate: ${options.gate}...\n`));
|
|
394
|
-
const start = Date.now();
|
|
395
|
-
const result = await tool.invoke({
|
|
396
|
-
gateName: options.gate,
|
|
397
|
-
thresholds: {
|
|
398
|
-
coverage: { min: parseInt(options.coverageThreshold, 10) },
|
|
399
|
-
testsPassing: { min: parseInt(options.testPassThreshold, 10) },
|
|
400
|
-
securityVulnerabilities: { max: options.securityThreshold === 'critical' ? 0 : 5 },
|
|
401
|
-
},
|
|
402
|
-
includeTrends: options.includeTrends,
|
|
403
|
-
includeDeploymentAdvice: options.includeDeploymentAdvice,
|
|
404
|
-
}, options.streaming ? createStreamHandler() : {});
|
|
405
|
-
console.log(chalk.gray(` Duration: ${formatDuration(Date.now() - start)}`));
|
|
406
|
-
printResult(result);
|
|
407
|
-
});
|
|
408
|
-
}
|
|
409
|
-
// ============================================================================
|
|
410
|
-
// Defect Commands
|
|
411
|
-
// ============================================================================
|
|
412
|
-
export function registerDefectCommands(program) {
|
|
413
|
-
const defectCmd = program
|
|
414
|
-
.command('defects')
|
|
415
|
-
.description('Defect prediction and intelligence (MCP: qe/defects/*)');
|
|
416
|
-
// qe defects predict
|
|
417
|
-
defectCmd
|
|
418
|
-
.command('predict')
|
|
419
|
-
.description('Predict defects using ML (MCP: qe/defects/predict)')
|
|
420
|
-
.argument('[target]', 'Target directory or file', '.')
|
|
421
|
-
.option('--min-risk <score>', 'Minimum risk score to report (0-1)', '0.3')
|
|
422
|
-
.option('--limit <count>', 'Maximum predictions to return', '20')
|
|
423
|
-
.option('--include-factors', 'Include risk factors', true)
|
|
424
|
-
.option('--include-recommendations', 'Include mitigation recommendations', true)
|
|
425
|
-
.option('--streaming', 'Enable streaming output', false)
|
|
426
|
-
.action(async (target, options) => {
|
|
427
|
-
const tool = new DefectPredictTool();
|
|
428
|
-
console.log(chalk.blue(`\n Predicting defects in: ${target}...\n`));
|
|
429
|
-
const start = Date.now();
|
|
430
|
-
const result = await tool.invoke({
|
|
431
|
-
target,
|
|
432
|
-
minRiskScore: parseFloat(options.minRisk),
|
|
433
|
-
limit: parseInt(options.limit, 10),
|
|
434
|
-
includeFactors: options.includeFactors,
|
|
435
|
-
includeRecommendations: options.includeRecommendations,
|
|
436
|
-
}, options.streaming ? createStreamHandler() : {});
|
|
437
|
-
console.log(chalk.gray(` Duration: ${formatDuration(Date.now() - start)}`));
|
|
438
|
-
printResult(result);
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
// ============================================================================
|
|
442
|
-
// Requirements Commands
|
|
443
|
-
// ============================================================================
|
|
444
|
-
export function registerRequirementsCommands(program) {
|
|
445
|
-
const reqCmd = program
|
|
446
|
-
.command('requirements')
|
|
447
|
-
.description('Requirements validation and BDD (MCP: qe/requirements/*)');
|
|
448
|
-
// qe requirements validate
|
|
449
|
-
reqCmd
|
|
450
|
-
.command('validate')
|
|
451
|
-
.description('Validate requirements and generate BDD scenarios (MCP: qe/requirements/validate)')
|
|
452
|
-
.argument('<requirements...>', 'Requirements to validate (file paths or text)')
|
|
453
|
-
.option('-f, --format <format>', 'Input format (text|markdown|jira|azure)', 'text')
|
|
454
|
-
.option('--generate-bdd', 'Generate BDD scenarios', true)
|
|
455
|
-
.option('--testability-scoring', 'Include testability scores', true)
|
|
456
|
-
.option('--streaming', 'Enable streaming output', false)
|
|
457
|
-
.action(async (requirements, options) => {
|
|
458
|
-
const tool = new RequirementsValidateTool();
|
|
459
|
-
console.log(chalk.blue(`\n Validating ${requirements.length} requirement(s)...\n`));
|
|
460
|
-
const start = Date.now();
|
|
461
|
-
const result = await tool.invoke({
|
|
462
|
-
requirements: requirements.map((r, i) => ({
|
|
463
|
-
id: `req-${i + 1}`,
|
|
464
|
-
title: `Requirement ${i + 1}`,
|
|
465
|
-
description: r,
|
|
466
|
-
type: 'functional',
|
|
467
|
-
})),
|
|
468
|
-
format: options.format,
|
|
469
|
-
generateBDDScenarios: options.generateBdd,
|
|
470
|
-
includeTestabilityScoring: options.testabilityScoring,
|
|
471
|
-
}, options.streaming ? createStreamHandler() : {});
|
|
472
|
-
console.log(chalk.gray(` Duration: ${formatDuration(Date.now() - start)}`));
|
|
473
|
-
printResult(result);
|
|
474
|
-
});
|
|
475
|
-
}
|
|
476
|
-
// ============================================================================
|
|
477
|
-
// Code Intelligence Commands
|
|
478
|
-
// ============================================================================
|
|
479
|
-
export function registerCodeCommands(program) {
|
|
480
|
-
const codeCmd = program
|
|
481
|
-
.command('code')
|
|
482
|
-
.description('Code intelligence with knowledge graph (MCP: qe/code/*)');
|
|
483
|
-
// qe code analyze
|
|
484
|
-
codeCmd
|
|
485
|
-
.command('analyze')
|
|
486
|
-
.description('Analyze code with knowledge graph (MCP: qe/code/analyze)')
|
|
487
|
-
.argument('<action>', 'Action: index | search | impact | dependencies')
|
|
488
|
-
.argument('[target]', 'Target path or query', '.')
|
|
489
|
-
.option('--depth <level>', 'Analysis depth', '3')
|
|
490
|
-
.option('--include-tests', 'Include test files', false)
|
|
491
|
-
.option('--streaming', 'Enable streaming output', false)
|
|
492
|
-
.action(async (action, target, options) => {
|
|
493
|
-
const tool = new CodeAnalyzeTool();
|
|
494
|
-
console.log(chalk.blue(`\n Code analysis (${action}): ${target}...\n`));
|
|
495
|
-
const start = Date.now();
|
|
496
|
-
const result = await tool.invoke({
|
|
497
|
-
action: action,
|
|
498
|
-
target,
|
|
499
|
-
depth: parseInt(options.depth, 10),
|
|
500
|
-
includeTests: options.includeTests,
|
|
501
|
-
}, options.streaming ? createStreamHandler() : {});
|
|
502
|
-
console.log(chalk.gray(` Duration: ${formatDuration(Date.now() - start)}`));
|
|
503
|
-
printResult(result);
|
|
504
|
-
});
|
|
505
|
-
}
|
|
506
|
-
// ============================================================================
|
|
507
|
-
// Security Commands
|
|
508
|
-
// ============================================================================
|
|
509
|
-
export function registerSecurityCommands(program) {
|
|
510
|
-
const securityCmd = program
|
|
511
|
-
.command('security')
|
|
512
|
-
.description('Security scanning and compliance (MCP: qe/security/*)');
|
|
513
|
-
// qe security scan
|
|
514
|
-
securityCmd
|
|
515
|
-
.command('scan')
|
|
516
|
-
.description('Run security scans (MCP: qe/security/scan)')
|
|
517
|
-
.argument('[target]', 'Target directory or file', '.')
|
|
518
|
-
.option('--sast', 'Run SAST scan', true)
|
|
519
|
-
.option('--dast', 'Run DAST scan', false)
|
|
520
|
-
.option('--dependencies', 'Scan dependencies', true)
|
|
521
|
-
.option('--secrets', 'Detect secrets', true)
|
|
522
|
-
.option('--compliance <frameworks>', 'Check compliance (comma-separated: owasp,gdpr,hipaa,soc2,pci)')
|
|
523
|
-
.option('--severity <level>', 'Minimum severity to report (critical|high|medium|low)', 'medium')
|
|
524
|
-
.option('--streaming', 'Enable streaming output', false)
|
|
525
|
-
.option('--wizard', 'Run interactive security scan wizard')
|
|
526
|
-
.action(async (target, options) => {
|
|
527
|
-
let scanTarget = target;
|
|
528
|
-
let sast = options.sast;
|
|
529
|
-
let dast = options.dast;
|
|
530
|
-
let dependencies = options.dependencies;
|
|
531
|
-
let secrets = options.secrets;
|
|
532
|
-
let complianceFrameworks = options.compliance?.split(',');
|
|
533
|
-
let minSeverity = options.severity;
|
|
534
|
-
// Run wizard if requested (ADR-041)
|
|
535
|
-
if (options.wizard) {
|
|
536
|
-
try {
|
|
537
|
-
const wizardResult = await runSecurityScanWizard({
|
|
538
|
-
defaultTarget: target !== '.' ? target : undefined,
|
|
539
|
-
defaultScanTypes: undefined, // Use wizard defaults
|
|
540
|
-
defaultSeverity: options.severity !== 'medium' ? options.severity : undefined,
|
|
541
|
-
});
|
|
542
|
-
if (wizardResult.cancelled) {
|
|
543
|
-
console.log(chalk.yellow('\n Security scan cancelled.\n'));
|
|
544
|
-
process.exit(0);
|
|
545
|
-
}
|
|
546
|
-
// Use wizard results
|
|
547
|
-
scanTarget = wizardResult.target;
|
|
548
|
-
sast = wizardResult.scanTypes.includes('sast');
|
|
549
|
-
dast = wizardResult.scanTypes.includes('dast');
|
|
550
|
-
dependencies = wizardResult.scanTypes.includes('dependency');
|
|
551
|
-
secrets = wizardResult.scanTypes.includes('secret');
|
|
552
|
-
complianceFrameworks = wizardResult.complianceFrameworks.length > 0 ? wizardResult.complianceFrameworks : undefined;
|
|
553
|
-
minSeverity = wizardResult.severity;
|
|
554
|
-
console.log(chalk.green('\n Starting security scan...\n'));
|
|
555
|
-
}
|
|
556
|
-
catch (err) {
|
|
557
|
-
console.error(chalk.red('\n Wizard error:'), err);
|
|
558
|
-
process.exit(1);
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
const tool = new SecurityScanTool();
|
|
562
|
-
console.log(chalk.blue(`\n Running security scan on: ${scanTarget}...\n`));
|
|
563
|
-
const start = Date.now();
|
|
564
|
-
const result = await tool.invoke({
|
|
565
|
-
target: scanTarget,
|
|
566
|
-
scanTypes: {
|
|
567
|
-
sast,
|
|
568
|
-
dast,
|
|
569
|
-
dependencies,
|
|
570
|
-
secrets,
|
|
571
|
-
},
|
|
572
|
-
complianceFrameworks,
|
|
573
|
-
minSeverity,
|
|
574
|
-
}, options.streaming ? createStreamHandler() : {});
|
|
575
|
-
console.log(chalk.gray(` Duration: ${formatDuration(Date.now() - start)}`));
|
|
576
|
-
printResult(result);
|
|
577
|
-
});
|
|
578
|
-
}
|
|
579
|
-
// ============================================================================
|
|
580
|
-
// Contract Testing Commands
|
|
581
|
-
// ============================================================================
|
|
582
|
-
export function registerContractCommands(program) {
|
|
583
|
-
const contractCmd = program
|
|
584
|
-
.command('contracts')
|
|
585
|
-
.description('API contract testing (MCP: qe/contracts/*)');
|
|
586
|
-
// qe contracts validate
|
|
587
|
-
contractCmd
|
|
588
|
-
.command('validate')
|
|
589
|
-
.description('Validate API contracts (MCP: qe/contracts/validate)')
|
|
590
|
-
.argument('[contract]', 'Contract file path')
|
|
591
|
-
.option('-f, --format <format>', 'Contract format (openapi|pact|graphql|asyncapi)', 'openapi')
|
|
592
|
-
.option('--provider <url>', 'Provider URL for verification')
|
|
593
|
-
.option('--consumer <name>', 'Consumer name')
|
|
594
|
-
.option('--baseline <version>', 'Baseline version for breaking change detection')
|
|
595
|
-
.option('--check-breaking', 'Check for breaking changes', true)
|
|
596
|
-
.option('--streaming', 'Enable streaming output', false)
|
|
597
|
-
.action(async (contract, options) => {
|
|
598
|
-
const tool = new ContractValidateTool();
|
|
599
|
-
console.log(chalk.blue(`\n Validating ${options.format} contract...\n`));
|
|
600
|
-
const start = Date.now();
|
|
601
|
-
const result = await tool.invoke({
|
|
602
|
-
contractPath: contract,
|
|
603
|
-
format: options.format,
|
|
604
|
-
providerUrl: options.provider,
|
|
605
|
-
consumerName: options.consumer,
|
|
606
|
-
baselineVersion: options.baseline,
|
|
607
|
-
checkBreakingChanges: options.checkBreaking,
|
|
608
|
-
}, options.streaming ? createStreamHandler() : {});
|
|
609
|
-
console.log(chalk.gray(` Duration: ${formatDuration(Date.now() - start)}`));
|
|
610
|
-
printResult(result);
|
|
611
|
-
});
|
|
612
|
-
}
|
|
613
|
-
// ============================================================================
|
|
614
|
-
// Visual Testing Commands
|
|
615
|
-
// ============================================================================
|
|
616
|
-
export function registerVisualCommands(program) {
|
|
617
|
-
const visualCmd = program
|
|
618
|
-
.command('visual')
|
|
619
|
-
.description('Visual regression testing (MCP: qe/visual/*)');
|
|
620
|
-
// qe visual compare
|
|
621
|
-
visualCmd
|
|
622
|
-
.command('compare')
|
|
623
|
-
.description('Compare visual snapshots (MCP: qe/visual/compare)')
|
|
624
|
-
.argument('<baseline>', 'Baseline image or directory')
|
|
625
|
-
.argument('<current>', 'Current image or directory')
|
|
626
|
-
.option('--threshold <percent>', 'Difference threshold', '5')
|
|
627
|
-
.option('--ignore-regions <regions>', 'Regions to ignore (JSON)')
|
|
628
|
-
.option('--generate-diff', 'Generate diff images', true)
|
|
629
|
-
.option('--streaming', 'Enable streaming output', false)
|
|
630
|
-
.action(async (baseline, current, options) => {
|
|
631
|
-
const tool = new VisualCompareTool();
|
|
632
|
-
console.log(chalk.blue(`\n Comparing visual snapshots...\n`));
|
|
633
|
-
const start = Date.now();
|
|
634
|
-
const result = await tool.invoke({
|
|
635
|
-
urls: [baseline, current],
|
|
636
|
-
baselineUrl: baseline,
|
|
637
|
-
currentUrl: current,
|
|
638
|
-
threshold: parseFloat(options.threshold),
|
|
639
|
-
ignoreRegions: options.ignoreRegions ? parseJsonOption(options.ignoreRegions, 'ignoreRegions') : undefined,
|
|
640
|
-
generateDiff: options.generateDiff,
|
|
641
|
-
}, options.streaming ? createStreamHandler() : {});
|
|
642
|
-
console.log(chalk.gray(` Duration: ${formatDuration(Date.now() - start)}`));
|
|
643
|
-
printResult(result);
|
|
644
|
-
});
|
|
645
|
-
}
|
|
646
|
-
// ============================================================================
|
|
647
|
-
// Accessibility Commands
|
|
648
|
-
// ============================================================================
|
|
649
|
-
export function registerA11yCommands(program) {
|
|
650
|
-
const a11yCmd = program
|
|
651
|
-
.command('a11y')
|
|
652
|
-
.description('Accessibility testing (MCP: qe/a11y/*)');
|
|
653
|
-
// qe a11y audit
|
|
654
|
-
a11yCmd
|
|
655
|
-
.command('audit')
|
|
656
|
-
.description('Run accessibility audit (MCP: qe/a11y/audit)')
|
|
657
|
-
.argument('<target>', 'URL or HTML file to audit')
|
|
658
|
-
.option('--standard <standard>', 'WCAG standard (wcag2a|wcag2aa|wcag2aaa|section508)', 'wcag2aa')
|
|
659
|
-
.option('--include-passes', 'Include passing rules', false)
|
|
660
|
-
.option('--include-inapplicable', 'Include inapplicable rules', false)
|
|
661
|
-
.option('--streaming', 'Enable streaming output', false)
|
|
662
|
-
.action(async (target, options) => {
|
|
663
|
-
const tool = new A11yAuditTool();
|
|
664
|
-
console.log(chalk.blue(`\n Running accessibility audit on: ${target}...\n`));
|
|
665
|
-
const start = Date.now();
|
|
666
|
-
const result = await tool.invoke({
|
|
667
|
-
urls: [target],
|
|
668
|
-
standard: options.standard,
|
|
669
|
-
includePasses: options.includePasses,
|
|
670
|
-
includeInapplicable: options.includeInapplicable,
|
|
671
|
-
}, options.streaming ? createStreamHandler() : {});
|
|
672
|
-
console.log(chalk.gray(` Duration: ${formatDuration(Date.now() - start)}`));
|
|
673
|
-
printResult(result);
|
|
674
|
-
});
|
|
675
|
-
}
|
|
676
|
-
// ============================================================================
|
|
677
|
-
// Chaos Engineering Commands
|
|
678
|
-
// ============================================================================
|
|
679
|
-
export function registerChaosCommands(program) {
|
|
680
|
-
const chaosCmd = program
|
|
681
|
-
.command('chaos')
|
|
682
|
-
.description('Chaos engineering and resilience testing (MCP: qe/chaos/*)');
|
|
683
|
-
// qe chaos inject
|
|
684
|
-
chaosCmd
|
|
685
|
-
.command('inject')
|
|
686
|
-
.description('Inject faults for chaos testing (MCP: qe/chaos/inject)')
|
|
687
|
-
.argument('<fault>', 'Fault type: latency|error|timeout|cpu-stress|memory-stress|network-partition|packet-loss|dns-failure|process-kill')
|
|
688
|
-
.argument('<target>', 'Target service or endpoint')
|
|
689
|
-
.option('-d, --duration <ms>', 'Fault duration in ms', '30000')
|
|
690
|
-
.option('-i, --intensity <percent>', 'Fault intensity (0-100)', '50')
|
|
691
|
-
.option('--dry-run', 'Simulate without actual injection', true)
|
|
692
|
-
.option('--hypothesis <text>', 'Hypothesis to validate')
|
|
693
|
-
.option('--rollback', 'Auto-rollback on failure', true)
|
|
694
|
-
.option('--streaming', 'Enable streaming output', false)
|
|
695
|
-
.action(async (fault, target, options) => {
|
|
696
|
-
const tool = new ChaosInjectTool();
|
|
697
|
-
const modeStr = options.dryRun ? chalk.yellow('[DRY RUN]') : chalk.red('[LIVE]');
|
|
698
|
-
console.log(chalk.blue(`\n ${modeStr} Injecting ${fault} fault on: ${target}...\n`));
|
|
699
|
-
const start = Date.now();
|
|
700
|
-
const result = await tool.invoke({
|
|
701
|
-
faultType: fault,
|
|
702
|
-
target,
|
|
703
|
-
duration: parseInt(options.duration, 10),
|
|
704
|
-
intensity: parseInt(options.intensity, 10),
|
|
705
|
-
dryRun: options.dryRun,
|
|
706
|
-
hypothesis: options.hypothesis,
|
|
707
|
-
rollbackOnFailure: options.rollback,
|
|
708
|
-
}, options.streaming ? createStreamHandler() : {});
|
|
709
|
-
console.log(chalk.gray(` Duration: ${formatDuration(Date.now() - start)}`));
|
|
710
|
-
printResult(result);
|
|
711
|
-
});
|
|
712
|
-
}
|
|
713
|
-
// ============================================================================
|
|
714
|
-
// Learning Commands
|
|
715
|
-
// ============================================================================
|
|
716
|
-
export function registerLearningCommands(program) {
|
|
717
|
-
const learningCmd = program
|
|
718
|
-
.command('learning')
|
|
719
|
-
.description('Learning optimization and pattern management (MCP: qe/learning/*)');
|
|
720
|
-
// qe learning optimize
|
|
721
|
-
learningCmd
|
|
722
|
-
.command('optimize')
|
|
723
|
-
.description('Optimize learning and strategies (MCP: qe/learning/optimize)')
|
|
724
|
-
.argument('<action>', 'Action: learn|optimize|transfer|patterns|dashboard')
|
|
725
|
-
.option('-d, --domain <domain>', 'Source domain')
|
|
726
|
-
.option('--target-domain <domain>', 'Target domain for transfer')
|
|
727
|
-
.option('--metric <name>', 'Optimization metric')
|
|
728
|
-
.option('--direction <dir>', 'Optimization direction (maximize|minimize)', 'maximize')
|
|
729
|
-
.option('--experience-ids <ids>', 'Experience IDs to learn from (comma-separated)')
|
|
730
|
-
.option('--streaming', 'Enable streaming output', false)
|
|
731
|
-
.action(async (action, options) => {
|
|
732
|
-
const tool = new LearningOptimizeTool();
|
|
733
|
-
console.log(chalk.blue(`\n Learning optimization (${action})...\n`));
|
|
734
|
-
const start = Date.now();
|
|
735
|
-
const result = await tool.invoke({
|
|
736
|
-
action: action,
|
|
737
|
-
domain: options.domain,
|
|
738
|
-
targetDomain: options.targetDomain,
|
|
739
|
-
experienceIds: options.experienceIds?.split(','),
|
|
740
|
-
objective: options.metric ? {
|
|
741
|
-
metric: options.metric,
|
|
742
|
-
direction: options.direction,
|
|
743
|
-
} : undefined,
|
|
744
|
-
}, options.streaming ? createStreamHandler() : {});
|
|
745
|
-
console.log(chalk.gray(` Duration: ${formatDuration(Date.now() - start)}`));
|
|
746
|
-
printResult(result);
|
|
747
|
-
});
|
|
748
|
-
}
|
|
749
|
-
// ============================================================================
|
|
750
|
-
// Registration
|
|
751
|
-
// ============================================================================
|
|
752
|
-
/**
|
|
753
|
-
* Register all QE MCP tool commands with a Commander program.
|
|
754
|
-
*
|
|
755
|
-
* @param program - Commander program instance
|
|
756
|
-
*/
|
|
757
|
-
export function registerQEToolCommands(program) {
|
|
758
|
-
registerTestCommands(program);
|
|
759
|
-
registerCoverageCommands(program);
|
|
760
|
-
registerQualityCommands(program);
|
|
761
|
-
registerDefectCommands(program);
|
|
762
|
-
registerRequirementsCommands(program);
|
|
763
|
-
registerCodeCommands(program);
|
|
764
|
-
registerSecurityCommands(program);
|
|
765
|
-
registerContractCommands(program);
|
|
766
|
-
registerVisualCommands(program);
|
|
767
|
-
registerA11yCommands(program);
|
|
768
|
-
registerChaosCommands(program);
|
|
769
|
-
registerLearningCommands(program);
|
|
770
|
-
}
|
|
771
|
-
//# sourceMappingURL=qe-tools.js.map
|