agentic-qe 3.6.10 → 3.6.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/.claude/helpers/learning-service.mjs +2 -0
  2. package/.claude/helpers/statusline-v3.cjs +2 -0
  3. package/.claude/skills/skills-manifest.json +1 -1
  4. package/package.json +1 -1
  5. package/scripts/migrate-v2-to-v3-memory.js +2 -0
  6. package/scripts/sync-claude-flow.cjs +1 -0
  7. package/v3/CHANGELOG.md +39 -0
  8. package/v3/dist/adapters/claude-flow/trajectory-bridge.js +2 -2
  9. package/v3/dist/adapters/claude-flow/trajectory-bridge.js.map +1 -1
  10. package/v3/dist/benchmarks/performance-benchmarks.js +1 -1
  11. package/v3/dist/cli/bundle.js +659 -427
  12. package/v3/dist/cli/commands/code.d.ts.map +1 -1
  13. package/v3/dist/cli/commands/code.js +9 -85
  14. package/v3/dist/cli/commands/code.js.map +1 -1
  15. package/v3/dist/cli/commands/coverage.d.ts.map +1 -1
  16. package/v3/dist/cli/commands/coverage.js +3 -28
  17. package/v3/dist/cli/commands/coverage.js.map +1 -1
  18. package/v3/dist/cli/commands/learning-helpers.d.ts.map +1 -1
  19. package/v3/dist/cli/commands/learning-helpers.js +3 -4
  20. package/v3/dist/cli/commands/learning-helpers.js.map +1 -1
  21. package/v3/dist/cli/commands/learning.d.ts.map +1 -1
  22. package/v3/dist/cli/commands/learning.js +5 -8
  23. package/v3/dist/cli/commands/learning.js.map +1 -1
  24. package/v3/dist/cli/commands/migrate.js +2 -2
  25. package/v3/dist/cli/commands/security.d.ts.map +1 -1
  26. package/v3/dist/cli/commands/security.js +3 -29
  27. package/v3/dist/cli/commands/security.js.map +1 -1
  28. package/v3/dist/cli/commands/test.d.ts.map +1 -1
  29. package/v3/dist/cli/commands/test.js +5 -58
  30. package/v3/dist/cli/commands/test.js.map +1 -1
  31. package/v3/dist/cli/utils/file-discovery.d.ts +27 -0
  32. package/v3/dist/cli/utils/file-discovery.d.ts.map +1 -0
  33. package/v3/dist/cli/utils/file-discovery.js +105 -0
  34. package/v3/dist/cli/utils/file-discovery.js.map +1 -0
  35. package/v3/dist/coordination/constants.d.ts +1 -1
  36. package/v3/dist/coordination/constants.js +1 -1
  37. package/v3/dist/coordination/task-executor.d.ts.map +1 -1
  38. package/v3/dist/coordination/task-executor.js +612 -104
  39. package/v3/dist/coordination/task-executor.js.map +1 -1
  40. package/v3/dist/domains/code-intelligence/coordinator-hypergraph.js +2 -2
  41. package/v3/dist/domains/code-intelligence/coordinator-hypergraph.js.map +1 -1
  42. package/v3/dist/domains/code-intelligence/coordinator.d.ts.map +1 -1
  43. package/v3/dist/domains/code-intelligence/coordinator.js +10 -3
  44. package/v3/dist/domains/code-intelligence/coordinator.js.map +1 -1
  45. package/v3/dist/domains/code-intelligence/services/metric-collector/index.d.ts.map +1 -1
  46. package/v3/dist/domains/code-intelligence/services/metric-collector/index.js +10 -0
  47. package/v3/dist/domains/code-intelligence/services/metric-collector/index.js.map +1 -1
  48. package/v3/dist/domains/code-intelligence/services/metric-collector/interfaces.d.ts +7 -1
  49. package/v3/dist/domains/code-intelligence/services/metric-collector/interfaces.d.ts.map +1 -1
  50. package/v3/dist/domains/code-intelligence/services/metric-collector/interfaces.js +10 -1
  51. package/v3/dist/domains/code-intelligence/services/metric-collector/interfaces.js.map +1 -1
  52. package/v3/dist/domains/code-intelligence/services/metric-collector/loc-counter.js +34 -10
  53. package/v3/dist/domains/code-intelligence/services/metric-collector/loc-counter.js.map +1 -1
  54. package/v3/dist/domains/coverage-analysis/coordinator.js +1 -1
  55. package/v3/dist/domains/coverage-analysis/services/coverage-analyzer.js +1 -1
  56. package/v3/dist/domains/coverage-analysis/services/coverage-embedder.d.ts +1 -1
  57. package/v3/dist/domains/coverage-analysis/services/coverage-embedder.js +1 -1
  58. package/v3/dist/domains/coverage-analysis/services/gap-detector.js +1 -1
  59. package/v3/dist/domains/coverage-analysis/services/ghost-coverage-analyzer.js +1 -1
  60. package/v3/dist/domains/coverage-analysis/services/hnsw-index.d.ts +10 -1
  61. package/v3/dist/domains/coverage-analysis/services/hnsw-index.d.ts.map +1 -1
  62. package/v3/dist/domains/coverage-analysis/services/hnsw-index.js +40 -5
  63. package/v3/dist/domains/coverage-analysis/services/hnsw-index.js.map +1 -1
  64. package/v3/dist/domains/coverage-analysis/services/sublinear-analyzer.d.ts +1 -1
  65. package/v3/dist/domains/coverage-analysis/services/sublinear-analyzer.js +1 -1
  66. package/v3/dist/init/fleet-integration.d.ts.map +1 -1
  67. package/v3/dist/init/fleet-integration.js +3 -4
  68. package/v3/dist/init/fleet-integration.js.map +1 -1
  69. package/v3/dist/init/init-wizard-hooks.d.ts +8 -1
  70. package/v3/dist/init/init-wizard-hooks.d.ts.map +1 -1
  71. package/v3/dist/init/init-wizard-hooks.js +47 -39
  72. package/v3/dist/init/init-wizard-hooks.js.map +1 -1
  73. package/v3/dist/init/init-wizard-migration.d.ts.map +1 -1
  74. package/v3/dist/init/init-wizard-migration.js +3 -7
  75. package/v3/dist/init/init-wizard-migration.js.map +1 -1
  76. package/v3/dist/init/init-wizard-steps.d.ts.map +1 -1
  77. package/v3/dist/init/init-wizard-steps.js +3 -4
  78. package/v3/dist/init/init-wizard-steps.js.map +1 -1
  79. package/v3/dist/init/migration/data-migrator.d.ts.map +1 -1
  80. package/v3/dist/init/migration/data-migrator.js +6 -10
  81. package/v3/dist/init/migration/data-migrator.js.map +1 -1
  82. package/v3/dist/init/migration/detector.d.ts.map +1 -1
  83. package/v3/dist/init/migration/detector.js +2 -4
  84. package/v3/dist/init/migration/detector.js.map +1 -1
  85. package/v3/dist/init/phases/01-detection.d.ts.map +1 -1
  86. package/v3/dist/init/phases/01-detection.js +2 -4
  87. package/v3/dist/init/phases/01-detection.js.map +1 -1
  88. package/v3/dist/init/phases/06-code-intelligence.d.ts.map +1 -1
  89. package/v3/dist/init/phases/06-code-intelligence.js +4 -6
  90. package/v3/dist/init/phases/06-code-intelligence.js.map +1 -1
  91. package/v3/dist/init/phases/07-hooks.d.ts +22 -1
  92. package/v3/dist/init/phases/07-hooks.d.ts.map +1 -1
  93. package/v3/dist/init/phases/07-hooks.js +137 -51
  94. package/v3/dist/init/phases/07-hooks.js.map +1 -1
  95. package/v3/dist/init/phases/12-verification.d.ts.map +1 -1
  96. package/v3/dist/init/phases/12-verification.js +2 -4
  97. package/v3/dist/init/phases/12-verification.js.map +1 -1
  98. package/v3/dist/init/settings-merge.d.ts +35 -0
  99. package/v3/dist/init/settings-merge.d.ts.map +1 -0
  100. package/v3/dist/init/settings-merge.js +140 -0
  101. package/v3/dist/init/settings-merge.js.map +1 -0
  102. package/v3/dist/integrations/agentic-flow/model-router/router.js +1 -1
  103. package/v3/dist/integrations/agentic-flow/model-router/router.js.map +1 -1
  104. package/v3/dist/integrations/agentic-flow/model-router/score-calculator.d.ts.map +1 -1
  105. package/v3/dist/integrations/agentic-flow/model-router/score-calculator.js +18 -3
  106. package/v3/dist/integrations/agentic-flow/model-router/score-calculator.js.map +1 -1
  107. package/v3/dist/integrations/agentic-flow/model-router/signal-collector.d.ts +3 -3
  108. package/v3/dist/integrations/agentic-flow/model-router/signal-collector.d.ts.map +1 -1
  109. package/v3/dist/integrations/agentic-flow/model-router/signal-collector.js +18 -0
  110. package/v3/dist/integrations/agentic-flow/model-router/signal-collector.js.map +1 -1
  111. package/v3/dist/integrations/embeddings/cache/EmbeddingCache.d.ts.map +1 -1
  112. package/v3/dist/integrations/embeddings/cache/EmbeddingCache.js +2 -2
  113. package/v3/dist/integrations/embeddings/cache/EmbeddingCache.js.map +1 -1
  114. package/v3/dist/kernel/constants.d.ts +1 -1
  115. package/v3/dist/kernel/constants.js +1 -1
  116. package/v3/dist/kernel/unified-memory-hnsw.d.ts.map +1 -1
  117. package/v3/dist/kernel/unified-memory-hnsw.js +25 -6
  118. package/v3/dist/kernel/unified-memory-hnsw.js.map +1 -1
  119. package/v3/dist/kernel/unified-memory-migration.d.ts.map +1 -1
  120. package/v3/dist/kernel/unified-memory-migration.js +3 -3
  121. package/v3/dist/kernel/unified-memory-migration.js.map +1 -1
  122. package/v3/dist/learning/metrics-tracker.d.ts.map +1 -1
  123. package/v3/dist/learning/metrics-tracker.js +2 -2
  124. package/v3/dist/learning/metrics-tracker.js.map +1 -1
  125. package/v3/dist/learning/sqlite-persistence.d.ts.map +1 -1
  126. package/v3/dist/learning/sqlite-persistence.js +3 -6
  127. package/v3/dist/learning/sqlite-persistence.js.map +1 -1
  128. package/v3/dist/learning/v2-to-v3-migration.d.ts.map +1 -1
  129. package/v3/dist/learning/v2-to-v3-migration.js +4 -5
  130. package/v3/dist/learning/v2-to-v3-migration.js.map +1 -1
  131. package/v3/dist/mcp/bundle.js +1266 -245
  132. package/v3/dist/mcp/handlers/domain-handler-configs.d.ts.map +1 -1
  133. package/v3/dist/mcp/handlers/domain-handler-configs.js +40 -31
  134. package/v3/dist/mcp/handlers/domain-handler-configs.js.map +1 -1
  135. package/v3/dist/mcp/handlers/task-handlers.d.ts.map +1 -1
  136. package/v3/dist/mcp/handlers/task-handlers.js +68 -5
  137. package/v3/dist/mcp/handlers/task-handlers.js.map +1 -1
  138. package/v3/dist/mcp/protocol-server.d.ts.map +1 -1
  139. package/v3/dist/mcp/protocol-server.js +16 -2
  140. package/v3/dist/mcp/protocol-server.js.map +1 -1
  141. package/v3/dist/mcp/tools/security-compliance/scan.d.ts +3 -1
  142. package/v3/dist/mcp/tools/security-compliance/scan.d.ts.map +1 -1
  143. package/v3/dist/mcp/tools/security-compliance/scan.js +417 -72
  144. package/v3/dist/mcp/tools/security-compliance/scan.js.map +1 -1
  145. package/v3/dist/planning/plan-executor.d.ts.map +1 -1
  146. package/v3/dist/planning/plan-executor.js +2 -2
  147. package/v3/dist/planning/plan-executor.js.map +1 -1
  148. package/v3/dist/shared/safe-db.d.ts +32 -0
  149. package/v3/dist/shared/safe-db.d.ts.map +1 -0
  150. package/v3/dist/shared/safe-db.js +41 -0
  151. package/v3/dist/shared/safe-db.js.map +1 -0
  152. package/v3/dist/sync/claude-flow-bridge.js +5 -5
  153. package/v3/dist/sync/claude-flow-bridge.js.map +1 -1
  154. package/v3/dist/sync/embeddings/sync-embedding-generator.js +3 -3
  155. package/v3/dist/sync/embeddings/sync-embedding-generator.js.map +1 -1
  156. package/v3/dist/sync/readers/sqlite-reader.d.ts.map +1 -1
  157. package/v3/dist/sync/readers/sqlite-reader.js +2 -2
  158. package/v3/dist/sync/readers/sqlite-reader.js.map +1 -1
  159. package/v3/package.json +1 -1
@@ -4421,7 +4421,7 @@ var init_constants = __esm({
4421
4421
  /**
4422
4422
  * Vector dimension for coverage analysis embeddings.
4423
4423
  */
4424
- COVERAGE_VECTOR_DIMENSION: 128
4424
+ COVERAGE_VECTOR_DIMENSION: 768
4425
4425
  };
4426
4426
  AGENT_CONSTANTS = {
4427
4427
  /**
@@ -4643,6 +4643,12 @@ var init_gnn = __esm({
4643
4643
  });
4644
4644
 
4645
4645
  // src/kernel/unified-memory-hnsw.ts
4646
+ var unified_memory_hnsw_exports = {};
4647
+ __export(unified_memory_hnsw_exports, {
4648
+ BinaryHeap: () => BinaryHeap,
4649
+ InMemoryHNSWIndex: () => InMemoryHNSWIndex,
4650
+ RuvectorFlatIndex: () => RuvectorFlatIndex
4651
+ });
4646
4652
  function computeNorm(v62) {
4647
4653
  let sum = 0;
4648
4654
  for (let i58 = 0; i58 < v62.length; i58++) sum += v62[i58] * v62[i58];
@@ -5036,7 +5042,10 @@ var init_unified_memory_hnsw = __esm({
5036
5042
  search(query, k68) {
5037
5043
  if (this.ids.length === 0) return [];
5038
5044
  const actualK = Math.min(k68, this.ids.length);
5039
- if (ruvectorDifferentiableSearch && this.vectors.length > 0) {
5045
+ const storedDim = this.vectors.length > 0 ? this.vectors[0].length : 0;
5046
+ const queryDim = query.length;
5047
+ const dimensionsMatch = storedDim === queryDim;
5048
+ if (ruvectorDifferentiableSearch && this.vectors.length > 0 && dimensionsMatch) {
5040
5049
  const queryF322 = new Float32Array(query);
5041
5050
  const queryNorm2 = computeNorm(queryF322);
5042
5051
  const result = ruvectorDifferentiableSearch(
@@ -5054,10 +5063,20 @@ var init_unified_memory_hnsw = __esm({
5054
5063
  const queryNorm = computeNorm(queryF32);
5055
5064
  const scored = [];
5056
5065
  for (let i58 = 0; i58 < this.ids.length; i58++) {
5057
- scored.push({
5058
- id: this.ids[i58],
5059
- score: fastCosine(queryF32, this.vectors[i58], queryNorm, this.norms[i58])
5060
- });
5066
+ const vec = this.vectors[i58];
5067
+ if (vec.length !== queryF32.length) {
5068
+ if (i58 === 0) {
5069
+ console.warn(
5070
+ `[RuvectorFlatIndex] Dimension mismatch: query=${queryF32.length}, stored=${vec.length}. Skipping ${this.ids.length} mismatched vectors. Re-index with correct dimensions.`
5071
+ );
5072
+ }
5073
+ continue;
5074
+ } else {
5075
+ scored.push({
5076
+ id: this.ids[i58],
5077
+ score: fastCosine(queryF32, vec, queryNorm, this.norms[i58])
5078
+ });
5079
+ }
5061
5080
  }
5062
5081
  scored.sort((a37, b68) => b68.score - a37.score);
5063
5082
  return scored.slice(0, actualK);
@@ -11337,7 +11356,7 @@ function createHNSWIndex(memory, config) {
11337
11356
  return new HNSWIndex(memory, config);
11338
11357
  }
11339
11358
  async function benchmarkHNSW(index, vectorCount = 1e4, searchCount = 1e3) {
11340
- const dimensions = 128;
11359
+ const dimensions = 768;
11341
11360
  const startInsert = performance.now();
11342
11361
  for (let i58 = 0; i58 < vectorCount; i58++) {
11343
11362
  const vector = Array.from({ length: dimensions }, () => Math.random());
@@ -11366,7 +11385,7 @@ var init_hnsw_index = __esm({
11366
11385
  QEGNNEmbeddingIndexClass = null;
11367
11386
  ruvectorLoaded = false;
11368
11387
  DEFAULT_HNSW_CONFIG = {
11369
- dimensions: 128,
11388
+ dimensions: 768,
11370
11389
  M: 16,
11371
11390
  efConstruction: 200,
11372
11391
  efSearch: 100,
@@ -11461,7 +11480,7 @@ var init_hnsw_index = __esm({
11461
11480
  if (!this.initialized) {
11462
11481
  await this.initialize();
11463
11482
  }
11464
- this.validateVector(vector);
11483
+ vector = this.validateVector(vector);
11465
11484
  if (this.keyToLabel.has(key)) {
11466
11485
  await this.delete(key);
11467
11486
  }
@@ -11490,7 +11509,7 @@ var init_hnsw_index = __esm({
11490
11509
  if (!this.initialized) {
11491
11510
  await this.initialize();
11492
11511
  }
11493
- this.validateVector(query);
11512
+ query = this.validateVector(query);
11494
11513
  const startTime = performance.now();
11495
11514
  const results = this.stats.vectorCount > 0 ? this.searchRuvector(query, k68) : [];
11496
11515
  const endTime = performance.now();
@@ -11615,17 +11634,46 @@ var init_hnsw_index = __esm({
11615
11634
  // ============================================================================
11616
11635
  // Private Helper Methods
11617
11636
  // ============================================================================
11637
+ /**
11638
+ * Validate and auto-resize vectors to match HNSW configured dimensions.
11639
+ * Fix #279: Prevents Rust WASM panic when RealEmbeddings (768-dim) are
11640
+ * passed to a mismatched-dim HNSW index.
11641
+ */
11618
11642
  validateVector(vector) {
11619
11643
  if (vector.length !== this.config.dimensions) {
11620
- throw new Error(
11621
- `Vector dimension mismatch: expected ${this.config.dimensions}, got ${vector.length}`
11622
- );
11644
+ return this.resizeVector(vector, this.config.dimensions);
11623
11645
  }
11624
11646
  for (let i58 = 0; i58 < vector.length; i58++) {
11625
11647
  if (!Number.isFinite(vector[i58])) {
11626
11648
  throw new Error(`Invalid vector value at index ${i58}: ${vector[i58]}`);
11627
11649
  }
11628
11650
  }
11651
+ return vector;
11652
+ }
11653
+ /**
11654
+ * Resize vector to target dimensions using averaging (shrink) or zero-padding (grow).
11655
+ */
11656
+ resizeVector(vector, targetDim) {
11657
+ if (vector.length === targetDim) return vector;
11658
+ if (vector.length > targetDim) {
11659
+ const result2 = new Array(targetDim).fill(0);
11660
+ const ratio = vector.length / targetDim;
11661
+ for (let i58 = 0; i58 < targetDim; i58++) {
11662
+ const start = Math.floor(i58 * ratio);
11663
+ const end = Math.floor((i58 + 1) * ratio);
11664
+ let sum = 0;
11665
+ for (let j52 = start; j52 < end; j52++) {
11666
+ sum += vector[j52];
11667
+ }
11668
+ result2[i58] = sum / (end - start);
11669
+ }
11670
+ return result2;
11671
+ }
11672
+ const result = new Array(targetDim).fill(0);
11673
+ for (let i58 = 0; i58 < vector.length; i58++) {
11674
+ result[i58] = vector[i58];
11675
+ }
11676
+ return result;
11629
11677
  }
11630
11678
  buildKey(key) {
11631
11679
  return `${this.config.namespace}:${key}`;
@@ -11692,6 +11740,33 @@ var init_hnsw_index = __esm({
11692
11740
  }
11693
11741
  });
11694
11742
 
11743
+ // src/shared/safe-db.ts
11744
+ var safe_db_exports = {};
11745
+ __export(safe_db_exports, {
11746
+ openDatabase: () => openDatabase
11747
+ });
11748
+ function openDatabase(dbPath, opts) {
11749
+ const readonly = opts?.readonly ?? false;
11750
+ const fileMustExist = opts?.fileMustExist ?? false;
11751
+ const busyTimeout = opts?.busyTimeout ?? 5e3;
11752
+ const walMode = opts?.walMode ?? !readonly;
11753
+ const db = new better_sqlite3_default(dbPath, {
11754
+ readonly,
11755
+ fileMustExist
11756
+ });
11757
+ db.pragma(`busy_timeout = ${busyTimeout}`);
11758
+ if (walMode) {
11759
+ db.pragma("journal_mode = WAL");
11760
+ }
11761
+ return db;
11762
+ }
11763
+ var init_safe_db = __esm({
11764
+ "src/shared/safe-db.ts"() {
11765
+ "use strict";
11766
+ init_better_sqlite3();
11767
+ }
11768
+ });
11769
+
11695
11770
  // src/integrations/vibium/types.ts
11696
11771
  var init_types2 = __esm({
11697
11772
  "src/integrations/vibium/types.ts"() {
@@ -16304,7 +16379,7 @@ var DEFAULT_SQLITE_CONFIG, SQLitePatternStore;
16304
16379
  var init_sqlite_persistence = __esm({
16305
16380
  "src/learning/sqlite-persistence.ts"() {
16306
16381
  "use strict";
16307
- init_better_sqlite3();
16382
+ init_safe_db();
16308
16383
  init_esm_node();
16309
16384
  init_safe_json();
16310
16385
  init_error_utils();
@@ -16348,10 +16423,7 @@ var init_sqlite_persistence = __esm({
16348
16423
  if (!fs21.existsSync(dir)) {
16349
16424
  fs21.mkdirSync(dir, { recursive: true });
16350
16425
  }
16351
- this.db = new better_sqlite3_default(this.config.dbPath);
16352
- if (this.config.walMode) {
16353
- this.db.pragma("journal_mode = WAL");
16354
- }
16426
+ this.db = openDatabase(this.config.dbPath);
16355
16427
  this.db.pragma(`mmap_size = ${this.config.mmapSize}`);
16356
16428
  this.db.pragma(`cache_size = ${this.config.cacheSize}`);
16357
16429
  if (this.config.foreignKeys) {
@@ -17796,7 +17868,13 @@ var init_signal_collector = __esm({
17796
17868
  "test generation",
17797
17869
  "error handling",
17798
17870
  "validation logic",
17799
- "api integration"
17871
+ "api integration",
17872
+ "code index",
17873
+ "coverage analysis",
17874
+ "quality assessment",
17875
+ "defect prediction",
17876
+ "predict defect",
17877
+ "analyze coverage"
17800
17878
  ],
17801
17879
  // Tier 3 - High complexity
17802
17880
  complex: [
@@ -17807,7 +17885,14 @@ var init_signal_collector = __esm({
17807
17885
  "migration",
17808
17886
  "cross-domain",
17809
17887
  "workflow",
17810
- "system design"
17888
+ "system design",
17889
+ "analyze security",
17890
+ "security scan",
17891
+ "security analysis",
17892
+ "vulnerability scan",
17893
+ "chaos test",
17894
+ "resilience test",
17895
+ "contract validation"
17811
17896
  ],
17812
17897
  // Tier 4 - Critical/expert
17813
17898
  critical: [
@@ -17818,7 +17903,12 @@ var init_signal_collector = __esm({
17818
17903
  "system-wide",
17819
17904
  "vulnerability",
17820
17905
  "cryptography",
17821
- "performance critical"
17906
+ "performance critical",
17907
+ "hardcoded secret",
17908
+ "cve",
17909
+ "owasp",
17910
+ "penetration test",
17911
+ "exploit"
17822
17912
  ]
17823
17913
  };
17824
17914
  SCOPE_PATTERNS = {
@@ -18115,11 +18205,15 @@ var init_score_calculator = __esm({
18115
18205
  * Calculate overall complexity score (0-100)
18116
18206
  */
18117
18207
  calculateOverallComplexity(codeComplexity, reasoningComplexity, scopeComplexity, signals) {
18118
- if (signals.isMechanicalTransform) {
18208
+ if (signals.isMechanicalTransform && !signals.hasSecurityScope && !signals.hasArchitectureScope && !signals.requiresMultiStepReasoning && !signals.requiresCrossDomainCoordination && codeComplexity === 0 && reasoningComplexity === 0 && scopeComplexity === 0) {
18119
18209
  return 5;
18120
18210
  }
18121
18211
  const weighted = codeComplexity * 0.3 + reasoningComplexity * 0.4 + scopeComplexity * 0.3;
18122
- return Math.min(Math.round(weighted), 100);
18212
+ let minScore = 0;
18213
+ if (signals.hasSecurityScope) minScore = Math.max(minScore, 50);
18214
+ if (signals.hasArchitectureScope) minScore = Math.max(minScore, 55);
18215
+ if (signals.requiresCrossDomainCoordination) minScore = Math.max(minScore, 35);
18216
+ return Math.min(Math.max(Math.round(weighted), minScore), 100);
18123
18217
  }
18124
18218
  /**
18125
18219
  * Calculate confidence in complexity assessment (0-1)
@@ -18922,7 +19016,7 @@ var init_router = __esm({
18922
19016
  agentBoosterStats: {
18923
19017
  eligible: agentBoosterEligible,
18924
19018
  used: agentBoosterUsed,
18925
- fallbackToLLM: agentBoosterEligible - agentBoosterUsed,
19019
+ fallbackToLLM: Math.max(0, agentBoosterEligible - agentBoosterUsed),
18926
19020
  successRate: agentBoosterUsed > 0 ? agentBoosterSuccess / agentBoosterUsed : 0
18927
19021
  },
18928
19022
  budgetStats: {
@@ -21661,13 +21755,13 @@ var init_trajectory_bridge = __esm({
21661
21755
  const { existsSync: existsSync18, mkdirSync: mkdirSync6 } = await import("fs");
21662
21756
  const { createRequire: createRequire11 } = await import("module");
21663
21757
  const require3 = createRequire11(import.meta.url);
21664
- const Database = require3("better-sqlite3");
21758
+ const { openDatabase: openDatabase2 } = require3("../../shared/safe-db.js");
21665
21759
  const dbPath = join26(this.options.projectRoot, ".agentic-qe", "trajectories.db");
21666
21760
  const dir = join26(this.options.projectRoot, ".agentic-qe");
21667
21761
  if (!existsSync18(dir)) {
21668
21762
  mkdirSync6(dir, { recursive: true });
21669
21763
  }
21670
- const db = new Database(dbPath);
21764
+ const db = openDatabase2(dbPath);
21671
21765
  db.exec(`
21672
21766
  CREATE TABLE IF NOT EXISTS trajectories (
21673
21767
  id TEXT PRIMARY KEY,
@@ -65083,7 +65177,7 @@ var DEFAULT_CONFIG18 = {
65083
65177
  };
65084
65178
  var CoverageAnalyzerService = class _CoverageAnalyzerService {
65085
65179
  static DEFAULT_THRESHOLD = 80;
65086
- static VECTOR_DIMENSION = 128;
65180
+ static VECTOR_DIMENSION = 768;
65087
65181
  memory;
65088
65182
  config;
65089
65183
  llmRouter;
@@ -65617,7 +65711,7 @@ var DEFAULT_CONFIG19 = {
65617
65711
  };
65618
65712
  var GapDetectorService = class _GapDetectorService {
65619
65713
  static DEFAULT_MIN_COVERAGE = 80;
65620
- static VECTOR_DIMENSION = 128;
65714
+ static VECTOR_DIMENSION = 768;
65621
65715
  memory;
65622
65716
  config;
65623
65717
  llmRouter;
@@ -66615,7 +66709,7 @@ init_hnsw_index();
66615
66709
 
66616
66710
  // src/domains/coverage-analysis/services/coverage-embedder.ts
66617
66711
  var DEFAULT_EMBEDDER_CONFIG = {
66618
- dimensions: 128,
66712
+ dimensions: 768,
66619
66713
  includePathFeatures: true,
66620
66714
  includeTemporalFeatures: true,
66621
66715
  normalization: "l2"
@@ -67047,7 +67141,7 @@ var ALL_CATEGORIES = [
67047
67141
  "missing-security-check"
67048
67142
  ];
67049
67143
  var DEFAULT_CONFIG20 = {
67050
- dimensions: 128,
67144
+ dimensions: 768,
67051
67145
  minConfidence: 0.3,
67052
67146
  maxGaps: 50,
67053
67147
  riskWeight: 0.6,
@@ -68756,7 +68850,7 @@ var CoverageAnalysisCoordinator = class extends BaseDomainCoordinator {
68756
68850
  return forecast;
68757
68851
  }
68758
68852
  createGapEmbedding(gap) {
68759
- const VECTOR_DIMENSION = 128;
68853
+ const VECTOR_DIMENSION = 768;
68760
68854
  const embedding = new Array(VECTOR_DIMENSION).fill(0);
68761
68855
  embedding[0] = gap.riskScore;
68762
68856
  embedding[1] = Math.min(1, gap.lines.length / 100);
@@ -86100,7 +86194,35 @@ import { join as join10, extname as extname3 } from "path";
86100
86194
  // src/domains/code-intelligence/services/metric-collector/interfaces.ts
86101
86195
  var DEFAULT_METRIC_CONFIG = {
86102
86196
  timeout: 6e4,
86103
- excludeDirs: ["node_modules", "dist", "coverage", "build", ".git", "vendor", "target"],
86197
+ excludeDirs: [
86198
+ // JS/TS ecosystem
86199
+ "node_modules",
86200
+ "dist",
86201
+ "build",
86202
+ "coverage",
86203
+ ".nyc_output",
86204
+ ".next",
86205
+ ".nuxt",
86206
+ ".output",
86207
+ // Python ecosystem
86208
+ "__pycache__",
86209
+ ".venv",
86210
+ "venv",
86211
+ ".tox",
86212
+ ".mypy_cache",
86213
+ ".pytest_cache",
86214
+ ".eggs",
86215
+ "*.egg-info",
86216
+ // Rust / Java / Go
86217
+ "target",
86218
+ ".gradle",
86219
+ "vendor",
86220
+ ".bundle",
86221
+ // General
86222
+ ".git",
86223
+ ".svn",
86224
+ ".hg"
86225
+ ],
86104
86226
  testPatterns: ["**/*.test.ts", "**/*.spec.ts", "**/*.test.js", "**/*.spec.js"],
86105
86227
  enableCache: true,
86106
86228
  cacheTTL: 3e5
@@ -86108,7 +86230,7 @@ var DEFAULT_METRIC_CONFIG = {
86108
86230
 
86109
86231
  // src/domains/code-intelligence/services/metric-collector/loc-counter.ts
86110
86232
  import { execSync as execSync3, spawnSync as spawnSync2 } from "child_process";
86111
- import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync5 } from "fs";
86233
+ import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
86112
86234
  import { join as join8, extname } from "path";
86113
86235
  init_safe_json();
86114
86236
  async function countLOC(projectPath, config = {}) {
@@ -86252,22 +86374,35 @@ function getLanguageForExtension(ext) {
86252
86374
  function manualLOCCount(projectPath, config) {
86253
86375
  const byLanguage = {};
86254
86376
  let total = 0;
86255
- function walkDirectory2(dirPath) {
86256
- if (!existsSync6(dirPath)) {
86377
+ const excludeSet = new Set(config.excludeDirs);
86378
+ const MAX_FILE_SIZE = 2 * 1024 * 1024;
86379
+ function walkDirectory2(dirPath, depth) {
86380
+ if (!existsSync6(dirPath) || depth > 20) {
86381
+ return;
86382
+ }
86383
+ let entries;
86384
+ try {
86385
+ entries = readdirSync(dirPath, { withFileTypes: true });
86386
+ } catch {
86257
86387
  return;
86258
86388
  }
86259
- const entries = readdirSync(dirPath, { withFileTypes: true });
86260
86389
  for (const entry of entries) {
86261
86390
  const fullPath = join8(dirPath, entry.name);
86262
86391
  if (entry.isDirectory()) {
86263
- if (config.excludeDirs.includes(entry.name)) {
86392
+ if (excludeSet.has(entry.name) || entry.name.startsWith(".")) {
86264
86393
  continue;
86265
86394
  }
86266
- walkDirectory2(fullPath);
86395
+ walkDirectory2(fullPath, depth + 1);
86267
86396
  } else if (entry.isFile()) {
86268
86397
  const ext = extname(entry.name);
86269
86398
  const language = getLanguageForExtension(ext);
86270
86399
  if (language) {
86400
+ try {
86401
+ const stat6 = statSync2(fullPath);
86402
+ if (stat6.size > MAX_FILE_SIZE) continue;
86403
+ } catch {
86404
+ continue;
86405
+ }
86271
86406
  const lines = countFileLines(fullPath);
86272
86407
  byLanguage[language] = (byLanguage[language] || 0) + lines;
86273
86408
  total += lines;
@@ -86275,11 +86410,11 @@ function manualLOCCount(projectPath, config) {
86275
86410
  }
86276
86411
  }
86277
86412
  }
86278
- walkDirectory2(projectPath);
86413
+ walkDirectory2(projectPath, 0);
86279
86414
  return {
86280
86415
  total,
86281
86416
  byLanguage,
86282
- source: "fallback",
86417
+ source: "node-native",
86283
86418
  excludedDirs: config.excludeDirs
86284
86419
  };
86285
86420
  }
@@ -86910,12 +87045,19 @@ var MetricCollectorService = class {
86910
87045
  const toolsUsed = [];
86911
87046
  if (loc.source !== "fallback") toolsUsed.push(loc.source);
86912
87047
  if (tests.source !== "fallback") toolsUsed.push(tests.source);
87048
+ const locAccuracy = loc.source === "fallback" ? "approximate" : "accurate";
87049
+ const testAccuracy = tests.source === "fallback" ? "approximate" : "accurate";
86913
87050
  const metrics = {
86914
87051
  loc,
86915
87052
  tests,
86916
87053
  patterns,
86917
87054
  collectedAt: /* @__PURE__ */ new Date(),
86918
- toolsUsed
87055
+ toolsUsed,
87056
+ accuracy: {
87057
+ loc: locAccuracy,
87058
+ tests: testAccuracy,
87059
+ overall: locAccuracy === "accurate" && testAccuracy === "accurate" ? "accurate" : "approximate"
87060
+ }
86919
87061
  };
86920
87062
  if (this.config.enableCache) {
86921
87063
  this.setInCache(cacheKey, metrics);
@@ -88469,7 +88611,7 @@ var CodeIntelligenceCoordinator = class extends BaseDomainCoordinator {
88469
88611
  */
88470
88612
  async initializeHypergraph() {
88471
88613
  try {
88472
- const Database = (await Promise.resolve().then(() => (init_better_sqlite3(), better_sqlite3_exports))).default;
88614
+ const { openDatabase: openDatabase2 } = await Promise.resolve().then(() => (init_safe_db(), safe_db_exports));
88473
88615
  const fs21 = await import("fs");
88474
88616
  const path23 = await import("path");
88475
88617
  const { findProjectRoot: findProjectRoot2 } = await Promise.resolve().then(() => (init_unified_memory(), unified_memory_exports));
@@ -88479,7 +88621,7 @@ var CodeIntelligenceCoordinator = class extends BaseDomainCoordinator {
88479
88621
  if (!fs21.existsSync(dir)) {
88480
88622
  fs21.mkdirSync(dir, { recursive: true });
88481
88623
  }
88482
- this.hypergraphDb = new Database(dbPath);
88624
+ this.hypergraphDb = openDatabase2(dbPath);
88483
88625
  this.hypergraph = await createHypergraphEngine({
88484
88626
  db: this.hypergraphDb,
88485
88627
  maxTraversalDepth: 10,
@@ -89145,9 +89287,15 @@ var CodeIntelligenceCoordinator = class extends BaseDomainCoordinator {
89145
89287
  try {
89146
89288
  console.log(`[CodeIntelligence] Collecting real metrics for ${projectPath}`);
89147
89289
  const metrics = await this.metricCollector.collectAll(projectPath);
89290
+ const toolsLabel = metrics.toolsUsed.length > 0 ? metrics.toolsUsed.join(", ") : metrics.loc.source === "node-native" ? "node-native" : "fallback";
89148
89291
  console.log(
89149
- `[CodeIntelligence] Real metrics collected: ${metrics.loc.total} LOC, ${metrics.tests.total} tests, tools: ${metrics.toolsUsed.join(", ") || "fallback"}`
89292
+ `[CodeIntelligence] Real metrics collected: ${metrics.loc.total} LOC, ${metrics.tests.total} tests, tools: ${toolsLabel}`
89150
89293
  );
89294
+ if (metrics.loc.source === "node-native") {
89295
+ console.log(
89296
+ `[CodeIntelligence] Using Node.js-native line counter (no cloc/tokei needed)`
89297
+ );
89298
+ }
89151
89299
  await this.storeProjectMetricsInMemory(projectPath, metrics);
89152
89300
  if (this.config.publishEvents) {
89153
89301
  const event = createEvent(
@@ -132684,10 +132832,16 @@ function detectTransformType(task) {
132684
132832
  }
132685
132833
  async function loadCoverageData(targetPath) {
132686
132834
  const coverageLocations = [
132835
+ // JavaScript/TypeScript (Istanbul/nyc/vitest)
132687
132836
  path16.join(targetPath, "coverage", "coverage-final.json"),
132688
132837
  path16.join(targetPath, "coverage", "lcov.info"),
132689
132838
  path16.join(targetPath, ".nyc_output", "coverage-final.json"),
132690
- path16.join(targetPath, "coverage-final.json")
132839
+ path16.join(targetPath, "coverage-final.json"),
132840
+ // Python (pytest-cov, coverage.py)
132841
+ path16.join(targetPath, "coverage.xml"),
132842
+ path16.join(targetPath, "htmlcov", "status.json"),
132843
+ // Cobertura (generic)
132844
+ path16.join(targetPath, "cobertura-coverage.xml")
132691
132845
  ];
132692
132846
  for (const coveragePath of coverageLocations) {
132693
132847
  try {
@@ -132696,6 +132850,8 @@ async function loadCoverageData(targetPath) {
132696
132850
  return parseCoverageJson(content);
132697
132851
  } else if (coveragePath.endsWith(".info")) {
132698
132852
  return parseLcovInfo(content);
132853
+ } else if (coveragePath.endsWith(".xml")) {
132854
+ return parseCoberturaXml(content);
132699
132855
  }
132700
132856
  } catch {
132701
132857
  }
@@ -132847,16 +133003,166 @@ function parseLcovInfo(content) {
132847
133003
  }
132848
133004
  };
132849
133005
  }
133006
+ function parseCoberturaXml(content) {
133007
+ const files = [];
133008
+ function attr(element, name) {
133009
+ const match = element.match(new RegExp(`${name}=["']([^"']*)["']`));
133010
+ return match ? match[1] : null;
133011
+ }
133012
+ const classRegex = /<class\s[^>]*?>/g;
133013
+ let classMatch;
133014
+ while ((classMatch = classRegex.exec(content)) !== null) {
133015
+ const classTag = classMatch[0];
133016
+ const filename = attr(classTag, "filename");
133017
+ if (!filename) continue;
133018
+ const lineRate = parseFloat(attr(classTag, "line-rate") || "NaN");
133019
+ const branchRate = parseFloat(attr(classTag, "branch-rate") || "NaN");
133020
+ const classStart = classMatch.index;
133021
+ const classEnd = content.indexOf("</class>", classStart);
133022
+ const classContent = classEnd > classStart ? content.slice(classStart, classEnd) : "";
133023
+ let linesTotal = 0, linesCovered = 0;
133024
+ let branchesTotal = 0, branchesCovered = 0;
133025
+ let functionsTotal = 0, functionsCovered = 0;
133026
+ const uncoveredLines = [];
133027
+ const uncoveredBranches = [];
133028
+ const lineRegex = /<line\s([^>]*?)\/>/g;
133029
+ let lineMatch;
133030
+ while ((lineMatch = lineRegex.exec(classContent)) !== null) {
133031
+ const lineTag = lineMatch[1];
133032
+ const lineNum = parseInt(attr(lineTag, "number") || "0", 10);
133033
+ const hits = parseInt(attr(lineTag, "hits") || "0", 10);
133034
+ const isBranch = attr(lineTag, "branch") === "true";
133035
+ const condCoverage = attr(lineTag, "condition-coverage");
133036
+ linesTotal++;
133037
+ if (hits > 0) {
133038
+ linesCovered++;
133039
+ } else {
133040
+ uncoveredLines.push(lineNum);
133041
+ }
133042
+ if (isBranch) {
133043
+ branchesTotal++;
133044
+ const condPct = condCoverage ? parseInt(condCoverage, 10) : hits > 0 ? 100 : 0;
133045
+ if (condPct === 100) {
133046
+ branchesCovered++;
133047
+ } else {
133048
+ uncoveredBranches.push(lineNum);
133049
+ }
133050
+ }
133051
+ }
133052
+ const methodRegex = /<method\s([^>]*?)>/g;
133053
+ let methodMatch;
133054
+ while ((methodMatch = methodRegex.exec(classContent)) !== null) {
133055
+ functionsTotal++;
133056
+ const methodStart = methodMatch.index;
133057
+ const methodEnd = classContent.indexOf("</method>", methodStart);
133058
+ if (methodEnd > methodStart) {
133059
+ const methodContent = classContent.slice(methodStart, methodEnd);
133060
+ const methodLineRegex = /<line\s([^>]*?)\/>/g;
133061
+ let hasHits = false;
133062
+ let mLineMatch;
133063
+ while ((mLineMatch = methodLineRegex.exec(methodContent)) !== null) {
133064
+ if (parseInt(attr(mLineMatch[1], "hits") || "0", 10) > 0) {
133065
+ hasHits = true;
133066
+ break;
133067
+ }
133068
+ }
133069
+ if (hasHits) functionsCovered++;
133070
+ }
133071
+ }
133072
+ if (linesTotal === 0 && !isNaN(lineRate)) {
133073
+ linesTotal = 1;
133074
+ linesCovered = lineRate >= 0.5 ? 1 : 0;
133075
+ }
133076
+ files.push({
133077
+ path: filename,
133078
+ lines: { covered: linesCovered, total: linesTotal },
133079
+ branches: { covered: branchesCovered, total: branchesTotal },
133080
+ functions: { covered: functionsCovered, total: functionsTotal },
133081
+ statements: { covered: linesCovered, total: linesTotal },
133082
+ uncoveredLines,
133083
+ uncoveredBranches
133084
+ });
133085
+ }
133086
+ let totalLines = 0, totalCoveredLines = 0;
133087
+ let totalBranches = 0, totalCoveredBranches = 0;
133088
+ let totalFunctions = 0, totalCoveredFunctions = 0;
133089
+ for (const file of files) {
133090
+ totalLines += file.lines.total;
133091
+ totalCoveredLines += file.lines.covered;
133092
+ totalBranches += file.branches.total;
133093
+ totalCoveredBranches += file.branches.covered;
133094
+ totalFunctions += file.functions.total;
133095
+ totalCoveredFunctions += file.functions.covered;
133096
+ }
133097
+ const coverageTag = content.match(/<coverage\s[^>]*?>/);
133098
+ const summaryLineRate = coverageTag ? parseFloat(attr(coverageTag[0], "line-rate") || "NaN") * 100 : NaN;
133099
+ const summaryBranchRate = coverageTag ? parseFloat(attr(coverageTag[0], "branch-rate") || "NaN") * 100 : NaN;
133100
+ return {
133101
+ files,
133102
+ summary: {
133103
+ line: !isNaN(summaryLineRate) ? summaryLineRate : totalLines > 0 ? totalCoveredLines / totalLines * 100 : 0,
133104
+ branch: !isNaN(summaryBranchRate) ? summaryBranchRate : totalBranches > 0 ? totalCoveredBranches / totalBranches * 100 : 0,
133105
+ function: totalFunctions > 0 ? totalCoveredFunctions / totalFunctions * 100 : 0,
133106
+ statement: totalLines > 0 ? totalCoveredLines / totalLines * 100 : 0,
133107
+ files: files.length
133108
+ }
133109
+ };
133110
+ }
132850
133111
  async function discoverSourceFiles(targetPath, options = {}) {
132851
133112
  const files = [];
132852
133113
  const { includeTests = true, languages } = options;
132853
- let extensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
133114
+ let extensions = [
133115
+ ".ts",
133116
+ ".tsx",
133117
+ ".js",
133118
+ ".jsx",
133119
+ ".mjs",
133120
+ ".cjs",
133121
+ // JavaScript/TypeScript
133122
+ ".py",
133123
+ ".pyw",
133124
+ // Python
133125
+ ".go",
133126
+ // Go
133127
+ ".rs",
133128
+ // Rust
133129
+ ".java",
133130
+ ".kt",
133131
+ ".kts",
133132
+ // Java/Kotlin
133133
+ ".rb",
133134
+ // Ruby
133135
+ ".cs",
133136
+ // C#
133137
+ ".php",
133138
+ // PHP
133139
+ ".swift",
133140
+ // Swift
133141
+ ".c",
133142
+ ".h",
133143
+ ".cpp",
133144
+ ".hpp",
133145
+ ".cc",
133146
+ // C/C++
133147
+ ".scala"
133148
+ // Scala
133149
+ ];
132854
133150
  if (languages && languages.length > 0) {
132855
133151
  extensions = [];
132856
133152
  for (const lang of languages) {
132857
133153
  if (lang === "typescript") extensions.push(".ts", ".tsx");
132858
133154
  if (lang === "javascript") extensions.push(".js", ".jsx", ".mjs", ".cjs");
132859
- if (lang === "python") extensions.push(".py");
133155
+ if (lang === "python") extensions.push(".py", ".pyw");
133156
+ if (lang === "go") extensions.push(".go");
133157
+ if (lang === "rust") extensions.push(".rs");
133158
+ if (lang === "java") extensions.push(".java");
133159
+ if (lang === "kotlin") extensions.push(".kt", ".kts");
133160
+ if (lang === "ruby") extensions.push(".rb");
133161
+ if (lang === "csharp" || lang === "c#") extensions.push(".cs");
133162
+ if (lang === "php") extensions.push(".php");
133163
+ if (lang === "swift") extensions.push(".swift");
133164
+ if (lang === "c" || lang === "cpp" || lang === "c++") extensions.push(".c", ".h", ".cpp", ".hpp", ".cc");
133165
+ if (lang === "scala") extensions.push(".scala");
132860
133166
  }
132861
133167
  }
132862
133168
  async function walkDir(dir) {
@@ -132865,7 +133171,23 @@ async function discoverSourceFiles(targetPath, options = {}) {
132865
133171
  for (const entry of entries) {
132866
133172
  const fullPath = path16.join(dir, entry.name);
132867
133173
  if (entry.isDirectory()) {
132868
- if (["node_modules", ".git", "dist", "build", "coverage", ".nyc_output"].includes(entry.name)) {
133174
+ if ([
133175
+ "node_modules",
133176
+ ".git",
133177
+ "dist",
133178
+ "build",
133179
+ "coverage",
133180
+ ".nyc_output",
133181
+ "__pycache__",
133182
+ ".venv",
133183
+ "venv",
133184
+ ".tox",
133185
+ ".mypy_cache",
133186
+ "target",
133187
+ ".gradle",
133188
+ "vendor",
133189
+ ".bundle"
133190
+ ].includes(entry.name)) {
132869
133191
  continue;
132870
133192
  }
132871
133193
  await walkDir(fullPath);
@@ -133031,7 +133353,24 @@ var DomainTaskExecutor = class {
133031
133353
  } else if (payload.filePath) {
133032
133354
  sourceFiles = [payload.filePath];
133033
133355
  } else if (payload.sourceCode) {
133034
- const tempPath = `/tmp/aqe-temp-${v4_default()}.ts`;
133356
+ const langExtMap = {
133357
+ python: ".py",
133358
+ typescript: ".ts",
133359
+ javascript: ".js",
133360
+ go: ".go",
133361
+ rust: ".rs",
133362
+ java: ".java",
133363
+ ruby: ".rb",
133364
+ kotlin: ".kt",
133365
+ csharp: ".cs",
133366
+ php: ".php",
133367
+ swift: ".swift",
133368
+ cpp: ".cpp",
133369
+ c: ".c",
133370
+ scala: ".scala"
133371
+ };
133372
+ const ext = langExtMap[payload.language?.toLowerCase() || "typescript"] || ".ts";
133373
+ const tempPath = `/tmp/aqe-temp-${v4_default()}${ext}`;
133035
133374
  await fs15.writeFile(tempPath, payload.sourceCode, "utf-8");
133036
133375
  sourceFiles = [tempPath];
133037
133376
  }
@@ -133147,12 +133486,112 @@ var DomainTaskExecutor = class {
133147
133486
  sast: payload.sast !== false,
133148
133487
  dast: payload.dast || false
133149
133488
  },
133150
- warning: `No TypeScript/JavaScript files found in ${targetPath}`
133489
+ warning: `No source files found in ${targetPath}`
133151
133490
  });
133152
133491
  }
133153
- const filePathObjects = filesToScan.map((filePath) => FilePath.create(filePath));
133492
+ const jstsFiles = filesToScan.filter((f74) => /\.(ts|tsx|js|jsx|mjs|cjs)$/.test(f74));
133493
+ const otherFiles = filesToScan.filter((f74) => !/\.(ts|tsx|js|jsx|mjs|cjs)$/.test(f74));
133494
+ const crossLangVulns = [];
133495
+ for (const filePath of otherFiles) {
133496
+ try {
133497
+ const content = await fs15.readFile(filePath, "utf-8");
133498
+ const lines = content.split("\n");
133499
+ const relPath = filePath.startsWith(targetPath) ? filePath.slice(targetPath.length).replace(/^\//, "") : filePath;
133500
+ const secretPatterns = [
133501
+ { regex: /\w*(?:secret|password|passwd|api_key|apikey|private_key|jwt_secret)\w*\s*[=:]\s*['"][^'"]{4,}['"]/gi, title: "Hardcoded secret", severity: "critical" },
133502
+ { regex: /\w*(?:token|auth_token|access_key|secret_key)\w*\s*[=:]\s*['"][^'"]{8,}['"]/gi, title: "Hardcoded credential", severity: "critical" },
133503
+ { regex: /(?:AWS_SECRET|GITHUB_TOKEN|SLACK_TOKEN|OPENAI_API_KEY)\s*[=:]\s*['"][^'"]+['"]/gi, title: "Hardcoded cloud credential", severity: "critical" }
133504
+ ];
133505
+ for (const pattern of secretPatterns) {
133506
+ for (let i58 = 0; i58 < lines.length; i58++) {
133507
+ const matches = [...lines[i58].matchAll(pattern.regex)];
133508
+ for (const _m of matches) {
133509
+ crossLangVulns.push({
133510
+ title: pattern.title,
133511
+ severity: pattern.severity,
133512
+ location: { file: relPath, line: i58 + 1 },
133513
+ description: `Potential hardcoded secret found at line ${i58 + 1}`,
133514
+ category: "sensitive-data"
133515
+ });
133516
+ }
133517
+ }
133518
+ }
133519
+ const sqlPatterns = /(?:execute|query|cursor\.execute)\s*\(\s*(?:f['"]|['"].*%s|['"].*\+\s*\w)/gi;
133520
+ for (let i58 = 0; i58 < lines.length; i58++) {
133521
+ if (sqlPatterns.test(lines[i58])) {
133522
+ crossLangVulns.push({
133523
+ title: "Potential SQL injection",
133524
+ severity: "high",
133525
+ location: { file: relPath, line: i58 + 1 },
133526
+ description: "String interpolation in SQL query \u2014 use parameterized queries",
133527
+ category: "injection"
133528
+ });
133529
+ }
133530
+ sqlPatterns.lastIndex = 0;
133531
+ }
133532
+ const corsPatterns = [
133533
+ /allow_origins\s*=\s*\[?\s*['"]?\*['"]?\s*\]?/i,
133534
+ // Python FastAPI/Flask
133535
+ /cors\(\s*\{[^}]*origin:\s*['"]?\*['"]?/i,
133536
+ // Express.js cors()
133537
+ /Access-Control-Allow-Origin['":\s]+\*/i,
133538
+ // Raw header / Nginx / .htaccess
133539
+ /@CrossOrigin\(\s*origins?\s*=\s*["']\*["']/i,
133540
+ // Spring Boot
133541
+ /\.Header\(\)\.Set\(["']Access-Control-Allow-Origin["'],\s*["']\*["']/i
133542
+ // Go
133543
+ ];
133544
+ for (const corsPattern of corsPatterns) {
133545
+ if (corsPattern.test(content)) {
133546
+ crossLangVulns.push({
133547
+ title: "CORS wildcard origin",
133548
+ severity: "high",
133549
+ location: { file: relPath, line: lines.findIndex((l75) => corsPattern.test(l75)) + 1 },
133550
+ description: "CORS configured with wildcard (*) origin \u2014 restrict to specific domains",
133551
+ category: "security-misconfiguration"
133552
+ });
133553
+ break;
133554
+ }
133555
+ }
133556
+ if (/(?:DEBUG|debug)\s*[=:]\s*(?:True|true|1)/i.test(content)) {
133557
+ crossLangVulns.push({
133558
+ title: "Debug mode enabled",
133559
+ severity: "medium",
133560
+ location: { file: relPath, line: lines.findIndex((l75) => /DEBUG\s*[=:]\s*(?:True|true|1)/i.test(l75)) + 1 },
133561
+ description: "Debug mode should be disabled in production",
133562
+ category: "security-misconfiguration"
133563
+ });
133564
+ }
133565
+ if (/\b(?:eval|exec)\s*\(/i.test(content)) {
133566
+ crossLangVulns.push({
133567
+ title: "Dangerous eval/exec usage",
133568
+ severity: "high",
133569
+ location: { file: relPath, line: lines.findIndex((l75) => /\b(?:eval|exec)\s*\(/.test(l75)) + 1 },
133570
+ description: "eval/exec can lead to code injection \u2014 avoid using with user input",
133571
+ category: "injection"
133572
+ });
133573
+ }
133574
+ } catch {
133575
+ }
133576
+ }
133577
+ const depManifests = ["requirements.txt", "pyproject.toml", "Gemfile", "go.mod", "Cargo.toml"];
133578
+ for (const manifest of depManifests) {
133579
+ const manifestPath = path16.join(targetPath, manifest);
133580
+ try {
133581
+ await fs15.access(manifestPath);
133582
+ crossLangVulns.push({
133583
+ title: "Dependency audit recommended",
133584
+ severity: "informational",
133585
+ location: { file: manifest, line: 1 },
133586
+ description: `Found ${manifest} \u2014 run language-specific dependency audit (e.g., pip-audit, npm audit, cargo audit)`,
133587
+ category: "dependencies"
133588
+ });
133589
+ } catch {
133590
+ }
133591
+ }
133592
+ const filePathObjects = jstsFiles.map((filePath) => FilePath.create(filePath));
133154
133593
  let sastResult = null;
133155
- if (payload.sast !== false) {
133594
+ if (payload.sast !== false && filePathObjects.length > 0) {
133156
133595
  const result = await scanner.scanFiles(filePathObjects);
133157
133596
  if (result.success) {
133158
133597
  sastResult = result.value;
@@ -133169,16 +133608,24 @@ var DomainTaskExecutor = class {
133169
133608
  dastResult = result.value;
133170
133609
  }
133171
133610
  }
133611
+ const crossLangSeverityCounts = {
133612
+ critical: crossLangVulns.filter((v62) => v62.severity === "critical").length,
133613
+ high: crossLangVulns.filter((v62) => v62.severity === "high").length,
133614
+ medium: crossLangVulns.filter((v62) => v62.severity === "medium").length,
133615
+ low: crossLangVulns.filter((v62) => v62.severity === "low").length,
133616
+ informational: crossLangVulns.filter((v62) => v62.severity === "informational").length
133617
+ };
133172
133618
  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)
133619
+ critical: (sastResult?.summary?.critical || 0) + (dastResult?.summary?.critical || 0) + crossLangSeverityCounts.critical,
133620
+ high: (sastResult?.summary?.high || 0) + (dastResult?.summary?.high || 0) + crossLangSeverityCounts.high,
133621
+ medium: (sastResult?.summary?.medium || 0) + (dastResult?.summary?.medium || 0) + crossLangSeverityCounts.medium,
133622
+ low: (sastResult?.summary?.low || 0) + (dastResult?.summary?.low || 0) + crossLangSeverityCounts.low,
133623
+ informational: (sastResult?.summary?.informational || 0) + (dastResult?.summary?.informational || 0) + crossLangSeverityCounts.informational
133178
133624
  };
133179
133625
  const allVulns = [
133180
133626
  ...sastResult?.vulnerabilities || [],
133181
- ...dastResult?.vulnerabilities || []
133627
+ ...dastResult?.vulnerabilities || [],
133628
+ ...crossLangVulns
133182
133629
  ];
133183
133630
  const topVulnerabilities = allVulns.sort((a37, b68) => {
133184
133631
  const severityOrder = { critical: 0, high: 1, medium: 2, low: 3, informational: 4 };
@@ -133205,7 +133652,12 @@ var DomainTaskExecutor = class {
133205
133652
  dast: payload.dast || false
133206
133653
  },
133207
133654
  filesScanned: filesToScan.length,
133208
- coverage: sastResult?.coverage
133655
+ jstsFilesScanned: jstsFiles.length,
133656
+ otherFilesScanned: otherFiles.length,
133657
+ coverage: sastResult?.coverage,
133658
+ ...otherFiles.length > 0 && jstsFiles.length === 0 ? {
133659
+ note: "Non-JS/TS files were scanned with cross-language pattern matching. For deeper analysis, use language-specific security tools."
133660
+ } : {}
133209
133661
  });
133210
133662
  } catch (error) {
133211
133663
  return err(toError(error));
@@ -133228,9 +133680,9 @@ var DomainTaskExecutor = class {
133228
133680
  edgesCreated: 0,
133229
133681
  target: targetPath,
133230
133682
  incremental: payload.incremental || false,
133231
- languages: payload.languages || ["typescript", "javascript"],
133683
+ languages: payload.languages || [],
133232
133684
  duration: Date.now() - startTime,
133233
- warning: `No source files found in ${targetPath}`
133685
+ warning: `No source files found in ${targetPath}. Searched for: TypeScript, JavaScript, Python, Go, Rust, Java, Ruby, C/C++, and more.`
133234
133686
  });
133235
133687
  }
133236
133688
  const result = await kg.index({
@@ -133244,11 +133696,35 @@ var DomainTaskExecutor = class {
133244
133696
  }
133245
133697
  const indexResult = result.value;
133246
133698
  const detectedLanguages = /* @__PURE__ */ new Set();
133699
+ const extToLang = {
133700
+ ts: "typescript",
133701
+ tsx: "typescript",
133702
+ js: "javascript",
133703
+ jsx: "javascript",
133704
+ mjs: "javascript",
133705
+ cjs: "javascript",
133706
+ py: "python",
133707
+ pyw: "python",
133708
+ go: "go",
133709
+ rs: "rust",
133710
+ java: "java",
133711
+ kt: "kotlin",
133712
+ kts: "kotlin",
133713
+ rb: "ruby",
133714
+ cs: "csharp",
133715
+ php: "php",
133716
+ swift: "swift",
133717
+ c: "c",
133718
+ h: "c",
133719
+ cpp: "cpp",
133720
+ hpp: "cpp",
133721
+ cc: "cpp",
133722
+ scala: "scala"
133723
+ };
133247
133724
  for (const file of filesToIndex) {
133248
133725
  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");
133726
+ const lang = extToLang[ext];
133727
+ if (lang) detectedLanguages.add(lang);
133252
133728
  }
133253
133729
  return ok({
133254
133730
  filesIndexed: indexResult.filesIndexed,
@@ -133330,106 +133806,271 @@ var DomainTaskExecutor = class {
133330
133806
  });
133331
133807
  this.taskHandlers.set("execute-tests", async (task) => {
133332
133808
  const payload = task.payload;
133333
- const testCount = payload.testFiles?.length || 10;
133334
- const passed = Math.floor(testCount * 0.9);
133335
- const failed = testCount - passed;
133336
- return ok({
133337
- total: testCount,
133338
- passed,
133339
- failed,
133340
- skipped: 0,
133341
- duration: testCount * 50,
133342
- // ~50ms per test
133343
- coverage: 82.5,
133344
- failedTests: failed > 0 ? ["example.test.ts:42"] : []
133345
- });
133809
+ try {
133810
+ const { execSync: execSync6 } = await import("child_process");
133811
+ const testFiles = payload.testFiles || [];
133812
+ if (testFiles.length === 0) {
133813
+ return ok({
133814
+ total: 0,
133815
+ passed: 0,
133816
+ failed: 0,
133817
+ skipped: 0,
133818
+ duration: 0,
133819
+ coverage: 0,
133820
+ failedTests: [],
133821
+ warning: "No test files specified. Provide testFiles array with paths to test files."
133822
+ });
133823
+ }
133824
+ const cwd = process.cwd();
133825
+ let output;
133826
+ try {
133827
+ output = execSync6(
133828
+ `npx vitest run ${testFiles.join(" ")} --reporter=json 2>/dev/null || npx jest ${testFiles.join(" ")} --json 2>/dev/null`,
133829
+ { cwd, timeout: 12e4, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
133830
+ );
133831
+ } catch (execError) {
133832
+ output = execError.stdout || "";
133833
+ }
133834
+ try {
133835
+ const jsonStart = output.indexOf("{");
133836
+ if (jsonStart >= 0) {
133837
+ const json = JSON.parse(output.slice(jsonStart));
133838
+ if (json.testResults) {
133839
+ const total = json.numTotalTests || 0;
133840
+ const passed = json.numPassedTests || 0;
133841
+ const failed = json.numFailedTests || 0;
133842
+ return ok({ total, passed, failed, skipped: total - passed - failed, duration: 0, coverage: 0, failedTests: [] });
133843
+ }
133844
+ }
133845
+ } catch {
133846
+ }
133847
+ return ok({
133848
+ total: testFiles.length,
133849
+ passed: 0,
133850
+ failed: 0,
133851
+ skipped: 0,
133852
+ duration: 0,
133853
+ coverage: 0,
133854
+ failedTests: [],
133855
+ warning: "Could not parse test runner output. Check that vitest or jest is installed.",
133856
+ rawOutput: output.slice(0, 500)
133857
+ });
133858
+ } catch (error) {
133859
+ return err(toError(error));
133860
+ }
133346
133861
  });
133347
133862
  this.taskHandlers.set("predict-defects", async (task) => {
133348
133863
  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"
133864
+ try {
133865
+ const targetPath = payload.target || process.cwd();
133866
+ const minConfidence = payload.minConfidence || 0.5;
133867
+ const sourceFiles = await discoverSourceFiles(targetPath, { includeTests: false });
133868
+ if (sourceFiles.length === 0) {
133869
+ return ok({
133870
+ predictedDefects: [],
133871
+ riskScore: 0,
133872
+ recommendations: [
133873
+ `No source files found in ${targetPath}. Ensure the path contains source code files.`
133874
+ ],
133875
+ warning: `No source files found in ${targetPath}`,
133876
+ filesAnalyzed: 0
133877
+ });
133878
+ }
133879
+ const predictedDefects = [];
133880
+ for (const filePath of sourceFiles) {
133881
+ try {
133882
+ const content = await fs15.readFile(filePath, "utf-8");
133883
+ const lines = content.split("\n");
133884
+ const lineCount = lines.length;
133885
+ let probability = 0;
133886
+ const reasons = [];
133887
+ if (lineCount > 500) {
133888
+ probability += 0.25;
133889
+ reasons.push(`Large file (${lineCount} lines)`);
133890
+ } else if (lineCount > 300) {
133891
+ probability += 0.15;
133892
+ reasons.push(`Medium-large file (${lineCount} lines)`);
133893
+ }
133894
+ const branchKeywords = content.match(/\b(if|else|switch|case|for|while|catch|&&|\|\|)\b/g) || [];
133895
+ const branchDensity = branchKeywords.length / Math.max(lineCount, 1);
133896
+ if (branchDensity > 0.15) {
133897
+ probability += 0.25;
133898
+ reasons.push(`High branch density (${branchKeywords.length} branches in ${lineCount} lines)`);
133899
+ } else if (branchDensity > 0.08) {
133900
+ probability += 0.1;
133901
+ reasons.push("Moderate branch complexity");
133902
+ }
133903
+ const maxIndent = Math.max(...lines.map((l75) => {
133904
+ const match = l75.match(/^(\s*)/);
133905
+ return match ? match[1].length : 0;
133906
+ }));
133907
+ if (maxIndent > 20) {
133908
+ probability += 0.15;
133909
+ reasons.push("Deep nesting detected");
133910
+ }
133911
+ const debtComments = (content.match(/\b(TODO|FIXME|HACK|XXX|WORKAROUND)\b/gi) || []).length;
133912
+ if (debtComments > 3) {
133913
+ probability += 0.15;
133914
+ reasons.push(`${debtComments} technical debt markers`);
133915
+ }
133916
+ const functionStarts = (content.match(/\b(function|def|func|async)\b/g) || []).length;
133917
+ if (functionStarts > 0 && lineCount / functionStarts > 80) {
133918
+ probability += 0.1;
133919
+ reasons.push("Potentially long functions");
133920
+ }
133921
+ probability = Math.min(probability, 0.95);
133922
+ if (probability >= minConfidence) {
133923
+ const relativePath = filePath.startsWith(targetPath) ? filePath.slice(targetPath.length).replace(/^\//, "") : filePath;
133924
+ predictedDefects.push({
133925
+ file: relativePath,
133926
+ probability: Math.round(probability * 100) / 100,
133927
+ reason: reasons.join("; ")
133928
+ });
133929
+ }
133930
+ } catch {
133360
133931
  }
133361
- ],
133362
- riskScore: 42,
133363
- recommendations: [
133364
- "Add integration tests for complex-module.ts",
133365
- "Refactor legacy-handler.ts to reduce complexity"
133366
- ]
133367
- });
133932
+ }
133933
+ predictedDefects.sort((a37, b68) => b68.probability - a37.probability);
133934
+ const avgProb = predictedDefects.length > 0 ? predictedDefects.reduce((sum, d74) => sum + d74.probability, 0) / predictedDefects.length : 0;
133935
+ const riskScore = Math.round(avgProb * 100);
133936
+ const recommendations = [];
133937
+ if (predictedDefects.length > 0) {
133938
+ recommendations.push(`${predictedDefects.length} files flagged for potential defects out of ${sourceFiles.length} analyzed`);
133939
+ const topFile = predictedDefects[0];
133940
+ recommendations.push(`Highest risk: ${topFile.file} (${Math.round(topFile.probability * 100)}%) \u2014 ${topFile.reason}`);
133941
+ }
133942
+ if (predictedDefects.some((d74) => d74.reason.includes("Large file"))) {
133943
+ recommendations.push("Consider splitting large files to reduce complexity");
133944
+ }
133945
+ if (predictedDefects.some((d74) => d74.reason.includes("technical debt"))) {
133946
+ recommendations.push("Address TODO/FIXME comments to reduce technical debt");
133947
+ }
133948
+ if (predictedDefects.length === 0) {
133949
+ recommendations.push("No files exceeded the defect probability threshold \u2014 code looks healthy");
133950
+ }
133951
+ return ok({
133952
+ predictedDefects: predictedDefects.slice(0, 20),
133953
+ // Top 20
133954
+ riskScore,
133955
+ recommendations,
133956
+ filesAnalyzed: sourceFiles.length
133957
+ });
133958
+ } catch (error) {
133959
+ return err(toError(error));
133960
+ }
133368
133961
  });
133369
133962
  this.taskHandlers.set("validate-requirements", async (task) => {
133370
133963
  const payload = task.payload;
133371
- return ok({
133372
- requirementsAnalyzed: 15,
133373
- testable: 12,
133374
- ambiguous: 2,
133375
- untestable: 1,
133376
- coverage: 80,
133377
- bddScenarios: payload.generateBDD ? [
133378
- "Given a user is logged in, When they view the dashboard, Then they see their metrics",
133379
- "Given an API request fails, When the retry limit is exceeded, Then an error is returned"
133380
- ] : []
133381
- });
133964
+ try {
133965
+ const targetPath = payload.requirementsPath || process.cwd();
133966
+ const reqFiles = await discoverSourceFiles(targetPath, {
133967
+ includeTests: false,
133968
+ languages: []
133969
+ });
133970
+ const reqPatterns = [".md", ".feature", ".gherkin", ".txt", ".rst"];
133971
+ const requirementFiles = [];
133972
+ for (const f74 of reqFiles) {
133973
+ if (reqPatterns.some((ext) => f74.endsWith(ext))) {
133974
+ requirementFiles.push(f74);
133975
+ }
133976
+ }
133977
+ return ok({
133978
+ requirementsAnalyzed: requirementFiles.length,
133979
+ testable: 0,
133980
+ ambiguous: 0,
133981
+ untestable: 0,
133982
+ coverage: 0,
133983
+ bddScenarios: [],
133984
+ warning: requirementFiles.length === 0 ? "No requirement files (.md, .feature, .gherkin) found. Provide requirementsPath or add requirement docs." : "Requirements validation requires LLM analysis. File inventory returned \u2014 use task_orchestrate for deep analysis.",
133985
+ files: requirementFiles.map((f74) => f74.startsWith(targetPath) ? f74.slice(targetPath.length + 1) : f74).slice(0, 20)
133986
+ });
133987
+ } catch (error) {
133988
+ return err(toError(error));
133989
+ }
133382
133990
  });
133383
133991
  this.taskHandlers.set("validate-contracts", async (task) => {
133384
133992
  const payload = task.payload;
133385
- return ok({
133386
- contractPath: payload.contractPath,
133387
- valid: true,
133388
- breakingChanges: [],
133389
- warnings: [
133390
- 'Deprecated field "legacyId" should be removed in next major version'
133391
- ],
133392
- coverage: 95
133393
- });
133993
+ try {
133994
+ if (!payload.contractPath) {
133995
+ return ok({
133996
+ contractPath: "",
133997
+ valid: false,
133998
+ breakingChanges: [],
133999
+ warnings: [],
134000
+ coverage: 0,
134001
+ error: "contractPath is required. Provide a path to an OpenAPI spec, JSON Schema, or Protocol Buffer file."
134002
+ });
134003
+ }
134004
+ try {
134005
+ const content = await fs15.readFile(payload.contractPath, "utf-8");
134006
+ const isJson = payload.contractPath.endsWith(".json");
134007
+ const isYaml = payload.contractPath.endsWith(".yaml") || payload.contractPath.endsWith(".yml");
134008
+ if (isJson) {
134009
+ JSON.parse(content);
134010
+ }
134011
+ return ok({
134012
+ contractPath: payload.contractPath,
134013
+ valid: true,
134014
+ format: isJson ? "json" : isYaml ? "yaml" : "unknown",
134015
+ breakingChanges: [],
134016
+ warnings: [],
134017
+ linesAnalyzed: content.split("\n").length,
134018
+ note: "Structural validation passed. For semantic contract testing, use consumer-driven contract tests."
134019
+ });
134020
+ } catch (readErr) {
134021
+ return ok({
134022
+ contractPath: payload.contractPath,
134023
+ valid: false,
134024
+ breakingChanges: [],
134025
+ warnings: [],
134026
+ error: `Could not read or parse contract file: ${toErrorMessage(readErr)}`
134027
+ });
134028
+ }
134029
+ } catch (error) {
134030
+ return err(toError(error));
134031
+ }
133394
134032
  });
133395
134033
  this.taskHandlers.set("test-accessibility", async (task) => {
133396
134034
  const payload = task.payload;
133397
134035
  return ok({
133398
- url: payload.url,
134036
+ url: payload.url || "",
133399
134037
  standard: payload.standard || "wcag21-aa",
133400
- passed: true,
134038
+ passed: false,
133401
134039
  violations: [],
133402
- warnings: [
133403
- { rule: "color-contrast", impact: "minor", element: "nav > a" }
133404
- ],
133405
- score: 94
134040
+ warnings: [],
134041
+ score: 0,
134042
+ note: "Accessibility testing requires a browser environment (Puppeteer/Playwright). Use tools like axe-core, pa11y, or Lighthouse CLI for WCAG compliance testing. Example: npx pa11y " + (payload.url || "<url>")
133406
134043
  });
133407
134044
  });
133408
134045
  this.taskHandlers.set("run-chaos", async (task) => {
133409
134046
  const payload = task.payload;
133410
134047
  return ok({
133411
- faultType: payload.faultType,
133412
- target: payload.target,
133413
- dryRun: payload.dryRun,
133414
- duration: payload.duration,
133415
- systemBehavior: payload.dryRun ? "simulated" : "tested",
133416
- resilience: {
133417
- recovered: true,
133418
- recoveryTime: 2500,
133419
- dataLoss: false
133420
- }
134048
+ faultType: payload.faultType || "unknown",
134049
+ target: payload.target || "unknown",
134050
+ dryRun: payload.dryRun ?? true,
134051
+ duration: payload.duration || 0,
134052
+ systemBehavior: "not-executed",
134053
+ resilience: null,
134054
+ note: "Chaos engineering requires infrastructure-level fault injection. Use tools like Chaos Monkey, Litmus, or toxiproxy for real resilience testing. For Node.js apps, consider: nock (HTTP faults), testcontainers (dependency failures)."
133421
134055
  });
133422
134056
  });
133423
134057
  this.taskHandlers.set("optimize-learning", async (_task) => {
133424
- return ok({
133425
- patternsLearned: 12,
133426
- modelsUpdated: 3,
133427
- memoryConsolidated: true,
133428
- recommendations: [
133429
- "Pattern recognition improved for error handling",
133430
- "Test generation templates optimized"
133431
- ]
133432
- });
134058
+ try {
134059
+ const memUsage = await Promise.resolve().then(() => (init_unified_memory_hnsw(), unified_memory_hnsw_exports));
134060
+ return ok({
134061
+ patternsLearned: 0,
134062
+ modelsUpdated: 0,
134063
+ memoryConsolidated: false,
134064
+ note: 'Learning optimization runs during the dream cycle (SessionEnd hook). Use "npx agentic-qe hooks session-end --save-state" to trigger pattern consolidation.'
134065
+ });
134066
+ } catch {
134067
+ return ok({
134068
+ patternsLearned: 0,
134069
+ modelsUpdated: 0,
134070
+ memoryConsolidated: false,
134071
+ note: 'Learning system not initialized. Run "aqe init --auto" first.'
134072
+ });
134073
+ }
133433
134074
  });
133434
134075
  }
133435
134076
  // ============================================================================
@@ -137584,50 +138225,54 @@ var coverageAnalyzeConfig = {
137584
138225
  const learning = generateV2LearningFeedback("coverage-analyzer");
137585
138226
  const detailedGaps = gaps.map((gap, i58) => {
137586
138227
  const g67 = gap;
138228
+ if (!g67?.file) return null;
137587
138229
  return {
137588
138230
  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
138231
+ file: g67.file,
138232
+ line: g67.lines?.[0] || 0,
138233
+ uncoveredLines: g67.lines || [],
138234
+ type: g67.type || "uncovered-line",
138235
+ severity: g67.severity || "medium",
138236
+ reason: g67.reason || "Missing test case",
138237
+ priority: g67.priority || "medium",
138238
+ suggestion: g67.suggestedTest || "Add test coverage",
138239
+ suggestedTest: g67.suggestedTest || "Add test coverage",
138240
+ riskScore: g67.riskScore || 0.5,
138241
+ confidence: g67.confidence || 0.7
137600
138242
  };
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
- }),
138243
+ }).filter((g67) => g67 !== null);
138244
+ const coverageByFileData = data.coverageByFile;
138245
+ const realCoverageByFile = coverageByFileData ? coverageByFileData.map((f74) => ({
138246
+ file: f74.file,
138247
+ lineCoverage: f74.lineCoverage || 0,
138248
+ branchCoverage: f74.branchCoverage || 0,
138249
+ functionCoverage: f74.functionCoverage || 0
138250
+ })) : [];
138251
+ return {
138252
+ // V2-compatible fields — only real data, no synthetic file paths
138253
+ coverageByFile: realCoverageByFile,
137613
138254
  gapAnalysis: {
137614
138255
  totalGaps: detailedGaps.length,
137615
138256
  highPriority: detailedGaps.filter((g67) => g67.priority === "high").length,
137616
138257
  gaps: detailedGaps
137617
138258
  },
137618
138259
  trends: {
137619
- lineCoverageTrend: "stable",
137620
- branchCoverageTrend: "improving",
137621
- weeklyChange: 2.5
138260
+ lineCoverageTrend: totalFiles > 0 ? "stable" : "no-data",
138261
+ branchCoverageTrend: totalFiles > 0 ? "stable" : "no-data",
138262
+ weeklyChange: 0
137622
138263
  },
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"
138264
+ aiInsights: totalFiles > 0 ? {
138265
+ recommendations: data.recommendations || [
138266
+ "Run tests with coverage enabled to get accurate metrics"
137628
138267
  ],
137629
138268
  riskAssessment: lineCoverage < 70 ? "high" : lineCoverage < 85 ? "medium" : "low",
137630
138269
  confidence: 0.88
138270
+ } : {
138271
+ recommendations: [
138272
+ "No coverage data found. Run tests with coverage first (e.g., npm test -- --coverage, or pytest --cov)"
138273
+ ],
138274
+ riskAssessment: "unknown",
138275
+ confidence: 0
137631
138276
  },
137632
138277
  learning,
137633
138278
  // V3 fields
@@ -142822,6 +143467,44 @@ function extractHighlights(content, query) {
142822
143467
 
142823
143468
  // src/mcp/tools/security-compliance/scan.ts
142824
143469
  init_error_utils();
143470
+ var CROSS_LANG_SECRET_PATTERNS = [
143471
+ {
143472
+ id: "secret-key-assignment",
143473
+ pattern: /(?:SECRET_KEY|secret_key|SECRET|PRIVATE_KEY)\s*=\s*['"][^'"]{4,}['"]/g,
143474
+ severity: "critical",
143475
+ title: "Hardcoded Secret Key",
143476
+ description: "Secret key assigned as string literal in source code",
143477
+ cweId: "CWE-798",
143478
+ remediation: 'Use environment variables: SECRET_KEY = os.environ["SECRET_KEY"]'
143479
+ },
143480
+ {
143481
+ id: "cors-wildcard-credentials",
143482
+ pattern: /allow_origins\s*=\s*\[\s*["']\*["']\s*\]/g,
143483
+ severity: "high",
143484
+ title: "CORS Wildcard Origin",
143485
+ description: "CORS configured to allow all origins \u2014 combined with credentials this is a security risk",
143486
+ cweId: "CWE-942",
143487
+ remediation: "Restrict CORS origins to specific trusted domains"
143488
+ },
143489
+ {
143490
+ id: "cors-allow-credentials-wildcard",
143491
+ pattern: /allow_credentials\s*=\s*True/g,
143492
+ severity: "medium",
143493
+ title: "CORS Credentials Enabled",
143494
+ description: "CORS credentials enabled \u2014 verify origins are restricted",
143495
+ cweId: "CWE-942",
143496
+ remediation: 'Ensure allow_origins does not include "*" when credentials are enabled'
143497
+ },
143498
+ {
143499
+ id: "token-hardcoded",
143500
+ pattern: /(?:token|TOKEN)\s*[:=]\s*['"][a-zA-Z0-9_\-.]{20,}['"]/g,
143501
+ severity: "high",
143502
+ title: "Hardcoded Token",
143503
+ description: "Hardcoded token found in source code",
143504
+ cweId: "CWE-798",
143505
+ remediation: "Use environment variables or secrets manager for tokens"
143506
+ }
143507
+ ];
142825
143508
  var SecurityScanTool = class extends MCPToolBase {
142826
143509
  config = {
142827
143510
  name: "qe/security/scan",
@@ -142850,18 +143533,21 @@ var SecurityScanTool = class extends MCPToolBase {
142850
143533
  if (this.isAborted(context)) {
142851
143534
  return { success: false, error: "Operation aborted" };
142852
143535
  }
143536
+ const files = await discoverFiles(target, depth);
143537
+ this.emitStream(context, {
143538
+ status: "discovered",
143539
+ message: `Found ${files.length} files to scan`
143540
+ });
142853
143541
  const vulnerabilities = [];
142854
- if (scanType.includes("sast")) {
143542
+ if (scanType.includes("sast") || scanType.includes("secret")) {
142855
143543
  this.emitStream(context, { status: "sast", message: "Running static analysis" });
142856
- vulnerabilities.push(...generateSASTFindings());
143544
+ const sastVulns = await scanFilesWithPatterns(files, scanType);
143545
+ vulnerabilities.push(...sastVulns);
142857
143546
  }
142858
143547
  if (scanType.includes("dependency")) {
142859
143548
  this.emitStream(context, { status: "dependency", message: "Scanning dependencies" });
142860
- vulnerabilities.push(...generateDependencyFindings());
142861
- }
142862
- if (scanType.includes("secret")) {
142863
- this.emitStream(context, { status: "secret", message: "Scanning for secrets" });
142864
- vulnerabilities.push(...generateSecretFindings());
143549
+ const depVulns = await scanDependencies(target);
143550
+ vulnerabilities.push(...depVulns);
142865
143551
  }
142866
143552
  if (scanType.includes("dast") && dastUrl) {
142867
143553
  this.emitStream(context, { status: "dast", message: `Scanning ${dastUrl}` });
@@ -142876,7 +143562,7 @@ var SecurityScanTool = class extends MCPToolBase {
142876
143562
  medium: vulnerabilities.filter((v62) => v62.severity === "medium").length,
142877
143563
  low: vulnerabilities.filter((v62) => v62.severity === "low").length,
142878
143564
  informational: vulnerabilities.filter((v62) => v62.severity === "informational").length,
142879
- totalFiles: 150,
143565
+ totalFiles: files.length,
142880
143566
  scanDurationMs: Date.now() - startTime
142881
143567
  };
142882
143568
  const severityOrder = ["critical", "high", "medium", "low", "informational"];
@@ -142885,7 +143571,7 @@ var SecurityScanTool = class extends MCPToolBase {
142885
143571
  const passed = worstSeverity > failThreshold;
142886
143572
  this.emitStream(context, {
142887
143573
  status: "complete",
142888
- message: `Scan complete: ${vulnerabilities.length} vulnerabilities found`,
143574
+ message: `Scan complete: ${vulnerabilities.length} vulnerabilities found in ${files.length} files`,
142889
143575
  progress: 100
142890
143576
  });
142891
143577
  return {
@@ -142952,72 +143638,340 @@ var SECURITY_SCAN_SCHEMA = {
142952
143638
  }
142953
143639
  }
142954
143640
  };
142955
- function generateSASTFindings() {
142956
- return [
142957
- {
142958
- id: "SAST-001",
142959
- title: "SQL Injection Risk",
142960
- severity: "high",
142961
- category: "injection",
142962
- location: { file: "src/db/queries.ts", line: 45, snippet: "query = `SELECT * FROM ${table}`" },
142963
- description: "User input directly concatenated in SQL query",
142964
- remediation: "Use parameterized queries or prepared statements",
142965
- cweId: "CWE-89",
142966
- references: ["https://owasp.org/www-community/attacks/SQL_Injection"]
142967
- },
142968
- {
142969
- id: "SAST-002",
142970
- title: "Hardcoded Credentials",
142971
- severity: "critical",
142972
- category: "sensitive-data",
142973
- location: { file: "src/config/database.ts", line: 12, snippet: 'password: "admin123"' },
142974
- description: "Hardcoded password found in source code",
142975
- remediation: "Use environment variables or secure vault for credentials",
142976
- cweId: "CWE-798",
142977
- references: ["https://cwe.mitre.org/data/definitions/798.html"]
143641
+ var SCANNABLE_EXTENSIONS = /* @__PURE__ */ new Set([
143642
+ ".ts",
143643
+ ".tsx",
143644
+ ".js",
143645
+ ".jsx",
143646
+ ".mjs",
143647
+ ".cjs",
143648
+ // JavaScript/TypeScript
143649
+ ".py",
143650
+ ".pyw",
143651
+ // Python
143652
+ ".java",
143653
+ ".kt",
143654
+ ".scala",
143655
+ // JVM
143656
+ ".go",
143657
+ // Go
143658
+ ".rb",
143659
+ // Ruby
143660
+ ".php",
143661
+ // PHP
143662
+ ".rs",
143663
+ // Rust
143664
+ ".cs",
143665
+ // C#
143666
+ ".yaml",
143667
+ ".yml",
143668
+ ".json",
143669
+ ".toml",
143670
+ ".cfg",
143671
+ ".ini",
143672
+ // Config
143673
+ ".env",
143674
+ ".env.local",
143675
+ ".env.production",
143676
+ // Env files
143677
+ ".sh",
143678
+ ".bash"
143679
+ // Shell
143680
+ ]);
143681
+ var SKIP_DIRS = /* @__PURE__ */ new Set([
143682
+ "node_modules",
143683
+ ".git",
143684
+ "__pycache__",
143685
+ ".venv",
143686
+ "venv",
143687
+ "dist",
143688
+ "build",
143689
+ ".next",
143690
+ ".nuxt",
143691
+ "coverage",
143692
+ ".tox"
143693
+ ]);
143694
+ async function discoverFiles(target, depth) {
143695
+ const fs21 = await import("fs");
143696
+ const path23 = await import("path");
143697
+ const resolved = path23.resolve(target);
143698
+ const files = [];
143699
+ const maxFiles = depth === "quick" ? 50 : depth === "standard" ? 500 : 2e3;
143700
+ const maxDepth = depth === "quick" ? 3 : depth === "standard" ? 8 : 20;
143701
+ function walk(dir, currentDepth) {
143702
+ if (files.length >= maxFiles || currentDepth > maxDepth) return;
143703
+ let entries;
143704
+ try {
143705
+ entries = fs21.readdirSync(dir, { withFileTypes: true });
143706
+ } catch {
143707
+ return;
142978
143708
  }
142979
- ];
143709
+ for (const entry of entries) {
143710
+ if (files.length >= maxFiles) break;
143711
+ const fullPath = path23.join(dir, entry.name);
143712
+ if (entry.isDirectory()) {
143713
+ const SCAN_DOT_DIRS = /* @__PURE__ */ new Set([".github", ".docker", ".aws", ".circleci", ".gitlab"]);
143714
+ if (SKIP_DIRS.has(entry.name)) {
143715
+ } else if (entry.name.startsWith(".") && !SCAN_DOT_DIRS.has(entry.name)) {
143716
+ } else {
143717
+ walk(fullPath, currentDepth + 1);
143718
+ }
143719
+ } else if (entry.isFile()) {
143720
+ const ext = path23.extname(entry.name).toLowerCase();
143721
+ if (SCANNABLE_EXTENSIONS.has(ext) || entry.name === "Dockerfile" || entry.name === "Makefile" || entry.name.startsWith(".env")) {
143722
+ files.push(fullPath);
143723
+ }
143724
+ }
143725
+ }
143726
+ }
143727
+ try {
143728
+ const stat6 = fs21.statSync(resolved);
143729
+ if (stat6.isFile()) {
143730
+ files.push(resolved);
143731
+ } else {
143732
+ walk(resolved, 0);
143733
+ }
143734
+ } catch {
143735
+ }
143736
+ return files;
142980
143737
  }
142981
- function generateDependencyFindings() {
142982
- return [
142983
- {
142984
- id: "DEP-001",
142985
- title: "Vulnerable lodash version",
142986
- severity: "medium",
142987
- category: "vulnerable-components",
142988
- location: { file: "package.json", dependency: { name: "lodash", version: "4.17.19" } },
142989
- description: "lodash < 4.17.21 has prototype pollution vulnerability",
142990
- remediation: "Upgrade lodash to 4.17.21 or later",
142991
- cveId: "CVE-2021-23337",
142992
- references: ["https://nvd.nist.gov/vuln/detail/CVE-2021-23337"]
143738
+ async function scanFilesWithPatterns(files, scanTypes) {
143739
+ const fs21 = await import("fs");
143740
+ const path23 = await import("path");
143741
+ const vulnerabilities = [];
143742
+ let vulnCounter = 0;
143743
+ const patterns = [];
143744
+ if (scanTypes.includes("sast")) {
143745
+ for (const p74 of ALL_SECURITY_PATTERNS) {
143746
+ patterns.push({
143747
+ id: p74.id,
143748
+ pattern: new RegExp(p74.pattern.source, p74.pattern.flags),
143749
+ severity: p74.severity,
143750
+ title: p74.title,
143751
+ description: p74.description,
143752
+ cweId: p74.cweId,
143753
+ remediation: p74.remediation,
143754
+ category: p74.category
143755
+ });
142993
143756
  }
142994
- ];
143757
+ for (const p74 of CROSS_LANG_SECRET_PATTERNS) {
143758
+ patterns.push({
143759
+ id: p74.id,
143760
+ pattern: new RegExp(p74.pattern.source, p74.pattern.flags),
143761
+ severity: p74.severity,
143762
+ title: p74.title,
143763
+ description: p74.description,
143764
+ cweId: p74.cweId,
143765
+ remediation: p74.remediation,
143766
+ category: "sensitive-data"
143767
+ });
143768
+ }
143769
+ }
143770
+ if (scanTypes.includes("secret")) {
143771
+ for (const p74 of SECRET_PATTERNS) {
143772
+ if (!patterns.some((existing) => existing.id === p74.id)) {
143773
+ patterns.push({
143774
+ id: p74.id,
143775
+ pattern: new RegExp(p74.pattern.source, p74.pattern.flags),
143776
+ severity: p74.severity,
143777
+ title: p74.title,
143778
+ description: p74.description,
143779
+ cweId: p74.cweId,
143780
+ remediation: p74.remediation,
143781
+ category: p74.category
143782
+ });
143783
+ }
143784
+ }
143785
+ for (const p74 of CROSS_LANG_SECRET_PATTERNS) {
143786
+ if (!patterns.some((existing) => existing.id === p74.id)) {
143787
+ patterns.push({
143788
+ ...p74,
143789
+ category: "sensitive-data"
143790
+ });
143791
+ }
143792
+ }
143793
+ }
143794
+ for (const filePath of files) {
143795
+ let content;
143796
+ try {
143797
+ content = fs21.readFileSync(filePath, "utf-8");
143798
+ } catch {
143799
+ continue;
143800
+ }
143801
+ if (content.includes("\0") || content.length > 1e6) continue;
143802
+ const lines = content.split("\n");
143803
+ const relPath = path23.relative(process.cwd(), filePath);
143804
+ for (const patternDef of patterns) {
143805
+ const regex = new RegExp(patternDef.pattern.source, patternDef.pattern.flags);
143806
+ let match;
143807
+ while ((match = regex.exec(content)) !== null) {
143808
+ vulnCounter++;
143809
+ const lineNum = content.substring(0, match.index).split("\n").length;
143810
+ const matchedLine = lines[lineNum - 1] || "";
143811
+ const snippet = matchedLine.trim().length > 100 ? matchedLine.trim().substring(0, 100) + "..." : matchedLine.trim();
143812
+ vulnerabilities.push({
143813
+ id: `${patternDef.id}-${vulnCounter}`,
143814
+ title: patternDef.title,
143815
+ severity: patternDef.severity,
143816
+ category: patternDef.category || "security-misconfiguration",
143817
+ location: {
143818
+ file: relPath,
143819
+ line: lineNum,
143820
+ snippet
143821
+ },
143822
+ description: patternDef.description,
143823
+ remediation: patternDef.remediation,
143824
+ cweId: patternDef.cweId,
143825
+ references: []
143826
+ });
143827
+ if (vulnCounter > 200) break;
143828
+ }
143829
+ }
143830
+ }
143831
+ return vulnerabilities;
142995
143832
  }
142996
- function generateSecretFindings() {
142997
- return [
142998
- {
142999
- id: "SECRET-001",
143000
- title: "AWS Access Key Detected",
143001
- severity: "critical",
143002
- category: "sensitive-data",
143003
- location: { file: "src/services/aws.ts", line: 8, snippet: "AKIA...[REDACTED]" },
143004
- description: "AWS access key found in source code",
143005
- remediation: "Remove key, rotate credentials, use AWS IAM roles",
143006
- references: ["https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html"]
143833
+ async function scanDependencies(target) {
143834
+ const fs21 = await import("fs");
143835
+ const path23 = await import("path");
143836
+ const vulnerabilities = [];
143837
+ const resolved = path23.resolve(target);
143838
+ const pkgJsonPath = path23.join(resolved, "package.json");
143839
+ if (fs21.existsSync(pkgJsonPath)) {
143840
+ try {
143841
+ const pkg2 = JSON.parse(fs21.readFileSync(pkgJsonPath, "utf-8"));
143842
+ const allDeps = { ...pkg2.dependencies, ...pkg2.devDependencies };
143843
+ vulnerabilities.push(...checkKnownVulnerableDeps(allDeps, "package.json"));
143844
+ } catch {
143007
143845
  }
143008
- ];
143846
+ }
143847
+ const pyprojectPath = path23.join(resolved, "pyproject.toml");
143848
+ if (fs21.existsSync(pyprojectPath)) {
143849
+ try {
143850
+ const content = fs21.readFileSync(pyprojectPath, "utf-8");
143851
+ const deps = extractPythonDeps(content);
143852
+ vulnerabilities.push(...checkKnownVulnerablePythonDeps(deps, "pyproject.toml"));
143853
+ } catch {
143854
+ }
143855
+ }
143856
+ const reqPath = path23.join(resolved, "requirements.txt");
143857
+ if (fs21.existsSync(reqPath)) {
143858
+ try {
143859
+ const content = fs21.readFileSync(reqPath, "utf-8");
143860
+ const deps = extractRequirementsTxtDeps(content);
143861
+ vulnerabilities.push(...checkKnownVulnerablePythonDeps(deps, "requirements.txt"));
143862
+ } catch {
143863
+ }
143864
+ }
143865
+ if (vulnerabilities.length === 0) {
143866
+ const manifests = [pkgJsonPath, pyprojectPath, reqPath].filter((p74) => fs21.existsSync(p74));
143867
+ if (manifests.length > 0) {
143868
+ vulnerabilities.push({
143869
+ id: "DEP-INFO-001",
143870
+ title: "Dependency audit recommended",
143871
+ severity: "informational",
143872
+ category: "vulnerable-components",
143873
+ location: { file: path23.relative(process.cwd(), manifests[0]) },
143874
+ description: `Found ${path23.basename(manifests[0])} \u2014 run language-specific dependency audit for comprehensive results`,
143875
+ remediation: "Run npm audit, pip-audit, or equivalent for full vulnerability check",
143876
+ references: []
143877
+ });
143878
+ }
143879
+ }
143880
+ return vulnerabilities;
143881
+ }
143882
+ var KNOWN_VULNERABLE_NPM = {
143883
+ "lodash": { maxSafe: "4.17.21", cve: "CVE-2021-23337", severity: "high", desc: "Prototype pollution in lodash" },
143884
+ "minimist": { maxSafe: "1.2.6", cve: "CVE-2021-44906", severity: "critical", desc: "Prototype pollution in minimist" },
143885
+ "node-fetch": { maxSafe: "2.6.7", cve: "CVE-2022-0235", severity: "high", desc: "Information exposure in node-fetch" },
143886
+ "express": { maxSafe: "4.19.2", cve: "CVE-2024-29041", severity: "medium", desc: "Open redirect in express" }
143887
+ };
143888
+ function checkKnownVulnerableDeps(deps, manifest) {
143889
+ const vulns = [];
143890
+ for (const [name, version] of Object.entries(deps)) {
143891
+ const known = KNOWN_VULNERABLE_NPM[name];
143892
+ if (known) {
143893
+ const cleanVersion = version.replace(/^[\^~>=<]+/, "");
143894
+ if (compareVersions(cleanVersion, known.maxSafe) < 0) {
143895
+ vulns.push({
143896
+ id: `DEP-${name}-${known.cve}`,
143897
+ title: `Vulnerable ${name} version`,
143898
+ severity: known.severity,
143899
+ category: "vulnerable-components",
143900
+ location: { file: manifest, dependency: { name, version: cleanVersion } },
143901
+ description: known.desc,
143902
+ remediation: `Upgrade ${name} to >= ${known.maxSafe}`,
143903
+ cveId: known.cve,
143904
+ references: [`https://nvd.nist.gov/vuln/detail/${known.cve}`]
143905
+ });
143906
+ }
143907
+ }
143908
+ }
143909
+ return vulns;
143910
+ }
143911
+ var KNOWN_VULNERABLE_PYTHON = {
143912
+ "python-jose": { cve: "CVE-2024-33663", severity: "critical", desc: "python-jose is abandoned and has known JWT vulnerabilities" },
143913
+ "pyjwt": { cve: "CVE-2022-29217", severity: "high", desc: "PyJWT algorithm confusion vulnerability (upgrade to >= 2.4.0)" },
143914
+ "python-multipart": { cve: "CVE-2026-24486", severity: "high", desc: "python-multipart DoS vulnerability" },
143915
+ "jinja2": { cve: "CVE-2024-34064", severity: "medium", desc: "Jinja2 XSS via template injection" },
143916
+ "urllib3": { cve: "CVE-2023-45803", severity: "medium", desc: "urllib3 request body exposure on redirect" },
143917
+ "requests": { cve: "CVE-2023-32681", severity: "medium", desc: "Requests proxy credential exposure" }
143918
+ };
143919
+ function extractPythonDeps(tomlContent) {
143920
+ const deps = [];
143921
+ const depMatch = tomlContent.match(/dependencies\s*=\s*\[([\s\S]*?)\]/);
143922
+ if (depMatch) {
143923
+ const matches = depMatch[1].matchAll(/["']([a-zA-Z0-9_-]+)/g);
143924
+ for (const m74 of matches) {
143925
+ deps.push(m74[1].toLowerCase());
143926
+ }
143927
+ }
143928
+ return deps;
143929
+ }
143930
+ function extractRequirementsTxtDeps(content) {
143931
+ return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#")).map((line) => line.split(/[>=<!~\[]/)[0].trim().toLowerCase()).filter(Boolean);
143932
+ }
143933
+ function checkKnownVulnerablePythonDeps(deps, manifest) {
143934
+ const vulns = [];
143935
+ for (const dep of deps) {
143936
+ const known = KNOWN_VULNERABLE_PYTHON[dep];
143937
+ if (known) {
143938
+ vulns.push({
143939
+ id: `DEP-py-${dep}-${known.cve}`,
143940
+ title: `Vulnerable Python dependency: ${dep}`,
143941
+ severity: known.severity,
143942
+ category: "vulnerable-components",
143943
+ location: { file: manifest, dependency: { name: dep, version: "any" } },
143944
+ description: known.desc,
143945
+ remediation: dep === "python-jose" ? "Migrate to PyJWT or joserfc" : `Check for updates to ${dep}`,
143946
+ cveId: known.cve,
143947
+ references: [`https://nvd.nist.gov/vuln/detail/${known.cve}`]
143948
+ });
143949
+ }
143950
+ }
143951
+ return vulns;
143952
+ }
143953
+ function compareVersions(a37, b68) {
143954
+ const pa9 = a37.split(".").map(Number);
143955
+ const pb = b68.split(".").map(Number);
143956
+ for (let i58 = 0; i58 < 3; i58++) {
143957
+ const va5 = pa9[i58] || 0;
143958
+ const vb = pb[i58] || 0;
143959
+ if (va5 < vb) return -1;
143960
+ if (va5 > vb) return 1;
143961
+ }
143962
+ return 0;
143009
143963
  }
143010
143964
  function generateDASTFindings(url) {
143011
143965
  return [
143012
143966
  {
143013
- id: "DAST-001",
143014
- title: "Missing Security Headers",
143015
- severity: "medium",
143967
+ id: "DAST-INFO-001",
143968
+ title: "DAST scan target noted",
143969
+ severity: "informational",
143016
143970
  category: "security-misconfiguration",
143017
143971
  location: { file: url },
143018
- description: "X-Frame-Options and Content-Security-Policy headers missing",
143019
- remediation: "Add security headers to HTTP responses",
143020
- references: ["https://owasp.org/www-project-secure-headers/"]
143972
+ description: `DAST target ${url} recorded. Full DAST requires integration with a dynamic scanner (e.g., ZAP, Burp).`,
143973
+ remediation: "Configure a DAST tool to scan the live application",
143974
+ references: ["https://owasp.org/www-project-zap/"]
143021
143975
  }
143022
143976
  ];
143023
143977
  }
@@ -143055,6 +144009,9 @@ function generateRecommendations5(vulnerabilities, summary) {
143055
144009
  if (vulnerabilities.some((v62) => v62.category === "sensitive-data")) {
143056
144010
  recs.push("Implement proper secrets management");
143057
144011
  }
144012
+ if (vulnerabilities.some((v62) => v62.category === "vulnerable-components")) {
144013
+ recs.push("Run full dependency audit and update vulnerable packages");
144014
+ }
143058
144015
  if (recs.length === 0) {
143059
144016
  recs.push("No critical issues found. Continue regular security reviews.");
143060
144017
  }
@@ -147391,7 +148348,7 @@ function getSharedGOAPPlanner() {
147391
148348
  }
147392
148349
 
147393
148350
  // src/planning/plan-executor.ts
147394
- init_better_sqlite3();
148351
+ init_safe_db();
147395
148352
  init_unified_memory();
147396
148353
  init_error_utils();
147397
148354
  init_safe_json();
@@ -147426,7 +148383,7 @@ var PlanExecutor = class {
147426
148383
  this.spawner = spawner;
147427
148384
  this.config = { ...DEFAULT_CONFIG69, ...config };
147428
148385
  if (!this.config.useUnified) {
147429
- this.db = new better_sqlite3_default(dbPath ?? ":memory:");
148386
+ this.db = openDatabase(dbPath ?? ":memory:", { walMode: false });
147430
148387
  this.db.pragma("journal_mode = WAL");
147431
148388
  }
147432
148389
  }
@@ -149370,7 +150327,7 @@ init_logging();
149370
150327
  init_types();
149371
150328
 
149372
150329
  // src/learning/v2-to-v3-migration.ts
149373
- init_better_sqlite3();
150330
+ init_safe_db();
149374
150331
  init_error_utils();
149375
150332
  init_safe_json();
149376
150333
  init_logging();
@@ -149815,7 +150772,7 @@ init_logging();
149815
150772
  var logger17 = LoggerFactory.create("pattern-lifecycle");
149816
150773
 
149817
150774
  // src/learning/metrics-tracker.ts
149818
- init_better_sqlite3();
150775
+ init_safe_db();
149819
150776
  init_qe_patterns();
149820
150777
  init_safe_json();
149821
150778
  init_logging();
@@ -153347,14 +154304,22 @@ async function handleTaskOrchestrate(params) {
153347
154304
  }
153348
154305
  const { queen, workflowOrchestrator } = getFleetState();
153349
154306
  try {
154307
+ const inferredDomain = params.context?.project || inferDomainFromDescription(params.task);
154308
+ const inferredIsCritical = params.priority === "critical" || /\b(security|vulnerability|cve|owasp|critical|production|exploit)\b/i.test(params.task);
153350
154309
  const router = await getTaskRouter();
153351
154310
  const routingResult = await router.routeTask({
153352
154311
  task: params.task,
153353
154312
  codeContext: params.codeContext,
153354
154313
  filePaths: params.filePaths,
153355
154314
  manualTier: params.manualTier,
153356
- isCritical: params.priority === "critical",
153357
- domain: params.context?.project
154315
+ isCritical: inferredIsCritical,
154316
+ agentType: `qe-${inferredDomain}`,
154317
+ domain: inferredDomain,
154318
+ metadata: {
154319
+ inferredDomain,
154320
+ hasCodeContext: !!params.codeContext,
154321
+ fileCount: params.filePaths?.length
154322
+ }
153358
154323
  });
153359
154324
  const reasoningBankService = await getReasoningBankService();
153360
154325
  const experienceGuidance = await reasoningBankService.getExperienceGuidance(
@@ -153492,14 +154457,22 @@ async function handleTaskOrchestrate(params) {
153492
154457
  async function handleModelRoute(params) {
153493
154458
  try {
153494
154459
  const router = await getTaskRouter();
154460
+ const inferredDomain = params.domain || inferDomainFromDescription(params.task);
154461
+ const inferredIsCritical = params.isCritical ?? /\b(security|vulnerability|cve|owasp|critical|production|exploit)\b/i.test(params.task);
153495
154462
  const result = await router.routeTask({
153496
154463
  task: params.task,
153497
154464
  codeContext: params.codeContext,
153498
154465
  filePaths: params.filePaths,
153499
154466
  manualTier: params.manualTier,
153500
- isCritical: params.isCritical,
153501
- agentType: params.agentType,
153502
- domain: params.domain
154467
+ isCritical: inferredIsCritical,
154468
+ agentType: params.agentType || `qe-${inferredDomain}`,
154469
+ domain: inferredDomain,
154470
+ // Pass metadata to help the complexity analyzer
154471
+ metadata: {
154472
+ inferredDomain,
154473
+ hasCodeContext: !!params.codeContext,
154474
+ fileCount: params.filePaths?.length
154475
+ }
153503
154476
  });
153504
154477
  return {
153505
154478
  success: true,
@@ -153562,6 +154535,43 @@ async function handleRoutingMetrics(params) {
153562
154535
  };
153563
154536
  }
153564
154537
  }
154538
+ function inferDomainFromDescription(description) {
154539
+ const lower = description.toLowerCase();
154540
+ if (/\b(security|vulnerabilit|cve|owasp|secret|credential|injection|xss|csrf)\b/.test(lower)) {
154541
+ return "security-compliance";
154542
+ }
154543
+ if (/\b(chaos|resilience|fault.?inject|disaster|failover)\b/.test(lower)) {
154544
+ return "chaos-resilience";
154545
+ }
154546
+ if (/\b(defect|bug.?predict|risk.?assess|mutation)\b/.test(lower)) {
154547
+ return "defect-intelligence";
154548
+ }
154549
+ if (/\b(coverage|uncovered|gap.?analy)\b/.test(lower)) {
154550
+ return "coverage-analysis";
154551
+ }
154552
+ if (/\b(quality|code.?review|maintain|tech.?debt)\b/.test(lower)) {
154553
+ return "quality-assessment";
154554
+ }
154555
+ if (/\b(contract|api.?compat|breaking.?change|pact)\b/.test(lower)) {
154556
+ return "contract-testing";
154557
+ }
154558
+ if (/\b(index|knowledge.?graph|semantic|code.?intel)\b/.test(lower)) {
154559
+ return "code-intelligence";
154560
+ }
154561
+ if (/\b(accessib|a11y|wcag|screen.?read)\b/.test(lower)) {
154562
+ return "visual-accessibility";
154563
+ }
154564
+ if (/\b(requirement|bdd|acceptance|user.?stor)\b/.test(lower)) {
154565
+ return "requirements-validation";
154566
+ }
154567
+ if (/\b(generat.*test|test.*generat|write.*test|create.*test)\b/.test(lower)) {
154568
+ return "test-generation";
154569
+ }
154570
+ if (/\b(run.*test|execut.*test)\b/.test(lower)) {
154571
+ return "test-execution";
154572
+ }
154573
+ return "test-generation";
154574
+ }
153565
154575
  function inferTaskType(description) {
153566
154576
  const lower = description.toLowerCase();
153567
154577
  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 +156331,18 @@ var MCPProtocolServer = class {
155321
156331
  async start() {
155322
156332
  await initializeConnectionPool();
155323
156333
  this.transport.onRequest(async (request) => {
155324
- return this.handleRequest(request);
156334
+ try {
156335
+ return await this.handleRequest(request);
156336
+ } catch (err4) {
156337
+ const message = err4 instanceof Error ? err4.message : String(err4);
156338
+ console.error(`[MCP] Unhandled error in request handler: ${message}`);
156339
+ return {
156340
+ content: [{
156341
+ type: "text",
156342
+ text: JSON.stringify({ success: false, error: `Internal error: ${message}` })
156343
+ }]
156344
+ };
156345
+ }
155325
156346
  });
155326
156347
  this.transport.onNotification(async (notification) => {
155327
156348
  await this.handleNotification(notification);