agentic-qe 3.6.10 → 3.6.11

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 (71) hide show
  1. package/.claude/skills/skills-manifest.json +1 -1
  2. package/package.json +1 -1
  3. package/v3/CHANGELOG.md +25 -0
  4. package/v3/dist/cli/bundle.js +464 -339
  5. package/v3/dist/cli/commands/code.d.ts.map +1 -1
  6. package/v3/dist/cli/commands/code.js +9 -85
  7. package/v3/dist/cli/commands/code.js.map +1 -1
  8. package/v3/dist/cli/commands/coverage.d.ts.map +1 -1
  9. package/v3/dist/cli/commands/coverage.js +3 -28
  10. package/v3/dist/cli/commands/coverage.js.map +1 -1
  11. package/v3/dist/cli/commands/security.d.ts.map +1 -1
  12. package/v3/dist/cli/commands/security.js +3 -29
  13. package/v3/dist/cli/commands/security.js.map +1 -1
  14. package/v3/dist/cli/commands/test.d.ts.map +1 -1
  15. package/v3/dist/cli/commands/test.js +5 -58
  16. package/v3/dist/cli/commands/test.js.map +1 -1
  17. package/v3/dist/cli/utils/file-discovery.d.ts +27 -0
  18. package/v3/dist/cli/utils/file-discovery.d.ts.map +1 -0
  19. package/v3/dist/cli/utils/file-discovery.js +105 -0
  20. package/v3/dist/cli/utils/file-discovery.js.map +1 -0
  21. package/v3/dist/coordination/task-executor.d.ts.map +1 -1
  22. package/v3/dist/coordination/task-executor.js +304 -44
  23. package/v3/dist/coordination/task-executor.js.map +1 -1
  24. package/v3/dist/domains/code-intelligence/coordinator.d.ts.map +1 -1
  25. package/v3/dist/domains/code-intelligence/coordinator.js +8 -1
  26. package/v3/dist/domains/code-intelligence/coordinator.js.map +1 -1
  27. package/v3/dist/domains/code-intelligence/services/metric-collector/index.d.ts.map +1 -1
  28. package/v3/dist/domains/code-intelligence/services/metric-collector/index.js +10 -0
  29. package/v3/dist/domains/code-intelligence/services/metric-collector/index.js.map +1 -1
  30. package/v3/dist/domains/code-intelligence/services/metric-collector/interfaces.d.ts +7 -1
  31. package/v3/dist/domains/code-intelligence/services/metric-collector/interfaces.d.ts.map +1 -1
  32. package/v3/dist/domains/code-intelligence/services/metric-collector/interfaces.js +10 -1
  33. package/v3/dist/domains/code-intelligence/services/metric-collector/interfaces.js.map +1 -1
  34. package/v3/dist/domains/code-intelligence/services/metric-collector/loc-counter.js +34 -10
  35. package/v3/dist/domains/code-intelligence/services/metric-collector/loc-counter.js.map +1 -1
  36. package/v3/dist/domains/coverage-analysis/services/hnsw-index.d.ts +9 -0
  37. package/v3/dist/domains/coverage-analysis/services/hnsw-index.d.ts.map +1 -1
  38. package/v3/dist/domains/coverage-analysis/services/hnsw-index.js +38 -3
  39. package/v3/dist/domains/coverage-analysis/services/hnsw-index.js.map +1 -1
  40. package/v3/dist/init/init-wizard-hooks.d.ts +8 -1
  41. package/v3/dist/init/init-wizard-hooks.d.ts.map +1 -1
  42. package/v3/dist/init/init-wizard-hooks.js +47 -39
  43. package/v3/dist/init/init-wizard-hooks.js.map +1 -1
  44. package/v3/dist/init/phases/07-hooks.d.ts +11 -1
  45. package/v3/dist/init/phases/07-hooks.d.ts.map +1 -1
  46. package/v3/dist/init/phases/07-hooks.js +46 -50
  47. package/v3/dist/init/phases/07-hooks.js.map +1 -1
  48. package/v3/dist/init/settings-merge.d.ts +35 -0
  49. package/v3/dist/init/settings-merge.d.ts.map +1 -0
  50. package/v3/dist/init/settings-merge.js +140 -0
  51. package/v3/dist/init/settings-merge.js.map +1 -0
  52. package/v3/dist/integrations/agentic-flow/model-router/router.js +1 -1
  53. package/v3/dist/integrations/agentic-flow/model-router/router.js.map +1 -1
  54. package/v3/dist/integrations/agentic-flow/model-router/score-calculator.d.ts.map +1 -1
  55. package/v3/dist/integrations/agentic-flow/model-router/score-calculator.js +18 -3
  56. package/v3/dist/integrations/agentic-flow/model-router/score-calculator.js.map +1 -1
  57. package/v3/dist/integrations/agentic-flow/model-router/signal-collector.d.ts +3 -3
  58. package/v3/dist/integrations/agentic-flow/model-router/signal-collector.d.ts.map +1 -1
  59. package/v3/dist/integrations/agentic-flow/model-router/signal-collector.js +18 -0
  60. package/v3/dist/integrations/agentic-flow/model-router/signal-collector.js.map +1 -1
  61. package/v3/dist/mcp/bundle.js +546 -96
  62. package/v3/dist/mcp/handlers/domain-handler-configs.d.ts.map +1 -1
  63. package/v3/dist/mcp/handlers/domain-handler-configs.js +40 -31
  64. package/v3/dist/mcp/handlers/domain-handler-configs.js.map +1 -1
  65. package/v3/dist/mcp/handlers/task-handlers.d.ts.map +1 -1
  66. package/v3/dist/mcp/handlers/task-handlers.js +68 -5
  67. package/v3/dist/mcp/handlers/task-handlers.js.map +1 -1
  68. package/v3/dist/mcp/protocol-server.d.ts.map +1 -1
  69. package/v3/dist/mcp/protocol-server.js +16 -2
  70. package/v3/dist/mcp/protocol-server.js.map +1 -1
  71. package/v3/package.json +1 -1
@@ -11461,7 +11461,7 @@ var init_hnsw_index = __esm({
11461
11461
  if (!this.initialized) {
11462
11462
  await this.initialize();
11463
11463
  }
11464
- this.validateVector(vector);
11464
+ vector = this.validateVector(vector);
11465
11465
  if (this.keyToLabel.has(key)) {
11466
11466
  await this.delete(key);
11467
11467
  }
@@ -11490,7 +11490,7 @@ var init_hnsw_index = __esm({
11490
11490
  if (!this.initialized) {
11491
11491
  await this.initialize();
11492
11492
  }
11493
- this.validateVector(query);
11493
+ query = this.validateVector(query);
11494
11494
  const startTime = performance.now();
11495
11495
  const results = this.stats.vectorCount > 0 ? this.searchRuvector(query, k68) : [];
11496
11496
  const endTime = performance.now();
@@ -11615,17 +11615,46 @@ var init_hnsw_index = __esm({
11615
11615
  // ============================================================================
11616
11616
  // Private Helper Methods
11617
11617
  // ============================================================================
11618
+ /**
11619
+ * Validate and auto-resize vectors to match HNSW configured dimensions.
11620
+ * Fix #279: Prevents Rust WASM panic when RealEmbeddings (768-dim) are
11621
+ * passed to a 128-dim HNSW index.
11622
+ */
11618
11623
  validateVector(vector) {
11619
11624
  if (vector.length !== this.config.dimensions) {
11620
- throw new Error(
11621
- `Vector dimension mismatch: expected ${this.config.dimensions}, got ${vector.length}`
11622
- );
11625
+ return this.resizeVector(vector, this.config.dimensions);
11623
11626
  }
11624
11627
  for (let i58 = 0; i58 < vector.length; i58++) {
11625
11628
  if (!Number.isFinite(vector[i58])) {
11626
11629
  throw new Error(`Invalid vector value at index ${i58}: ${vector[i58]}`);
11627
11630
  }
11628
11631
  }
11632
+ return vector;
11633
+ }
11634
+ /**
11635
+ * Resize vector to target dimensions using averaging (shrink) or zero-padding (grow).
11636
+ */
11637
+ resizeVector(vector, targetDim) {
11638
+ if (vector.length === targetDim) return vector;
11639
+ if (vector.length > targetDim) {
11640
+ const result2 = new Array(targetDim).fill(0);
11641
+ const ratio = vector.length / targetDim;
11642
+ for (let i58 = 0; i58 < targetDim; i58++) {
11643
+ const start = Math.floor(i58 * ratio);
11644
+ const end = Math.floor((i58 + 1) * ratio);
11645
+ let sum = 0;
11646
+ for (let j52 = start; j52 < end; j52++) {
11647
+ sum += vector[j52];
11648
+ }
11649
+ result2[i58] = sum / (end - start);
11650
+ }
11651
+ return result2;
11652
+ }
11653
+ const result = new Array(targetDim).fill(0);
11654
+ for (let i58 = 0; i58 < vector.length; i58++) {
11655
+ result[i58] = vector[i58];
11656
+ }
11657
+ return result;
11629
11658
  }
11630
11659
  buildKey(key) {
11631
11660
  return `${this.config.namespace}:${key}`;
@@ -17796,7 +17825,13 @@ var init_signal_collector = __esm({
17796
17825
  "test generation",
17797
17826
  "error handling",
17798
17827
  "validation logic",
17799
- "api integration"
17828
+ "api integration",
17829
+ "code index",
17830
+ "coverage analysis",
17831
+ "quality assessment",
17832
+ "defect prediction",
17833
+ "predict defect",
17834
+ "analyze coverage"
17800
17835
  ],
17801
17836
  // Tier 3 - High complexity
17802
17837
  complex: [
@@ -17807,7 +17842,14 @@ var init_signal_collector = __esm({
17807
17842
  "migration",
17808
17843
  "cross-domain",
17809
17844
  "workflow",
17810
- "system design"
17845
+ "system design",
17846
+ "analyze security",
17847
+ "security scan",
17848
+ "security analysis",
17849
+ "vulnerability scan",
17850
+ "chaos test",
17851
+ "resilience test",
17852
+ "contract validation"
17811
17853
  ],
17812
17854
  // Tier 4 - Critical/expert
17813
17855
  critical: [
@@ -17818,7 +17860,12 @@ var init_signal_collector = __esm({
17818
17860
  "system-wide",
17819
17861
  "vulnerability",
17820
17862
  "cryptography",
17821
- "performance critical"
17863
+ "performance critical",
17864
+ "hardcoded secret",
17865
+ "cve",
17866
+ "owasp",
17867
+ "penetration test",
17868
+ "exploit"
17822
17869
  ]
17823
17870
  };
17824
17871
  SCOPE_PATTERNS = {
@@ -18115,11 +18162,15 @@ var init_score_calculator = __esm({
18115
18162
  * Calculate overall complexity score (0-100)
18116
18163
  */
18117
18164
  calculateOverallComplexity(codeComplexity, reasoningComplexity, scopeComplexity, signals) {
18118
- if (signals.isMechanicalTransform) {
18165
+ if (signals.isMechanicalTransform && !signals.hasSecurityScope && !signals.hasArchitectureScope && !signals.requiresMultiStepReasoning && !signals.requiresCrossDomainCoordination && codeComplexity === 0 && reasoningComplexity === 0 && scopeComplexity === 0) {
18119
18166
  return 5;
18120
18167
  }
18121
18168
  const weighted = codeComplexity * 0.3 + reasoningComplexity * 0.4 + scopeComplexity * 0.3;
18122
- return Math.min(Math.round(weighted), 100);
18169
+ let minScore = 0;
18170
+ if (signals.hasSecurityScope) minScore = Math.max(minScore, 50);
18171
+ if (signals.hasArchitectureScope) minScore = Math.max(minScore, 55);
18172
+ if (signals.requiresCrossDomainCoordination) minScore = Math.max(minScore, 35);
18173
+ return Math.min(Math.max(Math.round(weighted), minScore), 100);
18123
18174
  }
18124
18175
  /**
18125
18176
  * Calculate confidence in complexity assessment (0-1)
@@ -18922,7 +18973,7 @@ var init_router = __esm({
18922
18973
  agentBoosterStats: {
18923
18974
  eligible: agentBoosterEligible,
18924
18975
  used: agentBoosterUsed,
18925
- fallbackToLLM: agentBoosterEligible - agentBoosterUsed,
18976
+ fallbackToLLM: Math.max(0, agentBoosterEligible - agentBoosterUsed),
18926
18977
  successRate: agentBoosterUsed > 0 ? agentBoosterSuccess / agentBoosterUsed : 0
18927
18978
  },
18928
18979
  budgetStats: {
@@ -86100,7 +86151,35 @@ import { join as join10, extname as extname3 } from "path";
86100
86151
  // src/domains/code-intelligence/services/metric-collector/interfaces.ts
86101
86152
  var DEFAULT_METRIC_CONFIG = {
86102
86153
  timeout: 6e4,
86103
- excludeDirs: ["node_modules", "dist", "coverage", "build", ".git", "vendor", "target"],
86154
+ excludeDirs: [
86155
+ // JS/TS ecosystem
86156
+ "node_modules",
86157
+ "dist",
86158
+ "build",
86159
+ "coverage",
86160
+ ".nyc_output",
86161
+ ".next",
86162
+ ".nuxt",
86163
+ ".output",
86164
+ // Python ecosystem
86165
+ "__pycache__",
86166
+ ".venv",
86167
+ "venv",
86168
+ ".tox",
86169
+ ".mypy_cache",
86170
+ ".pytest_cache",
86171
+ ".eggs",
86172
+ "*.egg-info",
86173
+ // Rust / Java / Go
86174
+ "target",
86175
+ ".gradle",
86176
+ "vendor",
86177
+ ".bundle",
86178
+ // General
86179
+ ".git",
86180
+ ".svn",
86181
+ ".hg"
86182
+ ],
86104
86183
  testPatterns: ["**/*.test.ts", "**/*.spec.ts", "**/*.test.js", "**/*.spec.js"],
86105
86184
  enableCache: true,
86106
86185
  cacheTTL: 3e5
@@ -86108,7 +86187,7 @@ var DEFAULT_METRIC_CONFIG = {
86108
86187
 
86109
86188
  // src/domains/code-intelligence/services/metric-collector/loc-counter.ts
86110
86189
  import { execSync as execSync3, spawnSync as spawnSync2 } from "child_process";
86111
- import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync5 } from "fs";
86190
+ import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
86112
86191
  import { join as join8, extname } from "path";
86113
86192
  init_safe_json();
86114
86193
  async function countLOC(projectPath, config = {}) {
@@ -86252,22 +86331,35 @@ function getLanguageForExtension(ext) {
86252
86331
  function manualLOCCount(projectPath, config) {
86253
86332
  const byLanguage = {};
86254
86333
  let total = 0;
86255
- function walkDirectory2(dirPath) {
86256
- if (!existsSync6(dirPath)) {
86334
+ const excludeSet = new Set(config.excludeDirs);
86335
+ const MAX_FILE_SIZE = 2 * 1024 * 1024;
86336
+ function walkDirectory2(dirPath, depth) {
86337
+ if (!existsSync6(dirPath) || depth > 20) {
86338
+ return;
86339
+ }
86340
+ let entries;
86341
+ try {
86342
+ entries = readdirSync(dirPath, { withFileTypes: true });
86343
+ } catch {
86257
86344
  return;
86258
86345
  }
86259
- const entries = readdirSync(dirPath, { withFileTypes: true });
86260
86346
  for (const entry of entries) {
86261
86347
  const fullPath = join8(dirPath, entry.name);
86262
86348
  if (entry.isDirectory()) {
86263
- if (config.excludeDirs.includes(entry.name)) {
86349
+ if (excludeSet.has(entry.name) || entry.name.startsWith(".")) {
86264
86350
  continue;
86265
86351
  }
86266
- walkDirectory2(fullPath);
86352
+ walkDirectory2(fullPath, depth + 1);
86267
86353
  } else if (entry.isFile()) {
86268
86354
  const ext = extname(entry.name);
86269
86355
  const language = getLanguageForExtension(ext);
86270
86356
  if (language) {
86357
+ try {
86358
+ const stat6 = statSync2(fullPath);
86359
+ if (stat6.size > MAX_FILE_SIZE) continue;
86360
+ } catch {
86361
+ continue;
86362
+ }
86271
86363
  const lines = countFileLines(fullPath);
86272
86364
  byLanguage[language] = (byLanguage[language] || 0) + lines;
86273
86365
  total += lines;
@@ -86275,11 +86367,11 @@ function manualLOCCount(projectPath, config) {
86275
86367
  }
86276
86368
  }
86277
86369
  }
86278
- walkDirectory2(projectPath);
86370
+ walkDirectory2(projectPath, 0);
86279
86371
  return {
86280
86372
  total,
86281
86373
  byLanguage,
86282
- source: "fallback",
86374
+ source: "node-native",
86283
86375
  excludedDirs: config.excludeDirs
86284
86376
  };
86285
86377
  }
@@ -86910,12 +87002,19 @@ var MetricCollectorService = class {
86910
87002
  const toolsUsed = [];
86911
87003
  if (loc.source !== "fallback") toolsUsed.push(loc.source);
86912
87004
  if (tests.source !== "fallback") toolsUsed.push(tests.source);
87005
+ const locAccuracy = loc.source === "fallback" ? "approximate" : "accurate";
87006
+ const testAccuracy = tests.source === "fallback" ? "approximate" : "accurate";
86913
87007
  const metrics = {
86914
87008
  loc,
86915
87009
  tests,
86916
87010
  patterns,
86917
87011
  collectedAt: /* @__PURE__ */ new Date(),
86918
- toolsUsed
87012
+ toolsUsed,
87013
+ accuracy: {
87014
+ loc: locAccuracy,
87015
+ tests: testAccuracy,
87016
+ overall: locAccuracy === "accurate" && testAccuracy === "accurate" ? "accurate" : "approximate"
87017
+ }
86919
87018
  };
86920
87019
  if (this.config.enableCache) {
86921
87020
  this.setInCache(cacheKey, metrics);
@@ -89145,9 +89244,15 @@ var CodeIntelligenceCoordinator = class extends BaseDomainCoordinator {
89145
89244
  try {
89146
89245
  console.log(`[CodeIntelligence] Collecting real metrics for ${projectPath}`);
89147
89246
  const metrics = await this.metricCollector.collectAll(projectPath);
89247
+ const toolsLabel = metrics.toolsUsed.length > 0 ? metrics.toolsUsed.join(", ") : metrics.loc.source === "node-native" ? "node-native" : "fallback";
89148
89248
  console.log(
89149
- `[CodeIntelligence] Real metrics collected: ${metrics.loc.total} LOC, ${metrics.tests.total} tests, tools: ${metrics.toolsUsed.join(", ") || "fallback"}`
89249
+ `[CodeIntelligence] Real metrics collected: ${metrics.loc.total} LOC, ${metrics.tests.total} tests, tools: ${toolsLabel}`
89150
89250
  );
89251
+ if (metrics.loc.source === "node-native") {
89252
+ console.log(
89253
+ `[CodeIntelligence] Using Node.js-native line counter (no cloc/tokei needed)`
89254
+ );
89255
+ }
89151
89256
  await this.storeProjectMetricsInMemory(projectPath, metrics);
89152
89257
  if (this.config.publishEvents) {
89153
89258
  const event = createEvent(
@@ -132850,13 +132955,58 @@ function parseLcovInfo(content) {
132850
132955
  async function discoverSourceFiles(targetPath, options = {}) {
132851
132956
  const files = [];
132852
132957
  const { includeTests = true, languages } = options;
132853
- let extensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
132958
+ let extensions = [
132959
+ ".ts",
132960
+ ".tsx",
132961
+ ".js",
132962
+ ".jsx",
132963
+ ".mjs",
132964
+ ".cjs",
132965
+ // JavaScript/TypeScript
132966
+ ".py",
132967
+ ".pyw",
132968
+ // Python
132969
+ ".go",
132970
+ // Go
132971
+ ".rs",
132972
+ // Rust
132973
+ ".java",
132974
+ ".kt",
132975
+ ".kts",
132976
+ // Java/Kotlin
132977
+ ".rb",
132978
+ // Ruby
132979
+ ".cs",
132980
+ // C#
132981
+ ".php",
132982
+ // PHP
132983
+ ".swift",
132984
+ // Swift
132985
+ ".c",
132986
+ ".h",
132987
+ ".cpp",
132988
+ ".hpp",
132989
+ ".cc",
132990
+ // C/C++
132991
+ ".scala"
132992
+ // Scala
132993
+ ];
132854
132994
  if (languages && languages.length > 0) {
132855
132995
  extensions = [];
132856
132996
  for (const lang of languages) {
132857
132997
  if (lang === "typescript") extensions.push(".ts", ".tsx");
132858
132998
  if (lang === "javascript") extensions.push(".js", ".jsx", ".mjs", ".cjs");
132859
- if (lang === "python") extensions.push(".py");
132999
+ if (lang === "python") extensions.push(".py", ".pyw");
133000
+ if (lang === "go") extensions.push(".go");
133001
+ if (lang === "rust") extensions.push(".rs");
133002
+ if (lang === "java") extensions.push(".java");
133003
+ if (lang === "kotlin") extensions.push(".kt", ".kts");
133004
+ if (lang === "ruby") extensions.push(".rb");
133005
+ if (lang === "csharp" || lang === "c#") extensions.push(".cs");
133006
+ if (lang === "php") extensions.push(".php");
133007
+ if (lang === "swift") extensions.push(".swift");
133008
+ if (lang === "c" || lang === "cpp" || lang === "c++") extensions.push(".c", ".h", ".cpp", ".hpp", ".cc");
133009
+ if (lang === "scala") extensions.push(".scala");
132860
133010
  }
132861
133011
  }
132862
133012
  async function walkDir(dir) {
@@ -132865,7 +133015,23 @@ async function discoverSourceFiles(targetPath, options = {}) {
132865
133015
  for (const entry of entries) {
132866
133016
  const fullPath = path16.join(dir, entry.name);
132867
133017
  if (entry.isDirectory()) {
132868
- if (["node_modules", ".git", "dist", "build", "coverage", ".nyc_output"].includes(entry.name)) {
133018
+ if ([
133019
+ "node_modules",
133020
+ ".git",
133021
+ "dist",
133022
+ "build",
133023
+ "coverage",
133024
+ ".nyc_output",
133025
+ "__pycache__",
133026
+ ".venv",
133027
+ "venv",
133028
+ ".tox",
133029
+ ".mypy_cache",
133030
+ "target",
133031
+ ".gradle",
133032
+ "vendor",
133033
+ ".bundle"
133034
+ ].includes(entry.name)) {
132869
133035
  continue;
132870
133036
  }
132871
133037
  await walkDir(fullPath);
@@ -133031,7 +133197,24 @@ var DomainTaskExecutor = class {
133031
133197
  } else if (payload.filePath) {
133032
133198
  sourceFiles = [payload.filePath];
133033
133199
  } else if (payload.sourceCode) {
133034
- const tempPath = `/tmp/aqe-temp-${v4_default()}.ts`;
133200
+ const langExtMap = {
133201
+ python: ".py",
133202
+ typescript: ".ts",
133203
+ javascript: ".js",
133204
+ go: ".go",
133205
+ rust: ".rs",
133206
+ java: ".java",
133207
+ ruby: ".rb",
133208
+ kotlin: ".kt",
133209
+ csharp: ".cs",
133210
+ php: ".php",
133211
+ swift: ".swift",
133212
+ cpp: ".cpp",
133213
+ c: ".c",
133214
+ scala: ".scala"
133215
+ };
133216
+ const ext = langExtMap[payload.language?.toLowerCase() || "typescript"] || ".ts";
133217
+ const tempPath = `/tmp/aqe-temp-${v4_default()}${ext}`;
133035
133218
  await fs15.writeFile(tempPath, payload.sourceCode, "utf-8");
133036
133219
  sourceFiles = [tempPath];
133037
133220
  }
@@ -133147,12 +133330,96 @@ var DomainTaskExecutor = class {
133147
133330
  sast: payload.sast !== false,
133148
133331
  dast: payload.dast || false
133149
133332
  },
133150
- warning: `No TypeScript/JavaScript files found in ${targetPath}`
133333
+ warning: `No source files found in ${targetPath}`
133151
133334
  });
133152
133335
  }
133153
- const filePathObjects = filesToScan.map((filePath) => FilePath.create(filePath));
133336
+ const jstsFiles = filesToScan.filter((f74) => /\.(ts|tsx|js|jsx|mjs|cjs)$/.test(f74));
133337
+ const otherFiles = filesToScan.filter((f74) => !/\.(ts|tsx|js|jsx|mjs|cjs)$/.test(f74));
133338
+ const crossLangVulns = [];
133339
+ for (const filePath of otherFiles) {
133340
+ try {
133341
+ const content = await fs15.readFile(filePath, "utf-8");
133342
+ const lines = content.split("\n");
133343
+ const relPath = filePath.startsWith(targetPath) ? filePath.slice(targetPath.length).replace(/^\//, "") : filePath;
133344
+ const secretPatterns = [
133345
+ { regex: /(?:secret|password|api_key|apikey|token|jwt_secret|private_key)\s*[=:]\s*['"][^'"]{8,}['"]/gi, title: "Hardcoded secret", severity: "critical" },
133346
+ { regex: /(?:AWS_SECRET|GITHUB_TOKEN|SLACK_TOKEN)\s*[=:]\s*['"][^'"]+['"]/gi, title: "Hardcoded cloud credential", severity: "critical" }
133347
+ ];
133348
+ for (const pattern of secretPatterns) {
133349
+ for (let i58 = 0; i58 < lines.length; i58++) {
133350
+ if (pattern.regex.test(lines[i58])) {
133351
+ crossLangVulns.push({
133352
+ title: pattern.title,
133353
+ severity: pattern.severity,
133354
+ location: { file: relPath, line: i58 + 1 },
133355
+ description: `Potential hardcoded secret found at line ${i58 + 1}`,
133356
+ category: "sensitive-data"
133357
+ });
133358
+ }
133359
+ pattern.regex.lastIndex = 0;
133360
+ }
133361
+ }
133362
+ const sqlPatterns = /(?:execute|query|cursor\.execute)\s*\(\s*(?:f['"]|['"].*%s|['"].*\+\s*\w)/gi;
133363
+ for (let i58 = 0; i58 < lines.length; i58++) {
133364
+ if (sqlPatterns.test(lines[i58])) {
133365
+ crossLangVulns.push({
133366
+ title: "Potential SQL injection",
133367
+ severity: "high",
133368
+ location: { file: relPath, line: i58 + 1 },
133369
+ description: "String interpolation in SQL query \u2014 use parameterized queries",
133370
+ category: "injection"
133371
+ });
133372
+ }
133373
+ sqlPatterns.lastIndex = 0;
133374
+ }
133375
+ if (/allow_origins\s*=\s*\[?\s*['"]?\*['"]?\s*\]?/i.test(content)) {
133376
+ crossLangVulns.push({
133377
+ title: "CORS wildcard origin",
133378
+ severity: "high",
133379
+ location: { file: relPath, line: lines.findIndex((l75) => /allow_origins/i.test(l75)) + 1 },
133380
+ description: "CORS configured with wildcard (*) origin \u2014 restrict to specific domains",
133381
+ category: "security-misconfiguration"
133382
+ });
133383
+ }
133384
+ if (/(?:DEBUG|debug)\s*[=:]\s*(?:True|true|1)/i.test(content)) {
133385
+ crossLangVulns.push({
133386
+ title: "Debug mode enabled",
133387
+ severity: "medium",
133388
+ location: { file: relPath, line: lines.findIndex((l75) => /DEBUG\s*[=:]\s*(?:True|true|1)/i.test(l75)) + 1 },
133389
+ description: "Debug mode should be disabled in production",
133390
+ category: "security-misconfiguration"
133391
+ });
133392
+ }
133393
+ if (/\b(?:eval|exec)\s*\(/i.test(content)) {
133394
+ crossLangVulns.push({
133395
+ title: "Dangerous eval/exec usage",
133396
+ severity: "high",
133397
+ location: { file: relPath, line: lines.findIndex((l75) => /\b(?:eval|exec)\s*\(/.test(l75)) + 1 },
133398
+ description: "eval/exec can lead to code injection \u2014 avoid using with user input",
133399
+ category: "injection"
133400
+ });
133401
+ }
133402
+ } catch {
133403
+ }
133404
+ }
133405
+ const depManifests = ["requirements.txt", "pyproject.toml", "Gemfile", "go.mod", "Cargo.toml"];
133406
+ for (const manifest of depManifests) {
133407
+ const manifestPath = path16.join(targetPath, manifest);
133408
+ try {
133409
+ await fs15.access(manifestPath);
133410
+ crossLangVulns.push({
133411
+ title: "Dependency audit recommended",
133412
+ severity: "informational",
133413
+ location: { file: manifest, line: 1 },
133414
+ description: `Found ${manifest} \u2014 run language-specific dependency audit (e.g., pip-audit, npm audit, cargo audit)`,
133415
+ category: "dependencies"
133416
+ });
133417
+ } catch {
133418
+ }
133419
+ }
133420
+ const filePathObjects = jstsFiles.map((filePath) => FilePath.create(filePath));
133154
133421
  let sastResult = null;
133155
- if (payload.sast !== false) {
133422
+ if (payload.sast !== false && filePathObjects.length > 0) {
133156
133423
  const result = await scanner.scanFiles(filePathObjects);
133157
133424
  if (result.success) {
133158
133425
  sastResult = result.value;
@@ -133169,16 +133436,24 @@ var DomainTaskExecutor = class {
133169
133436
  dastResult = result.value;
133170
133437
  }
133171
133438
  }
133439
+ const crossLangSeverityCounts = {
133440
+ critical: crossLangVulns.filter((v62) => v62.severity === "critical").length,
133441
+ high: crossLangVulns.filter((v62) => v62.severity === "high").length,
133442
+ medium: crossLangVulns.filter((v62) => v62.severity === "medium").length,
133443
+ low: crossLangVulns.filter((v62) => v62.severity === "low").length,
133444
+ informational: crossLangVulns.filter((v62) => v62.severity === "informational").length
133445
+ };
133172
133446
  const summary = {
133173
- critical: (sastResult?.summary?.critical || 0) + (dastResult?.summary?.critical || 0),
133174
- high: (sastResult?.summary?.high || 0) + (dastResult?.summary?.high || 0),
133175
- medium: (sastResult?.summary?.medium || 0) + (dastResult?.summary?.medium || 0),
133176
- low: (sastResult?.summary?.low || 0) + (dastResult?.summary?.low || 0),
133177
- informational: (sastResult?.summary?.informational || 0) + (dastResult?.summary?.informational || 0)
133447
+ critical: (sastResult?.summary?.critical || 0) + (dastResult?.summary?.critical || 0) + crossLangSeverityCounts.critical,
133448
+ high: (sastResult?.summary?.high || 0) + (dastResult?.summary?.high || 0) + crossLangSeverityCounts.high,
133449
+ medium: (sastResult?.summary?.medium || 0) + (dastResult?.summary?.medium || 0) + crossLangSeverityCounts.medium,
133450
+ low: (sastResult?.summary?.low || 0) + (dastResult?.summary?.low || 0) + crossLangSeverityCounts.low,
133451
+ informational: (sastResult?.summary?.informational || 0) + (dastResult?.summary?.informational || 0) + crossLangSeverityCounts.informational
133178
133452
  };
133179
133453
  const allVulns = [
133180
133454
  ...sastResult?.vulnerabilities || [],
133181
- ...dastResult?.vulnerabilities || []
133455
+ ...dastResult?.vulnerabilities || [],
133456
+ ...crossLangVulns
133182
133457
  ];
133183
133458
  const topVulnerabilities = allVulns.sort((a37, b68) => {
133184
133459
  const severityOrder = { critical: 0, high: 1, medium: 2, low: 3, informational: 4 };
@@ -133205,7 +133480,12 @@ var DomainTaskExecutor = class {
133205
133480
  dast: payload.dast || false
133206
133481
  },
133207
133482
  filesScanned: filesToScan.length,
133208
- coverage: sastResult?.coverage
133483
+ jstsFilesScanned: jstsFiles.length,
133484
+ otherFilesScanned: otherFiles.length,
133485
+ coverage: sastResult?.coverage,
133486
+ ...otherFiles.length > 0 && jstsFiles.length === 0 ? {
133487
+ note: "Non-JS/TS files were scanned with cross-language pattern matching. For deeper analysis, use language-specific security tools."
133488
+ } : {}
133209
133489
  });
133210
133490
  } catch (error) {
133211
133491
  return err(toError(error));
@@ -133228,9 +133508,9 @@ var DomainTaskExecutor = class {
133228
133508
  edgesCreated: 0,
133229
133509
  target: targetPath,
133230
133510
  incremental: payload.incremental || false,
133231
- languages: payload.languages || ["typescript", "javascript"],
133511
+ languages: payload.languages || [],
133232
133512
  duration: Date.now() - startTime,
133233
- warning: `No source files found in ${targetPath}`
133513
+ warning: `No source files found in ${targetPath}. Searched for: TypeScript, JavaScript, Python, Go, Rust, Java, Ruby, C/C++, and more.`
133234
133514
  });
133235
133515
  }
133236
133516
  const result = await kg.index({
@@ -133244,11 +133524,35 @@ var DomainTaskExecutor = class {
133244
133524
  }
133245
133525
  const indexResult = result.value;
133246
133526
  const detectedLanguages = /* @__PURE__ */ new Set();
133527
+ const extToLang = {
133528
+ ts: "typescript",
133529
+ tsx: "typescript",
133530
+ js: "javascript",
133531
+ jsx: "javascript",
133532
+ mjs: "javascript",
133533
+ cjs: "javascript",
133534
+ py: "python",
133535
+ pyw: "python",
133536
+ go: "go",
133537
+ rs: "rust",
133538
+ java: "java",
133539
+ kt: "kotlin",
133540
+ kts: "kotlin",
133541
+ rb: "ruby",
133542
+ cs: "csharp",
133543
+ php: "php",
133544
+ swift: "swift",
133545
+ c: "c",
133546
+ h: "c",
133547
+ cpp: "cpp",
133548
+ hpp: "cpp",
133549
+ cc: "cpp",
133550
+ scala: "scala"
133551
+ };
133247
133552
  for (const file of filesToIndex) {
133248
133553
  const ext = path16.extname(file).slice(1);
133249
- if (["ts", "tsx"].includes(ext)) detectedLanguages.add("typescript");
133250
- if (["js", "jsx", "mjs", "cjs"].includes(ext)) detectedLanguages.add("javascript");
133251
- if (ext === "py") detectedLanguages.add("python");
133554
+ const lang = extToLang[ext];
133555
+ if (lang) detectedLanguages.add(lang);
133252
133556
  }
133253
133557
  return ok({
133254
133558
  filesIndexed: indexResult.filesIndexed,
@@ -133346,25 +133650,103 @@ var DomainTaskExecutor = class {
133346
133650
  });
133347
133651
  this.taskHandlers.set("predict-defects", async (task) => {
133348
133652
  const payload = task.payload;
133349
- return ok({
133350
- predictedDefects: [
133351
- {
133352
- file: `${payload.target}/complex-module.ts`,
133353
- probability: 0.78,
133354
- reason: "High cyclomatic complexity combined with low test coverage"
133355
- },
133356
- {
133357
- file: `${payload.target}/legacy-handler.ts`,
133358
- probability: 0.65,
133359
- reason: "Frequent changes in recent commits with error-prone patterns"
133653
+ try {
133654
+ const targetPath = payload.target || process.cwd();
133655
+ const minConfidence = payload.minConfidence || 0.5;
133656
+ const sourceFiles = await discoverSourceFiles(targetPath, { includeTests: false });
133657
+ if (sourceFiles.length === 0) {
133658
+ return ok({
133659
+ predictedDefects: [],
133660
+ riskScore: 0,
133661
+ recommendations: [
133662
+ `No source files found in ${targetPath}. Ensure the path contains source code files.`
133663
+ ],
133664
+ warning: `No source files found in ${targetPath}`,
133665
+ filesAnalyzed: 0
133666
+ });
133667
+ }
133668
+ const predictedDefects = [];
133669
+ for (const filePath of sourceFiles) {
133670
+ try {
133671
+ const content = await fs15.readFile(filePath, "utf-8");
133672
+ const lines = content.split("\n");
133673
+ const lineCount = lines.length;
133674
+ let probability = 0;
133675
+ const reasons = [];
133676
+ if (lineCount > 500) {
133677
+ probability += 0.25;
133678
+ reasons.push(`Large file (${lineCount} lines)`);
133679
+ } else if (lineCount > 300) {
133680
+ probability += 0.15;
133681
+ reasons.push(`Medium-large file (${lineCount} lines)`);
133682
+ }
133683
+ const branchKeywords = content.match(/\b(if|else|switch|case|for|while|catch|&&|\|\|)\b/g) || [];
133684
+ const branchDensity = branchKeywords.length / Math.max(lineCount, 1);
133685
+ if (branchDensity > 0.15) {
133686
+ probability += 0.25;
133687
+ reasons.push(`High branch density (${branchKeywords.length} branches in ${lineCount} lines)`);
133688
+ } else if (branchDensity > 0.08) {
133689
+ probability += 0.1;
133690
+ reasons.push("Moderate branch complexity");
133691
+ }
133692
+ const maxIndent = Math.max(...lines.map((l75) => {
133693
+ const match = l75.match(/^(\s*)/);
133694
+ return match ? match[1].length : 0;
133695
+ }));
133696
+ if (maxIndent > 20) {
133697
+ probability += 0.15;
133698
+ reasons.push("Deep nesting detected");
133699
+ }
133700
+ const debtComments = (content.match(/\b(TODO|FIXME|HACK|XXX|WORKAROUND)\b/gi) || []).length;
133701
+ if (debtComments > 3) {
133702
+ probability += 0.15;
133703
+ reasons.push(`${debtComments} technical debt markers`);
133704
+ }
133705
+ const functionStarts = (content.match(/\b(function|def|func|async)\b/g) || []).length;
133706
+ if (functionStarts > 0 && lineCount / functionStarts > 80) {
133707
+ probability += 0.1;
133708
+ reasons.push("Potentially long functions");
133709
+ }
133710
+ probability = Math.min(probability, 0.95);
133711
+ if (probability >= minConfidence) {
133712
+ const relativePath = filePath.startsWith(targetPath) ? filePath.slice(targetPath.length).replace(/^\//, "") : filePath;
133713
+ predictedDefects.push({
133714
+ file: relativePath,
133715
+ probability: Math.round(probability * 100) / 100,
133716
+ reason: reasons.join("; ")
133717
+ });
133718
+ }
133719
+ } catch {
133360
133720
  }
133361
- ],
133362
- riskScore: 42,
133363
- recommendations: [
133364
- "Add integration tests for complex-module.ts",
133365
- "Refactor legacy-handler.ts to reduce complexity"
133366
- ]
133367
- });
133721
+ }
133722
+ predictedDefects.sort((a37, b68) => b68.probability - a37.probability);
133723
+ const avgProb = predictedDefects.length > 0 ? predictedDefects.reduce((sum, d74) => sum + d74.probability, 0) / predictedDefects.length : 0;
133724
+ const riskScore = Math.round(avgProb * 100);
133725
+ const recommendations = [];
133726
+ if (predictedDefects.length > 0) {
133727
+ recommendations.push(`${predictedDefects.length} files flagged for potential defects out of ${sourceFiles.length} analyzed`);
133728
+ const topFile = predictedDefects[0];
133729
+ recommendations.push(`Highest risk: ${topFile.file} (${Math.round(topFile.probability * 100)}%) \u2014 ${topFile.reason}`);
133730
+ }
133731
+ if (predictedDefects.some((d74) => d74.reason.includes("Large file"))) {
133732
+ recommendations.push("Consider splitting large files to reduce complexity");
133733
+ }
133734
+ if (predictedDefects.some((d74) => d74.reason.includes("technical debt"))) {
133735
+ recommendations.push("Address TODO/FIXME comments to reduce technical debt");
133736
+ }
133737
+ if (predictedDefects.length === 0) {
133738
+ recommendations.push("No files exceeded the defect probability threshold \u2014 code looks healthy");
133739
+ }
133740
+ return ok({
133741
+ predictedDefects: predictedDefects.slice(0, 20),
133742
+ // Top 20
133743
+ riskScore,
133744
+ recommendations,
133745
+ filesAnalyzed: sourceFiles.length
133746
+ });
133747
+ } catch (error) {
133748
+ return err(toError(error));
133749
+ }
133368
133750
  });
133369
133751
  this.taskHandlers.set("validate-requirements", async (task) => {
133370
133752
  const payload = task.payload;
@@ -137584,50 +137966,54 @@ var coverageAnalyzeConfig = {
137584
137966
  const learning = generateV2LearningFeedback("coverage-analyzer");
137585
137967
  const detailedGaps = gaps.map((gap, i58) => {
137586
137968
  const g67 = gap;
137969
+ if (!g67?.file) return null;
137587
137970
  return {
137588
137971
  id: `gap-${Date.now()}-${i58}`,
137589
- file: g67?.file || `src/module${i58}.ts`,
137590
- line: g67?.lines?.[0] || 10 + i58 * 5,
137591
- uncoveredLines: g67?.lines || [10 + i58 * 5, 20 + i58 * 5],
137592
- type: g67?.type || "uncovered-line",
137593
- severity: g67?.severity || (i58 < 2 ? "high" : "medium"),
137594
- reason: g67?.reason || "Missing test case",
137595
- priority: g67?.priority || (i58 < 2 ? "high" : "medium"),
137596
- suggestion: g67?.suggestedTest || `Add test for line ${10 + i58 * 5}`,
137597
- suggestedTest: g67?.suggestedTest || `Add test for line ${10 + i58 * 5}`,
137598
- riskScore: g67?.riskScore || 0.8 - i58 * 0.1,
137599
- confidence: g67?.confidence || 0.85
137972
+ file: g67.file,
137973
+ line: g67.lines?.[0] || 0,
137974
+ uncoveredLines: g67.lines || [],
137975
+ type: g67.type || "uncovered-line",
137976
+ severity: g67.severity || "medium",
137977
+ reason: g67.reason || "Missing test case",
137978
+ priority: g67.priority || "medium",
137979
+ suggestion: g67.suggestedTest || "Add test coverage",
137980
+ suggestedTest: g67.suggestedTest || "Add test coverage",
137981
+ riskScore: g67.riskScore || 0.5,
137982
+ confidence: g67.confidence || 0.7
137600
137983
  };
137601
- });
137602
- return {
137603
- // V2-compatible fields
137604
- coverageByFile: Array.from({ length: totalFiles }, (_56, i58) => {
137605
- const variation = (i58 % 3 - 1) * 5;
137606
- return {
137607
- file: `src/module${i58}.ts`,
137608
- lineCoverage: Math.max(0, Math.min(100, lineCoverage + variation)),
137609
- branchCoverage: Math.max(0, Math.min(100, branchCoverage + variation - 2)),
137610
- functionCoverage: Math.max(0, Math.min(100, functionCoverage + variation + 2))
137611
- };
137612
- }),
137984
+ }).filter((g67) => g67 !== null);
137985
+ const coverageByFileData = data.coverageByFile;
137986
+ const realCoverageByFile = coverageByFileData ? coverageByFileData.map((f74) => ({
137987
+ file: f74.file,
137988
+ lineCoverage: f74.lineCoverage || 0,
137989
+ branchCoverage: f74.branchCoverage || 0,
137990
+ functionCoverage: f74.functionCoverage || 0
137991
+ })) : [];
137992
+ return {
137993
+ // V2-compatible fields — only real data, no synthetic file paths
137994
+ coverageByFile: realCoverageByFile,
137613
137995
  gapAnalysis: {
137614
137996
  totalGaps: detailedGaps.length,
137615
137997
  highPriority: detailedGaps.filter((g67) => g67.priority === "high").length,
137616
137998
  gaps: detailedGaps
137617
137999
  },
137618
138000
  trends: {
137619
- lineCoverageTrend: "stable",
137620
- branchCoverageTrend: "improving",
137621
- weeklyChange: 2.5
138001
+ lineCoverageTrend: totalFiles > 0 ? "stable" : "no-data",
138002
+ branchCoverageTrend: totalFiles > 0 ? "stable" : "no-data",
138003
+ weeklyChange: 0
137622
138004
  },
137623
- aiInsights: {
137624
- recommendations: [
137625
- "Focus on uncovered branches in authentication module",
137626
- "Add edge case tests for error handling paths",
137627
- "Consider property-based testing for utility functions"
138005
+ aiInsights: totalFiles > 0 ? {
138006
+ recommendations: data.recommendations || [
138007
+ "Run tests with coverage enabled to get accurate metrics"
137628
138008
  ],
137629
138009
  riskAssessment: lineCoverage < 70 ? "high" : lineCoverage < 85 ? "medium" : "low",
137630
138010
  confidence: 0.88
138011
+ } : {
138012
+ recommendations: [
138013
+ "No coverage data found. Run tests with coverage first (e.g., npm test -- --coverage, or pytest --cov)"
138014
+ ],
138015
+ riskAssessment: "unknown",
138016
+ confidence: 0
137631
138017
  },
137632
138018
  learning,
137633
138019
  // V3 fields
@@ -153347,14 +153733,22 @@ async function handleTaskOrchestrate(params) {
153347
153733
  }
153348
153734
  const { queen, workflowOrchestrator } = getFleetState();
153349
153735
  try {
153736
+ const inferredDomain = params.context?.project || inferDomainFromDescription(params.task);
153737
+ const inferredIsCritical = params.priority === "critical" || /\b(security|vulnerability|cve|owasp|critical|production|exploit)\b/i.test(params.task);
153350
153738
  const router = await getTaskRouter();
153351
153739
  const routingResult = await router.routeTask({
153352
153740
  task: params.task,
153353
153741
  codeContext: params.codeContext,
153354
153742
  filePaths: params.filePaths,
153355
153743
  manualTier: params.manualTier,
153356
- isCritical: params.priority === "critical",
153357
- domain: params.context?.project
153744
+ isCritical: inferredIsCritical,
153745
+ agentType: `qe-${inferredDomain}`,
153746
+ domain: inferredDomain,
153747
+ metadata: {
153748
+ inferredDomain,
153749
+ hasCodeContext: !!params.codeContext,
153750
+ fileCount: params.filePaths?.length
153751
+ }
153358
153752
  });
153359
153753
  const reasoningBankService = await getReasoningBankService();
153360
153754
  const experienceGuidance = await reasoningBankService.getExperienceGuidance(
@@ -153492,14 +153886,22 @@ async function handleTaskOrchestrate(params) {
153492
153886
  async function handleModelRoute(params) {
153493
153887
  try {
153494
153888
  const router = await getTaskRouter();
153889
+ const inferredDomain = params.domain || inferDomainFromDescription(params.task);
153890
+ const inferredIsCritical = params.isCritical ?? /\b(security|vulnerability|cve|owasp|critical|production|exploit)\b/i.test(params.task);
153495
153891
  const result = await router.routeTask({
153496
153892
  task: params.task,
153497
153893
  codeContext: params.codeContext,
153498
153894
  filePaths: params.filePaths,
153499
153895
  manualTier: params.manualTier,
153500
- isCritical: params.isCritical,
153501
- agentType: params.agentType,
153502
- domain: params.domain
153896
+ isCritical: inferredIsCritical,
153897
+ agentType: params.agentType || `qe-${inferredDomain}`,
153898
+ domain: inferredDomain,
153899
+ // Pass metadata to help the complexity analyzer
153900
+ metadata: {
153901
+ inferredDomain,
153902
+ hasCodeContext: !!params.codeContext,
153903
+ fileCount: params.filePaths?.length
153904
+ }
153503
153905
  });
153504
153906
  return {
153505
153907
  success: true,
@@ -153562,6 +153964,43 @@ async function handleRoutingMetrics(params) {
153562
153964
  };
153563
153965
  }
153564
153966
  }
153967
+ function inferDomainFromDescription(description) {
153968
+ const lower = description.toLowerCase();
153969
+ if (/\b(security|vulnerabilit|cve|owasp|secret|credential|injection|xss|csrf)\b/.test(lower)) {
153970
+ return "security-compliance";
153971
+ }
153972
+ if (/\b(chaos|resilience|fault.?inject|disaster|failover)\b/.test(lower)) {
153973
+ return "chaos-resilience";
153974
+ }
153975
+ if (/\b(defect|bug.?predict|risk.?assess|mutation)\b/.test(lower)) {
153976
+ return "defect-intelligence";
153977
+ }
153978
+ if (/\b(coverage|uncovered|gap.?analy)\b/.test(lower)) {
153979
+ return "coverage-analysis";
153980
+ }
153981
+ if (/\b(quality|code.?review|maintain|tech.?debt)\b/.test(lower)) {
153982
+ return "quality-assessment";
153983
+ }
153984
+ if (/\b(contract|api.?compat|breaking.?change|pact)\b/.test(lower)) {
153985
+ return "contract-testing";
153986
+ }
153987
+ if (/\b(index|knowledge.?graph|semantic|code.?intel)\b/.test(lower)) {
153988
+ return "code-intelligence";
153989
+ }
153990
+ if (/\b(accessib|a11y|wcag|screen.?read)\b/.test(lower)) {
153991
+ return "visual-accessibility";
153992
+ }
153993
+ if (/\b(requirement|bdd|acceptance|user.?stor)\b/.test(lower)) {
153994
+ return "requirements-validation";
153995
+ }
153996
+ if (/\b(generat.*test|test.*generat|write.*test|create.*test)\b/.test(lower)) {
153997
+ return "test-generation";
153998
+ }
153999
+ if (/\b(run.*test|execut.*test)\b/.test(lower)) {
154000
+ return "test-execution";
154001
+ }
154002
+ return "test-generation";
154003
+ }
153565
154004
  function inferTaskType(description) {
153566
154005
  const lower = description.toLowerCase();
153567
154006
  if (/run\s+(?:\w+\s+)*tests?/.test(lower) || /execute\s+(?:\w+\s+)*tests?/.test(lower) || lower.includes("run tests") || lower.includes("execute tests")) {
@@ -155321,7 +155760,18 @@ var MCPProtocolServer = class {
155321
155760
  async start() {
155322
155761
  await initializeConnectionPool();
155323
155762
  this.transport.onRequest(async (request) => {
155324
- return this.handleRequest(request);
155763
+ try {
155764
+ return await this.handleRequest(request);
155765
+ } catch (err4) {
155766
+ const message = err4 instanceof Error ? err4.message : String(err4);
155767
+ console.error(`[MCP] Unhandled error in request handler: ${message}`);
155768
+ return {
155769
+ content: [{
155770
+ type: "text",
155771
+ text: JSON.stringify({ success: false, error: `Internal error: ${message}` })
155772
+ }]
155773
+ };
155774
+ }
155325
155775
  });
155326
155776
  this.transport.onNotification(async (notification) => {
155327
155777
  await this.handleNotification(notification);