agentic-qe 3.7.14 → 3.7.16

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 (55) hide show
  1. package/.claude/helpers/brain-checkpoint.cjs +11 -0
  2. package/.claude/skills/skills-manifest.json +1 -1
  3. package/CHANGELOG.md +49 -0
  4. package/dist/cli/bundle.js +1260 -528
  5. package/dist/cli/commands/prove.d.ts +60 -0
  6. package/dist/cli/commands/prove.js +167 -0
  7. package/dist/cli/handlers/brain-handler.js +2 -1
  8. package/dist/cli/index.js +2 -0
  9. package/dist/domains/test-generation/coordinator.js +6 -4
  10. package/dist/domains/test-generation/pattern-injection/edge-case-injector.d.ts +6 -0
  11. package/dist/domains/test-generation/pattern-injection/edge-case-injector.js +30 -0
  12. package/dist/feedback/feedback-loop.d.ts +5 -0
  13. package/dist/feedback/feedback-loop.js +12 -0
  14. package/dist/feedback/index.d.ts +1 -1
  15. package/dist/feedback/index.js +1 -1
  16. package/dist/kernel/hnsw-adapter.d.ts +3 -0
  17. package/dist/kernel/hnsw-adapter.js +11 -1
  18. package/dist/kernel/unified-memory-schemas.d.ts +3 -3
  19. package/dist/kernel/unified-memory-schemas.js +28 -1
  20. package/dist/kernel/unified-memory.js +57 -0
  21. package/dist/learning/aqe-learning-engine.js +2 -1
  22. package/dist/learning/daily-log.d.ts +43 -0
  23. package/dist/learning/daily-log.js +91 -0
  24. package/dist/learning/experience-capture-middleware.js +24 -0
  25. package/dist/learning/experience-capture.d.ts +42 -0
  26. package/dist/learning/experience-capture.js +94 -4
  27. package/dist/learning/index.d.ts +4 -0
  28. package/dist/learning/index.js +8 -0
  29. package/dist/learning/opd-remediation.d.ts +55 -0
  30. package/dist/learning/opd-remediation.js +130 -0
  31. package/dist/learning/pattern-lifecycle.d.ts +12 -1
  32. package/dist/learning/pattern-lifecycle.js +18 -2
  33. package/dist/learning/pattern-store.d.ts +12 -4
  34. package/dist/learning/pattern-store.js +178 -19
  35. package/dist/learning/qe-hooks.d.ts +1 -0
  36. package/dist/learning/qe-hooks.js +30 -0
  37. package/dist/learning/qe-patterns.d.ts +6 -0
  38. package/dist/learning/qe-patterns.js +10 -1
  39. package/dist/learning/sqlite-persistence.d.ts +43 -0
  40. package/dist/learning/sqlite-persistence.js +237 -1
  41. package/dist/learning/token-tracker.js +4 -0
  42. package/dist/mcp/bundle.js +836 -48
  43. package/dist/mcp/handlers/core-handlers.d.ts +5 -0
  44. package/dist/mcp/handlers/core-handlers.js +11 -0
  45. package/dist/mcp/handlers/handler-factory.js +92 -11
  46. package/dist/mcp/index.d.ts +1 -0
  47. package/dist/mcp/index.js +2 -0
  48. package/dist/mcp/tool-scoping.d.ts +36 -0
  49. package/dist/mcp/tool-scoping.js +129 -0
  50. package/dist/routing/routing-feedback.d.ts +5 -0
  51. package/dist/routing/routing-feedback.js +29 -3
  52. package/dist/sync/pull-agent.js +2 -1
  53. package/dist/test-scheduling/pipeline.d.ts +7 -0
  54. package/dist/test-scheduling/pipeline.js +9 -0
  55. package/package.json +1 -1
@@ -11,10 +11,10 @@ var __require = /* @__PURE__ */ ((x67) => typeof require !== "undefined" ? requi
11
11
  if (typeof require !== "undefined") return require.apply(this, arguments);
12
12
  throw Error('Dynamic require of "' + x67 + '" is not supported');
13
13
  });
14
- var __glob = (map) => (path36) => {
15
- var fn = map[path36];
14
+ var __glob = (map) => (path37) => {
15
+ var fn = map[path37];
16
16
  if (fn) return fn();
17
- throw new Error("Module not found in bundle: " + path36);
17
+ throw new Error("Module not found in bundle: " + path37);
18
18
  };
19
19
  var __esm = (fn, res) => function __init() {
20
20
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
@@ -1876,7 +1876,19 @@ var init_hnsw_adapter = __esm({
1876
1876
  this.backend.add(id, vector, metadata);
1877
1877
  }
1878
1878
  search(query, k68) {
1879
- return this.backend.search(query, k68);
1879
+ const start = performance.now();
1880
+ const results = this.backend.search(query, k68);
1881
+ const elapsed = performance.now() - start;
1882
+ if (elapsed > 50) {
1883
+ console.warn(`[HNSW] search took ${elapsed.toFixed(1)}ms (k=${k68}, results=${results.length})`);
1884
+ }
1885
+ this._lastSearchLatencyMs = elapsed;
1886
+ return results;
1887
+ }
1888
+ /** Last search latency in ms, for instrumentation */
1889
+ _lastSearchLatencyMs = 0;
1890
+ get lastSearchLatencyMs() {
1891
+ return this._lastSearchLatencyMs;
1880
1892
  }
1881
1893
  remove(id) {
1882
1894
  return this.backend.remove(id);
@@ -2549,7 +2561,7 @@ var init_unified_memory_schemas = __esm({
2549
2561
  "src/kernel/unified-memory-schemas.ts"() {
2550
2562
  "use strict";
2551
2563
  init_add_hypergraph_tables();
2552
- SCHEMA_VERSION = 8;
2564
+ SCHEMA_VERSION = 9;
2553
2565
  SCHEMA_VERSION_TABLE = `
2554
2566
  CREATE TABLE IF NOT EXISTS schema_version (
2555
2567
  id INTEGER PRIMARY KEY CHECK (id = 1),
@@ -2855,6 +2867,31 @@ var init_unified_memory_schemas = __esm({
2855
2867
  FOREIGN KEY (execution_id) REFERENCES execution_results(id)
2856
2868
  );
2857
2869
 
2870
+ -- FTS5 full-text search index for hybrid vector/text search
2871
+ CREATE VIRTUAL TABLE IF NOT EXISTS qe_patterns_fts USING fts5(
2872
+ name, description, pattern_type, qe_domain,
2873
+ content='qe_patterns',
2874
+ content_rowid='rowid'
2875
+ );
2876
+
2877
+ -- FTS5 triggers to keep index in sync
2878
+ CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_insert AFTER INSERT ON qe_patterns BEGIN
2879
+ INSERT INTO qe_patterns_fts(rowid, name, description, pattern_type, qe_domain)
2880
+ VALUES (new.rowid, new.name, new.description, new.pattern_type, new.qe_domain);
2881
+ END;
2882
+
2883
+ CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_delete AFTER DELETE ON qe_patterns BEGIN
2884
+ INSERT INTO qe_patterns_fts(qe_patterns_fts, rowid, name, description, pattern_type, qe_domain)
2885
+ VALUES ('delete', old.rowid, old.name, old.description, old.pattern_type, old.qe_domain);
2886
+ END;
2887
+
2888
+ CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_update AFTER UPDATE ON qe_patterns BEGIN
2889
+ INSERT INTO qe_patterns_fts(qe_patterns_fts, rowid, name, description, pattern_type, qe_domain)
2890
+ VALUES ('delete', old.rowid, old.name, old.description, old.pattern_type, old.qe_domain);
2891
+ INSERT INTO qe_patterns_fts(rowid, name, description, pattern_type, qe_domain)
2892
+ VALUES (new.rowid, new.name, new.description, new.pattern_type, new.qe_domain);
2893
+ END;
2894
+
2858
2895
  -- QE Patterns indexes
2859
2896
  CREATE INDEX IF NOT EXISTS idx_qe_patterns_domain ON qe_patterns(qe_domain);
2860
2897
  CREATE INDEX IF NOT EXISTS idx_qe_patterns_type ON qe_patterns(pattern_type);
@@ -3048,10 +3085,12 @@ var init_unified_memory_schemas = __esm({
3048
3085
  quality_score REAL NOT NULL,
3049
3086
  duration_ms REAL NOT NULL,
3050
3087
  error TEXT,
3088
+ model_tier TEXT,
3051
3089
  created_at TEXT DEFAULT (datetime('now'))
3052
3090
  );
3053
3091
  CREATE INDEX IF NOT EXISTS idx_routing_outcomes_agent ON routing_outcomes(used_agent);
3054
3092
  CREATE INDEX IF NOT EXISTS idx_routing_outcomes_created ON routing_outcomes(created_at);
3093
+ CREATE INDEX IF NOT EXISTS idx_routing_outcomes_tier ON routing_outcomes(model_tier);
3055
3094
 
3056
3095
  -- Coverage sessions (ADR-023: Coverage Learning)
3057
3096
  CREATE TABLE IF NOT EXISTS coverage_sessions (
@@ -4045,6 +4084,7 @@ __export(unified_memory_exports, {
4045
4084
  validateTableName: () => validateTableName
4046
4085
  });
4047
4086
  import * as fs from "fs";
4087
+ import * as os from "os";
4048
4088
  import * as path from "path";
4049
4089
  function clearProjectRootCache() {
4050
4090
  _cachedProjectRoot = null;
@@ -4201,6 +4241,7 @@ var init_unified_memory = __esm({
4201
4241
  _UnifiedMemoryManager.instance = null;
4202
4242
  }
4203
4243
  _UnifiedMemoryManager.instancePromise = null;
4244
+ clearProjectRootCache();
4204
4245
  }
4205
4246
  async initialize() {
4206
4247
  if (this.initialized) return;
@@ -4212,6 +4253,17 @@ var init_unified_memory = __esm({
4212
4253
  async _doInitialize() {
4213
4254
  if (this.initialized) return;
4214
4255
  try {
4256
+ const envRoot = process.env.AQE_PROJECT_ROOT;
4257
+ if (envRoot) {
4258
+ const resolvedPath = path.resolve(this.config.dbPath);
4259
+ const resolvedRoot = path.resolve(envRoot);
4260
+ if (!resolvedPath.startsWith(resolvedRoot) && !resolvedPath.startsWith(os.tmpdir()) && resolvedPath.includes(".agentic-qe")) {
4261
+ console.error(
4262
+ `[UnifiedMemory] WARNING: DB path "${this.config.dbPath}" points to a production .agentic-qe/ while AQE_PROJECT_ROOT="${envRoot}". Redirecting to test-safe path.`
4263
+ );
4264
+ this.config.dbPath = path.join(envRoot, ".agentic-qe", "memory.db");
4265
+ }
4266
+ }
4215
4267
  const dir = path.dirname(this.config.dbPath);
4216
4268
  if (!fs.existsSync(dir)) {
4217
4269
  fs.mkdirSync(dir, { recursive: true });
@@ -4385,6 +4437,36 @@ var init_unified_memory = __esm({
4385
4437
  if (currentVersion < 6) this.db.exec(HYPERGRAPH_SCHEMA);
4386
4438
  if (currentVersion < 7) this.db.exec(SONA_PATTERNS_SCHEMA);
4387
4439
  if (currentVersion < 8) this.db.exec(FEEDBACK_SCHEMA);
4440
+ if (currentVersion < 9) {
4441
+ this.db.exec(`
4442
+ CREATE VIRTUAL TABLE IF NOT EXISTS qe_patterns_fts USING fts5(
4443
+ name, description, pattern_type, qe_domain,
4444
+ content='qe_patterns',
4445
+ content_rowid='rowid'
4446
+ );
4447
+
4448
+ CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_insert AFTER INSERT ON qe_patterns BEGIN
4449
+ INSERT INTO qe_patterns_fts(rowid, name, description, pattern_type, qe_domain)
4450
+ VALUES (new.rowid, new.name, new.description, new.pattern_type, new.qe_domain);
4451
+ END;
4452
+
4453
+ CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_delete AFTER DELETE ON qe_patterns BEGIN
4454
+ INSERT INTO qe_patterns_fts(qe_patterns_fts, rowid, name, description, pattern_type, qe_domain)
4455
+ VALUES ('delete', old.rowid, old.name, old.description, old.pattern_type, old.qe_domain);
4456
+ END;
4457
+
4458
+ CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_update AFTER UPDATE ON qe_patterns BEGIN
4459
+ INSERT INTO qe_patterns_fts(qe_patterns_fts, rowid, name, description, pattern_type, qe_domain)
4460
+ VALUES ('delete', old.rowid, old.name, old.description, old.pattern_type, old.qe_domain);
4461
+ INSERT INTO qe_patterns_fts(rowid, name, description, pattern_type, qe_domain)
4462
+ VALUES (new.rowid, new.name, new.description, new.pattern_type, new.qe_domain);
4463
+ END;
4464
+ `);
4465
+ this.db.exec(`
4466
+ INSERT INTO qe_patterns_fts(rowid, name, description, pattern_type, qe_domain)
4467
+ SELECT rowid, name, description, pattern_type, qe_domain FROM qe_patterns;
4468
+ `);
4469
+ }
4388
4470
  this.db.prepare(`
4389
4471
  INSERT OR REPLACE INTO schema_version (id, version, migrated_at)
4390
4472
  VALUES (1, ?, datetime('now'))
@@ -7327,7 +7409,7 @@ function calculateQualityScore(pattern) {
7327
7409
  return pattern.confidence * 0.3 + usageScore * 0.2 + pattern.successRate * 0.5;
7328
7410
  }
7329
7411
  function shouldPromotePattern(pattern, coherenceEnergy, coherenceThreshold = 0.4) {
7330
- const meetsUsageCriteria = pattern.tier === "short-term" && pattern.successfulUses >= 3;
7412
+ const meetsUsageCriteria = pattern.tier === "short-term" && pattern.successfulUses >= PROMOTION_THRESHOLD;
7331
7413
  const meetsQualityCriteria = pattern.successRate >= 0.7 && pattern.confidence >= 0.6;
7332
7414
  const meetsCoherenceCriteria = coherenceEnergy === void 0 || coherenceEnergy < coherenceThreshold;
7333
7415
  let blockReason;
@@ -7389,7 +7471,7 @@ function applyPatternTemplate(template, variables) {
7389
7471
  }
7390
7472
  return content;
7391
7473
  }
7392
- var QE_DOMAINS, QE_DOMAIN_LIST;
7474
+ var QE_DOMAINS, PROMOTION_THRESHOLD, QE_DOMAIN_LIST;
7393
7475
  var init_qe_patterns = __esm({
7394
7476
  "src/learning/qe-patterns.ts"() {
7395
7477
  "use strict";
@@ -7411,6 +7493,7 @@ var init_qe_patterns = __esm({
7411
7493
  "chaos-resilience": /chaos|resilience|fault|inject|blast|recover|latency|failure|stress|load/i,
7412
7494
  "learning-optimization": /learn|pattern|optim|neural|embedding|vector|memory|adapt|train/i
7413
7495
  };
7496
+ PROMOTION_THRESHOLD = 3;
7414
7497
  QE_DOMAIN_LIST = Object.keys(QE_DOMAINS);
7415
7498
  }
7416
7499
  });
@@ -11024,7 +11107,7 @@ var init_gnn_wrapper = __esm({
11024
11107
  * Save index to file
11025
11108
  * Note: @ruvector/gnn uses JSON serialization for layers
11026
11109
  */
11027
- async saveIndex(namespace, path36) {
11110
+ async saveIndex(namespace, path37) {
11028
11111
  const index = this.indexes.get(namespace);
11029
11112
  if (!index) {
11030
11113
  throw new Error(`Namespace ${namespace} not initialized`);
@@ -11034,15 +11117,15 @@ var init_gnn_wrapper = __esm({
11034
11117
  vector: Array.from(emb.vector),
11035
11118
  metadata: emb.metadata
11036
11119
  }));
11037
- const fs31 = await import("fs/promises");
11038
- await fs31.writeFile(path36, JSON.stringify(data, null, 2));
11120
+ const fs32 = await import("fs/promises");
11121
+ await fs32.writeFile(path37, JSON.stringify(data, null, 2));
11039
11122
  }
11040
11123
  /**
11041
11124
  * Load index from file
11042
11125
  */
11043
- async loadIndex(namespace, path36) {
11044
- const fs31 = await import("fs/promises");
11045
- const content = await fs31.readFile(path36, "utf-8");
11126
+ async loadIndex(namespace, path37) {
11127
+ const fs32 = await import("fs/promises");
11128
+ const content = await fs32.readFile(path37, "utf-8");
11046
11129
  const data = safeJsonParse(content);
11047
11130
  this.initializeIndex(namespace);
11048
11131
  for (const item of data) {
@@ -12544,7 +12627,7 @@ var init_path_traversal_validator = __esm({
12544
12627
  /**
12545
12628
  * Validate a file path against traversal attacks
12546
12629
  */
12547
- validate(path36, options = {}) {
12630
+ validate(path37, options = {}) {
12548
12631
  const {
12549
12632
  basePath = "",
12550
12633
  allowAbsolute = false,
@@ -12553,7 +12636,7 @@ var init_path_traversal_validator = __esm({
12553
12636
  maxDepth = 10,
12554
12637
  maxLength = 4096
12555
12638
  } = options;
12556
- if (path36.length > maxLength) {
12639
+ if (path37.length > maxLength) {
12557
12640
  return {
12558
12641
  valid: false,
12559
12642
  error: `Path exceeds maximum length of ${maxLength}`,
@@ -12561,7 +12644,7 @@ var init_path_traversal_validator = __esm({
12561
12644
  };
12562
12645
  }
12563
12646
  for (const pattern of PATH_TRAVERSAL_PATTERNS) {
12564
- if (pattern.test(path36)) {
12647
+ if (pattern.test(path37)) {
12565
12648
  return {
12566
12649
  valid: false,
12567
12650
  error: "Path traversal attempt detected",
@@ -12569,7 +12652,7 @@ var init_path_traversal_validator = __esm({
12569
12652
  };
12570
12653
  }
12571
12654
  }
12572
- if (!allowAbsolute && (path36.startsWith("/") || /^[A-Z]:/i.test(path36))) {
12655
+ if (!allowAbsolute && (path37.startsWith("/") || /^[A-Z]:/i.test(path37))) {
12573
12656
  return {
12574
12657
  valid: false,
12575
12658
  error: "Absolute paths are not allowed",
@@ -12577,7 +12660,7 @@ var init_path_traversal_validator = __esm({
12577
12660
  };
12578
12661
  }
12579
12662
  for (const pattern of DANGEROUS_PATH_COMPONENTS) {
12580
- if (pattern.test(path36)) {
12663
+ if (pattern.test(path37)) {
12581
12664
  return {
12582
12665
  valid: false,
12583
12666
  error: "Access to system paths is not allowed",
@@ -12585,7 +12668,7 @@ var init_path_traversal_validator = __esm({
12585
12668
  };
12586
12669
  }
12587
12670
  }
12588
- const normalizedPath = this.normalizePath(path36);
12671
+ const normalizedPath = this.normalizePath(path37);
12589
12672
  if (normalizedPath.includes("..")) {
12590
12673
  return {
12591
12674
  valid: false,
@@ -12648,8 +12731,8 @@ var init_path_traversal_validator = __esm({
12648
12731
  /**
12649
12732
  * Normalize a path by resolving . and .. components
12650
12733
  */
12651
- normalizePath(path36) {
12652
- let normalized = path36.replace(/\\/g, "/");
12734
+ normalizePath(path37) {
12735
+ let normalized = path37.replace(/\\/g, "/");
12653
12736
  normalized = normalized.replace(/\/+/g, "/");
12654
12737
  const parts = normalized.split("/");
12655
12738
  const result = [];
@@ -12690,13 +12773,13 @@ var init_path_traversal_validator = __esm({
12690
12773
  /**
12691
12774
  * Get file extension from path
12692
12775
  */
12693
- getExtension(path36) {
12694
- const match = path36.match(/\.([^./\\]+)$/);
12776
+ getExtension(path37) {
12777
+ const match = path37.match(/\.([^./\\]+)$/);
12695
12778
  return match ? match[1] : null;
12696
12779
  }
12697
12780
  };
12698
12781
  defaultValidator2 = new PathTraversalValidator();
12699
- validatePath = (path36, options) => defaultValidator2.validate(path36, options);
12782
+ validatePath = (path37, options) => defaultValidator2.validate(path37, options);
12700
12783
  }
12701
12784
  });
12702
12785
 
@@ -13797,23 +13880,23 @@ var init_knowledge_graph = __esm({
13797
13880
  if (!incremental) {
13798
13881
  await this.clear();
13799
13882
  }
13800
- for (const path36 of paths) {
13883
+ for (const path37 of paths) {
13801
13884
  try {
13802
13885
  if (languages && languages.length > 0) {
13803
- const ext = this.getFileExtension(path36);
13886
+ const ext = this.getFileExtension(path37);
13804
13887
  if (!this.matchesLanguage(ext, languages)) {
13805
13888
  continue;
13806
13889
  }
13807
13890
  }
13808
- if (!includeTests && this.isTestFile(path36)) {
13891
+ if (!includeTests && this.isTestFile(path37)) {
13809
13892
  continue;
13810
13893
  }
13811
- const result = await this.indexFile(path36);
13894
+ const result = await this.indexFile(path37);
13812
13895
  nodesCreated += result.nodes;
13813
13896
  edgesCreated += result.edges;
13814
13897
  } catch (fileError) {
13815
13898
  errors.push({
13816
- file: path36,
13899
+ file: path37,
13817
13900
  error: toErrorMessage(fileError)
13818
13901
  });
13819
13902
  }
@@ -14527,16 +14610,16 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
14527
14610
  }
14528
14611
  });
14529
14612
  }
14530
- async traverseDependencies(file, direction, depth, visited, nodes, edges, path36, cycles) {
14613
+ async traverseDependencies(file, direction, depth, visited, nodes, edges, path37, cycles) {
14531
14614
  if (depth <= 0 || visited.has(file)) {
14532
- const cycleStart = path36.indexOf(file);
14615
+ const cycleStart = path37.indexOf(file);
14533
14616
  if (cycleStart >= 0) {
14534
- cycles.push([...path36.slice(cycleStart), file]);
14617
+ cycles.push([...path37.slice(cycleStart), file]);
14535
14618
  }
14536
14619
  return;
14537
14620
  }
14538
14621
  visited.add(file);
14539
- path36.push(file);
14622
+ path37.push(file);
14540
14623
  const nodeId = this.pathToNodeId(file);
14541
14624
  const fileEdges = await this.getEdges(nodeId, direction);
14542
14625
  const inDegree = fileEdges.filter((e20) => e20.target === nodeId).length;
@@ -14566,12 +14649,12 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
14566
14649
  visited,
14567
14650
  nodes,
14568
14651
  edges,
14569
- path36,
14652
+ path37,
14570
14653
  cycles
14571
14654
  );
14572
14655
  }
14573
14656
  }
14574
- path36.pop();
14657
+ path37.pop();
14575
14658
  }
14576
14659
  calculateDependencyMetrics(nodes, edges) {
14577
14660
  const totalNodes = nodes.length;
@@ -14656,23 +14739,23 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
14656
14739
  const magnitude2 = Math.sqrt(embedding.reduce((sum, v65) => sum + v65 * v65, 0)) || 1;
14657
14740
  return embedding.map((v65) => v65 / magnitude2);
14658
14741
  }
14659
- pathToNodeId(path36) {
14660
- return path36.replace(/[/\\]/g, ":").replace(/\./g, "_");
14742
+ pathToNodeId(path37) {
14743
+ return path37.replace(/[/\\]/g, ":").replace(/\./g, "_");
14661
14744
  }
14662
14745
  nodeIdToPath(nodeId) {
14663
- const path36 = nodeId.replace(/:/g, "/").replace(/_(?=[^_]*$)/, ".");
14664
- return path36.includes("/") ? path36 : null;
14746
+ const path37 = nodeId.replace(/:/g, "/").replace(/_(?=[^_]*$)/, ".");
14747
+ return path37.includes("/") ? path37 : null;
14665
14748
  }
14666
- getFileName(path36) {
14667
- return path36.split(/[/\\]/).pop() || path36;
14749
+ getFileName(path37) {
14750
+ return path37.split(/[/\\]/).pop() || path37;
14668
14751
  }
14669
- getFileExtension(path36) {
14670
- const name = this.getFileName(path36);
14752
+ getFileExtension(path37) {
14753
+ const name = this.getFileName(path37);
14671
14754
  const parts = name.split(".");
14672
14755
  return parts.length > 1 ? parts.pop() : "";
14673
14756
  }
14674
- getFileType(path36) {
14675
- const ext = this.getFileExtension(path36);
14757
+ getFileType(path37) {
14758
+ const ext = this.getFileExtension(path37);
14676
14759
  const typeMap = {
14677
14760
  ts: "typescript",
14678
14761
  tsx: "typescript-react",
@@ -14701,7 +14784,7 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
14701
14784
  return exts.includes(ext);
14702
14785
  });
14703
14786
  }
14704
- isTestFile(path36) {
14787
+ isTestFile(path37) {
14705
14788
  const testPatterns = [
14706
14789
  /\.test\.[tj]sx?$/,
14707
14790
  /\.spec\.[tj]sx?$/,
@@ -14710,7 +14793,7 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
14710
14793
  /.*_test\.py$/,
14711
14794
  /.*_test\.go$/
14712
14795
  ];
14713
- return testPatterns.some((pattern) => pattern.test(path36));
14796
+ return testPatterns.some((pattern) => pattern.test(path37));
14714
14797
  }
14715
14798
  /**
14716
14799
  * Dispose of all resources and clear caches.
@@ -15049,7 +15132,7 @@ var init_impact_analyzer = __esm({
15049
15132
  // ============================================================================
15050
15133
  // Private Helper Methods
15051
15134
  // ============================================================================
15052
- isTestFile(path36) {
15135
+ isTestFile(path37) {
15053
15136
  const testPatterns = [
15054
15137
  /\.test\.[tj]sx?$/,
15055
15138
  /\.spec\.[tj]sx?$/,
@@ -15058,15 +15141,15 @@ var init_impact_analyzer = __esm({
15058
15141
  /.*_test\.py$/,
15059
15142
  /.*_test\.go$/
15060
15143
  ];
15061
- return testPatterns.some((pattern) => pattern.test(path36));
15144
+ return testPatterns.some((pattern) => pattern.test(path37));
15062
15145
  }
15063
- isCriticalPath(path36) {
15146
+ isCriticalPath(path37) {
15064
15147
  const criticalPatterns = this.config.criticalPaths.map(
15065
15148
  (p74) => p74.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*")
15066
15149
  );
15067
- return criticalPatterns.some((pattern) => new RegExp(pattern).test(path36));
15150
+ return criticalPatterns.some((pattern) => new RegExp(pattern).test(path37));
15068
15151
  }
15069
- isEntryPoint(path36) {
15152
+ isEntryPoint(path37) {
15070
15153
  const entryPatterns = [
15071
15154
  /\/index\.[tj]sx?$/,
15072
15155
  /\/main\.[tj]sx?$/,
@@ -15076,14 +15159,14 @@ var init_impact_analyzer = __esm({
15076
15159
  /\/__init__\.py$/,
15077
15160
  /\/main\.go$/
15078
15161
  ];
15079
- return entryPatterns.some((pattern) => pattern.test(path36));
15162
+ return entryPatterns.some((pattern) => pattern.test(path37));
15080
15163
  }
15081
- getBaseName(path36) {
15082
- const fileName = this.getFileName(path36);
15164
+ getBaseName(path37) {
15165
+ const fileName = this.getFileName(path37);
15083
15166
  return fileName.replace(/\.[^.]+$/, "");
15084
15167
  }
15085
- getFileName(path36) {
15086
- return path36.split(/[/\\]/).pop() || path36;
15168
+ getFileName(path37) {
15169
+ return path37.split(/[/\\]/).pop() || path37;
15087
15170
  }
15088
15171
  deduplicateImpact(impact) {
15089
15172
  const seen = /* @__PURE__ */ new Map();
@@ -18591,7 +18674,7 @@ var init_pattern_store = __esm({
18591
18674
  efSearch: 100,
18592
18675
  maxElements: 5e4
18593
18676
  },
18594
- promotionThreshold: 3,
18677
+ promotionThreshold: PROMOTION_THRESHOLD,
18595
18678
  minConfidence: 0.3,
18596
18679
  maxPatternsPerDomain: 5e3,
18597
18680
  autoCleanup: true,
@@ -18624,6 +18707,7 @@ var init_pattern_store = __esm({
18624
18707
  cleanupTimer;
18625
18708
  // Optional SQLite persistence delegate for delete/promote
18626
18709
  sqliteStore = null;
18710
+ loadingPromise = null;
18627
18711
  // In-memory caches for fast access
18628
18712
  patternCache = /* @__PURE__ */ new Map();
18629
18713
  domainIndex = /* @__PURE__ */ new Map();
@@ -18640,12 +18724,22 @@ var init_pattern_store = __esm({
18640
18724
  searchLatencies: []
18641
18725
  };
18642
18726
  /**
18643
- * Set SQLite persistence delegate for delete/promote operations.
18644
- * When set, PatternStore will forward these operations to SQLite
18645
- * in addition to updating the in-memory cache.
18727
+ * Set SQLite persistence delegate and load patterns into memory.
18728
+ *
18729
+ * When set, PatternStore will:
18730
+ * 1. Load existing patterns from SQLite into the in-memory cache
18731
+ * 2. Forward create/delete/promote operations to SQLite for persistence
18732
+ * 3. Persist embeddings alongside patterns on store()
18646
18733
  */
18647
18734
  setSqliteStore(store) {
18648
18735
  this.sqliteStore = store;
18736
+ if (this.initialized) {
18737
+ this.loadingPromise = this.loadPatterns().catch(
18738
+ (e20) => console.warn("[PatternStore] Failed to load patterns after setSqliteStore:", e20)
18739
+ ).finally(() => {
18740
+ this.loadingPromise = null;
18741
+ });
18742
+ }
18649
18743
  }
18650
18744
  /**
18651
18745
  * Initialize the pattern store
@@ -18716,6 +18810,40 @@ var init_pattern_store = __esm({
18716
18810
  );
18717
18811
  await Promise.race([initPromise3, timeoutPromise]);
18718
18812
  this.hnswAvailable = this.hnswIndex.isNativeAvailable();
18813
+ if (this.sqliteStore) {
18814
+ try {
18815
+ const embeddings = this.sqliteStore.getAllEmbeddings();
18816
+ const maxBootstrap = this.config.hnsw.maxElements;
18817
+ let loaded = 0;
18818
+ for (const { patternId, embedding } of embeddings) {
18819
+ if (loaded >= maxBootstrap) break;
18820
+ if (!embedding || embedding.length !== this.config.embeddingDimension) continue;
18821
+ const pattern = this.patternCache.get(patternId);
18822
+ if (!pattern) continue;
18823
+ try {
18824
+ await this.hnswIndex.insert(patternId, embedding, {
18825
+ filePath: pattern.patternType,
18826
+ lineCoverage: pattern.confidence * 100,
18827
+ branchCoverage: pattern.qualityScore * 100,
18828
+ functionCoverage: 0,
18829
+ statementCoverage: 0,
18830
+ uncoveredLineCount: 0,
18831
+ uncoveredBranchCount: 0,
18832
+ riskScore: 1 - pattern.confidence,
18833
+ lastUpdated: Date.now(),
18834
+ totalLines: 0
18835
+ });
18836
+ loaded++;
18837
+ } catch {
18838
+ }
18839
+ }
18840
+ if (loaded > 0) {
18841
+ console.log(`[PatternStore] Loaded ${loaded} embeddings from SQLite into HNSW`);
18842
+ }
18843
+ } catch (error) {
18844
+ console.warn("[PatternStore] Failed to load SQLite embeddings into HNSW:", toErrorMessage(error));
18845
+ }
18846
+ }
18719
18847
  console.log(
18720
18848
  `[PatternStore] HNSW lazy-initialized (native: ${this.hnswAvailable})`
18721
18849
  );
@@ -18729,9 +18857,32 @@ var init_pattern_store = __esm({
18729
18857
  }
18730
18858
  }
18731
18859
  /**
18732
- * Load existing patterns from memory with timeout protection
18860
+ * Load existing patterns from SQLite into in-memory cache.
18861
+ *
18862
+ * Previously this was a no-op after Issue #258 removed kv_store duplication,
18863
+ * but that left 15,634 SQLite patterns invisible to search on every restart.
18864
+ * Now properly loads from SQLitePatternStore when wired.
18733
18865
  */
18734
18866
  async loadPatterns() {
18867
+ if (!this.sqliteStore) {
18868
+ return;
18869
+ }
18870
+ try {
18871
+ const patterns = this.sqliteStore.getPatterns({ limit: 5e4 });
18872
+ for (const pattern of patterns) {
18873
+ this.indexPattern(pattern);
18874
+ }
18875
+ if (patterns.length > 0) {
18876
+ console.log(
18877
+ `[PatternStore] Loaded ${patterns.length} patterns from SQLite into memory cache`
18878
+ );
18879
+ }
18880
+ } catch (error) {
18881
+ console.warn(
18882
+ "[PatternStore] Failed to load patterns from SQLite:",
18883
+ toErrorMessage(error)
18884
+ );
18885
+ }
18735
18886
  }
18736
18887
  /**
18737
18888
  * Index a pattern in local caches
@@ -18746,7 +18897,11 @@ var init_pattern_store = __esm({
18746
18897
  this.typeIndex.set(pattern.patternType, /* @__PURE__ */ new Set());
18747
18898
  }
18748
18899
  this.typeIndex.get(pattern.patternType).add(pattern.id);
18749
- this.tierIndex.get(pattern.tier).add(pattern.id);
18900
+ const tier = pattern.tier === "long-term" ? "long-term" : "short-term";
18901
+ if (pattern.tier !== tier) {
18902
+ pattern.tier = tier;
18903
+ }
18904
+ this.tierIndex.get(tier).add(pattern.id);
18750
18905
  }
18751
18906
  /**
18752
18907
  * Remove pattern from local indices
@@ -18764,6 +18919,9 @@ var init_pattern_store = __esm({
18764
18919
  if (!this.initialized) {
18765
18920
  await this.initialize();
18766
18921
  }
18922
+ if (this.loadingPromise) {
18923
+ await this.loadingPromise;
18924
+ }
18767
18925
  const validation = validateQEPattern(pattern);
18768
18926
  if (!validation.valid) {
18769
18927
  return err(new Error(`Invalid pattern: ${validation.errors.join(", ")}`));
@@ -18780,6 +18938,13 @@ var init_pattern_store = __esm({
18780
18938
  await this.cleanupDomain(pattern.qeDomain);
18781
18939
  }
18782
18940
  this.indexPattern(pattern);
18941
+ if (this.sqliteStore) {
18942
+ try {
18943
+ this.sqliteStore.storePattern(pattern, pattern.embedding);
18944
+ } catch (error) {
18945
+ console.warn(`[PatternStore] SQLite persist failed for ${pattern.id}:`, toErrorMessage(error));
18946
+ }
18947
+ }
18783
18948
  if (pattern.embedding) {
18784
18949
  const hnsw = await this.ensureHNSW();
18785
18950
  if (hnsw) {
@@ -18875,6 +19040,9 @@ var init_pattern_store = __esm({
18875
19040
  if (!this.initialized) {
18876
19041
  await this.initialize();
18877
19042
  }
19043
+ if (this.loadingPromise) {
19044
+ await this.loadingPromise;
19045
+ }
18878
19046
  return this.patternCache.get(id) ?? null;
18879
19047
  }
18880
19048
  /**
@@ -18884,6 +19052,9 @@ var init_pattern_store = __esm({
18884
19052
  if (!this.initialized) {
18885
19053
  await this.initialize();
18886
19054
  }
19055
+ if (this.loadingPromise) {
19056
+ await this.loadingPromise;
19057
+ }
18887
19058
  const startTime = performance.now();
18888
19059
  const limit = options.limit || 10;
18889
19060
  const results = [];
@@ -18909,13 +19080,60 @@ var init_pattern_store = __esm({
18909
19080
  }
18910
19081
  }
18911
19082
  }
19083
+ if (typeof query === "string" && query.trim() && this.sqliteStore) {
19084
+ try {
19085
+ const ftsResults = this.sqliteStore.searchFTS(query, limit * 2);
19086
+ if (ftsResults.length > 0) {
19087
+ const ftsScoreMap = new Map(ftsResults.map((r54) => [r54.id, r54.ftsScore]));
19088
+ const existingIds = new Set(results.map((r54) => r54.pattern.id));
19089
+ for (const result of results) {
19090
+ const ftsScore = ftsScoreMap.get(result.pattern.id);
19091
+ if (ftsScore !== void 0) {
19092
+ result.score = 0.75 * result.score + 0.25 * ftsScore;
19093
+ }
19094
+ }
19095
+ for (const ftsResult of ftsResults) {
19096
+ if (existingIds.has(ftsResult.id)) continue;
19097
+ const pattern = await this.get(ftsResult.id);
19098
+ if (pattern && this.matchesFilters(pattern, options)) {
19099
+ const reuseInfo = this.calculateReuseInfo(pattern, ftsResult.ftsScore);
19100
+ results.push({
19101
+ pattern,
19102
+ score: 0.5 * ftsResult.ftsScore,
19103
+ // FTS-only: exact keyword match is valuable
19104
+ matchType: "exact",
19105
+ similarity: ftsResult.ftsScore,
19106
+ canReuse: reuseInfo.canReuse,
19107
+ estimatedTokenSavings: reuseInfo.estimatedTokenSavings,
19108
+ reuseConfidence: reuseInfo.reuseConfidence
19109
+ });
19110
+ }
19111
+ }
19112
+ }
19113
+ } catch {
19114
+ }
19115
+ }
18912
19116
  if (typeof query === "string" || results.length < limit) {
18913
19117
  const textResults = await this.searchByText(
18914
19118
  typeof query === "string" ? query : "",
18915
19119
  options,
18916
19120
  limit - results.length
18917
19121
  );
18918
- results.push(...textResults);
19122
+ const existingIds = new Set(results.map((r54) => r54.pattern.id));
19123
+ for (const tr3 of textResults) {
19124
+ if (!existingIds.has(tr3.pattern.id)) {
19125
+ results.push(tr3);
19126
+ }
19127
+ }
19128
+ }
19129
+ const TEMPORAL_HALF_LIFE_MS = 30 * 24 * 60 * 60 * 1e3;
19130
+ const now = Date.now();
19131
+ for (const result of results) {
19132
+ const lastUsed = result.pattern.lastUsedAt?.getTime() ?? result.pattern.createdAt.getTime();
19133
+ const ageMs = now - lastUsed;
19134
+ const decayFactor = Math.pow(0.5, ageMs / TEMPORAL_HALF_LIFE_MS);
19135
+ const effectiveDecay = result.pattern.usageCount > 0 ? decayFactor : 0.5;
19136
+ result.score = result.score * (0.7 + 0.3 * effectiveDecay);
18919
19137
  }
18920
19138
  results.sort((a37, b68) => b68.score - a37.score);
18921
19139
  const finalResults = results.slice(0, limit);
@@ -19067,6 +19285,13 @@ var init_pattern_store = __esm({
19067
19285
  qualityScore,
19068
19286
  lastUsedAt: now
19069
19287
  };
19288
+ if (this.sqliteStore) {
19289
+ try {
19290
+ this.sqliteStore.recordUsage(id, success);
19291
+ } catch (error) {
19292
+ console.warn(`[PatternStore] SQLite recordUsage failed for ${id}:`, toErrorMessage(error));
19293
+ }
19294
+ }
19070
19295
  const promotionCheck = shouldPromotePattern(updated);
19071
19296
  const shouldPromote = promotionCheck.meetsUsageCriteria && promotionCheck.meetsQualityCriteria && promotionCheck.meetsCoherenceCriteria;
19072
19297
  if (shouldPromote && updated.tier === "short-term") {
@@ -19192,7 +19417,8 @@ var init_pattern_store = __esm({
19192
19417
  continue;
19193
19418
  }
19194
19419
  if (pattern.tier === "short-term") {
19195
- const ageMs = Date.now() - pattern.createdAt.getTime();
19420
+ const createdTime = pattern.createdAt instanceof Date ? pattern.createdAt.getTime() : new Date(pattern.createdAt).getTime();
19421
+ const ageMs = Date.now() - createdTime;
19196
19422
  const isOld = ageMs > 7 * 24 * 60 * 60 * 1e3;
19197
19423
  const isLowQuality = pattern.qualityScore < 0.2;
19198
19424
  const isUnused = pattern.usageCount === 0 && ageMs > 24 * 60 * 60 * 1e3;
@@ -19830,9 +20056,9 @@ var init_opencode_installer = __esm({
19830
20056
  // NPM package location
19831
20057
  join32(__dirname3, "../../assets/opencode")
19832
20058
  ];
19833
- for (const path36 of possiblePaths) {
19834
- if (existsSync28(path36)) {
19835
- return path36;
20059
+ for (const path37 of possiblePaths) {
20060
+ if (existsSync28(path37)) {
20061
+ return path37;
19836
20062
  }
19837
20063
  }
19838
20064
  return join32(process.cwd(), ".opencode");
@@ -22312,47 +22538,47 @@ function saveIdMap(rvfPath, strToNum, nextLabel) {
22312
22538
  };
22313
22539
  writeFileSync31(idMapPath(rvfPath), JSON.stringify(data), "utf-8");
22314
22540
  }
22315
- function createRvfStore(path36, dimensions) {
22541
+ function createRvfStore(path37, dimensions) {
22316
22542
  const native = getNative();
22317
22543
  if (!native) {
22318
22544
  throw new Error(
22319
22545
  "@ruvector/rvf-node is not available \u2014 install the package or check platform compatibility"
22320
22546
  );
22321
22547
  }
22322
- const db = native.RvfDatabase.create(path36, { dimension: dimensions });
22548
+ const db = native.RvfDatabase.create(path37, { dimension: dimensions });
22323
22549
  const dim = db.dimension();
22324
22550
  return new RvfNativeAdapterImpl(
22325
22551
  db,
22326
- path36,
22552
+ path37,
22327
22553
  dim,
22328
22554
  /* @__PURE__ */ new Map(),
22329
22555
  /* @__PURE__ */ new Map(),
22330
22556
  1
22331
22557
  );
22332
22558
  }
22333
- function openRvfStore(path36) {
22559
+ function openRvfStore(path37) {
22334
22560
  const native = getNative();
22335
22561
  if (!native) {
22336
22562
  throw new Error(
22337
22563
  "@ruvector/rvf-node is not available \u2014 install the package or check platform compatibility"
22338
22564
  );
22339
22565
  }
22340
- const db = native.RvfDatabase.open(path36);
22566
+ const db = native.RvfDatabase.open(path37);
22341
22567
  const dim = db.dimension();
22342
- const { strToNum, numToStr, nextLabel } = loadIdMap(path36);
22343
- return new RvfNativeAdapterImpl(db, path36, dim, strToNum, numToStr, nextLabel);
22568
+ const { strToNum, numToStr, nextLabel } = loadIdMap(path37);
22569
+ return new RvfNativeAdapterImpl(db, path37, dim, strToNum, numToStr, nextLabel);
22344
22570
  }
22345
- function openRvfStoreReadonly(path36) {
22571
+ function openRvfStoreReadonly(path37) {
22346
22572
  const native = getNative();
22347
22573
  if (!native) {
22348
22574
  throw new Error(
22349
22575
  "@ruvector/rvf-node is not available \u2014 install the package or check platform compatibility"
22350
22576
  );
22351
22577
  }
22352
- const db = native.RvfDatabase.openReadonly(path36);
22578
+ const db = native.RvfDatabase.openReadonly(path37);
22353
22579
  const dim = db.dimension();
22354
- const { strToNum, numToStr, nextLabel } = loadIdMap(path36);
22355
- return new RvfNativeAdapterImpl(db, path36, dim, strToNum, numToStr, nextLabel);
22580
+ const { strToNum, numToStr, nextLabel } = loadIdMap(path37);
22581
+ return new RvfNativeAdapterImpl(db, path37, dim, strToNum, numToStr, nextLabel);
22356
22582
  }
22357
22583
  function isRvfNativeAvailable() {
22358
22584
  return getNative() !== null;
@@ -23473,15 +23699,15 @@ var init_vitest_executor = __esm({
23473
23699
  }
23474
23700
  async getCoverageFromReport() {
23475
23701
  try {
23476
- const fs31 = await import("fs/promises");
23477
- const path36 = await import("path");
23702
+ const fs32 = await import("fs/promises");
23703
+ const path37 = await import("path");
23478
23704
  const coverageDir = this.config.coverageDir || "coverage";
23479
- const coverageFile = path36.join(
23705
+ const coverageFile = path37.join(
23480
23706
  this.config.cwd || process.cwd(),
23481
23707
  coverageDir,
23482
23708
  "coverage-summary.json"
23483
23709
  );
23484
- const content = await fs31.readFile(coverageFile, "utf-8");
23710
+ const content = await fs32.readFile(coverageFile, "utf-8");
23485
23711
  const coverage = safeJsonParse(content);
23486
23712
  return (coverage.total?.lines?.pct ?? 0) / 100;
23487
23713
  } catch {
@@ -23533,14 +23759,14 @@ var init_test_selector = __esm({
23533
23759
  {
23534
23760
  sourcePattern: /^src\/(.+)\.ts$/,
23535
23761
  toTestPaths: (match, _sourceFile) => {
23536
- const path36 = match[1];
23762
+ const path37 = match[1];
23537
23763
  return [
23538
- `tests/unit/${path36}.test.ts`,
23539
- `tests/unit/${path36}.spec.ts`,
23540
- `tests/${path36}.test.ts`,
23541
- `tests/${path36}.spec.ts`,
23542
- `src/${path36}.test.ts`,
23543
- `src/${path36}.spec.ts`
23764
+ `tests/unit/${path37}.test.ts`,
23765
+ `tests/unit/${path37}.spec.ts`,
23766
+ `tests/${path37}.test.ts`,
23767
+ `tests/${path37}.spec.ts`,
23768
+ `src/${path37}.test.ts`,
23769
+ `src/${path37}.spec.ts`
23544
23770
  ];
23545
23771
  }
23546
23772
  },
@@ -23548,11 +23774,11 @@ var init_test_selector = __esm({
23548
23774
  {
23549
23775
  sourcePattern: /^src\/(.+)\/index\.ts$/,
23550
23776
  toTestPaths: (match, _sourceFile) => {
23551
- const path36 = match[1];
23777
+ const path37 = match[1];
23552
23778
  return [
23553
- `tests/unit/${path36}.test.ts`,
23554
- `tests/unit/${path36}/index.test.ts`,
23555
- `tests/unit/${path36}.spec.ts`
23779
+ `tests/unit/${path37}.test.ts`,
23780
+ `tests/unit/${path37}/index.test.ts`,
23781
+ `tests/unit/${path37}.spec.ts`
23556
23782
  ];
23557
23783
  }
23558
23784
  },
@@ -23624,8 +23850,8 @@ var init_test_selector = __esm({
23624
23850
  * Get tests for a specific list of changed files
23625
23851
  */
23626
23852
  async selectTestsForFiles(files) {
23627
- const changedFiles = files.map((path36) => ({
23628
- path: path36,
23853
+ const changedFiles = files.map((path37) => ({
23854
+ path: path37,
23629
23855
  changeType: "modified"
23630
23856
  }));
23631
23857
  const { selectedTests, mappings, runAllTests, runAllReason } = await this.mapChangesToTests(changedFiles);
@@ -23651,7 +23877,7 @@ var init_test_selector = __esm({
23651
23877
  const changedFiles = [];
23652
23878
  for (const line of lines) {
23653
23879
  const [status, ...pathParts] = line.split(" ");
23654
- const path36 = pathParts.join(" ");
23880
+ const path37 = pathParts.join(" ");
23655
23881
  let changeType;
23656
23882
  let previousPath;
23657
23883
  switch (status[0]) {
@@ -23666,13 +23892,13 @@ var init_test_selector = __esm({
23666
23892
  break;
23667
23893
  case "R":
23668
23894
  changeType = "renamed";
23669
- previousPath = path36;
23895
+ previousPath = path37;
23670
23896
  break;
23671
23897
  default:
23672
23898
  changeType = "modified";
23673
23899
  }
23674
23900
  changedFiles.push({
23675
- path: changeType === "renamed" ? pathParts[1] || path36 : path36,
23901
+ path: changeType === "renamed" ? pathParts[1] || path37 : path37,
23676
23902
  changeType,
23677
23903
  previousPath
23678
23904
  });
@@ -23749,8 +23975,8 @@ var init_test_selector = __esm({
23749
23975
  /**
23750
23976
  * Check if a file is a config file that should trigger full test run
23751
23977
  */
23752
- isConfigFile(path36) {
23753
- return /^(vitest\.config|jest\.config|tsconfig|package\.json)/.test(path36);
23978
+ isConfigFile(path37) {
23979
+ return /^(vitest\.config|jest\.config|tsconfig|package\.json)/.test(path37);
23754
23980
  }
23755
23981
  async findTestsHeuristically(sourcePath) {
23756
23982
  const baseName = basename7(sourcePath, ".ts").replace(/\.(tsx?|jsx?)$/, "");
@@ -23765,12 +23991,12 @@ var init_test_selector = __esm({
23765
23991
  return this.filterExistingFiles(candidates);
23766
23992
  }
23767
23993
  async filterExistingFiles(files) {
23768
- const fs31 = await import("fs/promises");
23994
+ const fs32 = await import("fs/promises");
23769
23995
  const existing = [];
23770
23996
  for (const file of files) {
23771
23997
  try {
23772
23998
  const fullPath = resolve11(this.cwd, file);
23773
- await fs31.access(fullPath);
23999
+ await fs32.access(fullPath);
23774
24000
  existing.push(file);
23775
24001
  } catch (error) {
23776
24002
  console.debug("[TestSelector] File access check failed:", error instanceof Error ? error.message : error);
@@ -23810,8 +24036,8 @@ function createFlakyTracker(config) {
23810
24036
  async function loadFlakyTracker(historyPath, config) {
23811
24037
  const tracker = createFlakyTracker({ ...config, historyPath });
23812
24038
  try {
23813
- const fs31 = await import("fs/promises");
23814
- const content = await fs31.readFile(historyPath, "utf-8");
24039
+ const fs32 = await import("fs/promises");
24040
+ const content = await fs32.readFile(historyPath, "utf-8");
23815
24041
  const records = safeJsonParse(content);
23816
24042
  tracker.importHistory(records);
23817
24043
  } catch (error) {
@@ -23820,9 +24046,9 @@ async function loadFlakyTracker(historyPath, config) {
23820
24046
  return tracker;
23821
24047
  }
23822
24048
  async function saveFlakyTracker(tracker, historyPath) {
23823
- const fs31 = await import("fs/promises");
24049
+ const fs32 = await import("fs/promises");
23824
24050
  const history = tracker.exportHistory();
23825
- await fs31.writeFile(historyPath, JSON.stringify(history, null, 2));
24051
+ await fs32.writeFile(historyPath, JSON.stringify(history, null, 2));
23826
24052
  }
23827
24053
  var DEFAULT_CONFIG62, FlakyTestTracker;
23828
24054
  var init_flaky_tracker = __esm({
@@ -24131,16 +24357,16 @@ var init_github_actions = __esm({
24131
24357
  */
24132
24358
  async writeOutput(results) {
24133
24359
  const output = this.generateOutput(results);
24134
- const fs31 = await import("fs/promises");
24360
+ const fs32 = await import("fs/promises");
24135
24361
  for (const annotation of output.annotations) {
24136
24362
  this.writeAnnotation(annotation);
24137
24363
  }
24138
24364
  if (output.summary && process.env.GITHUB_STEP_SUMMARY) {
24139
- await fs31.appendFile(process.env.GITHUB_STEP_SUMMARY, output.summary);
24365
+ await fs32.appendFile(process.env.GITHUB_STEP_SUMMARY, output.summary);
24140
24366
  }
24141
24367
  if (process.env.GITHUB_OUTPUT) {
24142
24368
  const outputLines = Object.entries(output.outputs).map(([key, value]) => `${key}=${value}`).join("\n");
24143
- await fs31.appendFile(process.env.GITHUB_OUTPUT, outputLines + "\n");
24369
+ await fs32.appendFile(process.env.GITHUB_OUTPUT, outputLines + "\n");
24144
24370
  }
24145
24371
  }
24146
24372
  // --------------------------------------------------------------------------
@@ -24372,6 +24598,7 @@ var init_pipeline = __esm({
24372
24598
  const startTime = Date.now();
24373
24599
  let selectedTests = [];
24374
24600
  let ranAllTests = this.config.runAllTests ?? false;
24601
+ const selectionStart = performance.now();
24375
24602
  if (!ranAllTests) {
24376
24603
  const selectionResult = await this.selector.selectAffectedTests();
24377
24604
  if (selectionResult.runAllTests) {
@@ -24385,19 +24612,26 @@ var init_pipeline = __esm({
24385
24612
  console.log(`[TestSchedulingPipeline] Selected ${selectedTests.length} affected tests`);
24386
24613
  }
24387
24614
  }
24615
+ const selectionMs = performance.now() - selectionStart;
24616
+ const executionStart = performance.now();
24388
24617
  let phaseResults;
24389
24618
  if (ranAllTests) {
24390
24619
  phaseResults = await this.scheduler.run();
24391
24620
  } else {
24392
24621
  phaseResults = await this.runWithSelectedTests(selectedTests);
24393
24622
  }
24623
+ const executionMs = performance.now() - executionStart;
24624
+ const analysisStart = performance.now();
24394
24625
  const flakyAnalysis = this.flakyTracker.analyze();
24395
24626
  if (this.config.flakyHistoryPath) {
24396
24627
  await saveFlakyTracker(this.flakyTracker, this.config.flakyHistoryPath);
24397
24628
  }
24629
+ const analysisMs = performance.now() - analysisStart;
24630
+ const reportingStart = performance.now();
24398
24631
  if (this.ciEnvironment.isCI) {
24399
24632
  await this.reporter.writeOutput(phaseResults);
24400
24633
  }
24634
+ const reportingMs = performance.now() - reportingStart;
24401
24635
  const totalDurationMs = Date.now() - startTime;
24402
24636
  return {
24403
24637
  phaseResults,
@@ -24405,7 +24639,8 @@ var init_pipeline = __esm({
24405
24639
  ranAllTests,
24406
24640
  flakyAnalysis,
24407
24641
  ciEnvironment: this.ciEnvironment,
24408
- totalDurationMs
24642
+ totalDurationMs,
24643
+ stepLatencies: { selectionMs, executionMs, analysisMs, reportingMs }
24409
24644
  };
24410
24645
  }
24411
24646
  /**
@@ -26188,6 +26423,24 @@ var init_visual_security = __esm({
26188
26423
  });
26189
26424
 
26190
26425
  // src/learning/sqlite-persistence.ts
26426
+ function hashEmbedding(text, dimension = 384) {
26427
+ const embedding = new Array(dimension).fill(0);
26428
+ const normalized = text.toLowerCase().trim();
26429
+ for (let pass = 0; pass < 3; pass++) {
26430
+ for (let i58 = 0; i58 < normalized.length; i58++) {
26431
+ const charCode = normalized.charCodeAt(i58);
26432
+ const idx = charCode * (i58 + 1) * (pass + 1) % dimension;
26433
+ embedding[idx] += Math.sin(charCode * (pass + 1)) / (i58 + 1);
26434
+ }
26435
+ }
26436
+ const magnitude2 = Math.sqrt(embedding.reduce((sum, val) => sum + val * val, 0));
26437
+ if (magnitude2 > 0) {
26438
+ for (let i58 = 0; i58 < dimension; i58++) {
26439
+ embedding[i58] /= magnitude2;
26440
+ }
26441
+ }
26442
+ return embedding;
26443
+ }
26191
26444
  function createSQLitePatternStore(config = {}) {
26192
26445
  return new SQLitePatternStore(config);
26193
26446
  }
@@ -26200,6 +26453,7 @@ var init_sqlite_persistence = __esm({
26200
26453
  init_safe_json();
26201
26454
  init_error_utils();
26202
26455
  init_unified_memory();
26456
+ init_real_embeddings();
26203
26457
  DEFAULT_SQLITE_CONFIG = {
26204
26458
  // LEGACY: Ignored when useUnified=true (the default). All data goes to memory.db
26205
26459
  dbPath: ".agentic-qe/memory.db",
@@ -26233,11 +26487,11 @@ var init_sqlite_persistence = __esm({
26233
26487
  this.db = this.unifiedMemory.getDatabase();
26234
26488
  console.log(`[SQLitePatternStore] Using unified storage: ${this.unifiedMemory.getDbPath()}`);
26235
26489
  } else {
26236
- const path36 = await import("path");
26237
- const fs31 = await import("fs");
26238
- const dir = path36.dirname(this.config.dbPath);
26239
- if (!fs31.existsSync(dir)) {
26240
- fs31.mkdirSync(dir, { recursive: true });
26490
+ const path37 = await import("path");
26491
+ const fs32 = await import("fs");
26492
+ const dir = path37.dirname(this.config.dbPath);
26493
+ if (!fs32.existsSync(dir)) {
26494
+ fs32.mkdirSync(dir, { recursive: true });
26241
26495
  }
26242
26496
  this.db = openDatabase(this.config.dbPath);
26243
26497
  this.db.pragma(`mmap_size = ${this.config.mmapSize}`);
@@ -26332,6 +26586,31 @@ var init_sqlite_persistence = __esm({
26332
26586
  CREATE UNIQUE INDEX IF NOT EXISTS idx_patterns_unique_name_domain_type
26333
26587
  ON qe_patterns(name, qe_domain, pattern_type);
26334
26588
 
26589
+ -- FTS5 full-text search index for hybrid vector/text search
26590
+ CREATE VIRTUAL TABLE IF NOT EXISTS qe_patterns_fts USING fts5(
26591
+ name, description, pattern_type, qe_domain,
26592
+ content='qe_patterns',
26593
+ content_rowid='rowid'
26594
+ );
26595
+
26596
+ -- FTS5 triggers to keep index in sync
26597
+ CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_insert AFTER INSERT ON qe_patterns BEGIN
26598
+ INSERT INTO qe_patterns_fts(rowid, name, description, pattern_type, qe_domain)
26599
+ VALUES (new.rowid, new.name, new.description, new.pattern_type, new.qe_domain);
26600
+ END;
26601
+
26602
+ CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_delete AFTER DELETE ON qe_patterns BEGIN
26603
+ INSERT INTO qe_patterns_fts(qe_patterns_fts, rowid, name, description, pattern_type, qe_domain)
26604
+ VALUES ('delete', old.rowid, old.name, old.description, old.pattern_type, old.qe_domain);
26605
+ END;
26606
+
26607
+ CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_update AFTER UPDATE ON qe_patterns BEGIN
26608
+ INSERT INTO qe_patterns_fts(qe_patterns_fts, rowid, name, description, pattern_type, qe_domain)
26609
+ VALUES ('delete', old.rowid, old.name, old.description, old.pattern_type, old.qe_domain);
26610
+ INSERT INTO qe_patterns_fts(rowid, name, description, pattern_type, qe_domain)
26611
+ VALUES (new.rowid, new.name, new.description, new.pattern_type, new.qe_domain);
26612
+ END;
26613
+
26335
26614
  -- Indexes for performance
26336
26615
  CREATE INDEX IF NOT EXISTS idx_patterns_domain ON qe_patterns(qe_domain);
26337
26616
  CREATE INDEX IF NOT EXISTS idx_patterns_type ON qe_patterns(pattern_type);
@@ -26394,10 +26673,22 @@ var init_sqlite_persistence = __esm({
26394
26673
  prepareStatements() {
26395
26674
  if (!this.db) throw new Error("Database not initialized");
26396
26675
  this.prepared.set("insertPattern", this.db.prepare(`
26397
- INSERT OR REPLACE INTO qe_patterns (
26676
+ INSERT INTO qe_patterns (
26398
26677
  id, pattern_type, qe_domain, domain, name, description,
26399
26678
  confidence, tier, template_json, context_json
26400
26679
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
26680
+ ON CONFLICT(id) DO UPDATE SET
26681
+ confidence = excluded.confidence,
26682
+ tier = excluded.tier,
26683
+ template_json = excluded.template_json,
26684
+ context_json = excluded.context_json,
26685
+ updated_at = datetime('now')
26686
+ ON CONFLICT(name, qe_domain, pattern_type) DO UPDATE SET
26687
+ confidence = excluded.confidence,
26688
+ tier = excluded.tier,
26689
+ template_json = excluded.template_json,
26690
+ context_json = excluded.context_json,
26691
+ updated_at = datetime('now')
26401
26692
  `));
26402
26693
  this.prepared.set("insertEmbedding", this.db.prepare(`
26403
26694
  INSERT OR REPLACE INTO qe_pattern_embeddings (pattern_id, embedding, dimension, model)
@@ -26506,6 +26797,69 @@ var init_sqlite_persistence = __esm({
26506
26797
  }
26507
26798
  return rows.map((row) => this.rowToPattern(row));
26508
26799
  }
26800
+ /**
26801
+ * FTS5 full-text search for patterns.
26802
+ * Returns pattern IDs with BM25 relevance scores.
26803
+ */
26804
+ searchFTS(query, limit = 20) {
26805
+ if (!this.db) throw new Error("Database not initialized");
26806
+ if (!query.trim()) return [];
26807
+ const sanitized = '"' + query.replace(/"/g, '""') + '"';
26808
+ const start = performance.now();
26809
+ try {
26810
+ const rows = this.db.prepare(`
26811
+ SELECT p.id, rank AS fts_score
26812
+ FROM qe_patterns_fts fts
26813
+ JOIN qe_patterns p ON p.rowid = fts.rowid
26814
+ WHERE qe_patterns_fts MATCH ?
26815
+ ORDER BY rank
26816
+ LIMIT ?
26817
+ `).all(sanitized, limit);
26818
+ const elapsed = performance.now() - start;
26819
+ if (elapsed > 50) {
26820
+ console.warn(`[FTS5] searchFTS took ${elapsed.toFixed(1)}ms (results=${rows.length})`);
26821
+ }
26822
+ this._lastFtsLatencyMs = elapsed;
26823
+ const maxAbsScore = Math.max(...rows.map((r54) => Math.abs(r54.fts_score)), 1);
26824
+ return rows.map((r54) => ({
26825
+ id: r54.id,
26826
+ ftsScore: Math.abs(r54.fts_score) / maxAbsScore
26827
+ }));
26828
+ } catch {
26829
+ return [];
26830
+ }
26831
+ }
26832
+ /** Last FTS5 search latency in ms, for instrumentation */
26833
+ _lastFtsLatencyMs = 0;
26834
+ get lastFtsLatencyMs() {
26835
+ return this._lastFtsLatencyMs;
26836
+ }
26837
+ /**
26838
+ * Ghost pattern check: find patterns in SQLite that have no embeddings.
26839
+ * Used by aqe_health to detect data integrity issues.
26840
+ */
26841
+ getGhostPatternCount() {
26842
+ if (!this.db) throw new Error("Database not initialized");
26843
+ const total = this.db.prepare(
26844
+ `SELECT COUNT(*) as c FROM qe_patterns WHERE id NOT LIKE 'bench-%'`
26845
+ ).get().c;
26846
+ const ghostCount = this.db.prepare(`
26847
+ SELECT COUNT(*) as c FROM qe_patterns p
26848
+ WHERE p.id NOT LIKE 'bench-%'
26849
+ AND p.id NOT IN (SELECT pattern_id FROM qe_pattern_embeddings)
26850
+ `).get().c;
26851
+ const sampleGhosts = this.db.prepare(`
26852
+ SELECT p.id FROM qe_patterns p
26853
+ WHERE p.id NOT LIKE 'bench-%'
26854
+ AND p.id NOT IN (SELECT pattern_id FROM qe_pattern_embeddings)
26855
+ LIMIT 10
26856
+ `).all();
26857
+ return {
26858
+ total,
26859
+ withoutEmbeddings: ghostCount,
26860
+ sampleGhostIds: sampleGhosts.map((g67) => g67.id)
26861
+ };
26862
+ }
26509
26863
  /**
26510
26864
  * Get all embeddings for HNSW indexing
26511
26865
  */
@@ -26838,6 +27192,95 @@ var init_sqlite_persistence = __esm({
26838
27192
  };
26839
27193
  }
26840
27194
  }
27195
+ /**
27196
+ * Backfill embeddings for patterns that don't have them.
27197
+ * Uses real all-MiniLM-L6-v2 transformer embeddings via @xenova/transformers.
27198
+ * Falls back to hash-based embeddings if ONNX is unavailable.
27199
+ * Skips bench/test patterns (id LIKE 'bench-%').
27200
+ *
27201
+ * @param batchSize - Patterns per inference batch (default: 32, matches model batch size)
27202
+ * @returns Stats about the backfill operation
27203
+ */
27204
+ async backfillEmbeddings(batchSize = 32) {
27205
+ if (!this.db) throw new Error("Database not initialized");
27206
+ const dimension = getEmbeddingDimension();
27207
+ const patternsWithout = this.db.prepare(`
27208
+ SELECT p.id, p.name, p.description, p.pattern_type, p.qe_domain
27209
+ FROM qe_patterns p
27210
+ WHERE p.id NOT IN (SELECT pattern_id FROM qe_pattern_embeddings)
27211
+ AND p.id NOT LIKE 'bench-%'
27212
+ ORDER BY p.quality_score DESC
27213
+ `).all();
27214
+ const alreadyHad = this.db.prepare(`
27215
+ SELECT COUNT(*) as c FROM qe_pattern_embeddings
27216
+ `).get();
27217
+ if (patternsWithout.length === 0) {
27218
+ console.log(`[SQLitePatternStore] Backfill: all patterns already have embeddings (${alreadyHad.c} total)`);
27219
+ return { processed: 0, skipped: 0, errors: 0, alreadyHad: alreadyHad.c, method: "transformer" };
27220
+ }
27221
+ console.log(`[SQLitePatternStore] Backfill: ${patternsWithout.length} patterns need embeddings (${alreadyHad.c} already have)`);
27222
+ const insertEmbedding = this.prepared.get("insertEmbedding");
27223
+ if (!insertEmbedding) {
27224
+ throw new Error("Prepared statements not ready");
27225
+ }
27226
+ let processed = 0;
27227
+ let skipped = 0;
27228
+ let errors = 0;
27229
+ let method = "transformer";
27230
+ for (let i58 = 0; i58 < patternsWithout.length; i58 += batchSize) {
27231
+ const batch = patternsWithout.slice(i58, i58 + batchSize);
27232
+ const textsWithIds = [];
27233
+ for (const pattern of batch) {
27234
+ const text = [
27235
+ pattern.name,
27236
+ pattern.description,
27237
+ pattern.pattern_type,
27238
+ pattern.qe_domain
27239
+ ].filter(Boolean).join(" ");
27240
+ if (!text.trim()) {
27241
+ skipped++;
27242
+ continue;
27243
+ }
27244
+ textsWithIds.push({ id: pattern.id, text });
27245
+ }
27246
+ if (textsWithIds.length === 0) continue;
27247
+ let embeddings;
27248
+ try {
27249
+ embeddings = await computeBatchEmbeddings(textsWithIds.map((t50) => t50.text));
27250
+ } catch (e20) {
27251
+ console.warn(`[SQLitePatternStore] Transformer unavailable, falling back to hash embeddings: ${toErrorMessage(e20)}`);
27252
+ method = "hash-fallback";
27253
+ embeddings = textsWithIds.map((t50) => hashEmbedding(t50.text, dimension));
27254
+ }
27255
+ const embeddingTag = method === "transformer" ? "transformer-backfill" : "hash-backfill";
27256
+ const insertBatch = this.db.transaction(() => {
27257
+ for (let j52 = 0; j52 < textsWithIds.length; j52++) {
27258
+ try {
27259
+ const embedding = embeddings[j52];
27260
+ if (!embedding || embedding.length !== dimension) {
27261
+ errors++;
27262
+ continue;
27263
+ }
27264
+ const buffer = Buffer.from(new Float32Array(embedding).buffer);
27265
+ insertEmbedding.run(textsWithIds[j52].id, buffer, dimension, embeddingTag);
27266
+ processed++;
27267
+ } catch (e20) {
27268
+ errors++;
27269
+ if (errors <= 3) {
27270
+ console.warn(`[SQLitePatternStore] Backfill error for ${textsWithIds[j52].id}:`, toErrorMessage(e20));
27271
+ }
27272
+ }
27273
+ }
27274
+ });
27275
+ insertBatch();
27276
+ const progress = Math.min(i58 + batchSize, patternsWithout.length);
27277
+ if (progress % 100 === 0 || progress >= patternsWithout.length) {
27278
+ console.log(`[SQLitePatternStore] Backfill progress: ${progress}/${patternsWithout.length}`);
27279
+ }
27280
+ }
27281
+ console.log(`[SQLitePatternStore] Backfill complete (${method}): ${processed} processed, ${skipped} skipped, ${errors} errors`);
27282
+ return { processed, skipped, errors, alreadyHad: alreadyHad.c, method };
27283
+ }
26841
27284
  /**
26842
27285
  * Close the database
26843
27286
  */
@@ -29398,7 +29841,7 @@ var init_shared_rvf_dual_writer = __esm({
29398
29841
 
29399
29842
  // src/workflows/browser/workflow-loader.ts
29400
29843
  import { readFile as readFile9, readdir as readdir4 } from "fs/promises";
29401
- import { join as join65, basename as basename10 } from "path";
29844
+ import { join as join66, basename as basename10 } from "path";
29402
29845
  import { parse as parseYaml2 } from "yaml";
29403
29846
  function interpolateVariables(template, variables) {
29404
29847
  return template.replace(/\{\{([^}]+)\}\}/g, (match, key) => {
@@ -29432,7 +29875,7 @@ var init_workflow_loader = __esm({
29432
29875
  templatesDir;
29433
29876
  cache = /* @__PURE__ */ new Map();
29434
29877
  constructor(templatesDir) {
29435
- this.templatesDir = templatesDir || join65(__dirname, "templates");
29878
+ this.templatesDir = templatesDir || join66(__dirname, "templates");
29436
29879
  }
29437
29880
  /**
29438
29881
  * Load a workflow template by name
@@ -29442,7 +29885,7 @@ var init_workflow_loader = __esm({
29442
29885
  return this.cache.get(templateName);
29443
29886
  }
29444
29887
  try {
29445
- const templatePath = join65(this.templatesDir, `${templateName}.yaml`);
29888
+ const templatePath = join66(this.templatesDir, `${templateName}.yaml`);
29446
29889
  const content = await readFile9(templatePath, "utf-8");
29447
29890
  const workflow = parseYaml2(content);
29448
29891
  const validation = await this.validate(workflow);
@@ -29583,7 +30026,7 @@ ${validation.errors.join("\n")}`
29583
30026
  */
29584
30027
  async getMetadata(templateName) {
29585
30028
  try {
29586
- const templatePath = join65(this.templatesDir, `${templateName}.yaml`);
30029
+ const templatePath = join66(this.templatesDir, `${templateName}.yaml`);
29587
30030
  const content = await readFile9(templatePath, "utf-8");
29588
30031
  const workflow = parseYaml2(content);
29589
30032
  return {
@@ -29828,7 +30271,7 @@ var init_browser_workflow = __esm({
29828
30271
 
29829
30272
  // src/cli/index.ts
29830
30273
  init_error_utils();
29831
- import { Command as Command20 } from "commander";
30274
+ import { Command as Command21 } from "commander";
29832
30275
  import chalk33 from "chalk";
29833
30276
 
29834
30277
  // src/kernel/kernel.ts
@@ -44014,6 +44457,103 @@ var TestQualityGate = class {
44014
44457
  }
44015
44458
  };
44016
44459
 
44460
+ // src/learning/opd-remediation.ts
44461
+ function generateRemediationHints(pattern, executionHistory, config) {
44462
+ const hints = [];
44463
+ const maxHints = config?.maxHintsPerPattern ?? 3;
44464
+ const totalCount = executionHistory.length;
44465
+ if (totalCount === 0) return hints;
44466
+ const failCount = executionHistory.filter((e20) => !e20.success).length;
44467
+ const failRate = failCount / totalCount;
44468
+ if (failRate > 0.2 && failRate < 0.8 && totalCount >= 3) {
44469
+ hints.push({
44470
+ patternId: pattern.id,
44471
+ observation: `Pattern "${pattern.name}" fails ${(failRate * 100).toFixed(0)}% of the time (${failCount}/${totalCount} executions)`,
44472
+ diagnosis: "Intermittent failures suggest timing dependencies, external service flakiness, or non-deterministic behavior",
44473
+ suggestion: "Add retry logic, mock external dependencies, or add explicit waits for async operations",
44474
+ confidence: Math.min(0.9, 0.5 + totalCount * 0.05),
44475
+ category: "flaky"
44476
+ });
44477
+ }
44478
+ if (failRate >= 0.8 && totalCount >= 2) {
44479
+ hints.push({
44480
+ patternId: pattern.id,
44481
+ observation: `Pattern "${pattern.name}" fails ${(failRate * 100).toFixed(0)}% of executions \u2014 effectively broken`,
44482
+ diagnosis: "Consistent failures indicate the pattern logic is incorrect or the target code changed",
44483
+ suggestion: "Review the pattern against current code. Consider quarantining and creating a replacement pattern.",
44484
+ confidence: 0.85,
44485
+ category: "false-positive"
44486
+ });
44487
+ }
44488
+ if (totalCount >= 5) {
44489
+ const recentFails = executionHistory.slice(-3).filter((e20) => !e20.success).length;
44490
+ const earlySuccesses = executionHistory.slice(0, Math.max(1, totalCount - 3)).filter((e20) => e20.success).length;
44491
+ if (recentFails >= 2 && earlySuccesses >= 2) {
44492
+ hints.push({
44493
+ patternId: pattern.id,
44494
+ observation: `Pattern "${pattern.name}" worked previously but now fails consistently`,
44495
+ diagnosis: "Recent code changes likely broke compatibility with this pattern",
44496
+ suggestion: "Update pattern to match current code structure. Check git log for recent changes to affected files.",
44497
+ confidence: 0.8,
44498
+ category: "outdated"
44499
+ });
44500
+ }
44501
+ }
44502
+ if (pattern.description && pattern.description.length < 20 && failRate > 0.3) {
44503
+ hints.push({
44504
+ patternId: pattern.id,
44505
+ observation: `Pattern "${pattern.name}" has a vague description and high failure rate`,
44506
+ diagnosis: "Pattern may be too broadly scoped \u2014 matching contexts where it does not apply",
44507
+ suggestion: "Narrow the pattern scope by adding specific tags, domain constraints, or more detailed matching criteria",
44508
+ confidence: 0.6,
44509
+ category: "wrong-scope"
44510
+ });
44511
+ }
44512
+ const feedbackMessages = executionHistory.filter((e20) => !e20.success && e20.feedback).map((e20) => e20.feedback).slice(-3);
44513
+ if (feedbackMessages.length > 0) {
44514
+ const commonWords = findCommonKeywords(feedbackMessages);
44515
+ if (commonWords.length > 0) {
44516
+ hints.push({
44517
+ patternId: pattern.id,
44518
+ observation: `Failure feedback contains recurring themes: ${commonWords.join(", ")}`,
44519
+ diagnosis: `Common failure keywords suggest a systematic issue: ${commonWords.slice(0, 3).join(", ")}`,
44520
+ suggestion: `Address the recurring "${commonWords[0]}" issue in the pattern logic or preconditions`,
44521
+ confidence: 0.65,
44522
+ category: "missing-context"
44523
+ });
44524
+ }
44525
+ }
44526
+ return hints.slice(0, maxHints);
44527
+ }
44528
+ var STOP_WORDS = /* @__PURE__ */ new Set([
44529
+ "the",
44530
+ "a",
44531
+ "an",
44532
+ "is",
44533
+ "was",
44534
+ "in",
44535
+ "to",
44536
+ "for",
44537
+ "of",
44538
+ "and",
44539
+ "or",
44540
+ "not",
44541
+ "with",
44542
+ "test",
44543
+ "error"
44544
+ ]);
44545
+ function findCommonKeywords(feedbacks) {
44546
+ const wordCounts = /* @__PURE__ */ new Map();
44547
+ for (const feedback of feedbacks) {
44548
+ const words = feedback.toLowerCase().split(/\W+/).filter((w54) => w54.length > 2 && !STOP_WORDS.has(w54));
44549
+ const uniqueWords = new Set(words);
44550
+ for (const word of uniqueWords) {
44551
+ wordCounts.set(word, (wordCounts.get(word) ?? 0) + 1);
44552
+ }
44553
+ }
44554
+ return Array.from(wordCounts.entries()).filter(([, count]) => count >= 2).sort((a37, b68) => b68[1] - a37[1]).map(([word]) => word).slice(0, 5);
44555
+ }
44556
+
44017
44557
  // src/domains/test-generation/pattern-injection/edge-case-injector.ts
44018
44558
  var DEFAULT_INJECTION_CONFIG = {
44019
44559
  topN: 3,
@@ -44179,6 +44719,7 @@ var EdgeCaseInjector = class {
44179
44719
  }
44180
44720
  /**
44181
44721
  * Format selected patterns into a prompt context string.
44722
+ * Appends OPD remediation hints for patterns with low success rates.
44182
44723
  */
44183
44724
  formatPromptContext(patterns) {
44184
44725
  const lines = ["## Historical Edge Cases (from patterns that caught real bugs):"];
@@ -44188,8 +44729,36 @@ var EdgeCaseInjector = class {
44188
44729
  const desc = p74.description || p74.name;
44189
44730
  lines.push(`${i58 + 1}. [${tag}] ${desc}`);
44190
44731
  }
44732
+ const weakPatterns = patterns.filter((p74) => p74.successRate < 0.5);
44733
+ const allHints = [];
44734
+ for (const wp of weakPatterns) {
44735
+ const hints = generateRemediationHints(
44736
+ { id: wp.key, name: wp.name, description: wp.description, successRate: wp.successRate, usageCount: wp.usageCount, confidence: wp.confidence, tags: wp.tags },
44737
+ this.buildSyntheticHistory(wp)
44738
+ );
44739
+ allHints.push(...hints);
44740
+ }
44741
+ if (allHints.length > 0) {
44742
+ lines.push("");
44743
+ lines.push("## Remediation Notes (patterns with known issues):");
44744
+ for (const hint of allHints.slice(0, 3)) {
44745
+ lines.push(`- [${hint.category}] ${hint.suggestion}`);
44746
+ }
44747
+ }
44191
44748
  return lines.join("\n");
44192
44749
  }
44750
+ /**
44751
+ * Build a synthetic execution history from pattern metadata.
44752
+ * Used to feed into OPD remediation when full history is unavailable.
44753
+ */
44754
+ buildSyntheticHistory(pattern) {
44755
+ const total = Math.max(pattern.usageCount, 1);
44756
+ const successes = Math.round(total * pattern.successRate);
44757
+ const history = [];
44758
+ for (let i58 = 0; i58 < successes; i58++) history.push({ success: true });
44759
+ for (let i58 = 0; i58 < total - successes; i58++) history.push({ success: false });
44760
+ return history;
44761
+ }
44193
44762
  /**
44194
44763
  * Infer a short tag from pattern name when no tags are available.
44195
44764
  */
@@ -44331,7 +44900,7 @@ function resolveRequest(request) {
44331
44900
  import { execSync } from "child_process";
44332
44901
  import * as fs3 from "fs";
44333
44902
  import * as path3 from "path";
44334
- import * as os from "os";
44903
+ import * as os2 from "os";
44335
44904
  var COMPILE_COMMANDS = {
44336
44905
  typescript: { check: "npx tsc --noEmit --strict", fileExt: ".ts" },
44337
44906
  java: { check: "javac -d /dev/null", fileExt: ".java" },
@@ -44352,7 +44921,7 @@ var CompilationValidator = class {
44352
44921
  suggestions: [`No compilation check available for ${language} -- syntax validation skipped`]
44353
44922
  };
44354
44923
  }
44355
- const tmpDir = fs3.mkdtempSync(path3.join(os.tmpdir(), "aqe-compile-"));
44924
+ const tmpDir = fs3.mkdtempSync(path3.join(os2.tmpdir(), "aqe-compile-"));
44356
44925
  const tmpFile = path3.join(tmpDir, `test_validation${config.fileExt}`);
44357
44926
  try {
44358
44927
  fs3.writeFileSync(tmpFile, code, "utf-8");
@@ -46858,7 +47427,9 @@ var QE_HOOK_EVENTS = {
46858
47427
  // Pattern learning
46859
47428
  PatternLearned: "qe:pattern-learned",
46860
47429
  PatternApplied: "qe:pattern-applied",
46861
- PatternPromoted: "qe:pattern-promoted"
47430
+ PatternPromoted: "qe:pattern-promoted",
47431
+ // Session lifecycle
47432
+ PreCompaction: "qe:pre-compaction"
46862
47433
  };
46863
47434
  function createQEHookHandlers(reasoningBank) {
46864
47435
  return {
@@ -47242,6 +47813,32 @@ Factors: ${riskFactors.join("\n- ")}`,
47242
47813
  success: true,
47243
47814
  data: { patternId, newTier }
47244
47815
  };
47816
+ },
47817
+ // ========================================================================
47818
+ // Session Lifecycle Hooks
47819
+ // ========================================================================
47820
+ [QE_HOOK_EVENTS.PreCompaction]: async (ctx) => {
47821
+ const stats = { experiencesFlushed: 0, patternsPromoted: 0 };
47822
+ if (ctx.data?.experienceCaptureService) {
47823
+ const service = ctx.data.experienceCaptureService;
47824
+ const pendingCount = service.getPendingCount?.() ?? 0;
47825
+ if (pendingCount > 0) {
47826
+ const flushed = await service.flushPending?.();
47827
+ stats.experiencesFlushed = flushed ?? pendingCount;
47828
+ }
47829
+ }
47830
+ if (ctx.data?.patternLifecycleManager) {
47831
+ const manager = ctx.data.patternLifecycleManager;
47832
+ const promotionResult = manager.runPromotionSweep?.();
47833
+ if (promotionResult) {
47834
+ stats.patternsPromoted = promotionResult.promoted ?? 0;
47835
+ }
47836
+ }
47837
+ console.log("[QEHooks] Pre-compaction flush:", stats);
47838
+ return {
47839
+ success: true,
47840
+ data: stats
47841
+ };
47245
47842
  }
47246
47843
  };
47247
47844
  }
@@ -50624,12 +51221,12 @@ var DeterministicGatewayIntegration = class {
50624
51221
  /**
50625
51222
  * Validate a single value against its schema
50626
51223
  */
50627
- validateValue(value, schema, path36) {
51224
+ validateValue(value, schema, path37) {
50628
51225
  const errors = [];
50629
51226
  if (schema.required && (value === void 0 || value === null)) {
50630
51227
  errors.push({
50631
- path: path36,
50632
- message: `${path36} is required`,
51228
+ path: path37,
51229
+ message: `${path37} is required`,
50633
51230
  expected: schema.type,
50634
51231
  received: "undefined"
50635
51232
  });
@@ -50641,8 +51238,8 @@ var DeterministicGatewayIntegration = class {
50641
51238
  const actualType = Array.isArray(value) ? "array" : typeof value;
50642
51239
  if (actualType !== schema.type) {
50643
51240
  errors.push({
50644
- path: path36,
50645
- message: `${path36} must be of type ${schema.type}`,
51241
+ path: path37,
51242
+ message: `${path37} must be of type ${schema.type}`,
50646
51243
  expected: schema.type,
50647
51244
  received: actualType
50648
51245
  });
@@ -50651,16 +51248,16 @@ var DeterministicGatewayIntegration = class {
50651
51248
  if (schema.type === "string" && typeof value === "string") {
50652
51249
  if (schema.minLength !== void 0 && value.length < schema.minLength) {
50653
51250
  errors.push({
50654
- path: path36,
50655
- message: `${path36} must be at least ${schema.minLength} characters`,
51251
+ path: path37,
51252
+ message: `${path37} must be at least ${schema.minLength} characters`,
50656
51253
  expected: `minLength: ${schema.minLength}`,
50657
51254
  received: `length: ${value.length}`
50658
51255
  });
50659
51256
  }
50660
51257
  if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
50661
51258
  errors.push({
50662
- path: path36,
50663
- message: `${path36} must be at most ${schema.maxLength} characters`,
51259
+ path: path37,
51260
+ message: `${path37} must be at most ${schema.maxLength} characters`,
50664
51261
  expected: `maxLength: ${schema.maxLength}`,
50665
51262
  received: `length: ${value.length}`
50666
51263
  });
@@ -50668,8 +51265,8 @@ var DeterministicGatewayIntegration = class {
50668
51265
  const patternRegex = schema.pattern ? createSafeRegex(schema.pattern) : null;
50669
51266
  if (patternRegex && !patternRegex.test(value)) {
50670
51267
  errors.push({
50671
- path: path36,
50672
- message: `${path36} must match pattern ${schema.pattern}`,
51268
+ path: path37,
51269
+ message: `${path37} must match pattern ${schema.pattern}`,
50673
51270
  expected: `pattern: ${schema.pattern}`,
50674
51271
  received: value
50675
51272
  });
@@ -50678,16 +51275,16 @@ var DeterministicGatewayIntegration = class {
50678
51275
  if (schema.type === "number" && typeof value === "number") {
50679
51276
  if (schema.min !== void 0 && value < schema.min) {
50680
51277
  errors.push({
50681
- path: path36,
50682
- message: `${path36} must be at least ${schema.min}`,
51278
+ path: path37,
51279
+ message: `${path37} must be at least ${schema.min}`,
50683
51280
  expected: `min: ${schema.min}`,
50684
51281
  received: `${value}`
50685
51282
  });
50686
51283
  }
50687
51284
  if (schema.max !== void 0 && value > schema.max) {
50688
51285
  errors.push({
50689
- path: path36,
50690
- message: `${path36} must be at most ${schema.max}`,
51286
+ path: path37,
51287
+ message: `${path37} must be at most ${schema.max}`,
50691
51288
  expected: `max: ${schema.max}`,
50692
51289
  received: `${value}`
50693
51290
  });
@@ -50695,22 +51292,22 @@ var DeterministicGatewayIntegration = class {
50695
51292
  }
50696
51293
  if (schema.enum && !schema.enum.includes(value)) {
50697
51294
  errors.push({
50698
- path: path36,
50699
- message: `${path36} must be one of: ${schema.enum.join(", ")}`,
51295
+ path: path37,
51296
+ message: `${path37} must be one of: ${schema.enum.join(", ")}`,
50700
51297
  expected: `enum: [${schema.enum.join(", ")}]`,
50701
51298
  received: String(value)
50702
51299
  });
50703
51300
  }
50704
51301
  if (schema.type === "array" && Array.isArray(value) && schema.items) {
50705
51302
  value.forEach((item, index) => {
50706
- const itemErrors = this.validateValue(item, schema.items, `${path36}[${index}]`);
51303
+ const itemErrors = this.validateValue(item, schema.items, `${path37}[${index}]`);
50707
51304
  errors.push(...itemErrors);
50708
51305
  });
50709
51306
  }
50710
51307
  if (schema.type === "object" && typeof value === "object" && schema.properties) {
50711
51308
  const objValue = value;
50712
51309
  for (const [propName, propSchema] of Object.entries(schema.properties)) {
50713
- const propErrors = this.validateValue(objValue[propName], propSchema, `${path36}.${propName}`);
51310
+ const propErrors = this.validateValue(objValue[propName], propSchema, `${path37}.${propName}`);
50714
51311
  errors.push(...propErrors);
50715
51312
  }
50716
51313
  }
@@ -60486,8 +61083,8 @@ var TestGenerationCoordinator = class extends BaseDomainCoordinator {
60486
61083
  );
60487
61084
  console.log("[TestGenerationCoordinator] QEFlashAttention initialized for test-similarity");
60488
61085
  } catch (error) {
60489
- console.error("[TestGenerationCoordinator] Failed to initialize QEFlashAttention:", error);
60490
- throw new Error(`QEFlashAttention initialization failed: ${toErrorMessage(error)}`);
61086
+ console.warn("[TestGenerationCoordinator] QEFlashAttention unavailable (optional native module), continuing without it:", toErrorMessage(error));
61087
+ this.flashAttention = null;
60491
61088
  }
60492
61089
  }
60493
61090
  if (this.config.enableDecisionTransformer) {
@@ -60498,8 +61095,8 @@ var TestGenerationCoordinator = class extends BaseDomainCoordinator {
60498
61095
  });
60499
61096
  console.log("[TestGenerationCoordinator] DecisionTransformer created for test case selection");
60500
61097
  } catch (error) {
60501
- console.error("[TestGenerationCoordinator] Failed to create DecisionTransformer:", error);
60502
- throw new Error(`DecisionTransformer creation failed: ${toErrorMessage(error)}`);
61098
+ console.warn("[TestGenerationCoordinator] DecisionTransformer unavailable (optional native module), continuing without it:", toErrorMessage(error));
61099
+ this.decisionTransformer = null;
60503
61100
  }
60504
61101
  }
60505
61102
  this.subscribeToEvents();
@@ -64961,11 +65558,11 @@ var AgentBrowserCommandExecutor = class {
64961
65558
  /**
64962
65559
  * Take screenshot
64963
65560
  */
64964
- screenshot(path36, fullPage) {
65561
+ screenshot(path37, fullPage) {
64965
65562
  const args = [];
64966
- if (path36) args.push(path36);
65563
+ if (path37) args.push(path37);
64967
65564
  if (fullPage) args.push("--full");
64968
- if (!path36) args.push("--json");
65565
+ if (!path37) args.push("--json");
64969
65566
  return this.execute("screenshot", args);
64970
65567
  }
64971
65568
  // ========================================================================
@@ -65043,14 +65640,14 @@ var AgentBrowserCommandExecutor = class {
65043
65640
  /**
65044
65641
  * Save browser state (cookies, storage)
65045
65642
  */
65046
- saveState(path36) {
65047
- return this.execute("state", ["save", path36]);
65643
+ saveState(path37) {
65644
+ return this.execute("state", ["save", path37]);
65048
65645
  }
65049
65646
  /**
65050
65647
  * Load browser state
65051
65648
  */
65052
- loadState(path36) {
65053
- return this.execute("state", ["load", path36]);
65649
+ loadState(path37) {
65650
+ return this.execute("state", ["load", path37]);
65054
65651
  }
65055
65652
  // ========================================================================
65056
65653
  // Trace recording
@@ -66327,9 +66924,9 @@ var AgentBrowserClient = class {
66327
66924
  /**
66328
66925
  * Save browser state (cookies, storage, etc.)
66329
66926
  */
66330
- async saveState(path36) {
66927
+ async saveState(path37) {
66331
66928
  try {
66332
- const result = this.executor.saveState(path36);
66929
+ const result = this.executor.saveState(path37);
66333
66930
  if (!result.success) {
66334
66931
  return err2(new BrowserError(result.error ?? "Save state failed", "SAVE_STATE_FAILED", "agent-browser"));
66335
66932
  }
@@ -66348,9 +66945,9 @@ var AgentBrowserClient = class {
66348
66945
  /**
66349
66946
  * Load previously saved browser state
66350
66947
  */
66351
- async loadState(path36) {
66948
+ async loadState(path37) {
66352
66949
  try {
66353
- const result = this.executor.loadState(path36);
66950
+ const result = this.executor.loadState(path37);
66354
66951
  if (!result.success) {
66355
66952
  return err2(new BrowserError(result.error ?? "Load state failed", "LOAD_STATE_FAILED", "agent-browser"));
66356
66953
  }
@@ -73290,16 +73887,16 @@ var CoverageEmbedder = class {
73290
73887
  const idealRegions = Math.ceil(coverage.uncoveredLines.length / 5);
73291
73888
  return regions > 0 ? Math.min(1, idealRegions / regions) : 0;
73292
73889
  }
73293
- extractPathFeatures(path36) {
73294
- const parts = path36.split("/").filter(Boolean);
73295
- const extension = path36.split(".").pop() || "";
73890
+ extractPathFeatures(path37) {
73891
+ const parts = path37.split("/").filter(Boolean);
73892
+ const extension = path37.split(".").pop() || "";
73296
73893
  const fileName = parts[parts.length - 1] || "";
73297
73894
  return {
73298
73895
  depth: parts.length,
73299
73896
  extension,
73300
- hashNormalized: this.hashString(path36) / 1e6,
73301
- isTest: /\.(test|spec)\.(ts|js|tsx|jsx)$/.test(path36) || parts.includes("tests") || parts.includes("__tests__"),
73302
- isConfig: /\.(config|rc)\.(ts|js|json|yaml|yml)$/.test(path36),
73897
+ hashNormalized: this.hashString(path37) / 1e6,
73898
+ isTest: /\.(test|spec)\.(ts|js|tsx|jsx)$/.test(path37) || parts.includes("tests") || parts.includes("__tests__"),
73899
+ isConfig: /\.(config|rc)\.(ts|js|json|yaml|yml)$/.test(path37),
73303
73900
  isIndex: fileName.startsWith("index."),
73304
73901
  inSrc: parts.includes("src"),
73305
73902
  inLib: parts.includes("lib"),
@@ -73646,12 +74243,12 @@ var GhostCoverageAnalyzerService = class _GhostCoverageAnalyzerService {
73646
74243
  ratio(n61, d74) {
73647
74244
  return d74 > 0 ? n61 / d74 : 0;
73648
74245
  }
73649
- gapId(path36, cat) {
73650
- const h66 = `${path36}:${cat}`.split("").reduce((a37, c70) => (a37 << 5) - a37 + c70.charCodeAt(0) | 0, 0);
74246
+ gapId(path37, cat) {
74247
+ const h66 = `${path37}:${cat}`.split("").reduce((a37, c70) => (a37 << 5) - a37 + c70.charCodeAt(0) | 0, 0);
73651
74248
  return `phantom-${Math.abs(h66).toString(16)}`;
73652
74249
  }
73653
- gapDescription(path36, cat, dist) {
73654
- const n61 = path36.split("/").pop() || path36;
74250
+ gapDescription(path37, cat, dist) {
74251
+ const n61 = path37.split("/").pop() || path37;
73655
74252
  const s70 = dist > 0.7 ? "significant" : dist > 0.4 ? "moderate" : "minor";
73656
74253
  const m74 = {
73657
74254
  "missing-error-handler": `${n61}: ${s70} missing error handler tests. Cover error paths and failure recovery.`,
@@ -76085,7 +76682,7 @@ function getCodeMetricsAnalyzer() {
76085
76682
  }
76086
76683
 
76087
76684
  // src/shared/metrics/system-metrics.ts
76088
- import * as os2 from "os";
76685
+ import * as os3 from "os";
76089
76686
  var SystemMetricsCollector = class {
76090
76687
  lastCpuUsage = null;
76091
76688
  lastCpuTime = 0;
@@ -76117,8 +76714,8 @@ var SystemMetricsCollector = class {
76117
76714
  * Collect CPU metrics
76118
76715
  */
76119
76716
  collectCpuMetrics() {
76120
- const cpus2 = os2.cpus();
76121
- const loadAverage = os2.loadavg();
76717
+ const cpus2 = os3.cpus();
76718
+ const loadAverage = os3.loadavg();
76122
76719
  let totalIdle = 0;
76123
76720
  let totalTick = 0;
76124
76721
  for (const cpu of cpus2) {
@@ -76138,8 +76735,8 @@ var SystemMetricsCollector = class {
76138
76735
  * Collect memory metrics
76139
76736
  */
76140
76737
  collectMemoryMetrics() {
76141
- const total = os2.totalmem();
76142
- const free = os2.freemem();
76738
+ const total = os3.totalmem();
76739
+ const free = os3.freemem();
76143
76740
  const used = total - free;
76144
76741
  const usage = used / total * 100;
76145
76742
  return {
@@ -76162,7 +76759,7 @@ var SystemMetricsCollector = class {
76162
76759
  const cpuPercent = totalCpuUs / elapsedUs * 100;
76163
76760
  this.lastCpuUsage = cpuUsage;
76164
76761
  this.lastCpuTime = now;
76165
- const totalMem = os2.totalmem();
76762
+ const totalMem = os3.totalmem();
76166
76763
  const memPercent = memUsage.rss / totalMem * 100;
76167
76764
  return {
76168
76765
  cpuUsage: Math.min(100, Math.round(cpuPercent * 100) / 100),
@@ -76718,10 +77315,10 @@ ${codeContext.slice(0, 2e3)}
76718
77315
  const coverage = await this.memory.get(key);
76719
77316
  return coverage ?? null;
76720
77317
  }
76721
- hashFilePath(path36) {
77318
+ hashFilePath(path37) {
76722
77319
  let hash = 0;
76723
- for (let i58 = 0; i58 < path36.length; i58++) {
76724
- hash = (hash << 5) - hash + path36.charCodeAt(i58);
77320
+ for (let i58 = 0; i58 < path37.length; i58++) {
77321
+ hash = (hash << 5) - hash + path37.charCodeAt(i58);
76725
77322
  hash = hash & hash;
76726
77323
  }
76727
77324
  return hash.toString(16);
@@ -90935,10 +91532,10 @@ function countTestsByFilePattern(projectPath, config) {
90935
91532
  fileTests = countTestsInGoFile(fullPath);
90936
91533
  }
90937
91534
  total += fileTests;
90938
- const path36 = fullPath.toLowerCase();
90939
- if (path36.includes("e2e") || path36.includes("end-to-end")) {
91535
+ const path37 = fullPath.toLowerCase();
91536
+ if (path37.includes("e2e") || path37.includes("end-to-end")) {
90940
91537
  e2e += fileTests;
90941
- } else if (path36.includes("integration")) {
91538
+ } else if (path37.includes("integration")) {
90942
91539
  integration += fileTests;
90943
91540
  } else {
90944
91541
  unit += fileTests;
@@ -91768,7 +92365,7 @@ var HypergraphEngine = class {
91768
92365
  ];
91769
92366
  const effectiveMaxDepth = Math.min(maxDepth, this.config.maxTraversalDepth);
91770
92367
  while (queue.length > 0) {
91771
- const { nodeId, depth, path: path36 } = queue.shift();
92368
+ const { nodeId, depth, path: path37 } = queue.shift();
91772
92369
  if (!visitedNodes.has(nodeId)) {
91773
92370
  const node = await this.getNode(nodeId);
91774
92371
  if (node) {
@@ -91777,7 +92374,7 @@ var HypergraphEngine = class {
91777
92374
  }
91778
92375
  maxDepthReached = Math.max(maxDepthReached, depth);
91779
92376
  if (depth >= effectiveMaxDepth) {
91780
- paths.push(path36);
92377
+ paths.push(path37);
91781
92378
  continue;
91782
92379
  }
91783
92380
  const edgeCriteria = { sourceId: nodeId };
@@ -91786,15 +92383,15 @@ var HypergraphEngine = class {
91786
92383
  }
91787
92384
  const edges = await this.findEdges(edgeCriteria);
91788
92385
  if (edges.length === 0) {
91789
- paths.push(path36);
92386
+ paths.push(path37);
91790
92387
  continue;
91791
92388
  }
91792
92389
  for (const edge of edges) {
91793
92390
  if (!visitedEdges.has(edge.id)) {
91794
92391
  visitedEdges.set(edge.id, edge);
91795
92392
  const newPath = {
91796
- nodes: [...path36.nodes, edge.targetId],
91797
- edges: [...path36.edges, edge.id]
92393
+ nodes: [...path37.nodes, edge.targetId],
92394
+ edges: [...path37.edges, edge.id]
91798
92395
  };
91799
92396
  queue.push({
91800
92397
  nodeId: edge.targetId,
@@ -92175,11 +92772,11 @@ async function createHypergraphEngine(config) {
92175
92772
  init_wrappers();
92176
92773
  async function indexCodeEmbeddings(gnnIndex, fileReader, paths) {
92177
92774
  try {
92178
- for (const path36 of paths) {
92775
+ for (const path37 of paths) {
92179
92776
  try {
92180
- const result = await fileReader.readFile(path36);
92777
+ const result = await fileReader.readFile(path37);
92181
92778
  if (result.success && result.value) {
92182
- const embedding = await generateCodeEmbedding(path36, result.value);
92779
+ const embedding = await generateCodeEmbedding(path37, result.value);
92183
92780
  const embeddingObj = {
92184
92781
  vector: embedding,
92185
92782
  dimension: 384,
@@ -92187,12 +92784,12 @@ async function indexCodeEmbeddings(gnnIndex, fileReader, paths) {
92187
92784
  text: result.value.slice(0, 1e3),
92188
92785
  timestamp: Date.now(),
92189
92786
  quantization: "none",
92190
- metadata: { path: path36 }
92787
+ metadata: { path: path37 }
92191
92788
  };
92192
92789
  gnnIndex.addEmbedding(embeddingObj);
92193
92790
  }
92194
92791
  } catch (error) {
92195
- console.error(`Failed to index ${path36}:`, error);
92792
+ console.error(`Failed to index ${path37}:`, error);
92196
92793
  }
92197
92794
  }
92198
92795
  console.log(`[GNN] Indexed ${paths.length} code embeddings`);
@@ -92200,9 +92797,9 @@ async function indexCodeEmbeddings(gnnIndex, fileReader, paths) {
92200
92797
  console.error("Failed to index code embeddings:", error);
92201
92798
  }
92202
92799
  }
92203
- async function generateCodeEmbedding(path36, content) {
92800
+ async function generateCodeEmbedding(path37, content) {
92204
92801
  const features = [];
92205
- const ext = path36.split(".").pop();
92802
+ const ext = path37.split(".").pop();
92206
92803
  const typeHash = hashCode(ext || "");
92207
92804
  features.push(typeHash % 1e3 / 1e3);
92208
92805
  features.push(Math.min(1, content.length / 1e4));
@@ -92623,14 +93220,14 @@ var CodeIntelligenceCoordinator = class extends BaseDomainCoordinator {
92623
93220
  async initializeHypergraph() {
92624
93221
  try {
92625
93222
  const { openDatabase: openDatabase2 } = await Promise.resolve().then(() => (init_safe_db(), safe_db_exports));
92626
- const fs31 = await import("fs");
92627
- const path36 = await import("path");
93223
+ const fs32 = await import("fs");
93224
+ const path37 = await import("path");
92628
93225
  const { findProjectRoot: findProjectRoot2 } = await Promise.resolve().then(() => (init_unified_memory(), unified_memory_exports));
92629
93226
  const projectRoot = findProjectRoot2();
92630
- const dbPath = this.config.hypergraphDbPath || path36.join(projectRoot, ".agentic-qe", "hypergraph.db");
92631
- const dir = path36.dirname(dbPath);
92632
- if (!fs31.existsSync(dir)) {
92633
- fs31.mkdirSync(dir, { recursive: true });
93227
+ const dbPath = this.config.hypergraphDbPath || path37.join(projectRoot, ".agentic-qe", "hypergraph.db");
93228
+ const dir = path37.dirname(dbPath);
93229
+ if (!fs32.existsSync(dir)) {
93230
+ fs32.mkdirSync(dir, { recursive: true });
92634
93231
  }
92635
93232
  this.hypergraphDb = openDatabase2(dbPath);
92636
93233
  this.hypergraph = await createHypergraphEngine({
@@ -93158,11 +93755,11 @@ var CodeIntelligenceCoordinator = class extends BaseDomainCoordinator {
93158
93755
  // ============================================================================
93159
93756
  async indexForSemanticSearch(paths) {
93160
93757
  const filesToIndex = paths.slice(0, 100);
93161
- for (const path36 of filesToIndex) {
93758
+ for (const path37 of filesToIndex) {
93162
93759
  try {
93163
- const result = await this.fileReader.readFile(path36);
93760
+ const result = await this.fileReader.readFile(path37);
93164
93761
  if (result.success && result.value) {
93165
- await this.semanticAnalyzer.indexCode(path36, result.value);
93762
+ await this.semanticAnalyzer.indexCode(path37, result.value);
93166
93763
  }
93167
93764
  } catch {
93168
93765
  }
@@ -93370,8 +93967,8 @@ var CodeIntelligenceCoordinator = class extends BaseDomainCoordinator {
93370
93967
  for (const marker of markers) {
93371
93968
  try {
93372
93969
  const markerPath = `${currentPath}/${marker}`;
93373
- const fs31 = __require("fs");
93374
- if (fs31.existsSync(markerPath)) {
93970
+ const fs32 = __require("fs");
93971
+ if (fs32.existsSync(markerPath)) {
93375
93972
  return currentPath;
93376
93973
  }
93377
93974
  } catch {
@@ -93877,8 +94474,8 @@ var FilePath = class _FilePath {
93877
94474
  equals(other) {
93878
94475
  return this._value === other._value;
93879
94476
  }
93880
- static create(path36) {
93881
- return new _FilePath(path36);
94477
+ static create(path37) {
94478
+ return new _FilePath(path37);
93882
94479
  }
93883
94480
  };
93884
94481
  var RiskScore = class _RiskScore {
@@ -94616,8 +95213,8 @@ var SASTScanner = class {
94616
95213
  let content;
94617
95214
  let lines;
94618
95215
  try {
94619
- const fs31 = await import("fs/promises");
94620
- content = await fs31.readFile(filePath, "utf-8");
95216
+ const fs32 = await import("fs/promises");
95217
+ content = await fs32.readFile(filePath, "utf-8");
94621
95218
  lines = content.split("\n");
94622
95219
  } catch {
94623
95220
  return { vulnerabilities: [], linesScanned: 0 };
@@ -95307,10 +95904,10 @@ async function extractAndCrawlLinks(html, baseUrl, currentCrawled, maxDepth, vul
95307
95904
  }
95308
95905
  }
95309
95906
  const linksToCrawl = Array.from(discoveredLinks).slice(0, Math.min(10, maxCrawl - crawledUrls));
95310
- for (const path36 of linksToCrawl) {
95907
+ for (const path37 of linksToCrawl) {
95311
95908
  if (crawledUrls >= maxCrawl) break;
95312
95909
  try {
95313
- const crawlUrl = new URL(path36, baseUrl.origin).toString();
95910
+ const crawlUrl = new URL(path37, baseUrl.origin).toString();
95314
95911
  const crawlResponse = await fetch(crawlUrl, {
95315
95912
  method: "GET",
95316
95913
  headers: { "User-Agent": "AgenticQE-DAST-Scanner/3.0" },
@@ -95319,11 +95916,11 @@ async function extractAndCrawlLinks(html, baseUrl, currentCrawled, maxDepth, vul
95319
95916
  });
95320
95917
  crawledUrls++;
95321
95918
  if (crawlResponse.ok) {
95322
- if (path36.includes("password") || path36.includes("token") || path36.includes("api_key")) {
95919
+ if (path37.includes("password") || path37.includes("token") || path37.includes("api_key")) {
95323
95920
  vulnerabilities.push({
95324
95921
  id: v4_default(),
95325
95922
  title: "Sensitive Data in URL Path",
95326
- description: `URL path may contain sensitive parameter names: ${path36}`,
95923
+ description: `URL path may contain sensitive parameter names: ${path37}`,
95327
95924
  severity: "medium",
95328
95925
  category: "sensitive-data",
95329
95926
  location: { file: crawlUrl },
@@ -96832,8 +97429,8 @@ var DependencyScanner = class {
96832
97429
  */
96833
97430
  async scanPackageJson(packageJsonPath) {
96834
97431
  try {
96835
- const fs31 = await import("fs/promises");
96836
- const content = await fs31.readFile(packageJsonPath, "utf-8");
97432
+ const fs32 = await import("fs/promises");
97433
+ const content = await fs32.readFile(packageJsonPath, "utf-8");
96837
97434
  const packageJson = safeJsonParse(content);
96838
97435
  const allDependencies = {
96839
97436
  ...packageJson.dependencies || {},
@@ -101149,17 +101746,17 @@ Provide:
101149
101746
  warnings.push("No consumers defined for contract");
101150
101747
  }
101151
101748
  }
101152
- validateServiceInfo(info, path36, errors) {
101749
+ validateServiceInfo(info, path37, errors) {
101153
101750
  if (!info.name || info.name.trim() === "") {
101154
101751
  errors.push({
101155
- path: `${path36}.name`,
101752
+ path: `${path37}.name`,
101156
101753
  message: "Service name is required",
101157
101754
  code: "REQUIRED_FIELD"
101158
101755
  });
101159
101756
  }
101160
101757
  if (!info.version || info.version.trim() === "") {
101161
101758
  errors.push({
101162
- path: `${path36}.version`,
101759
+ path: `${path37}.version`,
101163
101760
  message: "Service version is required",
101164
101761
  code: "REQUIRED_FIELD"
101165
101762
  });
@@ -101805,13 +102402,13 @@ Provide:
101805
102402
  /**
101806
102403
  * Validate nested field selections
101807
102404
  */
101808
- validateGraphQLSelections(selections, typeName, schemaInfo, path36, errors) {
102405
+ validateGraphQLSelections(selections, typeName, schemaInfo, path37, errors) {
101809
102406
  const typeDef = schemaInfo.types[typeName];
101810
102407
  if (!typeDef) {
101811
102408
  if (["String", "Int", "Float", "Boolean", "ID"].includes(typeName)) {
101812
102409
  if (selections.length > 0) {
101813
102410
  errors.push({
101814
- path: path36,
102411
+ path: path37,
101815
102412
  keyword: "selection",
101816
102413
  message: `Cannot select fields on scalar type '${typeName}'`,
101817
102414
  params: { type: typeName }
@@ -101824,7 +102421,7 @@ Provide:
101824
102421
  const fieldDef = typeDef.fields[selection.name];
101825
102422
  if (!fieldDef) {
101826
102423
  errors.push({
101827
- path: `${path36}.${selection.name}`,
102424
+ path: `${path37}.${selection.name}`,
101828
102425
  keyword: "field",
101829
102426
  message: `Field '${selection.name}' does not exist on type '${typeName}'`,
101830
102427
  params: { field: selection.name, type: typeName }
@@ -101835,7 +102432,7 @@ Provide:
101835
102432
  selection.selections,
101836
102433
  nestedType,
101837
102434
  schemaInfo,
101838
- `${path36}.${selection.name}`,
102435
+ `${path37}.${selection.name}`,
101839
102436
  errors
101840
102437
  );
101841
102438
  }
@@ -101844,14 +102441,14 @@ Provide:
101844
102441
  /**
101845
102442
  * Validate variable type matches expected GraphQL type
101846
102443
  */
101847
- validateGraphQLVariableType(value, expectedType, path36, errors) {
102444
+ validateGraphQLVariableType(value, expectedType, path37, errors) {
101848
102445
  const baseType = this.unwrapGraphQLType(expectedType);
101849
102446
  const isNonNull = expectedType.endsWith("!");
101850
102447
  const isList = expectedType.includes("[");
101851
102448
  if (value === null || value === void 0) {
101852
102449
  if (isNonNull) {
101853
102450
  errors.push({
101854
- path: path36,
102451
+ path: path37,
101855
102452
  keyword: "type",
101856
102453
  message: `Variable cannot be null (expected ${expectedType})`,
101857
102454
  params: { expectedType }
@@ -101862,7 +102459,7 @@ Provide:
101862
102459
  if (isList) {
101863
102460
  if (!Array.isArray(value)) {
101864
102461
  errors.push({
101865
- path: path36,
102462
+ path: path37,
101866
102463
  keyword: "type",
101867
102464
  message: `Expected array for type ${expectedType}`,
101868
102465
  params: { expectedType, actualType: typeof value }
@@ -101875,7 +102472,7 @@ Provide:
101875
102472
  case "ID":
101876
102473
  if (typeof value !== "string") {
101877
102474
  errors.push({
101878
- path: path36,
102475
+ path: path37,
101879
102476
  keyword: "type",
101880
102477
  message: `Expected string for type ${baseType}`,
101881
102478
  params: { expectedType: baseType, actualType: typeof value }
@@ -101885,7 +102482,7 @@ Provide:
101885
102482
  case "Int":
101886
102483
  if (typeof value !== "number" || !Number.isInteger(value)) {
101887
102484
  errors.push({
101888
- path: path36,
102485
+ path: path37,
101889
102486
  keyword: "type",
101890
102487
  message: `Expected integer for type Int`,
101891
102488
  params: { expectedType: "Int", actualType: typeof value }
@@ -101895,7 +102492,7 @@ Provide:
101895
102492
  case "Float":
101896
102493
  if (typeof value !== "number") {
101897
102494
  errors.push({
101898
- path: path36,
102495
+ path: path37,
101899
102496
  keyword: "type",
101900
102497
  message: `Expected number for type Float`,
101901
102498
  params: { expectedType: "Float", actualType: typeof value }
@@ -101905,7 +102502,7 @@ Provide:
101905
102502
  case "Boolean":
101906
102503
  if (typeof value !== "boolean") {
101907
102504
  errors.push({
101908
- path: path36,
102505
+ path: path37,
101909
102506
  keyword: "type",
101910
102507
  message: `Expected boolean for type Boolean`,
101911
102508
  params: { expectedType: "Boolean", actualType: typeof value }
@@ -101916,7 +102513,7 @@ Provide:
101916
102513
  default:
101917
102514
  if (typeof value !== "object") {
101918
102515
  errors.push({
101919
- path: path36,
102516
+ path: path37,
101920
102517
  keyword: "type",
101921
102518
  message: `Expected object for type ${baseType}`,
101922
102519
  params: { expectedType: baseType, actualType: typeof value }
@@ -101924,10 +102521,10 @@ Provide:
101924
102521
  }
101925
102522
  }
101926
102523
  }
101927
- basicTypeValidation(data, schema, path36, errors, depth = 0) {
102524
+ basicTypeValidation(data, schema, path37, errors, depth = 0) {
101928
102525
  if (depth > this.config.maxSchemaDepth) {
101929
102526
  errors.push({
101930
- path: path36,
102527
+ path: path37,
101931
102528
  keyword: "maxDepth",
101932
102529
  message: "Maximum schema depth exceeded",
101933
102530
  params: { maxDepth: this.config.maxSchemaDepth }
@@ -101944,7 +102541,7 @@ Provide:
101944
102541
  for (const prop of required) {
101945
102542
  if (!(prop in dataObj)) {
101946
102543
  errors.push({
101947
- path: path36 ? `${path36}.${prop}` : prop,
102544
+ path: path37 ? `${path37}.${prop}` : prop,
101948
102545
  keyword: "required",
101949
102546
  message: `Required property '${prop}' is missing`,
101950
102547
  params: { missingProperty: prop }
@@ -101956,7 +102553,7 @@ Provide:
101956
102553
  this.basicTypeValidation(
101957
102554
  dataObj[prop],
101958
102555
  propSchema,
101959
- path36 ? `${path36}.${prop}` : prop,
102556
+ path37 ? `${path37}.${prop}` : prop,
101960
102557
  errors,
101961
102558
  depth + 1
101962
102559
  );
@@ -101965,26 +102562,26 @@ Provide:
101965
102562
  } else if (type === "array" && actualType === "array") {
101966
102563
  const items = schema.items;
101967
102564
  const dataArr = data;
101968
- this.validateArrayConstraints(dataArr, schema, path36, errors);
102565
+ this.validateArrayConstraints(dataArr, schema, path37, errors);
101969
102566
  if (items) {
101970
102567
  for (let i58 = 0; i58 < dataArr.length; i58++) {
101971
102568
  this.basicTypeValidation(
101972
102569
  dataArr[i58],
101973
102570
  items,
101974
- `${path36}[${i58}]`,
102571
+ `${path37}[${i58}]`,
101975
102572
  errors,
101976
102573
  depth + 1
101977
102574
  );
101978
102575
  }
101979
102576
  }
101980
102577
  } else if (type === "string" && actualType === "string") {
101981
- this.validateStringConstraints(data, schema, path36, errors);
102578
+ this.validateStringConstraints(data, schema, path37, errors);
101982
102579
  } else if ((type === "number" || type === "integer") && (actualType === "number" || actualType === "integer")) {
101983
- this.validateNumberConstraints(data, schema, path36, errors);
102580
+ this.validateNumberConstraints(data, schema, path37, errors);
101984
102581
  } else if (type !== actualType) {
101985
102582
  if (!(type === "number" && actualType === "integer")) {
101986
102583
  errors.push({
101987
- path: path36,
102584
+ path: path37,
101988
102585
  keyword: "type",
101989
102586
  message: `Expected type '${type}' but got '${actualType}'`,
101990
102587
  params: { expectedType: type, actualType }
@@ -101995,7 +102592,7 @@ Provide:
101995
102592
  const enumValues = schema.enum;
101996
102593
  if (!enumValues.some((v65) => JSON.stringify(v65) === JSON.stringify(data))) {
101997
102594
  errors.push({
101998
- path: path36,
102595
+ path: path37,
101999
102596
  keyword: "enum",
102000
102597
  message: `Value must be one of: ${enumValues.map((v65) => JSON.stringify(v65)).join(", ")}`,
102001
102598
  params: { allowedValues: enumValues }
@@ -102003,13 +102600,13 @@ Provide:
102003
102600
  }
102004
102601
  }
102005
102602
  }
102006
- validateStringConstraints(data, schema, path36, errors) {
102603
+ validateStringConstraints(data, schema, path37, errors) {
102007
102604
  const minLength = schema.minLength;
102008
102605
  const maxLength = schema.maxLength;
102009
102606
  const pattern = schema.pattern;
102010
102607
  if (minLength !== void 0 && data.length < minLength) {
102011
102608
  errors.push({
102012
- path: path36,
102609
+ path: path37,
102013
102610
  keyword: "minLength",
102014
102611
  message: `String must be at least ${minLength} characters`,
102015
102612
  params: { limit: minLength, actual: data.length }
@@ -102017,7 +102614,7 @@ Provide:
102017
102614
  }
102018
102615
  if (maxLength !== void 0 && data.length > maxLength) {
102019
102616
  errors.push({
102020
- path: path36,
102617
+ path: path37,
102021
102618
  keyword: "maxLength",
102022
102619
  message: `String must be at most ${maxLength} characters`,
102023
102620
  params: { limit: maxLength, actual: data.length }
@@ -102027,7 +102624,7 @@ Provide:
102027
102624
  const regex = createSafeRegex(pattern);
102028
102625
  if (regex && !regex.test(data)) {
102029
102626
  errors.push({
102030
- path: path36,
102627
+ path: path37,
102031
102628
  keyword: "pattern",
102032
102629
  message: `String must match pattern: ${pattern}`,
102033
102630
  params: { pattern }
@@ -102035,7 +102632,7 @@ Provide:
102035
102632
  }
102036
102633
  }
102037
102634
  }
102038
- validateNumberConstraints(data, schema, path36, errors) {
102635
+ validateNumberConstraints(data, schema, path37, errors) {
102039
102636
  const minimum = schema.minimum;
102040
102637
  const maximum = schema.maximum;
102041
102638
  const exclusiveMinimum = schema.exclusiveMinimum;
@@ -102043,7 +102640,7 @@ Provide:
102043
102640
  const multipleOf = schema.multipleOf;
102044
102641
  if (minimum !== void 0 && data < minimum) {
102045
102642
  errors.push({
102046
- path: path36,
102643
+ path: path37,
102047
102644
  keyword: "minimum",
102048
102645
  message: `Number must be >= ${minimum}`,
102049
102646
  params: { limit: minimum, actual: data }
@@ -102051,7 +102648,7 @@ Provide:
102051
102648
  }
102052
102649
  if (maximum !== void 0 && data > maximum) {
102053
102650
  errors.push({
102054
- path: path36,
102651
+ path: path37,
102055
102652
  keyword: "maximum",
102056
102653
  message: `Number must be <= ${maximum}`,
102057
102654
  params: { limit: maximum, actual: data }
@@ -102059,7 +102656,7 @@ Provide:
102059
102656
  }
102060
102657
  if (exclusiveMinimum !== void 0 && data <= exclusiveMinimum) {
102061
102658
  errors.push({
102062
- path: path36,
102659
+ path: path37,
102063
102660
  keyword: "exclusiveMinimum",
102064
102661
  message: `Number must be > ${exclusiveMinimum}`,
102065
102662
  params: { limit: exclusiveMinimum, actual: data }
@@ -102067,7 +102664,7 @@ Provide:
102067
102664
  }
102068
102665
  if (exclusiveMaximum !== void 0 && data >= exclusiveMaximum) {
102069
102666
  errors.push({
102070
- path: path36,
102667
+ path: path37,
102071
102668
  keyword: "exclusiveMaximum",
102072
102669
  message: `Number must be < ${exclusiveMaximum}`,
102073
102670
  params: { limit: exclusiveMaximum, actual: data }
@@ -102075,20 +102672,20 @@ Provide:
102075
102672
  }
102076
102673
  if (multipleOf !== void 0 && data % multipleOf !== 0) {
102077
102674
  errors.push({
102078
- path: path36,
102675
+ path: path37,
102079
102676
  keyword: "multipleOf",
102080
102677
  message: `Number must be a multiple of ${multipleOf}`,
102081
102678
  params: { multipleOf, actual: data }
102082
102679
  });
102083
102680
  }
102084
102681
  }
102085
- validateArrayConstraints(data, schema, path36, errors) {
102682
+ validateArrayConstraints(data, schema, path37, errors) {
102086
102683
  const minItems = schema.minItems;
102087
102684
  const maxItems = schema.maxItems;
102088
102685
  const uniqueItems = schema.uniqueItems;
102089
102686
  if (minItems !== void 0 && data.length < minItems) {
102090
102687
  errors.push({
102091
- path: path36,
102688
+ path: path37,
102092
102689
  keyword: "minItems",
102093
102690
  message: `Array must have at least ${minItems} items`,
102094
102691
  params: { limit: minItems, actual: data.length }
@@ -102096,7 +102693,7 @@ Provide:
102096
102693
  }
102097
102694
  if (maxItems !== void 0 && data.length > maxItems) {
102098
102695
  errors.push({
102099
- path: path36,
102696
+ path: path37,
102100
102697
  keyword: "maxItems",
102101
102698
  message: `Array must have at most ${maxItems} items`,
102102
102699
  params: { limit: maxItems, actual: data.length }
@@ -102108,7 +102705,7 @@ Provide:
102108
102705
  const serialized = JSON.stringify(data[i58]);
102109
102706
  if (seen.has(serialized)) {
102110
102707
  errors.push({
102111
- path: `${path36}[${i58}]`,
102708
+ path: `${path37}[${i58}]`,
102112
102709
  keyword: "uniqueItems",
102113
102710
  message: "Array items must be unique",
102114
102711
  params: { duplicateIndex: i58 }
@@ -102604,11 +103201,11 @@ var ApiCompatibilityService = class {
102604
103201
  } catch {
102605
103202
  }
102606
103203
  }
102607
- scanObjectForDeprecations(obj, path36, deprecations, version2, context2) {
103204
+ scanObjectForDeprecations(obj, path37, deprecations, version2, context2) {
102608
103205
  if (!obj || typeof obj !== "object") return;
102609
103206
  const record = obj;
102610
103207
  if (record.deprecated === true) {
102611
- const location = context2 ? `${context2} -> ${path36}` : path36;
103208
+ const location = context2 ? `${context2} -> ${path37}` : path37;
102612
103209
  deprecations.push({
102613
103210
  location,
102614
103211
  reason: typeof record.description === "string" ? record.description : "Field marked as deprecated",
@@ -102617,7 +103214,7 @@ var ApiCompatibilityService = class {
102617
103214
  });
102618
103215
  }
102619
103216
  if (record["x-deprecated"] === true) {
102620
- const location = context2 ? `${context2} -> ${path36}` : path36;
103217
+ const location = context2 ? `${context2} -> ${path37}` : path37;
102621
103218
  deprecations.push({
102622
103219
  location,
102623
103220
  reason: typeof record["x-deprecated-message"] === "string" ? record["x-deprecated-message"] : "Element marked as deprecated via x-deprecated",
@@ -102629,7 +103226,7 @@ var ApiCompatibilityService = class {
102629
103226
  for (const [propName, propValue] of Object.entries(props)) {
102630
103227
  this.scanObjectForDeprecations(
102631
103228
  propValue,
102632
- `${path36}.${propName}`,
103229
+ `${path37}.${propName}`,
102633
103230
  deprecations,
102634
103231
  version2,
102635
103232
  context2
@@ -102639,7 +103236,7 @@ var ApiCompatibilityService = class {
102639
103236
  if (record.items && typeof record.items === "object") {
102640
103237
  this.scanObjectForDeprecations(
102641
103238
  record.items,
102642
- `${path36}[]`,
103239
+ `${path37}[]`,
102643
103240
  deprecations,
102644
103241
  version2,
102645
103242
  context2
@@ -103388,13 +103985,13 @@ var ContractTestingCoordinator = class extends BaseDomainCoordinator {
103388
103985
  }
103389
103986
  return contracts;
103390
103987
  }
103391
- async loadContractFromPath(path36) {
103392
- const content = await this.loadFileContent(path36);
103988
+ async loadContractFromPath(path37) {
103989
+ const content = await this.loadFileContent(path37);
103393
103990
  if (!content) {
103394
103991
  return null;
103395
103992
  }
103396
103993
  try {
103397
- const filePath = path36.value.toLowerCase();
103994
+ const filePath = path37.value.toLowerCase();
103398
103995
  if (filePath.endsWith(".json")) {
103399
103996
  const parsed = safeJsonParse(content);
103400
103997
  if (parsed.openapi || parsed.swagger) {
@@ -103402,22 +103999,22 @@ var ContractTestingCoordinator = class extends BaseDomainCoordinator {
103402
103999
  }
103403
104000
  return parsed;
103404
104001
  } else if (filePath.endsWith(".yaml") || filePath.endsWith(".yml")) {
103405
- console.warn("YAML contract files not yet supported:", path36.value);
104002
+ console.warn("YAML contract files not yet supported:", path37.value);
103406
104003
  return null;
103407
104004
  }
103408
104005
  return safeJsonParse(content);
103409
104006
  } catch (error) {
103410
104007
  console.error(
103411
- `Failed to parse contract from ${path36.value}:`,
104008
+ `Failed to parse contract from ${path37.value}:`,
103412
104009
  toErrorMessage(error)
103413
104010
  );
103414
104011
  return null;
103415
104012
  }
103416
104013
  }
103417
- async loadFileContent(path36) {
103418
- const result = await this.fileReader.readFile(path36.value);
104014
+ async loadFileContent(path37) {
104015
+ const result = await this.fileReader.readFile(path37.value);
103419
104016
  if (!result.success) {
103420
- console.error(`Failed to read file ${path36.value}:`, result.error);
104017
+ console.error(`Failed to read file ${path37.value}:`, result.error);
103421
104018
  return null;
103422
104019
  }
103423
104020
  return result.value;
@@ -103428,13 +104025,13 @@ var ContractTestingCoordinator = class extends BaseDomainCoordinator {
103428
104025
  const paths = spec.paths || {};
103429
104026
  const endpoints = [];
103430
104027
  const schemas = [];
103431
- for (const [path36, methods] of Object.entries(paths)) {
104028
+ for (const [path37, methods] of Object.entries(paths)) {
103432
104029
  const httpMethods = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
103433
104030
  for (const method of httpMethods) {
103434
104031
  const operation = methods[method.toLowerCase()];
103435
104032
  if (operation) {
103436
104033
  endpoints.push({
103437
- path: path36,
104034
+ path: path37,
103438
104035
  method,
103439
104036
  requestSchema: this.extractRequestSchema(operation),
103440
104037
  responseSchema: this.extractResponseSchema(operation),
@@ -104163,10 +104760,10 @@ var SchemaValidatorService = class {
104163
104760
  // ============================================================================
104164
104761
  // Private Validation Methods
104165
104762
  // ============================================================================
104166
- validateValue(value, schema, path36, errors, depth) {
104763
+ validateValue(value, schema, path37, errors, depth) {
104167
104764
  if (depth > this.config.maxRecursionDepth) {
104168
104765
  errors.push({
104169
- path: path36,
104766
+ path: path37,
104170
104767
  keyword: "maxDepth",
104171
104768
  message: "Maximum recursion depth exceeded",
104172
104769
  params: { maxDepth: this.config.maxRecursionDepth }
@@ -104179,7 +104776,7 @@ var SchemaValidatorService = class {
104179
104776
  }
104180
104777
  if (this.config.strictMode) {
104181
104778
  errors.push({
104182
- path: path36,
104779
+ path: path37,
104183
104780
  keyword: "type",
104184
104781
  message: "Value cannot be null",
104185
104782
  params: {}
@@ -104189,15 +104786,15 @@ var SchemaValidatorService = class {
104189
104786
  }
104190
104787
  const schemaType = schema.type;
104191
104788
  if (schema.oneOf) {
104192
- this.validateOneOf(value, schema.oneOf, path36, errors, depth);
104789
+ this.validateOneOf(value, schema.oneOf, path37, errors, depth);
104193
104790
  return;
104194
104791
  }
104195
104792
  if (schema.anyOf) {
104196
- this.validateAnyOf(value, schema.anyOf, path36, errors, depth);
104793
+ this.validateAnyOf(value, schema.anyOf, path37, errors, depth);
104197
104794
  return;
104198
104795
  }
104199
104796
  if (schema.allOf) {
104200
- this.validateAllOf(value, schema.allOf, path36, errors, depth);
104797
+ this.validateAllOf(value, schema.allOf, path37, errors, depth);
104201
104798
  return;
104202
104799
  }
104203
104800
  if (schemaType) {
@@ -104205,7 +104802,7 @@ var SchemaValidatorService = class {
104205
104802
  const actualType = this.getJsonType(value);
104206
104803
  if (!types.some((t50) => this.typesMatch(actualType, t50))) {
104207
104804
  errors.push({
104208
- path: path36,
104805
+ path: path37,
104209
104806
  keyword: "type",
104210
104807
  message: `Expected type '${types.join(" | ")}' but got '${actualType}'`,
104211
104808
  params: { expectedType: types, actualType }
@@ -104214,19 +104811,19 @@ var SchemaValidatorService = class {
104214
104811
  }
104215
104812
  }
104216
104813
  if (typeof value === "object" && value !== null && !Array.isArray(value)) {
104217
- this.validateObject(value, schema, path36, errors, depth);
104814
+ this.validateObject(value, schema, path37, errors, depth);
104218
104815
  } else if (Array.isArray(value)) {
104219
- this.validateArray(value, schema, path36, errors, depth);
104816
+ this.validateArray(value, schema, path37, errors, depth);
104220
104817
  } else if (typeof value === "string") {
104221
- this.validateString(value, schema, path36, errors);
104818
+ this.validateString(value, schema, path37, errors);
104222
104819
  } else if (typeof value === "number") {
104223
- this.validateNumber(value, schema, path36, errors);
104820
+ this.validateNumber(value, schema, path37, errors);
104224
104821
  }
104225
104822
  if (schema.enum) {
104226
104823
  const enumValues = schema.enum;
104227
104824
  if (!enumValues.includes(value)) {
104228
104825
  errors.push({
104229
- path: path36,
104826
+ path: path37,
104230
104827
  keyword: "enum",
104231
104828
  message: `Value must be one of: ${enumValues.map((v65) => JSON.stringify(v65)).join(", ")}`,
104232
104829
  params: { allowedValues: enumValues }
@@ -104236,7 +104833,7 @@ var SchemaValidatorService = class {
104236
104833
  if ("const" in schema) {
104237
104834
  if (value !== schema.const) {
104238
104835
  errors.push({
104239
- path: path36,
104836
+ path: path37,
104240
104837
  keyword: "const",
104241
104838
  message: `Value must be ${JSON.stringify(schema.const)}`,
104242
104839
  params: { expected: schema.const }
@@ -104244,14 +104841,14 @@ var SchemaValidatorService = class {
104244
104841
  }
104245
104842
  }
104246
104843
  }
104247
- validateObject(value, schema, path36, errors, depth) {
104844
+ validateObject(value, schema, path37, errors, depth) {
104248
104845
  const properties = schema.properties || {};
104249
104846
  const required = schema.required || [];
104250
104847
  const additionalProperties = schema.additionalProperties;
104251
104848
  for (const prop of required) {
104252
104849
  if (!(prop in value)) {
104253
104850
  errors.push({
104254
- path: path36 ? `${path36}.${prop}` : prop,
104851
+ path: path37 ? `${path37}.${prop}` : prop,
104255
104852
  keyword: "required",
104256
104853
  message: `Required property '${prop}' is missing`,
104257
104854
  params: { missingProperty: prop }
@@ -104259,7 +104856,7 @@ var SchemaValidatorService = class {
104259
104856
  }
104260
104857
  }
104261
104858
  for (const [prop, propValue] of Object.entries(value)) {
104262
- const propPath = path36 ? `${path36}.${prop}` : prop;
104859
+ const propPath = path37 ? `${path37}.${prop}` : prop;
104263
104860
  if (prop in properties) {
104264
104861
  this.validateValue(propValue, properties[prop], propPath, errors, depth + 1);
104265
104862
  } else if (this.config.strictMode && additionalProperties === false) {
@@ -104282,7 +104879,7 @@ var SchemaValidatorService = class {
104282
104879
  const propCount = Object.keys(value).length;
104283
104880
  if (typeof schema.minProperties === "number" && propCount < schema.minProperties) {
104284
104881
  errors.push({
104285
- path: path36,
104882
+ path: path37,
104286
104883
  keyword: "minProperties",
104287
104884
  message: `Object must have at least ${schema.minProperties} properties`,
104288
104885
  params: { limit: schema.minProperties, actual: propCount }
@@ -104290,23 +104887,23 @@ var SchemaValidatorService = class {
104290
104887
  }
104291
104888
  if (typeof schema.maxProperties === "number" && propCount > schema.maxProperties) {
104292
104889
  errors.push({
104293
- path: path36,
104890
+ path: path37,
104294
104891
  keyword: "maxProperties",
104295
104892
  message: `Object must have at most ${schema.maxProperties} properties`,
104296
104893
  params: { limit: schema.maxProperties, actual: propCount }
104297
104894
  });
104298
104895
  }
104299
104896
  }
104300
- validateArray(value, schema, path36, errors, depth) {
104897
+ validateArray(value, schema, path37, errors, depth) {
104301
104898
  const items = schema.items;
104302
104899
  if (items) {
104303
104900
  for (let i58 = 0; i58 < value.length; i58++) {
104304
- this.validateValue(value[i58], items, `${path36}[${i58}]`, errors, depth + 1);
104901
+ this.validateValue(value[i58], items, `${path37}[${i58}]`, errors, depth + 1);
104305
104902
  }
104306
104903
  }
104307
104904
  if (typeof schema.minItems === "number" && value.length < schema.minItems) {
104308
104905
  errors.push({
104309
- path: path36,
104906
+ path: path37,
104310
104907
  keyword: "minItems",
104311
104908
  message: `Array must have at least ${schema.minItems} items`,
104312
104909
  params: { limit: schema.minItems, actual: value.length }
@@ -104314,7 +104911,7 @@ var SchemaValidatorService = class {
104314
104911
  }
104315
104912
  if (typeof schema.maxItems === "number" && value.length > schema.maxItems) {
104316
104913
  errors.push({
104317
- path: path36,
104914
+ path: path37,
104318
104915
  keyword: "maxItems",
104319
104916
  message: `Array must have at most ${schema.maxItems} items`,
104320
104917
  params: { limit: schema.maxItems, actual: value.length }
@@ -104326,7 +104923,7 @@ var SchemaValidatorService = class {
104326
104923
  const serialized = JSON.stringify(value[i58]);
104327
104924
  if (seen.has(serialized)) {
104328
104925
  errors.push({
104329
- path: `${path36}[${i58}]`,
104926
+ path: `${path37}[${i58}]`,
104330
104927
  keyword: "uniqueItems",
104331
104928
  message: "Array items must be unique",
104332
104929
  params: { duplicateIndex: i58 }
@@ -104336,10 +104933,10 @@ var SchemaValidatorService = class {
104336
104933
  }
104337
104934
  }
104338
104935
  }
104339
- validateString(value, schema, path36, errors) {
104936
+ validateString(value, schema, path37, errors) {
104340
104937
  if (typeof schema.minLength === "number" && value.length < schema.minLength) {
104341
104938
  errors.push({
104342
- path: path36,
104939
+ path: path37,
104343
104940
  keyword: "minLength",
104344
104941
  message: `String must be at least ${schema.minLength} characters`,
104345
104942
  params: { limit: schema.minLength, actual: value.length }
@@ -104347,7 +104944,7 @@ var SchemaValidatorService = class {
104347
104944
  }
104348
104945
  if (typeof schema.maxLength === "number" && value.length > schema.maxLength) {
104349
104946
  errors.push({
104350
- path: path36,
104947
+ path: path37,
104351
104948
  keyword: "maxLength",
104352
104949
  message: `String must be at most ${schema.maxLength} characters`,
104353
104950
  params: { limit: schema.maxLength, actual: value.length }
@@ -104357,7 +104954,7 @@ var SchemaValidatorService = class {
104357
104954
  const regex = createSafeRegex(schema.pattern);
104358
104955
  if (regex && !regex.test(value)) {
104359
104956
  errors.push({
104360
- path: path36,
104957
+ path: path37,
104361
104958
  keyword: "pattern",
104362
104959
  message: `String must match pattern '${schema.pattern}'`,
104363
104960
  params: { pattern: schema.pattern }
@@ -104365,15 +104962,15 @@ var SchemaValidatorService = class {
104365
104962
  }
104366
104963
  }
104367
104964
  if (typeof schema.format === "string") {
104368
- this.validateFormat(value, schema.format, path36, errors);
104965
+ this.validateFormat(value, schema.format, path37, errors);
104369
104966
  }
104370
104967
  }
104371
- validateNumber(value, schema, path36, errors) {
104968
+ validateNumber(value, schema, path37, errors) {
104372
104969
  if (typeof schema.minimum === "number") {
104373
104970
  if (schema.exclusiveMinimum === true) {
104374
104971
  if (value <= schema.minimum) {
104375
104972
  errors.push({
104376
- path: path36,
104973
+ path: path37,
104377
104974
  keyword: "exclusiveMinimum",
104378
104975
  message: `Number must be greater than ${schema.minimum}`,
104379
104976
  params: { limit: schema.minimum, actual: value }
@@ -104381,7 +104978,7 @@ var SchemaValidatorService = class {
104381
104978
  }
104382
104979
  } else if (value < schema.minimum) {
104383
104980
  errors.push({
104384
- path: path36,
104981
+ path: path37,
104385
104982
  keyword: "minimum",
104386
104983
  message: `Number must be at least ${schema.minimum}`,
104387
104984
  params: { limit: schema.minimum, actual: value }
@@ -104392,7 +104989,7 @@ var SchemaValidatorService = class {
104392
104989
  if (schema.exclusiveMaximum === true) {
104393
104990
  if (value >= schema.maximum) {
104394
104991
  errors.push({
104395
- path: path36,
104992
+ path: path37,
104396
104993
  keyword: "exclusiveMaximum",
104397
104994
  message: `Number must be less than ${schema.maximum}`,
104398
104995
  params: { limit: schema.maximum, actual: value }
@@ -104400,7 +104997,7 @@ var SchemaValidatorService = class {
104400
104997
  }
104401
104998
  } else if (value > schema.maximum) {
104402
104999
  errors.push({
104403
- path: path36,
105000
+ path: path37,
104404
105001
  keyword: "maximum",
104405
105002
  message: `Number must be at most ${schema.maximum}`,
104406
105003
  params: { limit: schema.maximum, actual: value }
@@ -104411,7 +105008,7 @@ var SchemaValidatorService = class {
104411
105008
  const remainder = value % schema.multipleOf;
104412
105009
  if (Math.abs(remainder) > 1e-10) {
104413
105010
  errors.push({
104414
- path: path36,
105011
+ path: path37,
104415
105012
  keyword: "multipleOf",
104416
105013
  message: `Number must be a multiple of ${schema.multipleOf}`,
104417
105014
  params: { multipleOf: schema.multipleOf, actual: value }
@@ -104419,7 +105016,7 @@ var SchemaValidatorService = class {
104419
105016
  }
104420
105017
  }
104421
105018
  }
104422
- validateFormat(value, format, path36, errors) {
105019
+ validateFormat(value, format, path37, errors) {
104423
105020
  let isValid = true;
104424
105021
  switch (format) {
104425
105022
  case "email":
@@ -104456,46 +105053,46 @@ var SchemaValidatorService = class {
104456
105053
  }
104457
105054
  if (!isValid) {
104458
105055
  errors.push({
104459
- path: path36,
105056
+ path: path37,
104460
105057
  keyword: "format",
104461
105058
  message: `String must be a valid ${format}`,
104462
105059
  params: { format }
104463
105060
  });
104464
105061
  }
104465
105062
  }
104466
- validateOneOf(value, schemas, path36, errors, depth) {
105063
+ validateOneOf(value, schemas, path37, errors, depth) {
104467
105064
  const validCount = schemas.reduce((count, schema) => {
104468
105065
  const subErrors = [];
104469
- this.validateValue(value, schema, path36, subErrors, depth + 1);
105066
+ this.validateValue(value, schema, path37, subErrors, depth + 1);
104470
105067
  return count + (subErrors.length === 0 ? 1 : 0);
104471
105068
  }, 0);
104472
105069
  if (validCount !== 1) {
104473
105070
  errors.push({
104474
- path: path36,
105071
+ path: path37,
104475
105072
  keyword: "oneOf",
104476
105073
  message: `Value must match exactly one schema (matched ${validCount})`,
104477
105074
  params: { matched: validCount }
104478
105075
  });
104479
105076
  }
104480
105077
  }
104481
- validateAnyOf(value, schemas, path36, errors, depth) {
105078
+ validateAnyOf(value, schemas, path37, errors, depth) {
104482
105079
  const hasValid = schemas.some((schema) => {
104483
105080
  const subErrors = [];
104484
- this.validateValue(value, schema, path36, subErrors, depth + 1);
105081
+ this.validateValue(value, schema, path37, subErrors, depth + 1);
104485
105082
  return subErrors.length === 0;
104486
105083
  });
104487
105084
  if (!hasValid) {
104488
105085
  errors.push({
104489
- path: path36,
105086
+ path: path37,
104490
105087
  keyword: "anyOf",
104491
105088
  message: "Value must match at least one schema",
104492
105089
  params: {}
104493
105090
  });
104494
105091
  }
104495
105092
  }
104496
- validateAllOf(value, schemas, path36, errors, depth) {
105093
+ validateAllOf(value, schemas, path37, errors, depth) {
104497
105094
  for (const schema of schemas) {
104498
- this.validateValue(value, schema, path36, errors, depth + 1);
105095
+ this.validateValue(value, schema, path37, errors, depth + 1);
104499
105096
  }
104500
105097
  }
104501
105098
  getJsonType(value) {
@@ -104528,20 +105125,20 @@ var SchemaValidatorService = class {
104528
105125
  });
104529
105126
  }
104530
105127
  }
104531
- compareSchemaObjects(oldSchema, newSchema, path36, additions, removals, modifications) {
105128
+ compareSchemaObjects(oldSchema, newSchema, path37, additions, removals, modifications) {
104532
105129
  const oldProps = oldSchema.properties || {};
104533
105130
  const newProps = newSchema.properties || {};
104534
105131
  const oldRequired = new Set(oldSchema.required || []);
104535
105132
  const newRequired = new Set(newSchema.required || []);
104536
105133
  for (const prop of Object.keys(oldProps)) {
104537
105134
  if (!(prop in newProps)) {
104538
- const propPath = path36 ? `${path36}.${prop}` : prop;
105135
+ const propPath = path37 ? `${path37}.${prop}` : prop;
104539
105136
  removals.push(propPath);
104540
105137
  }
104541
105138
  }
104542
105139
  for (const prop of Object.keys(newProps)) {
104543
105140
  if (!(prop in oldProps)) {
104544
- const propPath = path36 ? `${path36}.${prop}` : prop;
105141
+ const propPath = path37 ? `${path37}.${prop}` : prop;
104545
105142
  additions.push(propPath);
104546
105143
  if (newRequired.has(prop)) {
104547
105144
  modifications.push({
@@ -104555,7 +105152,7 @@ var SchemaValidatorService = class {
104555
105152
  }
104556
105153
  if (oldSchema.type !== newSchema.type) {
104557
105154
  modifications.push({
104558
- path: path36 || "root",
105155
+ path: path37 || "root",
104559
105156
  oldType: String(oldSchema.type || "any"),
104560
105157
  newType: String(newSchema.type || "any"),
104561
105158
  isBreaking: true
@@ -104564,7 +105161,7 @@ var SchemaValidatorService = class {
104564
105161
  const newRequiredArray = Array.from(newRequired);
104565
105162
  for (const prop of newRequiredArray) {
104566
105163
  if (!oldRequired.has(prop) && prop in oldProps) {
104567
- const propPath = path36 ? `${path36}.${prop}` : prop;
105164
+ const propPath = path37 ? `${path37}.${prop}` : prop;
104568
105165
  modifications.push({
104569
105166
  path: propPath,
104570
105167
  oldType: "optional",
@@ -105440,7 +106037,7 @@ var VisualTesterService = class {
105440
106037
  const timestamp = /* @__PURE__ */ new Date();
105441
106038
  const urlHash = this.hashUrl(url);
105442
106039
  const viewportKey = `${viewport.width}x${viewport.height}`;
105443
- const path36 = FilePath.create(
106040
+ const path37 = FilePath.create(
105444
106041
  `${this.config.baselineDirectory}/${urlHash}_${viewportKey}_${screenshotId}.png`
105445
106042
  );
105446
106043
  const loadTime = this.estimateLoadTime(url, viewport);
@@ -105456,7 +106053,7 @@ var VisualTesterService = class {
105456
106053
  url,
105457
106054
  viewport,
105458
106055
  timestamp,
105459
- path: path36,
106056
+ path: path37,
105460
106057
  metadata
105461
106058
  };
105462
106059
  await this.storeScreenshotMetadata(screenshot);
@@ -105473,7 +106070,7 @@ var VisualTesterService = class {
105473
106070
  const viewport = options?.viewport || this.config.defaultViewport;
105474
106071
  const screenshotId = v4_default();
105475
106072
  const timestamp = /* @__PURE__ */ new Date();
105476
- const path36 = FilePath.create(
106073
+ const path37 = FilePath.create(
105477
106074
  `${this.config.baselineDirectory}/${screenshotId}.png`
105478
106075
  );
105479
106076
  const metadata = {
@@ -105488,7 +106085,7 @@ var VisualTesterService = class {
105488
106085
  url,
105489
106086
  viewport,
105490
106087
  timestamp,
105491
- path: path36,
106088
+ path: path37,
105492
106089
  metadata
105493
106090
  };
105494
106091
  await this.storeScreenshotMetadata(screenshot);
@@ -109700,12 +110297,12 @@ var VisualAccessibilityCoordinator = class extends BaseDomainCoordinator {
109700
110297
  */
109701
110298
  extractPathFeatures(url) {
109702
110299
  const features = [];
109703
- const path36 = new URL(url).pathname;
110300
+ const path37 = new URL(url).pathname;
109704
110301
  const commonPaths = ["dashboard", "checkout", "login", "profile", "settings", "api", "admin", "search"];
109705
110302
  for (const cp of commonPaths) {
109706
- features.push(path36.includes(cp) ? 1 : 0);
110303
+ features.push(path37.includes(cp) ? 1 : 0);
109707
110304
  }
109708
- const depth = path36.split("/").filter(Boolean).length;
110305
+ const depth = path37.split("/").filter(Boolean).length;
109709
110306
  features.push(depth / 10);
109710
110307
  features.push(url.includes("?") ? 1 : 0);
109711
110308
  features.push(url.startsWith("https://") ? 1 : 0);
@@ -113304,12 +113901,12 @@ var ChaosResilienceCoordinator = class extends BaseDomainCoordinator {
113304
113901
  }
113305
113902
  return experiments;
113306
113903
  }
113307
- generateCriticalPathExperiment(path36, _architecture) {
113308
- const pathName = path36.join("-");
113904
+ generateCriticalPathExperiment(path37, _architecture) {
113905
+ const pathName = path37.join("-");
113309
113906
  return {
113310
113907
  id: v4_default(),
113311
113908
  name: `critical-path-${pathName}`,
113312
- description: `Test critical path: ${path36.join(" -> ")}`,
113909
+ description: `Test critical path: ${path37.join(" -> ")}`,
113313
113910
  hypothesis: {
113314
113911
  statement: "System should handle partial path failure gracefully",
113315
113912
  metrics: [
@@ -113322,7 +113919,7 @@ var ChaosResilienceCoordinator = class extends BaseDomainCoordinator {
113322
113919
  },
113323
113920
  steadyState: {
113324
113921
  description: "All services in path are healthy",
113325
- probes: path36.map((service) => ({
113922
+ probes: path37.map((service) => ({
113326
113923
  name: `${service}-health`,
113327
113924
  type: "http",
113328
113925
  target: `http://${service}/health`,
@@ -113330,7 +113927,7 @@ var ChaosResilienceCoordinator = class extends BaseDomainCoordinator {
113330
113927
  timeout: 5e3
113331
113928
  }))
113332
113929
  },
113333
- faults: path36.slice(0, -1).map((service) => ({
113930
+ faults: path37.slice(0, -1).map((service) => ({
113334
113931
  id: v4_default(),
113335
113932
  type: "latency",
113336
113933
  target: {
@@ -120174,8 +120771,8 @@ var WorkflowOrchestrator = class {
120174
120771
  }
120175
120772
  }
120176
120773
  }
120177
- getValueByPath(obj, path36) {
120178
- const parts = path36.split(".");
120774
+ getValueByPath(obj, path37) {
120775
+ const parts = path37.split(".");
120179
120776
  let current = obj;
120180
120777
  for (const part of parts) {
120181
120778
  if (current === null || current === void 0) return void 0;
@@ -120184,8 +120781,8 @@ var WorkflowOrchestrator = class {
120184
120781
  }
120185
120782
  return current;
120186
120783
  }
120187
- setValueByPath(obj, path36, value) {
120188
- const parts = path36.split(".");
120784
+ setValueByPath(obj, path37, value) {
120785
+ const parts = path37.split(".");
120189
120786
  const dangerousKeys = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
120190
120787
  for (const part of parts) {
120191
120788
  if (dangerousKeys.has(part)) throw new Error(`Invalid path: contains dangerous prototype key`);
@@ -120332,15 +120929,15 @@ var WorkflowOrchestrator = class {
120332
120929
  detectCircularDependencies(steps) {
120333
120930
  const visited = /* @__PURE__ */ new Set();
120334
120931
  const recursionStack = /* @__PURE__ */ new Set();
120335
- const visit = (stepId, path36) => {
120336
- if (recursionStack.has(stepId)) return [...path36, stepId].join(" -> ");
120932
+ const visit = (stepId, path37) => {
120933
+ if (recursionStack.has(stepId)) return [...path37, stepId].join(" -> ");
120337
120934
  if (visited.has(stepId)) return null;
120338
120935
  visited.add(stepId);
120339
120936
  recursionStack.add(stepId);
120340
120937
  const step = steps.find((s70) => s70.id === stepId);
120341
120938
  if (step?.dependsOn) {
120342
120939
  for (const dep of step.dependsOn) {
120343
- const result = visit(dep, [...path36, stepId]);
120940
+ const result = visit(dep, [...path37, stepId]);
120344
120941
  if (result) return result;
120345
120942
  }
120346
120943
  }
@@ -129311,8 +129908,8 @@ var CrossPhaseHookExecutor = class {
129311
129908
  try {
129312
129909
  const parts = condition.split(/\s*(>|<|>=|<=|==|!=)\s*/);
129313
129910
  if (parts.length !== 3) return false;
129314
- const [path36, op, value] = parts;
129315
- const actual = this.getValueFromPath(context2, path36);
129911
+ const [path37, op, value] = parts;
129912
+ const actual = this.getValueFromPath(context2, path37);
129316
129913
  const expected = isNaN(Number(value)) ? value : Number(value);
129317
129914
  const actualNum = typeof actual === "number" ? actual : Number(actual);
129318
129915
  const expectedNum = typeof expected === "number" ? expected : Number(expected);
@@ -129336,8 +129933,8 @@ var CrossPhaseHookExecutor = class {
129336
129933
  return false;
129337
129934
  }
129338
129935
  }
129339
- getValueFromPath(obj, path36) {
129340
- return path36.split(".").reduce((curr, key) => {
129936
+ getValueFromPath(obj, path37) {
129937
+ return path37.split(".").reduce((curr, key) => {
129341
129938
  if (curr && typeof curr === "object" && key in curr) {
129342
129939
  return curr[key];
129343
129940
  }
@@ -129346,8 +129943,8 @@ var CrossPhaseHookExecutor = class {
129346
129943
  }
129347
129944
  extractFromContext(extract, context2) {
129348
129945
  const result = {};
129349
- for (const [key, path36] of Object.entries(extract)) {
129350
- result[key] = this.getValueFromPath(context2, path36);
129946
+ for (const [key, path37] of Object.entries(extract)) {
129947
+ result[key] = this.getValueFromPath(context2, path37);
129351
129948
  }
129352
129949
  return result;
129353
129950
  }
@@ -132189,6 +132786,9 @@ var TokenMetricsCollectorImpl = class _TokenMetricsCollectorImpl {
132189
132786
  if (config) {
132190
132787
  this.costConfig = { ...DEFAULT_COST_CONFIG, ...config };
132191
132788
  }
132789
+ this.initializeDb().catch(() => {
132790
+ });
132791
+ this.startAutoSave();
132192
132792
  }
132193
132793
  /**
132194
132794
  * Set cost configuration for token pricing.
@@ -132244,6 +132844,7 @@ var TokenMetricsCollectorImpl = class _TokenMetricsCollectorImpl {
132244
132844
  this.totalTokensSaved += tokensSaved;
132245
132845
  }
132246
132846
  this.isDirty = true;
132847
+ this.maybePersistToKv();
132247
132848
  }
132248
132849
  /**
132249
132850
  * Record pattern reuse for a task (tokens saved by skipping LLM call).
@@ -132516,8 +133117,8 @@ var TokenMetricsCollectorImpl = class _TokenMetricsCollectorImpl {
132516
133117
  * Save metrics to persistent storage
132517
133118
  */
132518
133119
  async save() {
132519
- const fs31 = await import("fs");
132520
- const path36 = await import("path");
133120
+ const fs32 = await import("fs");
133121
+ const path37 = await import("path");
132521
133122
  const data = {
132522
133123
  version: "1.0.0",
132523
133124
  sessionId: this.sessionId,
@@ -132531,26 +133132,26 @@ var TokenMetricsCollectorImpl = class _TokenMetricsCollectorImpl {
132531
133132
  },
132532
133133
  lastSavedAt: Date.now()
132533
133134
  };
132534
- const filePath = path36.resolve(this.persistenceConfig.filePath);
132535
- const dirPath = path36.dirname(filePath);
132536
- if (!fs31.existsSync(dirPath)) {
132537
- fs31.mkdirSync(dirPath, { recursive: true });
133135
+ const filePath = path37.resolve(this.persistenceConfig.filePath);
133136
+ const dirPath = path37.dirname(filePath);
133137
+ if (!fs32.existsSync(dirPath)) {
133138
+ fs32.mkdirSync(dirPath, { recursive: true });
132538
133139
  }
132539
- fs31.writeFileSync(filePath, JSON.stringify(data, null, 2));
133140
+ fs32.writeFileSync(filePath, JSON.stringify(data, null, 2));
132540
133141
  this.isDirty = false;
132541
133142
  }
132542
133143
  /**
132543
133144
  * Load metrics from persistent storage
132544
133145
  */
132545
133146
  async load() {
132546
- const fs31 = await import("fs");
132547
- const path36 = await import("path");
132548
- const filePath = path36.resolve(this.persistenceConfig.filePath);
132549
- if (!fs31.existsSync(filePath)) {
133147
+ const fs32 = await import("fs");
133148
+ const path37 = await import("path");
133149
+ const filePath = path37.resolve(this.persistenceConfig.filePath);
133150
+ if (!fs32.existsSync(filePath)) {
132550
133151
  return false;
132551
133152
  }
132552
133153
  try {
132553
- const content = fs31.readFileSync(filePath, "utf-8");
133154
+ const content = fs32.readFileSync(filePath, "utf-8");
132554
133155
  const data = safeJsonParse(content);
132555
133156
  if (!data.version || !data.version.startsWith("1.")) {
132556
133157
  console.warn("[TokenMetricsCollector] Incompatible data version, skipping load");
@@ -133718,9 +134319,9 @@ function validatePipeline(pipeline11) {
133718
134319
  function detectCircularDependencies(stages) {
133719
134320
  const visited = /* @__PURE__ */ new Set();
133720
134321
  const recursionStack = /* @__PURE__ */ new Set();
133721
- const visit = (stageName, path36) => {
134322
+ const visit = (stageName, path37) => {
133722
134323
  if (recursionStack.has(stageName)) {
133723
- return [...path36, stageName].join(" -> ");
134324
+ return [...path37, stageName].join(" -> ");
133724
134325
  }
133725
134326
  if (visited.has(stageName)) {
133726
134327
  return null;
@@ -133730,7 +134331,7 @@ function detectCircularDependencies(stages) {
133730
134331
  const stage = stages.find((s70) => s70.name === stageName);
133731
134332
  if (stage?.depends_on) {
133732
134333
  for (const dep of stage.depends_on) {
133733
- const result = visit(dep, [...path36, stageName]);
134334
+ const result = visit(dep, [...path37, stageName]);
133734
134335
  if (result) return result;
133735
134336
  }
133736
134337
  }
@@ -133850,7 +134451,7 @@ init_safe_json();
133850
134451
  import { randomUUID as randomUUID17 } from "crypto";
133851
134452
  import * as fs18 from "fs";
133852
134453
  import * as path19 from "path";
133853
- import * as os3 from "os";
134454
+ import * as os4 from "os";
133854
134455
  init_safe_json();
133855
134456
  init_error_utils();
133856
134457
  var DEFAULT_CONFIG_DIR = ".aqe";
@@ -133877,7 +134478,7 @@ var PersistentScheduler = class {
133877
134478
  * Prevents writing to arbitrary filesystem locations
133878
134479
  */
133879
134480
  validateSchedulesPath(schedulesPath) {
133880
- const homeDir = os3.homedir();
134481
+ const homeDir = os4.homedir();
133881
134482
  const resolvedPath = path19.resolve(schedulesPath);
133882
134483
  const resolvedHome = path19.resolve(homeDir);
133883
134484
  if (resolvedPath.startsWith(resolvedHome + path19.sep) || resolvedPath === resolvedHome) {
@@ -133888,7 +134489,7 @@ var PersistentScheduler = class {
133888
134489
  if (resolvedPath.startsWith(resolvedCwd + path19.sep) || resolvedPath === resolvedCwd) {
133889
134490
  return;
133890
134491
  }
133891
- const tmpDir = os3.tmpdir();
134492
+ const tmpDir = os4.tmpdir();
133892
134493
  const resolvedTmp = path19.resolve(tmpDir);
133893
134494
  if (resolvedPath.startsWith(resolvedTmp + path19.sep) || resolvedPath === resolvedTmp) {
133894
134495
  return;
@@ -133901,7 +134502,7 @@ var PersistentScheduler = class {
133901
134502
  * Get the default path for schedules.json
133902
134503
  */
133903
134504
  getDefaultSchedulesPath() {
133904
- const homeDir = os3.homedir();
134505
+ const homeDir = os4.homedir();
133905
134506
  return path19.join(homeDir, DEFAULT_CONFIG_DIR, SCHEDULES_FILE);
133906
134507
  }
133907
134508
  /**
@@ -134351,7 +134952,7 @@ var ALL_DOMAINS2 = [
134351
134952
  "enterprise-integration"
134352
134953
  ];
134353
134954
  function getAQEVersion() {
134354
- return true ? "3.7.14" : "3.0.0";
134955
+ return true ? "3.7.16" : "3.0.0";
134355
134956
  }
134356
134957
  function createDefaultConfig(projectName, projectRoot) {
134357
134958
  return {
@@ -137135,9 +137736,9 @@ var N8nInstaller = class {
137135
137736
  // NPM package location
137136
137737
  join24(__dirname2, "../../assets/agents/n8n")
137137
137738
  ];
137138
- for (const path36 of possiblePaths) {
137139
- if (existsSync20(path36)) {
137140
- return path36;
137739
+ for (const path37 of possiblePaths) {
137740
+ if (existsSync20(path37)) {
137741
+ return path37;
137141
137742
  }
137142
137743
  }
137143
137744
  return join24(process.cwd(), ".claude/agents/n8n");
@@ -137151,9 +137752,9 @@ var N8nInstaller = class {
137151
137752
  join24(process.cwd(), ".claude/skills"),
137152
137753
  join24(__dirname2, "../../assets/skills")
137153
137754
  ];
137154
- for (const path36 of possiblePaths) {
137155
- if (existsSync20(path36)) {
137156
- return path36;
137755
+ for (const path37 of possiblePaths) {
137756
+ if (existsSync20(path37)) {
137757
+ return path37;
137157
137758
  }
137158
137759
  }
137159
137760
  return join24(process.cwd(), ".claude/skills");
@@ -142556,6 +143157,7 @@ function createProtocolHandler(cleanupAndExit2, ensureInitialized2) {
142556
143157
  }
142557
143158
 
142558
143159
  // src/cli/handlers/brain-handler.ts
143160
+ init_unified_memory();
142559
143161
  import path20 from "path";
142560
143162
  import chalk9 from "chalk";
142561
143163
 
@@ -143594,10 +144196,10 @@ function resolveFormat(format) {
143594
144196
  }
143595
144197
  return isRvfAvailable() ? "rvf" : "jsonl";
143596
144198
  }
143597
- function detectImportFormat(path36, format) {
144199
+ function detectImportFormat(path37, format) {
143598
144200
  if (format === "rvf") return "rvf";
143599
144201
  if (format === "jsonl") return "jsonl";
143600
- if (path36.endsWith(".rvf")) return "rvf";
144202
+ if (path37.endsWith(".rvf")) return "rvf";
143601
144203
  return "jsonl";
143602
144204
  }
143603
144205
 
@@ -143823,7 +144425,7 @@ Examples:
143823
144425
  }
143824
144426
  };
143825
144427
  function defaultDbPath() {
143826
- return path20.join(process.cwd(), ".agentic-qe", "memory.db");
144428
+ return path20.join(findProjectRoot(), ".agentic-qe", "memory.db");
143827
144429
  }
143828
144430
  function formatBytes(bytes) {
143829
144431
  if (bytes < 1024) return `${bytes} B`;
@@ -143936,8 +144538,8 @@ function createTestCommand(context2, cleanupAndExit2, ensureInitialized2) {
143936
144538
  console.log(chalk10.red("Test generation domain not available"));
143937
144539
  return;
143938
144540
  }
143939
- const path36 = await import("path");
143940
- const targetPath = path36.resolve(target || ".");
144541
+ const path37 = await import("path");
144542
+ const targetPath = path37.resolve(target || ".");
143941
144543
  const sourceFiles = walkSourceFiles(targetPath, { includeTests: false });
143942
144544
  if (sourceFiles.length === 0) {
143943
144545
  console.log(chalk10.yellow("No source files found"));
@@ -143973,14 +144575,14 @@ function createTestCommand(context2, cleanupAndExit2, ensureInitialized2) {
143973
144575
  console.log(chalk10.cyan(" Tests:"));
143974
144576
  for (const test of generated.tests.slice(0, 10)) {
143975
144577
  console.log(` ${chalk10.white(test.name)}`);
143976
- console.log(chalk10.gray(` Source: ${path36.basename(test.sourceFile)}`));
144578
+ console.log(chalk10.gray(` Source: ${path37.basename(test.sourceFile)}`));
143977
144579
  console.log(chalk10.gray(` Assertions: ${test.assertions}`));
143978
144580
  if (test.testCode) {
143979
144581
  console.log(chalk10.gray(` Test File: ${test.testFile}`));
143980
- const fs31 = await import("fs");
143981
- const testDir = path36.dirname(test.testFile);
143982
- fs31.mkdirSync(testDir, { recursive: true });
143983
- fs31.writeFileSync(test.testFile, test.testCode, "utf-8");
144582
+ const fs32 = await import("fs");
144583
+ const testDir = path37.dirname(test.testFile);
144584
+ fs32.mkdirSync(testDir, { recursive: true });
144585
+ fs32.writeFileSync(test.testFile, test.testCode, "utf-8");
143984
144586
  console.log(chalk10.green(` Written to: ${test.testFile}`));
143985
144587
  }
143986
144588
  }
@@ -144005,8 +144607,8 @@ function createTestCommand(context2, cleanupAndExit2, ensureInitialized2) {
144005
144607
  console.log(chalk10.red("Test execution domain not available"));
144006
144608
  return;
144007
144609
  }
144008
- const path36 = await import("path");
144009
- const targetPath = path36.resolve(target || ".");
144610
+ const path37 = await import("path");
144611
+ const targetPath = path37.resolve(target || ".");
144010
144612
  const testFiles = walkSourceFiles(targetPath, { testsOnly: true });
144011
144613
  if (testFiles.length === 0) {
144012
144614
  console.log(chalk10.yellow("No test files found"));
@@ -144362,8 +144964,8 @@ var WizardFormat = class {
144362
144964
  /**
144363
144965
  * Format a path relative to cwd
144364
144966
  */
144365
- static relativePath(path36, cwd) {
144366
- return relative7(cwd, path36) || ".";
144967
+ static relativePath(path37, cwd) {
144968
+ return relative7(cwd, path37) || ".";
144367
144969
  }
144368
144970
  /**
144369
144971
  * Format a boolean as Yes/No
@@ -145179,8 +145781,8 @@ function createCoverageCommand(context2, cleanupAndExit2, ensureInitialized2) {
145179
145781
  console.log(chalk14.red("Coverage analysis domain not available"));
145180
145782
  return;
145181
145783
  }
145182
- const path36 = await import("path");
145183
- const targetPath = path36.resolve(analyzeTarget);
145784
+ const path37 = await import("path");
145785
+ const targetPath = path37.resolve(analyzeTarget);
145184
145786
  const sourceFiles = walkSourceFiles(targetPath, { includeTests: false });
145185
145787
  if (sourceFiles.length === 0) {
145186
145788
  console.log(chalk14.yellow("No source files found"));
@@ -145502,8 +146104,8 @@ function createSecurityCommand(context2, cleanupAndExit2, ensureInitialized2) {
145502
146104
  console.log(chalk16.red("Security domain not available"));
145503
146105
  return;
145504
146106
  }
145505
- const path36 = await import("path");
145506
- const targetPath = path36.resolve(options.target);
146107
+ const path37 = await import("path");
146108
+ const targetPath = path37.resolve(options.target);
145507
146109
  const files = walkSourceFiles(targetPath, { includeTests: true });
145508
146110
  if (files.length === 0) {
145509
146111
  console.log(chalk16.yellow("No files found to scan"));
@@ -145616,13 +146218,13 @@ function createCodeCommand(context2, cleanupAndExit2, ensureInitialized2) {
145616
146218
  console.log(chalk17.red("Code intelligence domain not available"));
145617
146219
  return;
145618
146220
  }
145619
- const path36 = await import("path");
146221
+ const path37 = await import("path");
145620
146222
  const format = options.format || "text";
145621
146223
  if (action === "index") {
145622
146224
  console.log(chalk17.blue(`
145623
146225
  Indexing codebase at ${target || "."}...
145624
146226
  `));
145625
- const targetPath = path36.resolve(target || ".");
146227
+ const targetPath = path37.resolve(target || ".");
145626
146228
  const paths = walkSourceFiles(targetPath, {
145627
146229
  includeTests: options.includeTests || false
145628
146230
  });
@@ -145691,7 +146293,7 @@ function createCodeCommand(context2, cleanupAndExit2, ensureInitialized2) {
145691
146293
  console.log(chalk17.blue(`
145692
146294
  Analyzing impact for ${target || "recent changes"}...
145693
146295
  `));
145694
- const targetPath = path36.resolve(target || ".");
146296
+ const targetPath = path37.resolve(target || ".");
145695
146297
  const changedFiles = walkSourceFiles(targetPath, { maxDepth: 2 }).slice(0, 10);
145696
146298
  const result = await codeAPI.analyzeImpact({
145697
146299
  changedFiles,
@@ -145741,7 +146343,7 @@ function createCodeCommand(context2, cleanupAndExit2, ensureInitialized2) {
145741
146343
  console.log(chalk17.blue(`
145742
146344
  Mapping dependencies for ${target || "."}...
145743
146345
  `));
145744
- const targetPath = path36.resolve(target || ".");
146346
+ const targetPath = path37.resolve(target || ".");
145745
146347
  const files = walkSourceFiles(targetPath, { maxDepth: 2 }).slice(0, 50);
145746
146348
  const result = await codeAPI.mapDependencies({
145747
146349
  files,
@@ -145897,32 +146499,32 @@ var v3Agents = [
145897
146499
  function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
145898
146500
  const migrateCmd = new Command6("migrate").description("V2-to-V3 migration tools with agent compatibility (ADR-048)");
145899
146501
  migrateCmd.command("run").description("Run full migration from v2 to v3").option("--dry-run", "Preview migration without making changes").option("--backup", "Create backup before migration (recommended)", true).option("--skip-memory", "Skip memory database migration").option("--skip-patterns", "Skip pattern migration").option("--skip-config", "Skip configuration migration").option("--skip-agents", "Skip agent name migration").option("--target <component>", "Migrate specific component (agents, skills, config, memory)").option("--force", "Force migration even if v3 already exists").action(async (options) => {
145900
- const fs31 = await import("fs");
145901
- const path36 = await import("path");
146502
+ const fs32 = await import("fs");
146503
+ const path37 = await import("path");
145902
146504
  console.log(chalk18.blue("\n V2 to V3 Migration (ADR-048)\n"));
145903
146505
  const cwd = process.cwd();
145904
- const v2Dir = path36.join(cwd, ".agentic-qe");
145905
- const v3Dir = path36.join(cwd, ".aqe");
145906
- const claudeAgentDir = path36.join(cwd, ".claude", "agents");
146506
+ const v2Dir = path37.join(cwd, ".agentic-qe");
146507
+ const v3Dir = path37.join(cwd, ".aqe");
146508
+ const claudeAgentDir = path37.join(cwd, ".claude", "agents");
145907
146509
  console.log(chalk18.white("1. Detecting v2 installation..."));
145908
- const hasV2Dir = fs31.existsSync(v2Dir);
145909
- const hasClaudeAgents = fs31.existsSync(claudeAgentDir);
146510
+ const hasV2Dir = fs32.existsSync(v2Dir);
146511
+ const hasClaudeAgents = fs32.existsSync(claudeAgentDir);
145910
146512
  if (!hasV2Dir && !hasClaudeAgents) {
145911
146513
  console.log(chalk18.yellow(" ! No v2 installation found"));
145912
146514
  console.log(chalk18.gray(" This might be a fresh project. Use `aqe init` instead."));
145913
146515
  await cleanupAndExit2(0);
145914
146516
  }
145915
146517
  const v2Files = {
145916
- memoryDb: path36.join(v2Dir, "memory.db"),
145917
- config: path36.join(v2Dir, "config.json"),
145918
- patterns: path36.join(v2Dir, "patterns")
146518
+ memoryDb: path37.join(v2Dir, "memory.db"),
146519
+ config: path37.join(v2Dir, "config.json"),
146520
+ patterns: path37.join(v2Dir, "patterns")
145919
146521
  };
145920
- const hasMemory = hasV2Dir && fs31.existsSync(v2Files.memoryDb);
145921
- const hasConfig = hasV2Dir && fs31.existsSync(v2Files.config);
145922
- const hasPatterns = hasV2Dir && fs31.existsSync(v2Files.patterns);
146522
+ const hasMemory = hasV2Dir && fs32.existsSync(v2Files.memoryDb);
146523
+ const hasConfig = hasV2Dir && fs32.existsSync(v2Files.config);
146524
+ const hasPatterns = hasV2Dir && fs32.existsSync(v2Files.patterns);
145923
146525
  const agentsToMigrate = [];
145924
146526
  if (hasClaudeAgents) {
145925
- const files = fs31.readdirSync(claudeAgentDir);
146527
+ const files = fs32.readdirSync(claudeAgentDir);
145926
146528
  for (const file of files) {
145927
146529
  if (file.endsWith(".md") && file.startsWith("qe-")) {
145928
146530
  const agentName = file.replace(".md", "");
@@ -145939,7 +146541,7 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
145939
146541
  console.log(chalk18.gray(` Agents to migrate: ${agentsToMigrate.length}
145940
146542
  `));
145941
146543
  console.log(chalk18.white("2. Checking v3 status..."));
145942
- if (fs31.existsSync(v3Dir) && !options.force) {
146544
+ if (fs32.existsSync(v3Dir) && !options.force) {
145943
146545
  console.log(chalk18.yellow(" ! v3 directory already exists at .aqe/"));
145944
146546
  console.log(chalk18.gray(" Use --force to overwrite existing v3 installation."));
145945
146547
  await cleanupAndExit2(1);
@@ -145948,14 +146550,14 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
145948
146550
  if (options.dryRun) {
145949
146551
  console.log(chalk18.blue(" Dry Run - Migration Plan:\n"));
145950
146552
  if (!options.skipMemory && hasMemory) {
145951
- const stats = fs31.statSync(v2Files.memoryDb);
146553
+ const stats = fs32.statSync(v2Files.memoryDb);
145952
146554
  console.log(chalk18.gray(` - Migrate memory.db (${(stats.size / 1024).toFixed(1)} KB)`));
145953
146555
  }
145954
146556
  if (!options.skipConfig && hasConfig) {
145955
146557
  console.log(chalk18.gray(" - Convert config.json to v3 format"));
145956
146558
  }
145957
146559
  if (!options.skipPatterns && hasPatterns) {
145958
- const patternFiles = fs31.readdirSync(v2Files.patterns);
146560
+ const patternFiles = fs32.readdirSync(v2Files.patterns);
145959
146561
  console.log(chalk18.gray(` - Migrate ${patternFiles.length} pattern files`));
145960
146562
  }
145961
146563
  if (!options.skipAgents && agentsToMigrate.length > 0) {
@@ -145970,22 +146572,22 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
145970
146572
  }
145971
146573
  if (options.backup) {
145972
146574
  console.log(chalk18.white("3. Creating backup..."));
145973
- const backupDir = path36.join(cwd, ".aqe-backup", `backup-${Date.now()}`);
146575
+ const backupDir = path37.join(cwd, ".aqe-backup", `backup-${Date.now()}`);
145974
146576
  try {
145975
- fs31.mkdirSync(backupDir, { recursive: true });
146577
+ fs32.mkdirSync(backupDir, { recursive: true });
145976
146578
  const copyDir = (src, dest) => {
145977
- if (!fs31.existsSync(src)) return;
145978
- if (fs31.statSync(src).isDirectory()) {
145979
- fs31.mkdirSync(dest, { recursive: true });
145980
- for (const file of fs31.readdirSync(src)) {
145981
- copyDir(path36.join(src, file), path36.join(dest, file));
146579
+ if (!fs32.existsSync(src)) return;
146580
+ if (fs32.statSync(src).isDirectory()) {
146581
+ fs32.mkdirSync(dest, { recursive: true });
146582
+ for (const file of fs32.readdirSync(src)) {
146583
+ copyDir(path37.join(src, file), path37.join(dest, file));
145982
146584
  }
145983
146585
  } else {
145984
- fs31.copyFileSync(src, dest);
146586
+ fs32.copyFileSync(src, dest);
145985
146587
  }
145986
146588
  };
145987
- if (hasV2Dir) copyDir(v2Dir, path36.join(backupDir, ".agentic-qe"));
145988
- if (hasClaudeAgents) copyDir(claudeAgentDir, path36.join(backupDir, ".claude", "agents"));
146589
+ if (hasV2Dir) copyDir(v2Dir, path37.join(backupDir, ".agentic-qe"));
146590
+ if (hasClaudeAgents) copyDir(claudeAgentDir, path37.join(backupDir, ".claude", "agents"));
145989
146591
  console.log(chalk18.green(` * Backup created at .aqe-backup/
145990
146592
  `));
145991
146593
  } catch (err3) {
@@ -145998,11 +146600,11 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
145998
146600
  if (!options.target || options.target === "config" || options.target === "memory") {
145999
146601
  console.log(chalk18.white("4. Creating v3 directory structure..."));
146000
146602
  try {
146001
- fs31.mkdirSync(v3Dir, { recursive: true });
146002
- fs31.mkdirSync(path36.join(v3Dir, "agentdb"), { recursive: true });
146003
- fs31.mkdirSync(path36.join(v3Dir, "reasoning-bank"), { recursive: true });
146004
- fs31.mkdirSync(path36.join(v3Dir, "cache"), { recursive: true });
146005
- fs31.mkdirSync(path36.join(v3Dir, "logs"), { recursive: true });
146603
+ fs32.mkdirSync(v3Dir, { recursive: true });
146604
+ fs32.mkdirSync(path37.join(v3Dir, "agentdb"), { recursive: true });
146605
+ fs32.mkdirSync(path37.join(v3Dir, "reasoning-bank"), { recursive: true });
146606
+ fs32.mkdirSync(path37.join(v3Dir, "cache"), { recursive: true });
146607
+ fs32.mkdirSync(path37.join(v3Dir, "logs"), { recursive: true });
146006
146608
  console.log(chalk18.green(" * Directory structure created\n"));
146007
146609
  } catch (err3) {
146008
146610
  console.log(chalk18.red(` x Failed: ${err3}
@@ -146013,17 +146615,17 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
146013
146615
  if ((!options.target || options.target === "memory") && !options.skipMemory && hasMemory) {
146014
146616
  console.log(chalk18.white("5. Migrating memory database..."));
146015
146617
  try {
146016
- const destDb = path36.join(v3Dir, "agentdb", "memory.db");
146017
- fs31.copyFileSync(v2Files.memoryDb, destDb);
146018
- const indexFile = path36.join(v3Dir, "agentdb", "index.json");
146019
- fs31.writeFileSync(indexFile, JSON.stringify({
146618
+ const destDb = path37.join(v3Dir, "agentdb", "memory.db");
146619
+ fs32.copyFileSync(v2Files.memoryDb, destDb);
146620
+ const indexFile = path37.join(v3Dir, "agentdb", "index.json");
146621
+ fs32.writeFileSync(indexFile, JSON.stringify({
146020
146622
  version: "3.0.0",
146021
146623
  migratedFrom: "v2",
146022
146624
  migratedAt: (/* @__PURE__ */ new Date()).toISOString(),
146023
146625
  hnswEnabled: true,
146024
146626
  vectorDimensions: 384
146025
146627
  }, null, 2));
146026
- const stats = fs31.statSync(v2Files.memoryDb);
146628
+ const stats = fs32.statSync(v2Files.memoryDb);
146027
146629
  console.log(chalk18.green(` * Memory database migrated (${(stats.size / 1024).toFixed(1)} KB)
146028
146630
  `));
146029
146631
  } catch (err3) {
@@ -146040,7 +146642,7 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
146040
146642
  if ((!options.target || options.target === "config") && !options.skipConfig && hasConfig) {
146041
146643
  console.log(chalk18.white("6. Migrating configuration..."));
146042
146644
  try {
146043
- const v2ConfigRaw = fs31.readFileSync(v2Files.config, "utf-8");
146645
+ const v2ConfigRaw = fs32.readFileSync(v2Files.config, "utf-8");
146044
146646
  const v2Config = parseJsonFile(v2ConfigRaw, v2Files.config);
146045
146647
  const v3Config = {
146046
146648
  version: "3.0.0",
@@ -146076,8 +146678,8 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
146076
146678
  migrationDate: (/* @__PURE__ */ new Date()).toISOString()
146077
146679
  }
146078
146680
  };
146079
- const destConfig = path36.join(v3Dir, "config.json");
146080
- fs31.writeFileSync(destConfig, JSON.stringify(v3Config, null, 2));
146681
+ const destConfig = path37.join(v3Dir, "config.json");
146682
+ fs32.writeFileSync(destConfig, JSON.stringify(v3Config, null, 2));
146081
146683
  console.log(chalk18.green(" * Configuration migrated\n"));
146082
146684
  } catch (err3) {
146083
146685
  console.log(chalk18.red(` x Config migration failed: ${err3}
@@ -146093,18 +146695,18 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
146093
146695
  if ((!options.target || options.target === "memory") && !options.skipPatterns && hasPatterns) {
146094
146696
  console.log(chalk18.white("7. Migrating patterns to ReasoningBank..."));
146095
146697
  try {
146096
- const patternFiles = fs31.readdirSync(v2Files.patterns);
146698
+ const patternFiles = fs32.readdirSync(v2Files.patterns);
146097
146699
  let migratedCount = 0;
146098
146700
  for (const file of patternFiles) {
146099
- const srcPath = path36.join(v2Files.patterns, file);
146100
- const destPath = path36.join(v3Dir, "reasoning-bank", file);
146101
- if (fs31.statSync(srcPath).isFile()) {
146102
- fs31.copyFileSync(srcPath, destPath);
146701
+ const srcPath = path37.join(v2Files.patterns, file);
146702
+ const destPath = path37.join(v3Dir, "reasoning-bank", file);
146703
+ if (fs32.statSync(srcPath).isFile()) {
146704
+ fs32.copyFileSync(srcPath, destPath);
146103
146705
  migratedCount++;
146104
146706
  }
146105
146707
  }
146106
- const indexPath = path36.join(v3Dir, "reasoning-bank", "index.json");
146107
- fs31.writeFileSync(indexPath, JSON.stringify({
146708
+ const indexPath = path37.join(v3Dir, "reasoning-bank", "index.json");
146709
+ fs32.writeFileSync(indexPath, JSON.stringify({
146108
146710
  version: "3.0.0",
146109
146711
  migratedFrom: "v2",
146110
146712
  migratedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -146125,17 +146727,17 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
146125
146727
  if ((!options.target || options.target === "agents") && !options.skipAgents && agentsToMigrate.length > 0) {
146126
146728
  console.log(chalk18.white("8. Migrating agent names (ADR-048)..."));
146127
146729
  let migratedAgents = 0;
146128
- const deprecatedDir = path36.join(claudeAgentDir, "deprecated");
146129
- if (!fs31.existsSync(deprecatedDir)) {
146130
- fs31.mkdirSync(deprecatedDir, { recursive: true });
146730
+ const deprecatedDir = path37.join(claudeAgentDir, "deprecated");
146731
+ if (!fs32.existsSync(deprecatedDir)) {
146732
+ fs32.mkdirSync(deprecatedDir, { recursive: true });
146131
146733
  }
146132
146734
  for (const v2Name of agentsToMigrate) {
146133
146735
  const v3Name = resolveAgentName(v2Name);
146134
- const v2FilePath = path36.join(claudeAgentDir, `${v2Name}.md`);
146135
- const v3FilePath = path36.join(claudeAgentDir, `${v3Name}.md`);
146136
- const deprecatedPath = path36.join(deprecatedDir, `${v2Name}.md.v2`);
146736
+ const v2FilePath = path37.join(claudeAgentDir, `${v2Name}.md`);
146737
+ const v3FilePath = path37.join(claudeAgentDir, `${v3Name}.md`);
146738
+ const deprecatedPath = path37.join(deprecatedDir, `${v2Name}.md.v2`);
146137
146739
  try {
146138
- const content = fs31.readFileSync(v2FilePath, "utf-8");
146740
+ const content = fs32.readFileSync(v2FilePath, "utf-8");
146139
146741
  const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
146140
146742
  if (!frontmatterMatch) {
146141
146743
  console.log(chalk18.yellow(` ! ${v2Name}: No frontmatter found, skipping`));
@@ -146163,8 +146765,8 @@ v2_compat:
146163
146765
  const newContent = `---
146164
146766
  ${newFrontmatter}
146165
146767
  ---${body}`;
146166
- fs31.writeFileSync(v3FilePath, newContent, "utf-8");
146167
- fs31.renameSync(v2FilePath, deprecatedPath);
146768
+ fs32.writeFileSync(v3FilePath, newContent, "utf-8");
146769
+ fs32.renameSync(v2FilePath, deprecatedPath);
146168
146770
  console.log(chalk18.gray(` ${v2Name} -> ${v3Name}`));
146169
146771
  migratedAgents++;
146170
146772
  } catch (err3) {
@@ -146185,10 +146787,10 @@ ${newFrontmatter}
146185
146787
  }
146186
146788
  console.log(chalk18.white("9. Validating migration..."));
146187
146789
  const validationResults = {
146188
- v3DirExists: fs31.existsSync(v3Dir),
146189
- configExists: fs31.existsSync(path36.join(v3Dir, "config.json")),
146190
- agentdbExists: fs31.existsSync(path36.join(v3Dir, "agentdb")),
146191
- reasoningBankExists: fs31.existsSync(path36.join(v3Dir, "reasoning-bank"))
146790
+ v3DirExists: fs32.existsSync(v3Dir),
146791
+ configExists: fs32.existsSync(path37.join(v3Dir, "config.json")),
146792
+ agentdbExists: fs32.existsSync(path37.join(v3Dir, "agentdb")),
146793
+ reasoningBankExists: fs32.existsSync(path37.join(v3Dir, "reasoning-bank"))
146192
146794
  };
146193
146795
  const allValid = Object.values(validationResults).every((v65) => v65);
146194
146796
  if (allValid) {
@@ -146208,18 +146810,18 @@ ${newFrontmatter}
146208
146810
  await cleanupAndExit2(0);
146209
146811
  });
146210
146812
  migrateCmd.command("status").description("Check migration status of current project").option("--json", "Output as JSON").action(async (options) => {
146211
- const fs31 = await import("fs");
146212
- const path36 = await import("path");
146813
+ const fs32 = await import("fs");
146814
+ const path37 = await import("path");
146213
146815
  const cwd = process.cwd();
146214
- const v2Dir = path36.join(cwd, ".agentic-qe");
146215
- const v3Dir = path36.join(cwd, ".aqe");
146216
- const claudeAgentDir = path36.join(cwd, ".claude", "agents");
146217
- const isV2Project = fs31.existsSync(v2Dir);
146218
- const isV3Project = fs31.existsSync(v3Dir);
146816
+ const v2Dir = path37.join(cwd, ".agentic-qe");
146817
+ const v3Dir = path37.join(cwd, ".aqe");
146818
+ const claudeAgentDir = path37.join(cwd, ".claude", "agents");
146819
+ const isV2Project = fs32.existsSync(v2Dir);
146820
+ const isV3Project = fs32.existsSync(v3Dir);
146219
146821
  const agentsToMigrate = [];
146220
146822
  const agentsMigrated = [];
146221
- if (fs31.existsSync(claudeAgentDir)) {
146222
- const files = fs31.readdirSync(claudeAgentDir);
146823
+ if (fs32.existsSync(claudeAgentDir)) {
146824
+ const files = fs32.readdirSync(claudeAgentDir);
146223
146825
  for (const file of files) {
146224
146826
  if (file.endsWith(".md") && file.startsWith("qe-")) {
146225
146827
  const agentName = file.replace(".md", "");
@@ -146268,15 +146870,15 @@ ${newFrontmatter}
146268
146870
  await cleanupAndExit2(0);
146269
146871
  });
146270
146872
  migrateCmd.command("verify").description("Verify migration integrity").option("--fix", "Attempt to fix issues automatically").action(async (options) => {
146271
- const fs31 = await import("fs");
146272
- const path36 = await import("path");
146873
+ const fs32 = await import("fs");
146874
+ const path37 = await import("path");
146273
146875
  console.log(chalk18.bold("\n Verifying Migration...\n"));
146274
146876
  const cwd = process.cwd();
146275
- const v3Dir = path36.join(cwd, ".aqe");
146276
- const claudeAgentDir = path36.join(cwd, ".claude", "agents");
146877
+ const v3Dir = path37.join(cwd, ".aqe");
146878
+ const claudeAgentDir = path37.join(cwd, ".claude", "agents");
146277
146879
  const deprecatedInUse = [];
146278
- if (fs31.existsSync(claudeAgentDir)) {
146279
- const files = fs31.readdirSync(claudeAgentDir);
146880
+ if (fs32.existsSync(claudeAgentDir)) {
146881
+ const files = fs32.readdirSync(claudeAgentDir);
146280
146882
  for (const file of files) {
146281
146883
  if (file.endsWith(".md") && file.startsWith("qe-")) {
146282
146884
  const agentName = file.replace(".md", "");
@@ -146289,8 +146891,8 @@ ${newFrontmatter}
146289
146891
  const checks = [
146290
146892
  {
146291
146893
  name: "V3 Directory",
146292
- passed: fs31.existsSync(v3Dir),
146293
- message: fs31.existsSync(v3Dir) ? "Exists" : "Missing .aqe/"
146894
+ passed: fs32.existsSync(v3Dir),
146895
+ message: fs32.existsSync(v3Dir) ? "Exists" : "Missing .aqe/"
146294
146896
  },
146295
146897
  {
146296
146898
  name: "Agent Compatibility",
@@ -146299,7 +146901,7 @@ ${newFrontmatter}
146299
146901
  },
146300
146902
  {
146301
146903
  name: "Config Format",
146302
- passed: fs31.existsSync(path36.join(v3Dir, "config.json")),
146904
+ passed: fs32.existsSync(path37.join(v3Dir, "config.json")),
146303
146905
  message: "Valid v3 config"
146304
146906
  }
146305
146907
  ];
@@ -146324,15 +146926,15 @@ ${newFrontmatter}
146324
146926
  await cleanupAndExit2(0);
146325
146927
  });
146326
146928
  migrateCmd.command("rollback").description("Rollback to previous version from backup").option("--backup-id <id>", "Specific backup to restore").option("--force", "Skip confirmation").action(async (options) => {
146327
- const fs31 = await import("fs");
146328
- const path36 = await import("path");
146929
+ const fs32 = await import("fs");
146930
+ const path37 = await import("path");
146329
146931
  const cwd = process.cwd();
146330
- const backupRoot = path36.join(cwd, ".aqe-backup");
146331
- if (!fs31.existsSync(backupRoot)) {
146932
+ const backupRoot = path37.join(cwd, ".aqe-backup");
146933
+ if (!fs32.existsSync(backupRoot)) {
146332
146934
  console.log(chalk18.yellow("\n! No backups found.\n"));
146333
146935
  return;
146334
146936
  }
146335
- const backups = fs31.readdirSync(backupRoot).filter((f74) => f74.startsWith("backup-")).sort().reverse();
146937
+ const backups = fs32.readdirSync(backupRoot).filter((f74) => f74.startsWith("backup-")).sort().reverse();
146336
146938
  if (backups.length === 0) {
146337
146939
  console.log(chalk18.yellow("\n! No backups found.\n"));
146338
146940
  return;
@@ -146344,8 +146946,8 @@ ${newFrontmatter}
146344
146946
  console.log(` ${chalk18.cyan(backup)} - ${date.toLocaleString()}`);
146345
146947
  }
146346
146948
  const targetBackup = options.backupId || backups[0];
146347
- const backupPath = path36.join(backupRoot, targetBackup);
146348
- if (!fs31.existsSync(backupPath)) {
146949
+ const backupPath = path37.join(backupRoot, targetBackup);
146950
+ if (!fs32.existsSync(backupPath)) {
146349
146951
  console.log(chalk18.red(`
146350
146952
  Backup not found: ${targetBackup}
146351
146953
  `));
@@ -146360,21 +146962,21 @@ ${newFrontmatter}
146360
146962
  console.log(chalk18.bold(`
146361
146963
  Rolling back to ${targetBackup}...
146362
146964
  `));
146363
- const v2Backup = path36.join(backupPath, ".agentic-qe");
146364
- const agentsBackup = path36.join(backupPath, ".claude", "agents");
146365
- if (fs31.existsSync(v2Backup)) {
146366
- const v2Dir = path36.join(cwd, ".agentic-qe");
146367
- fs31.cpSync(v2Backup, v2Dir, { recursive: true });
146965
+ const v2Backup = path37.join(backupPath, ".agentic-qe");
146966
+ const agentsBackup = path37.join(backupPath, ".claude", "agents");
146967
+ if (fs32.existsSync(v2Backup)) {
146968
+ const v2Dir = path37.join(cwd, ".agentic-qe");
146969
+ fs32.cpSync(v2Backup, v2Dir, { recursive: true });
146368
146970
  console.log(chalk18.dim(" Restored .agentic-qe/"));
146369
146971
  }
146370
- if (fs31.existsSync(agentsBackup)) {
146371
- const agentsDir = path36.join(cwd, ".claude", "agents");
146372
- fs31.cpSync(agentsBackup, agentsDir, { recursive: true });
146972
+ if (fs32.existsSync(agentsBackup)) {
146973
+ const agentsDir = path37.join(cwd, ".claude", "agents");
146974
+ fs32.cpSync(agentsBackup, agentsDir, { recursive: true });
146373
146975
  console.log(chalk18.dim(" Restored .claude/agents/"));
146374
146976
  }
146375
- const v3Dir = path36.join(cwd, ".aqe");
146376
- if (fs31.existsSync(v3Dir)) {
146377
- fs31.rmSync(v3Dir, { recursive: true, force: true });
146977
+ const v3Dir = path37.join(cwd, ".aqe");
146978
+ if (fs32.existsSync(v3Dir)) {
146979
+ fs32.rmSync(v3Dir, { recursive: true, force: true });
146378
146980
  console.log(chalk18.dim(" Removed .aqe/"));
146379
146981
  }
146380
146982
  console.log(chalk18.green("\n Rollback complete!\n"));
@@ -147932,8 +148534,8 @@ function createCompletionsCommand(cleanupAndExit2) {
147932
148534
  console.log(generateCompletion("powershell"));
147933
148535
  });
147934
148536
  completionsCmd.command("install").description("Auto-install completions for current shell").option("-s, --shell <shell>", "Target shell (bash|zsh|fish|powershell)").action(async (options) => {
147935
- const fs31 = await import("fs");
147936
- const path36 = await import("path");
148537
+ const fs32 = await import("fs");
148538
+ const path37 = await import("path");
147937
148539
  const shellInfo = options.shell ? { name: options.shell, configFile: null, detected: false } : detectShell();
147938
148540
  if (shellInfo.name === "unknown") {
147939
148541
  console.log(chalk19.red("Could not detect shell. Please specify with --shell option.\n"));
@@ -147947,11 +148549,11 @@ Installing completions for ${shellInfo.name}...
147947
148549
  const script = generateCompletion(shellInfo.name);
147948
148550
  if (shellInfo.name === "fish") {
147949
148551
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
147950
- const fishCompletionsDir = path36.join(homeDir, ".config", "fish", "completions");
148552
+ const fishCompletionsDir = path37.join(homeDir, ".config", "fish", "completions");
147951
148553
  try {
147952
- fs31.mkdirSync(fishCompletionsDir, { recursive: true });
147953
- const completionFile = path36.join(fishCompletionsDir, "aqe.fish");
147954
- fs31.writeFileSync(completionFile, script);
148554
+ fs32.mkdirSync(fishCompletionsDir, { recursive: true });
148555
+ const completionFile = path37.join(fishCompletionsDir, "aqe.fish");
148556
+ fs32.writeFileSync(completionFile, script);
147955
148557
  console.log(chalk19.green(`Completions installed to: ${completionFile}`));
147956
148558
  console.log(chalk19.gray("\nRestart your shell or run: source ~/.config/fish/completions/aqe.fish\n"));
147957
148559
  } catch (err3) {
@@ -156391,6 +156993,7 @@ async function syncIncrementalToCloud(since, config) {
156391
156993
  init_esm_node();
156392
156994
  import * as fs29 from "fs";
156393
156995
  import * as path29 from "path";
156996
+ init_unified_memory();
156394
156997
  init_error_utils();
156395
156998
  init_logging();
156396
156999
  var logger21 = LoggerFactory.create("pull-agent");
@@ -156612,7 +157215,7 @@ var PullSyncAgent = class {
156612
157215
  if (this.config.targetDb) {
156613
157216
  return path29.resolve(this.config.targetDb);
156614
157217
  }
156615
- return path29.resolve(process.cwd(), ".agentic-qe/memory.db");
157218
+ return path29.resolve(findProjectRoot(), ".agentic-qe/memory.db");
156616
157219
  }
156617
157220
  backupLocalDb() {
156618
157221
  if (this.config.dryRun) return;
@@ -158150,11 +158753,11 @@ function createCategoryEngineWrapper(rawEngine) {
158150
158753
  add_morphism(source, target, name) {
158151
158754
  morphisms.push({ source, target, name });
158152
158755
  },
158153
- verify_composition(path36) {
158154
- if (path36.length < 2) return true;
158155
- for (let i58 = 0; i58 < path36.length - 1; i58++) {
158156
- const source = path36[i58];
158157
- const target = path36[i58 + 1];
158756
+ verify_composition(path37) {
158757
+ if (path37.length < 2) return true;
158758
+ for (let i58 = 0; i58 < path37.length - 1; i58++) {
158759
+ const source = path37[i58];
158760
+ const target = path37[i58 + 1];
158158
158761
  const hasMorphism = morphisms.some((m74) => m74.source === source && m74.target === target);
158159
158762
  if (!hasMorphism) return false;
158160
158763
  }
@@ -158269,14 +158872,14 @@ var CategoryAdapter = class {
158269
158872
  * @param path - Array of type names representing a composition path
158270
158873
  * @returns True if the composition is valid
158271
158874
  */
158272
- verifyComposition(path36) {
158875
+ verifyComposition(path37) {
158273
158876
  this.ensureInitialized();
158274
- if (path36.length < 2) {
158877
+ if (path37.length < 2) {
158275
158878
  return true;
158276
158879
  }
158277
- const isValid = this.engine.verify_composition(path36);
158880
+ const isValid = this.engine.verify_composition(path37);
158278
158881
  this.logger.debug("Verified composition", {
158279
- path: path36,
158882
+ path: path37,
158280
158883
  isValid
158281
158884
  });
158282
158885
  return isValid;
@@ -158315,8 +158918,8 @@ var CategoryAdapter = class {
158315
158918
  for (const element of pipeline11.elements) {
158316
158919
  this.addMorphism(element.inputType, element.outputType, element.name);
158317
158920
  }
158318
- const path36 = this.buildCompositionPath(pipeline11);
158319
- const compositionValid = this.verifyComposition(path36);
158921
+ const path37 = this.buildCompositionPath(pipeline11);
158922
+ const compositionValid = this.verifyComposition(path37);
158320
158923
  const mismatches = this.checkTypeConsistency();
158321
158924
  const warnings = this.generateWarnings(pipeline11, compositionValid, mismatches);
158322
158925
  const durationMs = Date.now() - startTime;
@@ -158340,17 +158943,17 @@ var CategoryAdapter = class {
158340
158943
  * Build a composition path from a pipeline
158341
158944
  */
158342
158945
  buildCompositionPath(pipeline11) {
158343
- const path36 = [pipeline11.inputType];
158946
+ const path37 = [pipeline11.inputType];
158344
158947
  for (const element of pipeline11.elements) {
158345
- if (element.inputType !== path36[path36.length - 1]) {
158346
- path36.push(element.inputType);
158948
+ if (element.inputType !== path37[path37.length - 1]) {
158949
+ path37.push(element.inputType);
158347
158950
  }
158348
- path36.push(element.outputType);
158951
+ path37.push(element.outputType);
158349
158952
  }
158350
- if (path36[path36.length - 1] !== pipeline11.outputType) {
158351
- path36.push(pipeline11.outputType);
158953
+ if (path37[path37.length - 1] !== pipeline11.outputType) {
158954
+ path37.push(pipeline11.outputType);
158352
158955
  }
158353
- return path36;
158956
+ return path37;
158354
158957
  }
158355
158958
  /**
158356
158959
  * Infer a schema from a type name
@@ -159988,8 +160591,8 @@ var WasmLoader = class {
159988
160591
  })(),
159989
160592
  join63(process.cwd(), "node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm")
159990
160593
  ].filter((p74) => p74 !== null);
159991
- for (const path36 of wasmPaths) {
159992
- if (existsSync64(path36)) {
160594
+ for (const path37 of wasmPaths) {
160595
+ if (existsSync64(path37)) {
159993
160596
  return true;
159994
160597
  }
159995
160598
  }
@@ -160251,9 +160854,9 @@ var WasmLoader = class {
160251
160854
  join63(process.cwd(), "node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm")
160252
160855
  ].filter((p74) => p74 !== null);
160253
160856
  let wasmPath = null;
160254
- for (const path36 of wasmPaths) {
160255
- if (existsSync64(path36)) {
160256
- wasmPath = path36;
160857
+ for (const path37 of wasmPaths) {
160858
+ if (existsSync64(path37)) {
160859
+ wasmPath = path37;
160257
160860
  break;
160258
160861
  }
160259
160862
  }
@@ -163398,6 +164001,134 @@ function capitalize(s70) {
163398
164001
  return s70.charAt(0).toUpperCase() + s70.slice(1);
163399
164002
  }
163400
164003
 
164004
+ // src/cli/commands/prove.ts
164005
+ import { Command as Command20 } from "commander";
164006
+ import * as crypto6 from "crypto";
164007
+ import * as fs31 from "fs";
164008
+ import * as path36 from "path";
164009
+ function hashAttestation(data) {
164010
+ const serialized = JSON.stringify(data, null, 0);
164011
+ return crypto6.createHash("sha256").update(serialized).digest("hex");
164012
+ }
164013
+ async function collectMetrics(projectRoot) {
164014
+ const metrics = {
164015
+ testCount: 0,
164016
+ passRate: 0,
164017
+ coveragePercent: 0,
164018
+ vulnerabilities: 0,
164019
+ qualityScore: 0,
164020
+ patternsUsed: 0
164021
+ };
164022
+ try {
164023
+ const junitPath = path36.join(projectRoot, "junit.xml");
164024
+ if (fs31.existsSync(junitPath)) {
164025
+ const content = fs31.readFileSync(junitPath, "utf-8");
164026
+ const testsMatch = content.match(/tests="(\d+)"/);
164027
+ const failsMatch = content.match(/failures="(\d+)"/);
164028
+ if (testsMatch) {
164029
+ metrics.testCount = parseInt(testsMatch[1], 10);
164030
+ const failures = failsMatch ? parseInt(failsMatch[1], 10) : 0;
164031
+ metrics.passRate = metrics.testCount > 0 ? (metrics.testCount - failures) / metrics.testCount * 100 : 0;
164032
+ }
164033
+ }
164034
+ } catch {
164035
+ }
164036
+ try {
164037
+ const coveragePath = path36.join(projectRoot, "coverage", "coverage-summary.json");
164038
+ if (fs31.existsSync(coveragePath)) {
164039
+ const coverage = JSON.parse(fs31.readFileSync(coveragePath, "utf-8"));
164040
+ metrics.coveragePercent = coverage?.total?.lines?.pct ?? 0;
164041
+ }
164042
+ } catch {
164043
+ }
164044
+ try {
164045
+ const dbPath = path36.join(projectRoot, ".agentic-qe", "memory.db");
164046
+ if (fs31.existsSync(dbPath)) {
164047
+ metrics.patternsUsed = 1;
164048
+ }
164049
+ } catch {
164050
+ }
164051
+ metrics.qualityScore = Math.round(
164052
+ metrics.passRate * 0.4 + metrics.coveragePercent * 0.3 + (metrics.vulnerabilities === 0 ? 100 : Math.max(0, 100 - metrics.vulnerabilities * 10)) * 0.3
164053
+ );
164054
+ return metrics;
164055
+ }
164056
+ function buildAttestation(projectRoot, metrics) {
164057
+ const data = {
164058
+ version: "1.0.0",
164059
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
164060
+ projectRoot,
164061
+ attestation: {
164062
+ testsExecuted: metrics.testCount > 0,
164063
+ coverageChecked: metrics.coveragePercent > 0,
164064
+ securityScanned: metrics.vulnerabilities === 0,
164065
+ qualityGatePassed: metrics.qualityScore >= 70
164066
+ },
164067
+ metrics,
164068
+ generatedBy: "agentic-qe prove"
164069
+ };
164070
+ const hash = hashAttestation(data);
164071
+ return { ...data, hash };
164072
+ }
164073
+ function formatMarkdown(att) {
164074
+ return [
164075
+ "# Proof of Quality",
164076
+ "",
164077
+ `**Generated:** ${att.timestamp}`,
164078
+ `**Project:** ${att.projectRoot}`,
164079
+ `**Hash:** \`${att.hash}\``,
164080
+ "",
164081
+ "## Attestation",
164082
+ "",
164083
+ "| Check | Status |",
164084
+ "|-------|--------|",
164085
+ `| Tests Executed | ${att.attestation.testsExecuted ? "PASS" : "FAIL"} |`,
164086
+ `| Coverage Checked | ${att.attestation.coverageChecked ? "PASS" : "FAIL"} |`,
164087
+ `| Security Scanned | ${att.attestation.securityScanned ? "PASS" : "FAIL"} |`,
164088
+ `| Quality Gate | ${att.attestation.qualityGatePassed ? "PASSED" : "FAILED"} |`,
164089
+ "",
164090
+ "## Metrics",
164091
+ "",
164092
+ "| Metric | Value |",
164093
+ "|--------|-------|",
164094
+ `| Tests | ${att.metrics.testCount} |`,
164095
+ `| Pass Rate | ${att.metrics.passRate.toFixed(1)}% |`,
164096
+ `| Coverage | ${att.metrics.coveragePercent.toFixed(1)}% |`,
164097
+ `| Vulnerabilities | ${att.metrics.vulnerabilities} |`,
164098
+ `| Quality Score | ${att.metrics.qualityScore}/100 |`,
164099
+ "",
164100
+ "---",
164101
+ `*${att.generatedBy}*`
164102
+ ].join("\n");
164103
+ }
164104
+ async function handleProve(options) {
164105
+ const projectRoot = options.projectRoot ?? process.cwd();
164106
+ const metrics = await collectMetrics(projectRoot);
164107
+ const attestation = buildAttestation(projectRoot, metrics);
164108
+ const content = options.format === "markdown" ? formatMarkdown(attestation) : JSON.stringify(attestation, null, 2);
164109
+ if (options.output) {
164110
+ fs31.writeFileSync(options.output, content);
164111
+ console.log(`Quality attestation written to ${options.output}`);
164112
+ } else {
164113
+ console.log(content);
164114
+ }
164115
+ return attestation;
164116
+ }
164117
+ function createProveCommand(_context, cleanupAndExit2, _ensureInitialized) {
164118
+ return new Command20("prove").description("Generate a verifiable Proof-of-Quality attestation").option("-F, --format <format>", "Output format (json|markdown)", "json").option("-o, --output <path>", "Write attestation to file").action(async (options) => {
164119
+ try {
164120
+ await handleProve({
164121
+ format: options.format,
164122
+ output: options.output
164123
+ });
164124
+ await cleanupAndExit2(0);
164125
+ } catch (error) {
164126
+ console.error("Failed to generate proof-of-quality:", error);
164127
+ await cleanupAndExit2(1);
164128
+ }
164129
+ });
164130
+ }
164131
+
163401
164132
  // src/cli/index.ts
163402
164133
  var INTERNAL_LOG_PREFIXES = [
163403
164134
  "[UnifiedMemory]",
@@ -163523,10 +164254,10 @@ async function ensureInitializedStrict() {
163523
164254
  if (context.initialized && context.kernel && context.queen) {
163524
164255
  return true;
163525
164256
  }
163526
- const fs31 = await import("fs");
163527
- const path36 = await import("path");
163528
- const configDir = path36.resolve(".agentic-qe");
163529
- if (!fs31.existsSync(configDir)) {
164257
+ const fs32 = await import("fs");
164258
+ const path37 = await import("path");
164259
+ const configDir = path37.resolve(".agentic-qe");
164260
+ if (!fs32.existsSync(configDir)) {
163530
164261
  console.error(chalk33.red("\nError: AQE system not initialized in this directory."));
163531
164262
  console.log(chalk33.yellow("Run `aqe init` first to set up this project.\n"));
163532
164263
  return false;
@@ -163581,15 +164312,15 @@ async function cleanupAndExit(code = 0) {
163581
164312
  }
163582
164313
  process.exit(code);
163583
164314
  }
163584
- var program = new Command20();
163585
- var VERSION = true ? "3.7.14" : "0.0.0-dev";
164315
+ var program = new Command21();
164316
+ var VERSION = true ? "3.7.16" : "0.0.0-dev";
163586
164317
  program.name("aqe").description("Agentic QE - Domain-Driven Quality Engineering").version(VERSION);
163587
164318
  var registry2 = createCommandRegistry(context, cleanupAndExit, ensureInitialized, ensureInitializedStrict);
163588
164319
  registry2.registerAll(program);
163589
164320
  var workflowCmd = program.command("workflow").description("Manage QE workflows and pipelines (ADR-041)");
163590
164321
  workflowCmd.command("run <file>").description("Execute a QE pipeline from YAML file").option("-w, --watch", "Watch execution progress").option("-v, --verbose", "Show detailed output").option("--params <json>", "Additional parameters as JSON", "{}").action(async (file, options) => {
163591
164322
  if (!await ensureInitialized()) return;
163592
- const fs31 = await import("fs");
164323
+ const fs32 = await import("fs");
163593
164324
  const pathModule = await import("path");
163594
164325
  const filePath = pathModule.resolve(file);
163595
164326
  try {
@@ -163829,14 +164560,14 @@ workflowCmd.command("list").description("List workflows").option("-s, --schedule
163829
164560
  }
163830
164561
  });
163831
164562
  workflowCmd.command("validate <file>").description("Validate a pipeline YAML file").option("-v, --verbose", "Show detailed validation results").action(async (file, options) => {
163832
- const fs31 = await import("fs");
164563
+ const fs32 = await import("fs");
163833
164564
  const pathModule = await import("path");
163834
164565
  const filePath = pathModule.resolve(file);
163835
164566
  try {
163836
164567
  console.log(chalk33.blue(`
163837
164568
  Validating pipeline: ${file}
163838
164569
  `));
163839
- if (!fs31.existsSync(filePath)) {
164570
+ if (!fs32.existsSync(filePath)) {
163840
164571
  console.log(chalk33.red(`File not found: ${filePath}`));
163841
164572
  await cleanupAndExit(1);
163842
164573
  }
@@ -164029,16 +164760,16 @@ workflowCmd.command("browser-load [template]").description("Load and validate a
164029
164760
  params.workflowYaml = options.yaml;
164030
164761
  } else if (template) {
164031
164762
  if (template.endsWith(".yaml") || template.endsWith(".yml")) {
164032
- const fs31 = await import("fs");
164763
+ const fs32 = await import("fs");
164033
164764
  const pathModule = await import("path");
164034
164765
  const filePath = pathModule.resolve(template);
164035
- if (!fs31.existsSync(filePath)) {
164766
+ if (!fs32.existsSync(filePath)) {
164036
164767
  console.log(chalk33.red(`
164037
164768
  File not found: ${filePath}
164038
164769
  `));
164039
164770
  await cleanupAndExit(1);
164040
164771
  }
164041
- params.workflowYaml = fs31.readFileSync(filePath, "utf-8");
164772
+ params.workflowYaml = fs32.readFileSync(filePath, "utf-8");
164042
164773
  } else {
164043
164774
  params.templateName = template;
164044
164775
  }
@@ -164121,6 +164852,7 @@ program.addCommand(createHooksCommand());
164121
164852
  program.addCommand(createLearningCommand());
164122
164853
  program.addCommand(createMcpCommand());
164123
164854
  program.addCommand(createPlatformCommand());
164855
+ program.addCommand(createProveCommand(context, cleanupAndExit, ensureInitialized));
164124
164856
  process.on("SIGINT", async () => {
164125
164857
  console.log(chalk33.yellow("\n\nShutting down..."));
164126
164858
  console.log(chalk33.green("Shutdown complete\n"));