agentic-qe 3.6.3 → 3.6.5

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 (210) hide show
  1. package/.claude/helpers/statusline-v3.cjs +4 -3
  2. package/.claude/helpers/v3/product-factors/sfdipot-reference-template.html +958 -0
  3. package/.claude/helpers/v3/quality-criteria/evidence-classification.md +116 -0
  4. package/.claude/helpers/v3/quality-criteria/htsm-categories.md +139 -0
  5. package/.claude/helpers/v3/quality-criteria/quality-criteria-reference-template.html +811 -0
  6. package/.claude/helpers/v3/quality-criteria/validate-quality-criteria.ts +167 -0
  7. package/.claude/skills/README.md +21 -8
  8. package/.claude/skills/release/SKILL.md +33 -2
  9. package/.claude/skills/skills-manifest.json +1 -1
  10. package/README.md +45 -49
  11. package/package.json +1 -1
  12. package/v3/CHANGELOG.md +38 -0
  13. package/v3/assets/agents/v3/README.md +9 -70
  14. package/v3/assets/agents/v3/qe-accessibility-auditor.md +8 -7
  15. package/v3/assets/agents/v3/qe-bdd-generator.md +8 -7
  16. package/v3/assets/agents/v3/qe-chaos-engineer.md +9 -8
  17. package/v3/assets/agents/v3/qe-code-complexity.md +8 -7
  18. package/v3/assets/agents/v3/qe-code-intelligence.md +8 -7
  19. package/v3/assets/agents/v3/qe-contract-validator.md +8 -7
  20. package/v3/assets/agents/v3/qe-coverage-specialist.md +8 -7
  21. package/v3/assets/agents/v3/qe-defect-predictor.md +8 -7
  22. package/v3/assets/agents/v3/qe-dependency-mapper.md +8 -7
  23. package/v3/assets/agents/v3/qe-deployment-advisor.md +8 -7
  24. package/v3/assets/agents/v3/qe-flaky-hunter.md +8 -7
  25. package/v3/assets/agents/v3/qe-fleet-commander.md +8 -7
  26. package/v3/assets/agents/v3/qe-gap-detector.md +8 -7
  27. package/v3/assets/agents/v3/qe-graphql-tester.md +8 -7
  28. package/v3/assets/agents/v3/qe-impact-analyzer.md +8 -7
  29. package/v3/assets/agents/v3/qe-kg-builder.md +8 -7
  30. package/v3/assets/agents/v3/qe-load-tester.md +8 -7
  31. package/v3/assets/agents/v3/qe-message-broker-tester.md +15 -10
  32. package/v3/assets/agents/v3/qe-metrics-optimizer.md +8 -7
  33. package/v3/assets/agents/v3/qe-middleware-validator.md +15 -10
  34. package/v3/assets/agents/v3/qe-mutation-tester.md +8 -7
  35. package/v3/assets/agents/v3/qe-odata-contract-tester.md +17 -12
  36. package/v3/assets/agents/v3/qe-performance-tester.md +8 -7
  37. package/v3/assets/agents/v3/qe-property-tester.md +8 -7
  38. package/v3/assets/agents/v3/qe-qx-partner.md +74 -14
  39. package/v3/assets/agents/v3/qe-regression-analyzer.md +8 -7
  40. package/v3/assets/agents/v3/qe-requirements-validator.md +8 -7
  41. package/v3/assets/agents/v3/qe-responsive-tester.md +8 -7
  42. package/v3/assets/agents/v3/qe-retry-handler.md +8 -7
  43. package/v3/assets/agents/v3/qe-risk-assessor.md +8 -7
  44. package/v3/assets/agents/v3/qe-root-cause-analyzer.md +8 -7
  45. package/v3/assets/agents/v3/qe-sap-idoc-tester.md +16 -11
  46. package/v3/assets/agents/v3/qe-sap-rfc-tester.md +15 -10
  47. package/v3/assets/agents/v3/qe-security-auditor.md +12 -7
  48. package/v3/assets/agents/v3/qe-security-scanner.md +9 -8
  49. package/v3/assets/agents/v3/qe-soap-tester.md +15 -10
  50. package/v3/assets/agents/v3/qe-sod-analyzer.md +17 -12
  51. package/v3/assets/agents/v3/qe-test-architect.md +8 -7
  52. package/v3/assets/agents/v3/qe-transfer-specialist.md +8 -7
  53. package/v3/assets/agents/v3/subagents/qe-code-reviewer.md +8 -7
  54. package/v3/assets/agents/v3/subagents/qe-integration-reviewer.md +8 -7
  55. package/v3/assets/agents/v3/subagents/qe-performance-reviewer.md +8 -7
  56. package/v3/assets/agents/v3/subagents/qe-security-reviewer.md +8 -7
  57. package/v3/assets/agents/v3/subagents/qe-tdd-green.md +8 -7
  58. package/v3/assets/agents/v3/subagents/qe-tdd-red.md +8 -7
  59. package/v3/assets/agents/v3/subagents/qe-tdd-refactor.md +8 -7
  60. package/v3/assets/agents/v3/templates/qx-report-template.html +26 -22
  61. package/v3/dist/adapters/a2a/auth/oauth-provider.d.ts +8 -0
  62. package/v3/dist/adapters/a2a/auth/oauth-provider.d.ts.map +1 -1
  63. package/v3/dist/adapters/a2a/auth/oauth-provider.js +32 -7
  64. package/v3/dist/adapters/a2a/auth/oauth-provider.js.map +1 -1
  65. package/v3/dist/adapters/claude-flow/detect.d.ts +38 -0
  66. package/v3/dist/adapters/claude-flow/detect.d.ts.map +1 -0
  67. package/v3/dist/adapters/claude-flow/detect.js +154 -0
  68. package/v3/dist/adapters/claude-flow/detect.js.map +1 -0
  69. package/v3/dist/adapters/claude-flow/index.d.ts +2 -0
  70. package/v3/dist/adapters/claude-flow/index.d.ts.map +1 -1
  71. package/v3/dist/adapters/claude-flow/index.js +1 -0
  72. package/v3/dist/adapters/claude-flow/index.js.map +1 -1
  73. package/v3/dist/adapters/claude-flow/model-router-bridge.d.ts +1 -1
  74. package/v3/dist/adapters/claude-flow/model-router-bridge.d.ts.map +1 -1
  75. package/v3/dist/adapters/claude-flow/model-router-bridge.js +5 -15
  76. package/v3/dist/adapters/claude-flow/model-router-bridge.js.map +1 -1
  77. package/v3/dist/adapters/claude-flow/pretrain-bridge.d.ts +1 -1
  78. package/v3/dist/adapters/claude-flow/pretrain-bridge.d.ts.map +1 -1
  79. package/v3/dist/adapters/claude-flow/pretrain-bridge.js +6 -16
  80. package/v3/dist/adapters/claude-flow/pretrain-bridge.js.map +1 -1
  81. package/v3/dist/adapters/claude-flow/trajectory-bridge.d.ts +1 -1
  82. package/v3/dist/adapters/claude-flow/trajectory-bridge.d.ts.map +1 -1
  83. package/v3/dist/adapters/claude-flow/trajectory-bridge.js +6 -16
  84. package/v3/dist/adapters/claude-flow/trajectory-bridge.js.map +1 -1
  85. package/v3/dist/cli/bundle.js +73791 -71858
  86. package/v3/dist/cli/commands/claude-flow-setup.d.ts.map +1 -1
  87. package/v3/dist/cli/commands/claude-flow-setup.js +42 -80
  88. package/v3/dist/cli/commands/claude-flow-setup.js.map +1 -1
  89. package/v3/dist/cli/commands/hooks.d.ts.map +1 -1
  90. package/v3/dist/cli/commands/hooks.js +170 -0
  91. package/v3/dist/cli/commands/hooks.js.map +1 -1
  92. package/v3/dist/cli/commands/learning.d.ts.map +1 -1
  93. package/v3/dist/cli/commands/learning.js +296 -0
  94. package/v3/dist/cli/commands/learning.js.map +1 -1
  95. package/v3/dist/cli/handlers/init-handler.d.ts.map +1 -1
  96. package/v3/dist/cli/handlers/init-handler.js +9 -1
  97. package/v3/dist/cli/handlers/init-handler.js.map +1 -1
  98. package/v3/dist/coordination/mincut/mincut-calculator.d.ts +7 -0
  99. package/v3/dist/coordination/mincut/mincut-calculator.d.ts.map +1 -1
  100. package/v3/dist/coordination/mincut/mincut-calculator.js +66 -7
  101. package/v3/dist/coordination/mincut/mincut-calculator.js.map +1 -1
  102. package/v3/dist/domains/contract-testing/services/contract-validator.d.ts.map +1 -1
  103. package/v3/dist/domains/contract-testing/services/contract-validator.js +10 -13
  104. package/v3/dist/domains/contract-testing/services/contract-validator.js.map +1 -1
  105. package/v3/dist/domains/contract-testing/services/schema-validator.d.ts.map +1 -1
  106. package/v3/dist/domains/contract-testing/services/schema-validator.js +4 -2
  107. package/v3/dist/domains/contract-testing/services/schema-validator.js.map +1 -1
  108. package/v3/dist/governance/deterministic-gateway-integration.d.ts.map +1 -1
  109. package/v3/dist/governance/deterministic-gateway-integration.js +3 -1
  110. package/v3/dist/governance/deterministic-gateway-integration.js.map +1 -1
  111. package/v3/dist/init/enhancements/claude-flow-adapter.d.ts +1 -1
  112. package/v3/dist/init/enhancements/claude-flow-adapter.d.ts.map +1 -1
  113. package/v3/dist/init/enhancements/claude-flow-adapter.js +15 -34
  114. package/v3/dist/init/enhancements/claude-flow-adapter.js.map +1 -1
  115. package/v3/dist/init/enhancements/detector.d.ts.map +1 -1
  116. package/v3/dist/init/enhancements/detector.js +7 -34
  117. package/v3/dist/init/enhancements/detector.js.map +1 -1
  118. package/v3/dist/init/phases/06-code-intelligence.d.ts +8 -0
  119. package/v3/dist/init/phases/06-code-intelligence.d.ts.map +1 -1
  120. package/v3/dist/init/phases/06-code-intelligence.js +118 -24
  121. package/v3/dist/init/phases/06-code-intelligence.js.map +1 -1
  122. package/v3/dist/init/phases/11-claude-md.d.ts.map +1 -1
  123. package/v3/dist/init/phases/11-claude-md.js +94 -16
  124. package/v3/dist/init/phases/11-claude-md.js.map +1 -1
  125. package/v3/dist/kernel/constants.d.ts +1 -1
  126. package/v3/dist/kernel/constants.js +1 -1
  127. package/v3/dist/kernel/unified-memory-migration.d.ts.map +1 -1
  128. package/v3/dist/kernel/unified-memory-migration.js +4 -3
  129. package/v3/dist/kernel/unified-memory-migration.js.map +1 -1
  130. package/v3/dist/kernel/unified-memory.d.ts +3 -1
  131. package/v3/dist/kernel/unified-memory.d.ts.map +1 -1
  132. package/v3/dist/kernel/unified-memory.js +119 -44
  133. package/v3/dist/kernel/unified-memory.js.map +1 -1
  134. package/v3/dist/learning/dream/concept-graph.d.ts +13 -2
  135. package/v3/dist/learning/dream/concept-graph.d.ts.map +1 -1
  136. package/v3/dist/learning/dream/concept-graph.js +69 -7
  137. package/v3/dist/learning/dream/concept-graph.js.map +1 -1
  138. package/v3/dist/learning/dream/dream-engine.d.ts +5 -0
  139. package/v3/dist/learning/dream/dream-engine.d.ts.map +1 -1
  140. package/v3/dist/learning/dream/dream-engine.js +54 -3
  141. package/v3/dist/learning/dream/dream-engine.js.map +1 -1
  142. package/v3/dist/learning/dream/spreading-activation.d.ts.map +1 -1
  143. package/v3/dist/learning/dream/spreading-activation.js +74 -6
  144. package/v3/dist/learning/dream/spreading-activation.js.map +1 -1
  145. package/v3/dist/learning/pattern-store.d.ts.map +1 -1
  146. package/v3/dist/learning/pattern-store.js +9 -8
  147. package/v3/dist/learning/pattern-store.js.map +1 -1
  148. package/v3/dist/learning/qe-patterns.d.ts +2 -0
  149. package/v3/dist/learning/qe-patterns.d.ts.map +1 -1
  150. package/v3/dist/learning/qe-patterns.js.map +1 -1
  151. package/v3/dist/learning/qe-reasoning-bank.d.ts +16 -0
  152. package/v3/dist/learning/qe-reasoning-bank.d.ts.map +1 -1
  153. package/v3/dist/learning/qe-reasoning-bank.js +709 -0
  154. package/v3/dist/learning/qe-reasoning-bank.js.map +1 -1
  155. package/v3/dist/learning/qe-unified-memory.d.ts.map +1 -1
  156. package/v3/dist/learning/qe-unified-memory.js +8 -7
  157. package/v3/dist/learning/qe-unified-memory.js.map +1 -1
  158. package/v3/dist/mcp/bundle.js +1581 -218
  159. package/v3/dist/mcp/connection-pool.d.ts +1 -1
  160. package/v3/dist/mcp/connection-pool.d.ts.map +1 -1
  161. package/v3/dist/mcp/connection-pool.js +27 -13
  162. package/v3/dist/mcp/connection-pool.js.map +1 -1
  163. package/v3/dist/mcp/handlers/handler-factory.d.ts +2 -0
  164. package/v3/dist/mcp/handlers/handler-factory.d.ts.map +1 -1
  165. package/v3/dist/mcp/handlers/handler-factory.js +52 -4
  166. package/v3/dist/mcp/handlers/handler-factory.js.map +1 -1
  167. package/v3/dist/mcp/http-server.d.ts.map +1 -1
  168. package/v3/dist/mcp/http-server.js +2 -1
  169. package/v3/dist/mcp/http-server.js.map +1 -1
  170. package/v3/dist/mcp/security/oauth21-provider.d.ts.map +1 -1
  171. package/v3/dist/mcp/security/oauth21-provider.js +25 -15
  172. package/v3/dist/mcp/security/oauth21-provider.js.map +1 -1
  173. package/v3/dist/mcp/security/rate-limiter.d.ts.map +1 -1
  174. package/v3/dist/mcp/security/rate-limiter.js +5 -4
  175. package/v3/dist/mcp/security/rate-limiter.js.map +1 -1
  176. package/v3/dist/mcp/security/schema-validator.d.ts.map +1 -1
  177. package/v3/dist/mcp/security/schema-validator.js +13 -9
  178. package/v3/dist/mcp/security/schema-validator.js.map +1 -1
  179. package/v3/dist/mcp/tools/contract-testing/validate.d.ts.map +1 -1
  180. package/v3/dist/mcp/tools/contract-testing/validate.js +3 -2
  181. package/v3/dist/mcp/tools/contract-testing/validate.js.map +1 -1
  182. package/v3/dist/mcp/transport/sse/connection-manager.d.ts +1 -0
  183. package/v3/dist/mcp/transport/sse/connection-manager.d.ts.map +1 -1
  184. package/v3/dist/mcp/transport/sse/connection-manager.js +31 -10
  185. package/v3/dist/mcp/transport/sse/connection-manager.js.map +1 -1
  186. package/v3/dist/mcp/transport/sse/sse-transport.d.ts.map +1 -1
  187. package/v3/dist/mcp/transport/sse/sse-transport.js +2 -1
  188. package/v3/dist/mcp/transport/sse/sse-transport.js.map +1 -1
  189. package/v3/dist/mcp/transport/stdio.d.ts.map +1 -1
  190. package/v3/dist/mcp/transport/stdio.js +2 -1
  191. package/v3/dist/mcp/transport/stdio.js.map +1 -1
  192. package/v3/dist/mcp/transport/websocket/websocket-transport.d.ts.map +1 -1
  193. package/v3/dist/mcp/transport/websocket/websocket-transport.js +2 -1
  194. package/v3/dist/mcp/transport/websocket/websocket-transport.js.map +1 -1
  195. package/v3/dist/performance/optimizer.d.ts.map +1 -1
  196. package/v3/dist/performance/optimizer.js +19 -3
  197. package/v3/dist/performance/optimizer.js.map +1 -1
  198. package/v3/dist/shared/sql-safety.d.ts +18 -0
  199. package/v3/dist/shared/sql-safety.d.ts.map +1 -0
  200. package/v3/dist/shared/sql-safety.js +44 -0
  201. package/v3/dist/shared/sql-safety.js.map +1 -0
  202. package/v3/dist/sync/embeddings/sync-embedding-generator.d.ts.map +1 -1
  203. package/v3/dist/sync/embeddings/sync-embedding-generator.js +9 -7
  204. package/v3/dist/sync/embeddings/sync-embedding-generator.js.map +1 -1
  205. package/v3/dist/sync/interfaces.js +5 -5
  206. package/v3/dist/sync/interfaces.js.map +1 -1
  207. package/v3/dist/sync/readers/sqlite-reader.d.ts.map +1 -1
  208. package/v3/dist/sync/readers/sqlite-reader.js +5 -4
  209. package/v3/dist/sync/readers/sqlite-reader.js.map +1 -1
  210. package/v3/package.json +3 -3
@@ -39,6 +39,110 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
39
39
  ));
40
40
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
41
41
 
42
+ // node_modules/secure-json-parse/index.js
43
+ var require_secure_json_parse = __commonJS({
44
+ "node_modules/secure-json-parse/index.js"(exports, module) {
45
+ "use strict";
46
+ var hasBuffer = typeof Buffer !== "undefined";
47
+ var suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/;
48
+ var suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
49
+ function _parse(text2, reviver, options) {
50
+ if (options == null) {
51
+ if (reviver !== null && typeof reviver === "object") {
52
+ options = reviver;
53
+ reviver = void 0;
54
+ }
55
+ }
56
+ if (hasBuffer && Buffer.isBuffer(text2)) {
57
+ text2 = text2.toString();
58
+ }
59
+ if (text2 && text2.charCodeAt(0) === 65279) {
60
+ text2 = text2.slice(1);
61
+ }
62
+ const obj = JSON.parse(text2, reviver);
63
+ if (obj === null || typeof obj !== "object") {
64
+ return obj;
65
+ }
66
+ const protoAction = options && options.protoAction || "error";
67
+ const constructorAction = options && options.constructorAction || "error";
68
+ if (protoAction === "ignore" && constructorAction === "ignore") {
69
+ return obj;
70
+ }
71
+ if (protoAction !== "ignore" && constructorAction !== "ignore") {
72
+ if (suspectProtoRx.test(text2) === false && suspectConstructorRx.test(text2) === false) {
73
+ return obj;
74
+ }
75
+ } else if (protoAction !== "ignore" && constructorAction === "ignore") {
76
+ if (suspectProtoRx.test(text2) === false) {
77
+ return obj;
78
+ }
79
+ } else {
80
+ if (suspectConstructorRx.test(text2) === false) {
81
+ return obj;
82
+ }
83
+ }
84
+ return filter(obj, { protoAction, constructorAction, safe: options && options.safe });
85
+ }
86
+ function filter(obj, { protoAction = "error", constructorAction = "error", safe } = {}) {
87
+ let next = [obj];
88
+ while (next.length) {
89
+ const nodes = next;
90
+ next = [];
91
+ for (const node of nodes) {
92
+ if (protoAction !== "ignore" && Object.prototype.hasOwnProperty.call(node, "__proto__")) {
93
+ if (safe === true) {
94
+ return null;
95
+ } else if (protoAction === "error") {
96
+ throw new SyntaxError("Object contains forbidden prototype property");
97
+ }
98
+ delete node.__proto__;
99
+ }
100
+ if (constructorAction !== "ignore" && Object.prototype.hasOwnProperty.call(node, "constructor") && node.constructor !== null && typeof node.constructor === "object" && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) {
101
+ if (safe === true) {
102
+ return null;
103
+ } else if (constructorAction === "error") {
104
+ throw new SyntaxError("Object contains forbidden prototype property");
105
+ }
106
+ delete node.constructor;
107
+ }
108
+ for (const key in node) {
109
+ const value = node[key];
110
+ if (value && typeof value === "object") {
111
+ next.push(value);
112
+ }
113
+ }
114
+ }
115
+ }
116
+ return obj;
117
+ }
118
+ function parse2(text2, reviver, options) {
119
+ const { stackTraceLimit } = Error;
120
+ Error.stackTraceLimit = 0;
121
+ try {
122
+ return _parse(text2, reviver, options);
123
+ } finally {
124
+ Error.stackTraceLimit = stackTraceLimit;
125
+ }
126
+ }
127
+ function safeParse(text2, reviver) {
128
+ const { stackTraceLimit } = Error;
129
+ Error.stackTraceLimit = 0;
130
+ try {
131
+ return _parse(text2, reviver, { safe: true });
132
+ } catch {
133
+ return void 0;
134
+ } finally {
135
+ Error.stackTraceLimit = stackTraceLimit;
136
+ }
137
+ }
138
+ module.exports = parse2;
139
+ module.exports.default = parse2;
140
+ module.exports.parse = parse2;
141
+ module.exports.safeParse = safeParse;
142
+ module.exports.scan = filter;
143
+ }
144
+ });
145
+
42
146
  // node_modules/uuid/dist/esm-node/rng.js
43
147
  import crypto2 from "crypto";
44
148
  function rng() {
@@ -4501,7 +4605,7 @@ var init_constants = __esm({
4501
4605
  * Default vector embedding dimensions for HNSW index.
4502
4606
  * 384 dimensions matches common sentence transformers.
4503
4607
  */
4504
- DEFAULT_VECTOR_DIMENSIONS: 384,
4608
+ DEFAULT_VECTOR_DIMENSIONS: 768,
4505
4609
  /**
4506
4610
  * Default search result limit for KV store queries.
4507
4611
  * Prevents unbounded result sets.
@@ -4674,6 +4778,64 @@ ${HYPERGRAPH_INDEXES_SCHEMA}
4674
4778
  }
4675
4779
  });
4676
4780
 
4781
+ // src/shared/sql-safety.ts
4782
+ function validateTableName(tableName) {
4783
+ if (!ALLOWED_TABLE_NAMES.has(tableName)) {
4784
+ throw new Error(`Invalid table name: "${tableName}" is not in the allowlist`);
4785
+ }
4786
+ return tableName;
4787
+ }
4788
+ var ALLOWED_TABLE_NAMES;
4789
+ var init_sql_safety = __esm({
4790
+ "src/shared/sql-safety.ts"() {
4791
+ "use strict";
4792
+ ALLOWED_TABLE_NAMES = /* @__PURE__ */ new Set([
4793
+ // Core kernel tables
4794
+ "schema_version",
4795
+ "kv_store",
4796
+ "vectors",
4797
+ "rl_q_values",
4798
+ // GOAP tables
4799
+ "goap_goals",
4800
+ "goap_actions",
4801
+ "goap_plans",
4802
+ "goap_execution_steps",
4803
+ "goap_plan_signatures",
4804
+ // Concept/dream tables
4805
+ "concept_nodes",
4806
+ "concept_edges",
4807
+ "dream_cycles",
4808
+ "dream_insights",
4809
+ // QE pattern tables
4810
+ "qe_patterns",
4811
+ "qe_pattern_embeddings",
4812
+ "qe_pattern_usage",
4813
+ "qe_trajectories",
4814
+ // Execution tables
4815
+ "embeddings",
4816
+ "execution_results",
4817
+ "executed_steps",
4818
+ // MinCut tables
4819
+ "mincut_snapshots",
4820
+ "mincut_history",
4821
+ "mincut_weak_vertices",
4822
+ "mincut_alerts",
4823
+ "mincut_healing_actions",
4824
+ "mincut_observations",
4825
+ // SONA tables
4826
+ "sona_patterns",
4827
+ // Sync tables
4828
+ "patterns",
4829
+ // Hypergraph tables
4830
+ "hypergraph_vertices",
4831
+ "hypergraph_hyperedges",
4832
+ "hypergraph_edge_vertices",
4833
+ "hypergraph_vertex_properties",
4834
+ "hypergraph_edge_properties"
4835
+ ]);
4836
+ }
4837
+ });
4838
+
4677
4839
  // src/memory/crdt/lww-register.ts
4678
4840
  function createLWWRegister(nodeId, initialValue, initialTimestamp) {
4679
4841
  let state2 = {
@@ -5584,6 +5746,19 @@ var init_crdt = __esm({
5584
5746
  });
5585
5747
 
5586
5748
  // src/kernel/unified-memory.ts
5749
+ var unified_memory_exports = {};
5750
+ __export(unified_memory_exports, {
5751
+ ALLOWED_TABLE_NAMES: () => ALLOWED_TABLE_NAMES,
5752
+ DEFAULT_UNIFIED_MEMORY_CONFIG: () => DEFAULT_UNIFIED_MEMORY_CONFIG,
5753
+ UnifiedMemoryManager: () => UnifiedMemoryManager,
5754
+ findProjectRoot: () => findProjectRoot,
5755
+ getDefaultDbPath: () => getDefaultDbPath,
5756
+ getResolvedDefaultConfig: () => getResolvedDefaultConfig,
5757
+ getUnifiedMemory: () => getUnifiedMemory,
5758
+ initializeUnifiedMemory: () => initializeUnifiedMemory,
5759
+ resetUnifiedMemory: () => resetUnifiedMemory,
5760
+ validateTableName: () => validateTableName
5761
+ });
5587
5762
  import Database from "better-sqlite3";
5588
5763
  import * as fs from "fs";
5589
5764
  import * as path from "path";
@@ -5633,6 +5808,11 @@ function getResolvedDefaultConfig() {
5633
5808
  function getUnifiedMemory(config) {
5634
5809
  return UnifiedMemoryManager.getInstance(config);
5635
5810
  }
5811
+ async function initializeUnifiedMemory(config) {
5812
+ const manager = getUnifiedMemory(config);
5813
+ await manager.initialize();
5814
+ return manager;
5815
+ }
5636
5816
  function resetUnifiedMemory() {
5637
5817
  UnifiedMemoryManager.resetInstance();
5638
5818
  }
@@ -5659,13 +5839,15 @@ function registerExitHandlers() {
5659
5839
  process.exit(0);
5660
5840
  });
5661
5841
  }
5662
- var DEFAULT_UNIFIED_MEMORY_CONFIG, SCHEMA_VERSION, SCHEMA_VERSION_TABLE, KV_STORE_SCHEMA, VECTORS_SCHEMA, RL_QVALUES_SCHEMA, GOAP_SCHEMA, DREAM_SCHEMA, QE_PATTERNS_SCHEMA, MINCUT_SCHEMA, SONA_PATTERNS_SCHEMA, InMemoryHNSWIndex, UnifiedMemoryManager, exitHandlersRegistered;
5842
+ var DEFAULT_UNIFIED_MEMORY_CONFIG, SCHEMA_VERSION, SCHEMA_VERSION_TABLE, KV_STORE_SCHEMA, VECTORS_SCHEMA, RL_QVALUES_SCHEMA, GOAP_SCHEMA, DREAM_SCHEMA, QE_PATTERNS_SCHEMA, MINCUT_SCHEMA, SONA_PATTERNS_SCHEMA, BinaryHeap, InMemoryHNSWIndex, UnifiedMemoryManager, exitHandlersRegistered;
5663
5843
  var init_unified_memory = __esm({
5664
5844
  "src/kernel/unified-memory.ts"() {
5665
5845
  "use strict";
5666
5846
  init_vector_math();
5667
5847
  init_add_hypergraph_tables();
5668
5848
  init_constants();
5849
+ init_sql_safety();
5850
+ init_sql_safety();
5669
5851
  init_crdt();
5670
5852
  DEFAULT_UNIFIED_MEMORY_CONFIG = {
5671
5853
  dbPath: ".agentic-qe/memory.db",
@@ -6149,6 +6331,64 @@ var init_unified_memory = __esm({
6149
6331
  CREATE INDEX IF NOT EXISTS idx_sona_patterns_confidence ON sona_patterns(confidence DESC);
6150
6332
  CREATE INDEX IF NOT EXISTS idx_sona_patterns_updated ON sona_patterns(updated_at DESC);
6151
6333
  `;
6334
+ BinaryHeap = class {
6335
+ data = [];
6336
+ compareFn;
6337
+ constructor(compareFn) {
6338
+ this.compareFn = compareFn;
6339
+ }
6340
+ push(item) {
6341
+ this.data.push(item);
6342
+ this.bubbleUp(this.data.length - 1);
6343
+ }
6344
+ pop() {
6345
+ if (this.data.length === 0) return void 0;
6346
+ const top = this.data[0];
6347
+ const last = this.data.pop();
6348
+ if (this.data.length > 0) {
6349
+ this.data[0] = last;
6350
+ this.sinkDown(0);
6351
+ }
6352
+ return top;
6353
+ }
6354
+ peek() {
6355
+ return this.data[0];
6356
+ }
6357
+ size() {
6358
+ return this.data.length;
6359
+ }
6360
+ bubbleUp(i58) {
6361
+ while (i58 > 0) {
6362
+ const parent = i58 - 1 >> 1;
6363
+ if (this.compareFn(this.data[i58], this.data[parent]) < 0) {
6364
+ [this.data[i58], this.data[parent]] = [this.data[parent], this.data[i58]];
6365
+ i58 = parent;
6366
+ } else {
6367
+ break;
6368
+ }
6369
+ }
6370
+ }
6371
+ sinkDown(i58) {
6372
+ const n61 = this.data.length;
6373
+ while (true) {
6374
+ let smallest = i58;
6375
+ const left = 2 * i58 + 1;
6376
+ const right = 2 * i58 + 2;
6377
+ if (left < n61 && this.compareFn(this.data[left], this.data[smallest]) < 0) {
6378
+ smallest = left;
6379
+ }
6380
+ if (right < n61 && this.compareFn(this.data[right], this.data[smallest]) < 0) {
6381
+ smallest = right;
6382
+ }
6383
+ if (smallest !== i58) {
6384
+ [this.data[i58], this.data[smallest]] = [this.data[smallest], this.data[i58]];
6385
+ i58 = smallest;
6386
+ } else {
6387
+ break;
6388
+ }
6389
+ }
6390
+ }
6391
+ };
6152
6392
  InMemoryHNSWIndex = class {
6153
6393
  nodes = /* @__PURE__ */ new Map();
6154
6394
  M = HNSW_CONSTANTS.M_CONNECTIONS;
@@ -6206,17 +6446,28 @@ var init_unified_memory = __esm({
6206
6446
  /**
6207
6447
  * Beam search at a single layer: starting from an entry point, explore
6208
6448
  * up to `ef` candidates and return the `ef` closest found.
6209
- * Uses a candidate set (max-heap behavior via sorted array) and a result
6210
- * set. Returns results sorted by descending similarity.
6449
+ * Uses a max-heap for candidates and a min-heap for results to achieve
6450
+ * O(log n) insertion instead of O(n) Array.splice.
6451
+ * Returns results sorted by descending similarity.
6211
6452
  */
6212
6453
  searchLayerBeam(query, entryIds, level, ef) {
6213
6454
  const visited = new Set(entryIds);
6214
- const candidates = entryIds.filter((id) => this.nodes.has(id)).map((id) => ({ id, score: this.similarity(query, id) }));
6215
- candidates.sort((a37, b68) => b68.score - a37.score);
6216
- const results = [...candidates];
6217
- while (candidates.length > 0) {
6218
- const closest = candidates.shift();
6219
- if (results.length >= ef && closest.score < results[results.length - 1].score) {
6455
+ const initial = entryIds.filter((id) => this.nodes.has(id)).map((id) => ({ id, score: this.similarity(query, id) }));
6456
+ const candidateHeap = new BinaryHeap(
6457
+ (a37, b68) => b68.score - a37.score
6458
+ // max-heap: highest score first
6459
+ );
6460
+ const resultHeap = new BinaryHeap(
6461
+ (a37, b68) => a37.score - b68.score
6462
+ // min-heap: lowest score first
6463
+ );
6464
+ for (const entry of initial) {
6465
+ candidateHeap.push(entry);
6466
+ resultHeap.push(entry);
6467
+ }
6468
+ while (candidateHeap.size() > 0) {
6469
+ const closest = candidateHeap.pop();
6470
+ if (resultHeap.size() >= ef && closest.score < resultHeap.peek().score) {
6220
6471
  break;
6221
6472
  }
6222
6473
  const node = this.nodes.get(closest.id);
@@ -6227,33 +6478,22 @@ var init_unified_memory = __esm({
6227
6478
  visited.add(neighborId);
6228
6479
  if (!this.nodes.has(neighborId)) continue;
6229
6480
  const score = this.similarity(query, neighborId);
6230
- const worstResult = results.length >= ef ? results[results.length - 1].score : -Infinity;
6231
- if (results.length < ef || score > worstResult) {
6232
- const candidateEntry = { id: neighborId, score };
6233
- let inserted = false;
6234
- for (let i58 = 0; i58 < candidates.length; i58++) {
6235
- if (score > candidates[i58].score) {
6236
- candidates.splice(i58, 0, candidateEntry);
6237
- inserted = true;
6238
- break;
6239
- }
6240
- }
6241
- if (!inserted) candidates.push(candidateEntry);
6242
- inserted = false;
6243
- for (let i58 = 0; i58 < results.length; i58++) {
6244
- if (score > results[i58].score) {
6245
- results.splice(i58, 0, candidateEntry);
6246
- inserted = true;
6247
- break;
6248
- }
6249
- }
6250
- if (!inserted) results.push(candidateEntry);
6251
- if (results.length > ef) {
6252
- results.pop();
6481
+ const worstResult = resultHeap.size() >= ef ? resultHeap.peek().score : -Infinity;
6482
+ if (resultHeap.size() < ef || score > worstResult) {
6483
+ const entry = { id: neighborId, score };
6484
+ candidateHeap.push(entry);
6485
+ resultHeap.push(entry);
6486
+ if (resultHeap.size() > ef) {
6487
+ resultHeap.pop();
6253
6488
  }
6254
6489
  }
6255
6490
  }
6256
6491
  }
6492
+ const results = [];
6493
+ while (resultHeap.size() > 0) {
6494
+ results.push(resultHeap.pop());
6495
+ }
6496
+ results.reverse();
6257
6497
  return results;
6258
6498
  }
6259
6499
  /**
@@ -6547,7 +6787,8 @@ var init_unified_memory = __esm({
6547
6787
  columnExists(tableName, columnName) {
6548
6788
  if (!this.db) return false;
6549
6789
  try {
6550
- const info = this.db.prepare(`PRAGMA table_info(${tableName})`).all();
6790
+ const safeName = validateTableName(tableName);
6791
+ const info = this.db.prepare(`PRAGMA table_info(${safeName})`).all();
6551
6792
  return info.some((col) => col.name === columnName);
6552
6793
  } catch {
6553
6794
  return false;
@@ -6585,7 +6826,7 @@ var init_unified_memory = __esm({
6585
6826
  ).get(table);
6586
6827
  if (tableExists && !this.columnExists(table, requiredColumn)) {
6587
6828
  console.log(`[UnifiedMemory] Upgrading v2 table: ${table} (missing ${requiredColumn})`);
6588
- this.db.exec(`DROP TABLE IF EXISTS ${table}`);
6829
+ this.db.exec(`DROP TABLE IF EXISTS ${validateTableName(table)}`);
6589
6830
  }
6590
6831
  }
6591
6832
  }
@@ -6766,17 +7007,23 @@ var init_unified_memory = __esm({
6766
7007
  return result.changes > 0;
6767
7008
  }
6768
7009
  /**
6769
- * Search for similar vectors
7010
+ * Search for similar vectors.
7011
+ * Uses batch SQL query instead of N+1 individual queries for metadata enrichment.
6770
7012
  */
6771
7013
  async vectorSearch(query, k68 = 10, namespace) {
6772
7014
  this.ensureInitialized();
6773
7015
  const results = this.vectorIndex.search(query, k68 * 2);
7016
+ if (results.length === 0) return [];
7017
+ const ids = results.map((r54) => r54.id);
7018
+ const placeholders = ids.map(() => "?").join(",");
7019
+ const rows = this.db.prepare(
7020
+ `SELECT id, namespace, metadata FROM vectors WHERE id IN (${placeholders})`
7021
+ ).all(...ids);
7022
+ const metadataMap = new Map(rows.map((row2) => [row2.id, row2]));
6774
7023
  if (namespace) {
6775
7024
  const filteredResults = [];
6776
7025
  for (const result of results) {
6777
- const row2 = this.db.prepare(
6778
- "SELECT namespace, metadata FROM vectors WHERE id = ?"
6779
- ).get(result.id);
7026
+ const row2 = metadataMap.get(result.id);
6780
7027
  if (row2 && row2.namespace === namespace) {
6781
7028
  filteredResults.push({
6782
7029
  id: result.id,
@@ -6789,9 +7036,7 @@ var init_unified_memory = __esm({
6789
7036
  return filteredResults;
6790
7037
  }
6791
7038
  return results.slice(0, k68).map((result) => {
6792
- const row2 = this.db.prepare(
6793
- "SELECT metadata FROM vectors WHERE id = ?"
6794
- ).get(result.id);
7039
+ const row2 = metadataMap.get(result.id);
6795
7040
  return {
6796
7041
  id: result.id,
6797
7042
  score: result.score,
@@ -11727,15 +11972,19 @@ var init_concept_graph = __esm({
11727
11972
  // Pattern Import
11728
11973
  // ==========================================================================
11729
11974
  /**
11730
- * Load patterns into the concept graph as nodes
11731
- * @returns Number of patterns loaded
11975
+ * Load patterns into the concept graph as nodes with edge discovery.
11976
+ * Idempotent skips patterns whose pattern_id already has a node.
11977
+ * After loading, discovers co_occurrence and similarity edges.
11978
+ * @returns Number of new patterns loaded
11732
11979
  */
11733
11980
  async loadFromPatterns(patterns) {
11734
11981
  this.ensureInitialized();
11735
11982
  let loaded = 0;
11736
11983
  for (const pattern of patterns) {
11737
11984
  try {
11738
- await this.addNode({
11985
+ const existing = await this.findNodeByPatternId(pattern.id);
11986
+ if (existing) continue;
11987
+ const patternNodeId = await this.addNode({
11739
11988
  conceptType: "pattern",
11740
11989
  content: `${pattern.name}: ${pattern.description}`,
11741
11990
  patternId: pattern.id,
@@ -11747,13 +11996,17 @@ var init_concept_graph = __esm({
11747
11996
  }
11748
11997
  });
11749
11998
  loaded++;
11750
- const domainNode = await this.findDomainNode(pattern.domain);
11999
+ let domainNode = await this.findDomainNode(pattern.domain);
11751
12000
  if (!domainNode) {
11752
- await this.addNode({
12001
+ const domainNodeId = await this.addNode({
11753
12002
  conceptType: "domain",
11754
12003
  content: pattern.domain,
11755
12004
  metadata: { patternCount: 1 }
11756
12005
  });
12006
+ domainNode = await this.getNode(domainNodeId);
12007
+ }
12008
+ if (domainNode) {
12009
+ await this.addEdge(patternNodeId, domainNode.id, "co_occurrence", 0.8);
11757
12010
  }
11758
12011
  } catch (error) {
11759
12012
  if (this.config.debug) {
@@ -11761,11 +12014,51 @@ var init_concept_graph = __esm({
11761
12014
  }
11762
12015
  }
11763
12016
  }
11764
- if (this.config.debug) {
11765
- console.log(`[ConceptGraph] Loaded ${loaded} patterns`);
12017
+ if (loaded > 0) {
12018
+ const edgesCreated = await this.discoverSameDomainEdges();
12019
+ if (this.config.debug) {
12020
+ console.log(`[ConceptGraph] Discovered ${edgesCreated} same-domain edges`);
12021
+ }
11766
12022
  }
12023
+ console.log(`[ConceptGraph] Loaded ${loaded} new patterns (${patterns.length - loaded} already existed)`);
11767
12024
  return loaded;
11768
12025
  }
12026
+ /**
12027
+ * Discover similarity edges between pattern nodes in the same domain.
12028
+ * Uses metadata.domain to group patterns, then creates bidirectional
12029
+ * similarity edges between siblings. Idempotent (addEdge strengthens
12030
+ * existing edges rather than duplicating).
12031
+ * @returns Number of new edges created
12032
+ */
12033
+ async discoverSameDomainEdges() {
12034
+ this.ensureInitialized();
12035
+ if (!this.db) return 0;
12036
+ const patternNodes = this.db.prepare(
12037
+ "SELECT * FROM concept_nodes WHERE concept_type = 'pattern'"
12038
+ ).all();
12039
+ const domainGroups = /* @__PURE__ */ new Map();
12040
+ for (const node of patternNodes) {
12041
+ const metadata = node.metadata ? JSON.parse(node.metadata) : {};
12042
+ const domain = metadata.domain || "unknown";
12043
+ if (!domainGroups.has(domain)) {
12044
+ domainGroups.set(domain, []);
12045
+ }
12046
+ domainGroups.get(domain).push(node);
12047
+ }
12048
+ let edgesCreated = 0;
12049
+ for (const [, nodes] of domainGroups) {
12050
+ for (let i58 = 0; i58 < nodes.length; i58++) {
12051
+ for (let j52 = i58 + 1; j52 < nodes.length; j52++) {
12052
+ const existingEdge = await this.getEdgeBetween(nodes[i58].id, nodes[j52].id);
12053
+ if (!existingEdge) {
12054
+ await this.addEdge(nodes[i58].id, nodes[j52].id, "similarity", 0.6);
12055
+ edgesCreated++;
12056
+ }
12057
+ }
12058
+ }
12059
+ }
12060
+ return edgesCreated;
12061
+ }
11769
12062
  // ==========================================================================
11770
12063
  // Statistics
11771
12064
  // ==========================================================================
@@ -11845,6 +12138,15 @@ var init_concept_graph = __esm({
11845
12138
  if (!row2) return null;
11846
12139
  return this.rowToNode(row2);
11847
12140
  }
12141
+ async findNodeByPatternId(patternId) {
12142
+ if (!this.db) return null;
12143
+ const stmt = this.db.prepare(
12144
+ "SELECT * FROM concept_nodes WHERE pattern_id = ? LIMIT 1"
12145
+ );
12146
+ const row2 = stmt.get(patternId);
12147
+ if (!row2) return null;
12148
+ return this.rowToNode(row2);
12149
+ }
11848
12150
  rowToNode(row2) {
11849
12151
  let embedding;
11850
12152
  if (row2.embedding) {
@@ -11885,6 +12187,46 @@ var init_concept_graph = __esm({
11885
12187
  });
11886
12188
 
11887
12189
  // src/learning/dream/spreading-activation.ts
12190
+ function quickselect(arr, k68) {
12191
+ if (k68 < 0 || k68 >= arr.length) return arr[0] ?? 0;
12192
+ let left = 0;
12193
+ let right = arr.length - 1;
12194
+ while (left < right) {
12195
+ const mid = left + right >> 1;
12196
+ if (arr[mid] < arr[left]) {
12197
+ const t51 = arr[left];
12198
+ arr[left] = arr[mid];
12199
+ arr[mid] = t51;
12200
+ }
12201
+ if (arr[right] < arr[left]) {
12202
+ const t51 = arr[left];
12203
+ arr[left] = arr[right];
12204
+ arr[right] = t51;
12205
+ }
12206
+ if (arr[mid] < arr[right]) {
12207
+ const t51 = arr[mid];
12208
+ arr[mid] = arr[right];
12209
+ arr[right] = t51;
12210
+ }
12211
+ const pivot = arr[right];
12212
+ let i58 = left;
12213
+ for (let j52 = left; j52 < right; j52++) {
12214
+ if (arr[j52] <= pivot) {
12215
+ const t51 = arr[i58];
12216
+ arr[i58] = arr[j52];
12217
+ arr[j52] = t51;
12218
+ i58++;
12219
+ }
12220
+ }
12221
+ const t50 = arr[i58];
12222
+ arr[i58] = arr[right];
12223
+ arr[right] = t50;
12224
+ if (i58 === k68) return arr[i58];
12225
+ if (i58 < k68) left = i58 + 1;
12226
+ else right = i58 - 1;
12227
+ }
12228
+ return arr[left];
12229
+ }
11888
12230
  var MAX_ACTIVATION_HISTORY_ENTRIES, MAX_COACTIVATION_ENTRIES, HISTORY_TRIM_TARGET_RATIO, DEFAULT_ACTIVATION_CONFIG, SpreadingActivation;
11889
12231
  var init_spreading_activation = __esm({
11890
12232
  "src/learning/dream/spreading-activation.ts"() {
@@ -12070,10 +12412,14 @@ var init_spreading_activation = __esm({
12070
12412
  */
12071
12413
  async findNovelAssociations(minActivation) {
12072
12414
  const threshold = minActivation ?? this.config.threshold;
12073
- const activeNodes = this.graph.getActiveNodes(threshold);
12415
+ let activeNodes = this.graph.getActiveNodes(threshold);
12074
12416
  if (activeNodes.length < 2) {
12075
12417
  return [];
12076
12418
  }
12419
+ const MAX_ACTIVE_NODES = 200;
12420
+ if (activeNodes.length > MAX_ACTIVE_NODES) {
12421
+ activeNodes = activeNodes.sort((a37, b68) => b68.activationLevel - a37.activationLevel).slice(0, MAX_ACTIVE_NODES);
12422
+ }
12077
12423
  const associations = [];
12078
12424
  for (let i58 = 0; i58 < activeNodes.length; i58++) {
12079
12425
  for (let j52 = i58 + 1; j52 < activeNodes.length; j52++) {
@@ -12155,9 +12501,17 @@ var init_spreading_activation = __esm({
12155
12501
  }
12156
12502
  const targetSize = Math.floor(MAX_COACTIVATION_ENTRIES * HISTORY_TRIM_TARGET_RATIO);
12157
12503
  const entriesToRemove = this.coActivationCounts.size - targetSize;
12158
- const sortedEntries = Array.from(this.coActivationCounts.entries()).sort((a37, b68) => a37[1] - b68[1]);
12159
- for (let i58 = 0; i58 < entriesToRemove && i58 < sortedEntries.length; i58++) {
12160
- this.coActivationCounts.delete(sortedEntries[i58][0]);
12504
+ const values = Array.from(this.coActivationCounts.values());
12505
+ const threshold = quickselect(values, entriesToRemove - 1);
12506
+ const toDelete = [];
12507
+ for (const [key, count] of this.coActivationCounts) {
12508
+ if (toDelete.length >= entriesToRemove) break;
12509
+ if (count <= threshold) {
12510
+ toDelete.push(key);
12511
+ }
12512
+ }
12513
+ for (const key of toDelete) {
12514
+ this.coActivationCounts.delete(key);
12161
12515
  }
12162
12516
  }
12163
12517
  /**
@@ -13018,6 +13372,7 @@ var init_dream_engine = __esm({
13018
13372
  await this.persistence.initialize();
13019
13373
  }
13020
13374
  this.db = this.persistence.getDatabase();
13375
+ this.migrateSchema();
13021
13376
  this.graph = new ConceptGraph();
13022
13377
  await this.graph.initialize();
13023
13378
  this.initialized = true;
@@ -13028,6 +13383,49 @@ var init_dream_engine = __esm({
13028
13383
  );
13029
13384
  }
13030
13385
  }
13386
+ /**
13387
+ * Migrate legacy schema if needed.
13388
+ * Handles the 'duration' → 'duration_ms' column rename in dream_cycles.
13389
+ */
13390
+ migrateSchema() {
13391
+ if (!this.db) return;
13392
+ try {
13393
+ const cycleCols = this.db.prepare("PRAGMA table_info(dream_cycles)").all();
13394
+ const hasDurationMs = cycleCols.some((c70) => c70.name === "duration_ms");
13395
+ const hasDuration = cycleCols.some((c70) => c70.name === "duration");
13396
+ if (!hasDurationMs && hasDuration) {
13397
+ this.db.exec("ALTER TABLE dream_cycles RENAME COLUMN duration TO duration_ms");
13398
+ }
13399
+ const insightCols = this.db.prepare("PRAGMA table_info(dream_insights)").all();
13400
+ const colNames = new Set(insightCols.map((c70) => c70.name));
13401
+ const hasInsightType = colNames.has("insight_type");
13402
+ const hasSourceConcepts = colNames.has("source_concepts");
13403
+ if (!hasInsightType || !hasSourceConcepts) {
13404
+ this.db.exec("DROP TABLE IF EXISTS dream_insights");
13405
+ this.db.exec(`
13406
+ CREATE TABLE IF NOT EXISTS dream_insights (
13407
+ id TEXT PRIMARY KEY,
13408
+ cycle_id TEXT NOT NULL,
13409
+ insight_type TEXT NOT NULL,
13410
+ source_concepts TEXT NOT NULL,
13411
+ description TEXT NOT NULL,
13412
+ novelty_score REAL DEFAULT 0.5,
13413
+ confidence_score REAL DEFAULT 0.5,
13414
+ actionable INTEGER DEFAULT 0,
13415
+ applied INTEGER DEFAULT 0,
13416
+ suggested_action TEXT,
13417
+ pattern_id TEXT,
13418
+ created_at TEXT DEFAULT (datetime('now')),
13419
+ FOREIGN KEY (cycle_id) REFERENCES dream_cycles(id) ON DELETE CASCADE
13420
+ )
13421
+ `);
13422
+ this.db.exec("CREATE INDEX IF NOT EXISTS idx_insight_cycle ON dream_insights(cycle_id)");
13423
+ this.db.exec("CREATE INDEX IF NOT EXISTS idx_insight_type ON dream_insights(insight_type)");
13424
+ this.db.exec("CREATE INDEX IF NOT EXISTS idx_insight_novelty ON dream_insights(novelty_score DESC)");
13425
+ }
13426
+ } catch {
13427
+ }
13428
+ }
13031
13429
  // ==========================================================================
13032
13430
  // Main Dream Cycle
13033
13431
  // ==========================================================================
@@ -13240,8 +13638,8 @@ var init_dream_engine = __esm({
13240
13638
  const stmt = this.db.prepare(`
13241
13639
  INSERT INTO dream_cycles
13242
13640
  (id, start_time, end_time, duration_ms, concepts_processed, associations_found,
13243
- insights_generated, status, error)
13244
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
13641
+ insights_generated, status, error, created_at)
13642
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
13245
13643
  `);
13246
13644
  stmt.run(
13247
13645
  cycle.id,
@@ -13252,7 +13650,8 @@ var init_dream_engine = __esm({
13252
13650
  cycle.associationsFound,
13253
13651
  cycle.insightsGenerated,
13254
13652
  cycle.status,
13255
- cycle.error ?? null
13653
+ cycle.error ?? null,
13654
+ cycle.startTime.toISOString()
13256
13655
  );
13257
13656
  }
13258
13657
  async updateCycle(cycle) {
@@ -15444,11 +15843,11 @@ var init_adapter = __esm({
15444
15843
  startTime
15445
15844
  );
15446
15845
  }
15447
- const cachedResult = this.cache.get(code, type);
15448
- if (cachedResult) {
15846
+ const cachedResult2 = this.cache.get(code, type);
15847
+ if (cachedResult2) {
15449
15848
  this.cacheHits++;
15450
15849
  this.logger.debug("Cache hit for transform", { type });
15451
- return { ...cachedResult, durationMs: Date.now() - startTime };
15850
+ return { ...cachedResult2, durationMs: Date.now() - startTime };
15452
15851
  }
15453
15852
  this.cacheMisses++;
15454
15853
  let result;
@@ -18348,13 +18747,16 @@ var init_pattern_store = __esm({
18348
18747
  (_56, reject) => setTimeout(() => reject(new Error("Pattern load timeout")), timeoutMs)
18349
18748
  );
18350
18749
  const keys = await Promise.race([searchPromise, timeoutPromise]);
18351
- for (const key of keys) {
18352
- try {
18353
- const pattern = await this.memory.get(key);
18750
+ const BATCH_SIZE = 50;
18751
+ for (let i58 = 0; i58 < keys.length; i58 += BATCH_SIZE) {
18752
+ const batch = keys.slice(i58, i58 + BATCH_SIZE);
18753
+ const patterns = await Promise.all(
18754
+ batch.map((key) => this.memory.get(key).catch(() => null))
18755
+ );
18756
+ for (const pattern of patterns) {
18354
18757
  if (pattern) {
18355
18758
  this.indexPattern(pattern);
18356
18759
  }
18357
- } catch {
18358
18760
  }
18359
18761
  }
18360
18762
  console.log(`[PatternStore] Loaded ${this.patternCache.size} patterns`);
@@ -18441,11 +18843,12 @@ var init_pattern_store = __esm({
18441
18843
  */
18442
18844
  async create(options) {
18443
18845
  const now = /* @__PURE__ */ new Date();
18846
+ const resolvedDomain = options.qeDomain || this.detectDomainFromType(options.patternType);
18444
18847
  const pattern = {
18445
18848
  id: v4_default(),
18446
18849
  patternType: options.patternType,
18447
- qeDomain: this.detectDomainFromType(options.patternType),
18448
- domain: mapQEDomainToAQE(this.detectDomainFromType(options.patternType)),
18850
+ qeDomain: resolvedDomain,
18851
+ domain: mapQEDomainToAQE(resolvedDomain),
18449
18852
  name: options.name,
18450
18853
  description: options.description,
18451
18854
  confidence: options.confidence ?? 0.5,
@@ -19025,6 +19428,11 @@ var init_qe_reasoning_bank = __esm({
19025
19428
  await this.patternStore.initialize();
19026
19429
  await this.loadPretrainedPatterns();
19027
19430
  this.initialized = true;
19431
+ try {
19432
+ await this.seedCrossDomainPatterns();
19433
+ } catch (error) {
19434
+ console.warn("[QEReasoningBank] Cross-domain seeding failed (non-fatal):", error);
19435
+ }
19028
19436
  console.log("[QEReasoningBank] Initialized");
19029
19437
  }
19030
19438
  /**
@@ -19149,6 +19557,602 @@ Check for:
19149
19557
  context: {
19150
19558
  tags: ["flaky", "timing", "async", "stability"]
19151
19559
  }
19560
+ },
19561
+ // ================================================================
19562
+ // quality-assessment domain seeds
19563
+ // ================================================================
19564
+ {
19565
+ patternType: "assertion-pattern",
19566
+ qeDomain: "quality-assessment",
19567
+ name: "Quality Gate Checklist",
19568
+ description: "Evaluate deployment readiness against quality gate criteria",
19569
+ template: {
19570
+ type: "prompt",
19571
+ content: `Quality gate evaluation for {{targetModule}}:
19572
+
19573
+ 1. Test coverage >= {{coverageThreshold}}%
19574
+ 2. No critical/high severity bugs open
19575
+ 3. All P1 tests passing
19576
+ 4. Performance benchmarks within SLA (p95 < {{latencyThresholdMs}}ms)
19577
+ 5. Security scan clean (no critical CVEs)
19578
+ 6. Code review approved
19579
+
19580
+ Fail the gate if ANY criterion is unmet. Report which criteria passed/failed.`,
19581
+ variables: [
19582
+ { name: "targetModule", type: "string", required: true, description: "Module or service to evaluate" },
19583
+ { name: "coverageThreshold", type: "number", required: false, defaultValue: 80, description: "Minimum coverage %" },
19584
+ { name: "latencyThresholdMs", type: "number", required: false, defaultValue: 500, description: "P95 latency limit in ms" }
19585
+ ]
19586
+ },
19587
+ context: {
19588
+ tags: ["quality-gate", "deployment", "readiness", "sla"]
19589
+ },
19590
+ confidence: 0.6
19591
+ },
19592
+ {
19593
+ patternType: "assertion-pattern",
19594
+ qeDomain: "quality-assessment",
19595
+ name: "Metric Threshold Validator",
19596
+ description: "Validate quality metrics against configurable thresholds",
19597
+ template: {
19598
+ type: "code",
19599
+ content: `function validateMetrics(metrics: Record<string, number>, thresholds: Record<string, { min?: number; max?: number }>) {
19600
+ const violations: string[] = [];
19601
+ for (const [metric, value] of Object.entries(metrics)) {
19602
+ const threshold = thresholds[metric];
19603
+ if (!threshold) continue;
19604
+ if (threshold.min !== undefined && value < threshold.min) {
19605
+ violations.push(\`\${metric}: \${value} < min \${threshold.min}\`);
19606
+ }
19607
+ if (threshold.max !== undefined && value > threshold.max) {
19608
+ violations.push(\`\${metric}: \${value} > max \${threshold.max}\`);
19609
+ }
19610
+ }
19611
+ return { pass: violations.length === 0, violations };
19612
+ }`,
19613
+ variables: []
19614
+ },
19615
+ context: {
19616
+ tags: ["metrics", "threshold", "validation", "scoring"]
19617
+ },
19618
+ confidence: 0.6
19619
+ },
19620
+ // ================================================================
19621
+ // defect-intelligence domain seeds
19622
+ // ================================================================
19623
+ {
19624
+ patternType: "error-handling",
19625
+ qeDomain: "defect-intelligence",
19626
+ name: "Root Cause Analysis Workflow",
19627
+ description: "Systematic root cause analysis for test failures and production incidents",
19628
+ template: {
19629
+ type: "prompt",
19630
+ content: `Root cause analysis for: {{incidentDescription}}
19631
+
19632
+ 1. **Reproduce**: Confirm the failure is deterministic
19633
+ 2. **Isolate**: Narrow down to the smallest failing component
19634
+ 3. **Timeline**: When did it last pass? What changed since?
19635
+ 4. **Categorize**: Is it a code bug, config issue, data issue, or environment?
19636
+ 5. **Five Whys**: Ask why at least 5 times to reach the root cause
19637
+ 6. **Fix**: Propose fix with test to prevent regression
19638
+ 7. **Verify**: Run the fix and confirm the original failure is resolved`,
19639
+ variables: [
19640
+ { name: "incidentDescription", type: "string", required: true, description: "Description of the failure or incident" }
19641
+ ]
19642
+ },
19643
+ context: {
19644
+ tags: ["root-cause", "rca", "debugging", "incident"]
19645
+ },
19646
+ confidence: 0.6
19647
+ },
19648
+ {
19649
+ patternType: "error-handling",
19650
+ qeDomain: "defect-intelligence",
19651
+ name: "Regression Risk Scorer",
19652
+ description: "Score change risk for regression based on code complexity and history",
19653
+ template: {
19654
+ type: "prompt",
19655
+ content: `Regression risk assessment for {{changePath}}:
19656
+
19657
+ Risk factors (score each 0-3):
19658
+ - Lines changed: {{linesChanged}} \u2192 complexity risk
19659
+ - Files affected: {{filesAffected}} \u2192 blast radius
19660
+ - Previous bugs in area: historical defect density
19661
+ - Test coverage of changed code: gap risk
19662
+ - Dependency depth: cascade risk
19663
+
19664
+ Total risk = sum / 15 \u2192 Low (<0.3), Medium (0.3-0.6), High (>0.6)`,
19665
+ variables: [
19666
+ { name: "changePath", type: "string", required: true, description: "File or module changed" },
19667
+ { name: "linesChanged", type: "number", required: true, description: "Number of lines changed" },
19668
+ { name: "filesAffected", type: "number", required: true, description: "Number of files affected" }
19669
+ ]
19670
+ },
19671
+ context: {
19672
+ tags: ["regression", "risk", "prediction", "change-analysis"]
19673
+ },
19674
+ confidence: 0.6
19675
+ },
19676
+ // ================================================================
19677
+ // requirements-validation domain seeds
19678
+ // ================================================================
19679
+ {
19680
+ patternType: "test-template",
19681
+ qeDomain: "requirements-validation",
19682
+ name: "Gherkin BDD Scenario",
19683
+ description: "Behavior-driven development scenario in Given/When/Then format",
19684
+ template: {
19685
+ type: "code",
19686
+ content: `Feature: {{featureName}}
19687
+
19688
+ Scenario: {{scenarioDescription}}
19689
+ Given {{precondition}}
19690
+ When {{action}}
19691
+ Then {{expectedOutcome}}
19692
+
19693
+ Scenario: {{scenarioDescription}} - error case
19694
+ Given {{precondition}}
19695
+ When {{errorAction}}
19696
+ Then {{errorOutcome}}`,
19697
+ variables: [
19698
+ { name: "featureName", type: "string", required: true, description: "Feature under test" },
19699
+ { name: "scenarioDescription", type: "string", required: true, description: "What the scenario validates" },
19700
+ { name: "precondition", type: "string", required: true, description: "Given precondition" },
19701
+ { name: "action", type: "string", required: true, description: "When action" },
19702
+ { name: "expectedOutcome", type: "string", required: true, description: "Then expected result" },
19703
+ { name: "errorAction", type: "string", required: true, description: "When error action" },
19704
+ { name: "errorOutcome", type: "string", required: true, description: "Then error result" }
19705
+ ]
19706
+ },
19707
+ context: {
19708
+ tags: ["bdd", "gherkin", "requirements", "acceptance"]
19709
+ },
19710
+ confidence: 0.6
19711
+ },
19712
+ {
19713
+ patternType: "test-template",
19714
+ qeDomain: "requirements-validation",
19715
+ name: "Acceptance Criteria Testability Check",
19716
+ description: "Evaluate whether acceptance criteria are testable and complete",
19717
+ template: {
19718
+ type: "prompt",
19719
+ content: `Testability assessment for: {{requirementId}} - {{requirementTitle}}
19720
+
19721
+ Acceptance criteria:
19722
+ {{acceptanceCriteria}}
19723
+
19724
+ Evaluate each criterion:
19725
+ 1. **Observable**: Can we verify the outcome without internal knowledge?
19726
+ 2. **Measurable**: Is there a quantifiable threshold or clear pass/fail?
19727
+ 3. **Atomic**: Does each criterion test exactly one thing?
19728
+ 4. **Achievable**: Can this be tested with available tools?
19729
+ 5. **Complete**: Are edge cases and error paths covered?
19730
+
19731
+ Flag any untestable or ambiguous criteria with suggested rewrites.`,
19732
+ variables: [
19733
+ { name: "requirementId", type: "string", required: true, description: "Requirement identifier" },
19734
+ { name: "requirementTitle", type: "string", required: true, description: "Requirement title" },
19735
+ { name: "acceptanceCriteria", type: "string", required: true, description: "The acceptance criteria text" }
19736
+ ]
19737
+ },
19738
+ context: {
19739
+ tags: ["requirements", "testability", "acceptance-criteria", "validation"]
19740
+ },
19741
+ confidence: 0.6
19742
+ },
19743
+ // ================================================================
19744
+ // code-intelligence domain seeds
19745
+ // ================================================================
19746
+ {
19747
+ patternType: "refactor-safe",
19748
+ name: "Safe Refactoring Checklist",
19749
+ description: "Ensure refactoring preserves behavior with systematic safety checks",
19750
+ template: {
19751
+ type: "prompt",
19752
+ content: `Safe refactoring checklist for {{targetPath}}:
19753
+
19754
+ Before refactoring:
19755
+ 1. Run existing tests \u2014 capture baseline results
19756
+ 2. Check coverage of code being refactored
19757
+ 3. Identify all callers and dependents via references
19758
+
19759
+ During refactoring:
19760
+ 4. Make one semantic change at a time
19761
+ 5. Keep public API signatures stable (or update all callers)
19762
+ 6. Preserve error handling contracts
19763
+
19764
+ After refactoring:
19765
+ 7. Run full test suite \u2014 compare to baseline
19766
+ 8. Check for any new uncovered paths
19767
+ 9. Verify no unused imports or dead code introduced`,
19768
+ variables: [
19769
+ { name: "targetPath", type: "string", required: true, description: "Path to refactor" }
19770
+ ]
19771
+ },
19772
+ context: {
19773
+ tags: ["refactor", "safety", "code-change", "impact"]
19774
+ },
19775
+ confidence: 0.6
19776
+ },
19777
+ {
19778
+ patternType: "refactor-safe",
19779
+ name: "Dependency Impact Analysis",
19780
+ description: "Analyze the blast radius of a code change through the dependency graph",
19781
+ template: {
19782
+ type: "prompt",
19783
+ content: `Impact analysis for changes in {{changedFile}}:
19784
+
19785
+ 1. Direct dependents: files that import/require {{changedFile}}
19786
+ 2. Transitive dependents: files that depend on direct dependents
19787
+ 3. Test coverage: which tests exercise the changed code?
19788
+ 4. Integration points: does this affect API contracts or events?
19789
+ 5. Risk tier: Critical (auth/payments) > High (business logic) > Medium (utils)
19790
+
19791
+ Output: sorted list of affected files with risk scores.`,
19792
+ variables: [
19793
+ { name: "changedFile", type: "string", required: true, description: "File being changed" }
19794
+ ]
19795
+ },
19796
+ context: {
19797
+ tags: ["impact", "dependency", "blast-radius", "analysis"]
19798
+ },
19799
+ confidence: 0.6
19800
+ },
19801
+ // ================================================================
19802
+ // security-compliance domain seeds
19803
+ // ================================================================
19804
+ {
19805
+ patternType: "assertion-pattern",
19806
+ qeDomain: "security-compliance",
19807
+ name: "OWASP Top 10 Security Audit",
19808
+ description: "Check code against OWASP Top 10 vulnerability categories",
19809
+ template: {
19810
+ type: "prompt",
19811
+ content: `Security audit for {{targetPath}} against OWASP Top 10:
19812
+
19813
+ 1. **A01 Broken Access Control**: Check authorization on every endpoint
19814
+ 2. **A02 Cryptographic Failures**: No plaintext secrets, proper hashing
19815
+ 3. **A03 Injection**: Parameterized queries, input sanitization
19816
+ 4. **A04 Insecure Design**: Threat modeling, least privilege
19817
+ 5. **A05 Security Misconfiguration**: Default creds, verbose errors
19818
+ 6. **A06 Vulnerable Components**: Check dependencies for CVEs
19819
+ 7. **A07 Auth Failures**: Brute force protection, session management
19820
+ 8. **A08 Data Integrity Failures**: Verify signatures, safe deserialization
19821
+ 9. **A09 Logging Failures**: Audit trail, no sensitive data in logs
19822
+ 10. **A10 SSRF**: Validate/allowlist outbound URLs
19823
+
19824
+ Flag findings as Critical/High/Medium/Low with remediation guidance.`,
19825
+ variables: [
19826
+ { name: "targetPath", type: "string", required: true, description: "Code path to audit" }
19827
+ ]
19828
+ },
19829
+ context: {
19830
+ tags: ["owasp", "security", "audit", "vulnerability"]
19831
+ },
19832
+ confidence: 0.6
19833
+ },
19834
+ {
19835
+ patternType: "assertion-pattern",
19836
+ qeDomain: "security-compliance",
19837
+ name: "Input Sanitization Pattern",
19838
+ description: "Validate and sanitize inputs at system boundaries to prevent injection",
19839
+ template: {
19840
+ type: "code",
19841
+ content: `// Input validation at system boundary
19842
+ function validateInput(input: unknown, schema: {
19843
+ type: 'string' | 'number' | 'boolean';
19844
+ maxLength?: number;
19845
+ pattern?: RegExp;
19846
+ allowedValues?: unknown[];
19847
+ }): { valid: boolean; sanitized: unknown; errors: string[] } {
19848
+ const errors: string[] = [];
19849
+ if (typeof input !== schema.type) {
19850
+ errors.push(\`Expected \${schema.type}, got \${typeof input}\`);
19851
+ return { valid: false, sanitized: null, errors };
19852
+ }
19853
+ if (schema.type === 'string') {
19854
+ let str = input as string;
19855
+ if (schema.maxLength && str.length > schema.maxLength) {
19856
+ str = str.slice(0, schema.maxLength);
19857
+ errors.push('Input truncated to max length');
19858
+ }
19859
+ if (schema.pattern && !schema.pattern.test(str)) {
19860
+ errors.push('Input does not match expected pattern');
19861
+ return { valid: false, sanitized: null, errors };
19862
+ }
19863
+ return { valid: errors.length === 0, sanitized: str, errors };
19864
+ }
19865
+ return { valid: true, sanitized: input, errors };
19866
+ }`,
19867
+ variables: []
19868
+ },
19869
+ context: {
19870
+ tags: ["security", "validation", "sanitization", "injection-prevention"]
19871
+ },
19872
+ confidence: 0.6
19873
+ },
19874
+ // ================================================================
19875
+ // contract-testing domain seeds
19876
+ // ================================================================
19877
+ {
19878
+ patternType: "api-contract",
19879
+ name: "OpenAPI Contract Validator",
19880
+ description: "Validate API responses against OpenAPI/Swagger schema",
19881
+ template: {
19882
+ type: "code",
19883
+ content: `describe('{{apiEndpoint}} contract', () => {
19884
+ it('should match the OpenAPI schema for {{operationId}}', async () => {
19885
+ const response = await request(app).{{httpMethod}}('{{apiEndpoint}}');
19886
+ expect(response.status).toBe({{expectedStatus}});
19887
+ expect(response.body).toMatchSchema(openApiSpec.paths['{{apiEndpoint}}'].{{httpMethod}}.responses['{{expectedStatus}}'].content['application/json'].schema);
19888
+ });
19889
+
19890
+ it('should return proper error for invalid input', async () => {
19891
+ const response = await request(app).{{httpMethod}}('{{apiEndpoint}}').send({{invalidPayload}});
19892
+ expect(response.status).toBe(400);
19893
+ expect(response.body).toHaveProperty('errors');
19894
+ });
19895
+ });`,
19896
+ variables: [
19897
+ { name: "apiEndpoint", type: "string", required: true, description: "API endpoint path" },
19898
+ { name: "operationId", type: "string", required: true, description: "OpenAPI operation ID" },
19899
+ { name: "httpMethod", type: "string", required: true, description: "HTTP method (get/post/put/delete)" },
19900
+ { name: "expectedStatus", type: "number", required: true, description: "Expected HTTP status code" },
19901
+ { name: "invalidPayload", type: "object", required: true, description: "Invalid request body for error case" }
19902
+ ]
19903
+ },
19904
+ context: {
19905
+ tags: ["api", "contract", "openapi", "schema-validation"]
19906
+ },
19907
+ confidence: 0.6
19908
+ },
19909
+ {
19910
+ patternType: "api-contract",
19911
+ name: "Consumer-Driven Contract Test",
19912
+ description: "Pact-style consumer-driven contract testing between services",
19913
+ template: {
19914
+ type: "code",
19915
+ content: `// Consumer side contract
19916
+ const pact = new Pact({
19917
+ consumer: '{{consumerName}}',
19918
+ provider: '{{providerName}}',
19919
+ });
19920
+
19921
+ describe('{{consumerName}} -> {{providerName}} contract', () => {
19922
+ beforeAll(() => pact.setup());
19923
+ afterAll(() => pact.finalize());
19924
+
19925
+ it('should receive {{expectedResource}}', async () => {
19926
+ await pact.addInteraction({
19927
+ state: '{{providerState}}',
19928
+ uponReceiving: '{{interactionDescription}}',
19929
+ withRequest: { method: '{{httpMethod}}', path: '{{requestPath}}' },
19930
+ willRespondWith: {
19931
+ status: 200,
19932
+ body: like({{expectedShape}}),
19933
+ },
19934
+ });
19935
+
19936
+ const result = await client.{{clientMethod}}();
19937
+ expect(result).toBeDefined();
19938
+ });
19939
+ });`,
19940
+ variables: [
19941
+ { name: "consumerName", type: "string", required: true, description: "Consumer service name" },
19942
+ { name: "providerName", type: "string", required: true, description: "Provider service name" },
19943
+ { name: "expectedResource", type: "string", required: true, description: "Resource being consumed" },
19944
+ { name: "providerState", type: "string", required: true, description: "Provider state precondition" },
19945
+ { name: "interactionDescription", type: "string", required: true, description: "Interaction description" },
19946
+ { name: "httpMethod", type: "string", required: true, description: "HTTP method" },
19947
+ { name: "requestPath", type: "string", required: true, description: "Request path" },
19948
+ { name: "expectedShape", type: "object", required: true, description: "Expected response shape" },
19949
+ { name: "clientMethod", type: "string", required: true, description: "Client method to call" }
19950
+ ]
19951
+ },
19952
+ context: {
19953
+ tags: ["contract", "pact", "consumer-driven", "microservice"]
19954
+ },
19955
+ confidence: 0.6
19956
+ },
19957
+ // ================================================================
19958
+ // visual-accessibility domain seeds
19959
+ // ================================================================
19960
+ {
19961
+ patternType: "a11y-check",
19962
+ name: "WCAG Contrast and ARIA Check",
19963
+ description: "Validate WCAG 2.2 color contrast ratios and ARIA attribute correctness",
19964
+ template: {
19965
+ type: "prompt",
19966
+ content: `Accessibility audit for {{componentName}}:
19967
+
19968
+ WCAG 2.2 AA Compliance:
19969
+ 1. **Color Contrast**: Text contrast ratio >= 4.5:1 (normal), >= 3:1 (large)
19970
+ 2. **ARIA Roles**: All interactive elements have correct role attributes
19971
+ 3. **ARIA Labels**: Forms and buttons have aria-label or aria-labelledby
19972
+ 4. **Focus Management**: Tab order is logical, focus visible on all interactive elements
19973
+ 5. **Screen Reader**: Content is meaningful when linearized
19974
+ 6. **Keyboard**: All functionality accessible via keyboard alone
19975
+
19976
+ Test with: axe-core, pa11y, or lighthouse --accessibility`,
19977
+ variables: [
19978
+ { name: "componentName", type: "string", required: true, description: "UI component to audit" }
19979
+ ]
19980
+ },
19981
+ context: {
19982
+ tags: ["wcag", "accessibility", "aria", "contrast", "a11y"]
19983
+ },
19984
+ confidence: 0.6
19985
+ },
19986
+ {
19987
+ patternType: "visual-baseline",
19988
+ name: "Visual Regression Baseline",
19989
+ description: "Capture and compare screenshots for visual regression detection",
19990
+ template: {
19991
+ type: "code",
19992
+ content: `describe('{{pageName}} visual regression', () => {
19993
+ it('should match baseline screenshot', async () => {
19994
+ await page.goto('{{pageUrl}}');
19995
+ await page.waitForLoadState('networkidle');
19996
+
19997
+ const screenshot = await page.screenshot({ fullPage: {{fullPage}} });
19998
+ expect(screenshot).toMatchSnapshot('{{pageName}}-baseline.png', {
19999
+ maxDiffPixelRatio: {{maxDiffRatio}},
20000
+ });
20001
+ });
20002
+
20003
+ it('should match baseline at mobile viewport', async () => {
20004
+ await page.setViewportSize({ width: 375, height: 812 });
20005
+ await page.goto('{{pageUrl}}');
20006
+ const screenshot = await page.screenshot({ fullPage: {{fullPage}} });
20007
+ expect(screenshot).toMatchSnapshot('{{pageName}}-mobile-baseline.png', {
20008
+ maxDiffPixelRatio: {{maxDiffRatio}},
20009
+ });
20010
+ });
20011
+ });`,
20012
+ variables: [
20013
+ { name: "pageName", type: "string", required: true, description: "Page name for snapshot naming" },
20014
+ { name: "pageUrl", type: "string", required: true, description: "Page URL to capture" },
20015
+ { name: "fullPage", type: "boolean", required: false, defaultValue: true, description: "Capture full page" },
20016
+ { name: "maxDiffRatio", type: "number", required: false, defaultValue: 0.01, description: "Max pixel diff ratio" }
20017
+ ]
20018
+ },
20019
+ context: {
20020
+ tags: ["visual", "screenshot", "regression", "baseline", "playwright"]
20021
+ },
20022
+ confidence: 0.6
20023
+ },
20024
+ // ================================================================
20025
+ // chaos-resilience domain seeds
20026
+ // ================================================================
20027
+ {
20028
+ patternType: "perf-benchmark",
20029
+ name: "Load Test Scenario",
20030
+ description: "k6-style load test with ramp-up stages and SLA assertions",
20031
+ template: {
20032
+ type: "code",
20033
+ content: `import http from 'k6/http';
20034
+ import { check, sleep } from 'k6';
20035
+
20036
+ export const options = {
20037
+ stages: [
20038
+ { duration: '{{rampUpDuration}}', target: {{peakUsers}} },
20039
+ { duration: '{{steadyDuration}}', target: {{peakUsers}} },
20040
+ { duration: '{{rampDownDuration}}', target: 0 },
20041
+ ],
20042
+ thresholds: {
20043
+ http_req_duration: ['p(95)<{{p95ThresholdMs}}'],
20044
+ http_req_failed: ['rate<{{errorRateThreshold}}'],
20045
+ },
20046
+ };
20047
+
20048
+ export default function () {
20049
+ const res = http.get('{{targetUrl}}');
20050
+ check(res, {
20051
+ 'status is 200': (r) => r.status === 200,
20052
+ 'response time < {{p95ThresholdMs}}ms': (r) => r.timings.duration < {{p95ThresholdMs}},
20053
+ });
20054
+ sleep(1);
20055
+ }`,
20056
+ variables: [
20057
+ { name: "targetUrl", type: "string", required: true, description: "Target URL to load test" },
20058
+ { name: "peakUsers", type: "number", required: true, description: "Peak concurrent users" },
20059
+ { name: "rampUpDuration", type: "string", required: false, defaultValue: "2m", description: "Ramp-up duration" },
20060
+ { name: "steadyDuration", type: "string", required: false, defaultValue: "5m", description: "Steady state duration" },
20061
+ { name: "rampDownDuration", type: "string", required: false, defaultValue: "1m", description: "Ramp-down duration" },
20062
+ { name: "p95ThresholdMs", type: "number", required: false, defaultValue: 500, description: "P95 latency threshold in ms" },
20063
+ { name: "errorRateThreshold", type: "number", required: false, defaultValue: 0.01, description: "Max error rate (0-1)" }
20064
+ ]
20065
+ },
20066
+ context: {
20067
+ tags: ["load-test", "k6", "performance", "sla"]
20068
+ },
20069
+ confidence: 0.6
20070
+ },
20071
+ {
20072
+ patternType: "perf-benchmark",
20073
+ name: "Circuit Breaker Resilience Test",
20074
+ description: "Test circuit breaker behavior under fault injection",
20075
+ template: {
20076
+ type: "prompt",
20077
+ content: `Resilience test for {{serviceName}} circuit breaker:
20078
+
20079
+ 1. **Closed state**: Verify normal requests pass through
20080
+ 2. **Fault injection**: Inject {{faultType}} faults at {{faultRate}}% rate
20081
+ 3. **Trip threshold**: Verify breaker opens after {{failureThreshold}} consecutive failures
20082
+ 4. **Open state**: Verify requests fail fast (no upstream calls)
20083
+ 5. **Half-open probe**: After {{cooldownMs}}ms, verify single probe request
20084
+ 6. **Recovery**: On probe success, verify breaker closes and traffic resumes
20085
+ 7. **Metrics**: Verify circuit state changes are logged and observable`,
20086
+ variables: [
20087
+ { name: "serviceName", type: "string", required: true, description: "Service with circuit breaker" },
20088
+ { name: "faultType", type: "string", required: false, defaultValue: "latency", description: "Type of fault (latency/error/timeout)" },
20089
+ { name: "faultRate", type: "number", required: false, defaultValue: 50, description: "Fault injection rate %" },
20090
+ { name: "failureThreshold", type: "number", required: false, defaultValue: 5, description: "Failures to trip breaker" },
20091
+ { name: "cooldownMs", type: "number", required: false, defaultValue: 3e4, description: "Cooldown before half-open" }
20092
+ ]
20093
+ },
20094
+ context: {
20095
+ tags: ["chaos", "circuit-breaker", "resilience", "fault-injection"]
20096
+ },
20097
+ confidence: 0.6
20098
+ },
20099
+ // ================================================================
20100
+ // learning-optimization domain seeds
20101
+ // ================================================================
20102
+ {
20103
+ patternType: "coverage-strategy",
20104
+ qeDomain: "learning-optimization",
20105
+ name: "Cross-Domain Pattern Transfer",
20106
+ description: "Strategy for transferring useful patterns from one QE domain to related domains",
20107
+ template: {
20108
+ type: "prompt",
20109
+ content: `Pattern transfer from {{sourceDomain}} to {{targetDomain}}:
20110
+
20111
+ 1. Identify generalizable patterns in source domain (success rate > 70%)
20112
+ 2. Check domain compatibility (related domains get 80% relevance, unrelated 50%)
20113
+ 3. Adapt pattern context: replace domain-specific terms with target equivalents
20114
+ 4. Set transferred pattern confidence to source * compatibility factor
20115
+ 5. Store in target domain with provenance metadata
20116
+ 6. Track transfer outcomes to learn which transfers are valuable`,
20117
+ variables: [
20118
+ { name: "sourceDomain", type: "string", required: true, description: "Source QE domain" },
20119
+ { name: "targetDomain", type: "string", required: true, description: "Target QE domain" }
20120
+ ]
20121
+ },
20122
+ context: {
20123
+ tags: ["transfer", "cross-domain", "learning", "pattern-reuse"]
20124
+ },
20125
+ confidence: 0.6
20126
+ },
20127
+ {
20128
+ patternType: "coverage-strategy",
20129
+ qeDomain: "learning-optimization",
20130
+ name: "Pattern Quality Promotion Pipeline",
20131
+ description: "Pipeline for promoting short-term patterns to long-term based on success evidence",
20132
+ template: {
20133
+ type: "prompt",
20134
+ content: `Pattern promotion evaluation for {{patternName}}:
20135
+
20136
+ Criteria (all must pass):
20137
+ 1. Usage count >= 3 successful applications
20138
+ 2. Success rate >= 70%
20139
+ 3. Confidence score >= 0.6
20140
+ 4. Coherence check: no contradiction with existing long-term patterns
20141
+ 5. Age: pattern has existed for at least 24 hours (not rushed)
20142
+
20143
+ On promotion:
20144
+ - Move from short-term to long-term tier
20145
+ - Boost confidence by 10%
20146
+ - Enable for cross-domain transfer to related domains
20147
+ - Mark as reusable for token savings optimization`,
20148
+ variables: [
20149
+ { name: "patternName", type: "string", required: true, description: "Pattern to evaluate for promotion" }
20150
+ ]
20151
+ },
20152
+ context: {
20153
+ tags: ["promotion", "learning", "quality", "pipeline"]
20154
+ },
20155
+ confidence: 0.6
19152
20156
  }
19153
20157
  ];
19154
20158
  for (const options of foundationalPatterns) {
@@ -19160,6 +20164,92 @@ Check for:
19160
20164
  }
19161
20165
  console.log(`[QEReasoningBank] Loaded ${foundationalPatterns.length} foundational patterns`);
19162
20166
  }
20167
+ /**
20168
+ * Seed cross-domain patterns by transferring generalizable patterns
20169
+ * from populated domains to their related domains.
20170
+ *
20171
+ * Uses the domain compatibility matrix to determine which domains
20172
+ * are related and applies a relevance decay to transferred patterns.
20173
+ */
20174
+ async seedCrossDomainPatterns() {
20175
+ if (!this.initialized) {
20176
+ await this.initialize();
20177
+ }
20178
+ const stats = await this.patternStore.getStats();
20179
+ let transferred = 0;
20180
+ let skipped = 0;
20181
+ const relatedDomains = {
20182
+ "test-generation": ["test-execution", "coverage-analysis", "requirements-validation"],
20183
+ "test-execution": ["test-generation", "coverage-analysis", "quality-assessment"],
20184
+ "coverage-analysis": ["test-generation", "test-execution", "quality-assessment"],
20185
+ "quality-assessment": ["test-execution", "coverage-analysis", "defect-intelligence"],
20186
+ "defect-intelligence": ["quality-assessment", "code-intelligence"],
20187
+ "requirements-validation": ["test-generation", "quality-assessment"],
20188
+ "code-intelligence": ["defect-intelligence", "security-compliance"],
20189
+ "security-compliance": ["code-intelligence", "quality-assessment"],
20190
+ "contract-testing": ["test-generation", "test-execution"],
20191
+ "visual-accessibility": ["quality-assessment"],
20192
+ "chaos-resilience": ["test-execution", "quality-assessment"],
20193
+ "learning-optimization": ["test-generation", "test-execution", "coverage-analysis", "quality-assessment", "defect-intelligence"]
20194
+ };
20195
+ for (const [sourceDomainStr, targetDomains] of Object.entries(relatedDomains)) {
20196
+ const sourceDomain = sourceDomainStr;
20197
+ const sourceCount = stats.byDomain[sourceDomain] || 0;
20198
+ if (sourceCount === 0) continue;
20199
+ const sourceResult = await this.searchPatterns("", {
20200
+ domain: sourceDomain,
20201
+ limit: 50
20202
+ });
20203
+ if (!sourceResult.success) continue;
20204
+ for (const targetDomain of targetDomains) {
20205
+ const targetCount = stats.byDomain[targetDomain] || 0;
20206
+ if (targetCount >= sourceCount) {
20207
+ skipped++;
20208
+ continue;
20209
+ }
20210
+ for (const { pattern: sourcePattern } of sourceResult.value) {
20211
+ const existingCheck = await this.searchPatterns(sourcePattern.name, {
20212
+ domain: targetDomain,
20213
+ limit: 1
20214
+ });
20215
+ if (existingCheck.success && existingCheck.value.length > 0) {
20216
+ const bestMatch = existingCheck.value[0];
20217
+ if (bestMatch.score > 0.8) {
20218
+ skipped++;
20219
+ continue;
20220
+ }
20221
+ }
20222
+ const transferredConfidence = Math.max(0.3, (sourcePattern.confidence || 0.5) * 0.8);
20223
+ const transferResult = await this.storePattern({
20224
+ patternType: sourcePattern.patternType,
20225
+ qeDomain: targetDomain,
20226
+ name: `${sourcePattern.name} (from ${sourceDomain})`,
20227
+ description: `${sourcePattern.description} [Transferred from ${sourceDomain} domain]`,
20228
+ template: sourcePattern.template,
20229
+ context: {
20230
+ ...sourcePattern.context,
20231
+ relatedDomains: [sourceDomain, targetDomain],
20232
+ tags: [
20233
+ ...sourcePattern.context.tags,
20234
+ "cross-domain-transfer",
20235
+ `source:${sourceDomain}`
20236
+ ]
20237
+ },
20238
+ confidence: transferredConfidence
20239
+ });
20240
+ if (transferResult.success) {
20241
+ transferred++;
20242
+ } else {
20243
+ skipped++;
20244
+ }
20245
+ }
20246
+ }
20247
+ }
20248
+ console.log(
20249
+ `[QEReasoningBank] Cross-domain transfer complete: ${transferred} transferred, ${skipped} skipped`
20250
+ );
20251
+ return { transferred, skipped };
20252
+ }
19163
20253
  /**
19164
20254
  * Store a new pattern
19165
20255
  */
@@ -19227,6 +20317,20 @@ Check for:
19227
20317
  outcome.patternId,
19228
20318
  outcome.success
19229
20319
  );
20320
+ try {
20321
+ const { getUnifiedMemory: getUnifiedMemory2 } = await Promise.resolve().then(() => (init_unified_memory(), unified_memory_exports));
20322
+ const db = getUnifiedMemory2().getDatabase();
20323
+ db.prepare(`
20324
+ INSERT INTO qe_pattern_usage (pattern_id, success, metrics_json, feedback)
20325
+ VALUES (?, ?, ?, ?)
20326
+ `).run(
20327
+ outcome.patternId,
20328
+ outcome.success ? 1 : 0,
20329
+ outcome.metrics ? JSON.stringify(outcome.metrics) : null,
20330
+ outcome.feedback || null
20331
+ );
20332
+ } catch {
20333
+ }
19230
20334
  if (result.success) {
19231
20335
  this.stats.learningOutcomes++;
19232
20336
  if (outcome.success) {
@@ -19555,11 +20659,96 @@ Check for:
19555
20659
  }
19556
20660
  });
19557
20661
 
20662
+ // src/adapters/claude-flow/detect.ts
20663
+ import { existsSync as existsSync12, readFileSync as readFileSync10 } from "node:fs";
20664
+ import { join as join17 } from "node:path";
20665
+ import { execSync as execSync6 } from "node:child_process";
20666
+ function detectClaudeFlow(projectRoot) {
20667
+ if (cachedResult && Date.now() - cacheTimestamp < CACHE_TTL_MS2) {
20668
+ return cachedResult;
20669
+ }
20670
+ const result = doDetection(projectRoot);
20671
+ cachedResult = result;
20672
+ cacheTimestamp = Date.now();
20673
+ return result;
20674
+ }
20675
+ function doDetection(projectRoot) {
20676
+ const mcpResult = checkMCPConfig(projectRoot);
20677
+ if (mcpResult) return mcpResult;
20678
+ const pkgResult = checkPackageJson(projectRoot);
20679
+ if (pkgResult) return pkgResult;
20680
+ const binaryResult = checkLocalBinary(projectRoot);
20681
+ if (binaryResult) return binaryResult;
20682
+ return { available: false };
20683
+ }
20684
+ function checkMCPConfig(projectRoot) {
20685
+ const mcpJsonPath = join17(projectRoot, ".claude", "mcp.json");
20686
+ if (existsSync12(mcpJsonPath)) {
20687
+ try {
20688
+ const config = JSON.parse(readFileSync10(mcpJsonPath, "utf-8"));
20689
+ if (config.mcpServers?.["claude-flow"]) {
20690
+ return { available: true, method: "mcp-config" };
20691
+ }
20692
+ } catch {
20693
+ }
20694
+ }
20695
+ const settingsPath = join17(projectRoot, ".claude", "settings.json");
20696
+ if (existsSync12(settingsPath)) {
20697
+ try {
20698
+ const settings = JSON.parse(readFileSync10(settingsPath, "utf-8"));
20699
+ const servers = settings.mcpServers || settings.mcp?.servers || {};
20700
+ if (servers["claude-flow"] || servers["@anthropic/claude-flow"]) {
20701
+ return { available: true, method: "mcp-config" };
20702
+ }
20703
+ } catch {
20704
+ }
20705
+ }
20706
+ return null;
20707
+ }
20708
+ function checkPackageJson(projectRoot) {
20709
+ const packageJsonPath = join17(projectRoot, "package.json");
20710
+ if (!existsSync12(packageJsonPath)) return null;
20711
+ try {
20712
+ const pkg2 = JSON.parse(readFileSync10(packageJsonPath, "utf-8"));
20713
+ const deps = { ...pkg2.dependencies, ...pkg2.devDependencies };
20714
+ if (deps["@claude-flow/cli"] || deps["claude-flow"]) {
20715
+ return { available: true, method: "npm-dependency" };
20716
+ }
20717
+ } catch {
20718
+ }
20719
+ return null;
20720
+ }
20721
+ function checkLocalBinary(projectRoot) {
20722
+ try {
20723
+ const result = execSync6("npx --no-install @claude-flow/cli --version", {
20724
+ encoding: "utf-8",
20725
+ timeout: 5e3,
20726
+ cwd: projectRoot,
20727
+ stdio: ["pipe", "pipe", "pipe"]
20728
+ // suppress stderr noise
20729
+ });
20730
+ const version = result.trim().match(/\d+\.\d+\.\d+[\w.-]*/)?.[0];
20731
+ return { available: true, method: "npx-cached", version };
20732
+ } catch {
20733
+ }
20734
+ return null;
20735
+ }
20736
+ var cachedResult, cacheTimestamp, CACHE_TTL_MS2;
20737
+ var init_detect = __esm({
20738
+ "src/adapters/claude-flow/detect.ts"() {
20739
+ "use strict";
20740
+ cachedResult = null;
20741
+ cacheTimestamp = 0;
20742
+ CACHE_TTL_MS2 = 6e4;
20743
+ }
20744
+ });
20745
+
19558
20746
  // src/adapters/claude-flow/trajectory-bridge.ts
19559
20747
  var TrajectoryBridge;
19560
20748
  var init_trajectory_bridge = __esm({
19561
20749
  "src/adapters/claude-flow/trajectory-bridge.ts"() {
19562
20750
  "use strict";
20751
+ init_detect();
19563
20752
  TrajectoryBridge = class {
19564
20753
  constructor(options) {
19565
20754
  this.options = options;
@@ -19573,20 +20762,10 @@ var init_trajectory_bridge = __esm({
19573
20762
  this.claudeFlowAvailable = await this.checkClaudeFlow();
19574
20763
  }
19575
20764
  /**
19576
- * Check if Claude Flow is available
20765
+ * Check if Claude Flow is available (no npm auto-install)
19577
20766
  */
19578
20767
  async checkClaudeFlow() {
19579
- try {
19580
- const { execSync: execSync6 } = await import("child_process");
19581
- execSync6("npx @claude-flow/cli@latest hooks metrics --period 1h", {
19582
- encoding: "utf-8",
19583
- timeout: 5e3,
19584
- cwd: this.options.projectRoot
19585
- });
19586
- return true;
19587
- } catch {
19588
- return false;
19589
- }
20768
+ return detectClaudeFlow(this.options.projectRoot).available;
19590
20769
  }
19591
20770
  /**
19592
20771
  * Start a new trajectory
@@ -19595,10 +20774,10 @@ var init_trajectory_bridge = __esm({
19595
20774
  const id = `trajectory-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
19596
20775
  if (this.claudeFlowAvailable) {
19597
20776
  try {
19598
- const { execSync: execSync6 } = await import("child_process");
20777
+ const { execSync: execSync7 } = await import("child_process");
19599
20778
  const agentArg = agent ? `--agent ${this.escapeArg(agent)}` : "";
19600
- const result = execSync6(
19601
- `npx @claude-flow/cli@latest hooks intelligence trajectory-start --task ${this.escapeArg(task)} ${agentArg}`,
20779
+ const result = execSync7(
20780
+ `npx --no-install @claude-flow/cli hooks intelligence trajectory-start --task ${this.escapeArg(task)} ${agentArg}`,
19602
20781
  { encoding: "utf-8", timeout: 1e4, cwd: this.options.projectRoot }
19603
20782
  );
19604
20783
  const match = result.match(/trajectoryId[:\s]+["']?([^"'\s,}]+)/i);
@@ -19624,11 +20803,11 @@ var init_trajectory_bridge = __esm({
19624
20803
  async recordStep(trajectoryId, action, result, quality) {
19625
20804
  if (this.claudeFlowAvailable) {
19626
20805
  try {
19627
- const { execSync: execSync6 } = await import("child_process");
20806
+ const { execSync: execSync7 } = await import("child_process");
19628
20807
  const resultArg = result ? `--result ${this.escapeArg(result)}` : "";
19629
20808
  const qualityArg = quality !== void 0 ? `--quality ${quality}` : "";
19630
- execSync6(
19631
- `npx @claude-flow/cli@latest hooks intelligence trajectory-step --trajectory-id ${this.escapeArg(trajectoryId)} --action ${this.escapeArg(action)} ${resultArg} ${qualityArg}`,
20809
+ execSync7(
20810
+ `npx --no-install @claude-flow/cli hooks intelligence trajectory-step --trajectory-id ${this.escapeArg(trajectoryId)} --action ${this.escapeArg(action)} ${resultArg} ${qualityArg}`,
19632
20811
  { encoding: "utf-8", timeout: 1e4, cwd: this.options.projectRoot }
19633
20812
  );
19634
20813
  return;
@@ -19653,10 +20832,10 @@ var init_trajectory_bridge = __esm({
19653
20832
  async endTrajectory(trajectoryId, success, feedback) {
19654
20833
  if (this.claudeFlowAvailable) {
19655
20834
  try {
19656
- const { execSync: execSync6 } = await import("child_process");
20835
+ const { execSync: execSync7 } = await import("child_process");
19657
20836
  const feedbackArg = feedback ? `--feedback ${this.escapeArg(feedback)}` : "";
19658
- execSync6(
19659
- `npx @claude-flow/cli@latest hooks intelligence trajectory-end --trajectory-id ${this.escapeArg(trajectoryId)} --success ${success} ${feedbackArg}`,
20837
+ execSync7(
20838
+ `npx --no-install @claude-flow/cli hooks intelligence trajectory-end --trajectory-id ${this.escapeArg(trajectoryId)} --success ${success} ${feedbackArg}`,
19660
20839
  { encoding: "utf-8", timeout: 1e4, cwd: this.options.projectRoot }
19661
20840
  );
19662
20841
  } catch {
@@ -19689,14 +20868,14 @@ var init_trajectory_bridge = __esm({
19689
20868
  */
19690
20869
  async persistTrajectory(trajectory) {
19691
20870
  try {
19692
- const { join: join25 } = await import("path");
19693
- const { existsSync: existsSync17, mkdirSync: mkdirSync6 } = await import("fs");
20871
+ const { join: join26 } = await import("path");
20872
+ const { existsSync: existsSync18, mkdirSync: mkdirSync6 } = await import("fs");
19694
20873
  const { createRequire: createRequire4 } = await import("module");
19695
20874
  const require3 = createRequire4(import.meta.url);
19696
20875
  const Database6 = require3("better-sqlite3");
19697
- const dbPath = join25(this.options.projectRoot, ".agentic-qe", "trajectories.db");
19698
- const dir = join25(this.options.projectRoot, ".agentic-qe");
19699
- if (!existsSync17(dir)) {
20876
+ const dbPath = join26(this.options.projectRoot, ".agentic-qe", "trajectories.db");
20877
+ const dir = join26(this.options.projectRoot, ".agentic-qe");
20878
+ if (!existsSync18(dir)) {
19700
20879
  mkdirSync6(dir, { recursive: true });
19701
20880
  }
19702
20881
  const db = new Database6(dbPath);
@@ -19750,6 +20929,7 @@ var COMPLEXITY_INDICATORS, ModelRouterBridge;
19750
20929
  var init_model_router_bridge = __esm({
19751
20930
  "src/adapters/claude-flow/model-router-bridge.ts"() {
19752
20931
  "use strict";
20932
+ init_detect();
19753
20933
  COMPLEXITY_INDICATORS = {
19754
20934
  low: [
19755
20935
  /simple/i,
@@ -19790,20 +20970,10 @@ var init_model_router_bridge = __esm({
19790
20970
  this.claudeFlowAvailable = await this.checkClaudeFlow();
19791
20971
  }
19792
20972
  /**
19793
- * Check if Claude Flow is available
20973
+ * Check if Claude Flow is available (no npm auto-install)
19794
20974
  */
19795
20975
  async checkClaudeFlow() {
19796
- try {
19797
- const { execSync: execSync6 } = await import("child_process");
19798
- execSync6("npx @claude-flow/cli@latest hooks model-stats", {
19799
- encoding: "utf-8",
19800
- timeout: 5e3,
19801
- cwd: this.options.projectRoot
19802
- });
19803
- return true;
19804
- } catch {
19805
- return false;
19806
- }
20976
+ return detectClaudeFlow(this.options.projectRoot).available;
19807
20977
  }
19808
20978
  /**
19809
20979
  * Route task to optimal model
@@ -19811,9 +20981,9 @@ var init_model_router_bridge = __esm({
19811
20981
  async routeTask(task) {
19812
20982
  if (this.claudeFlowAvailable) {
19813
20983
  try {
19814
- const { execSync: execSync6 } = await import("child_process");
19815
- const result = execSync6(
19816
- `npx @claude-flow/cli@latest hooks model-route --task ${this.escapeArg(task)}`,
20984
+ const { execSync: execSync7 } = await import("child_process");
20985
+ const result = execSync7(
20986
+ `npx --no-install @claude-flow/cli hooks model-route --task ${this.escapeArg(task)}`,
19817
20987
  { encoding: "utf-8", timeout: 1e4, cwd: this.options.projectRoot }
19818
20988
  );
19819
20989
  const modelMatch = result.match(/model[:\s]+["']?(haiku|sonnet|opus)/i);
@@ -19842,9 +21012,9 @@ var init_model_router_bridge = __esm({
19842
21012
  }
19843
21013
  if (this.claudeFlowAvailable) {
19844
21014
  try {
19845
- const { execSync: execSync6 } = await import("child_process");
19846
- execSync6(
19847
- `npx @claude-flow/cli@latest hooks model-outcome --task ${this.escapeArg(outcome.task)} --model ${outcome.model} --outcome ${outcome.outcome}`,
21015
+ const { execSync: execSync7 } = await import("child_process");
21016
+ execSync7(
21017
+ `npx --no-install @claude-flow/cli hooks model-outcome --task ${this.escapeArg(outcome.task)} --model ${outcome.model} --outcome ${outcome.outcome}`,
19848
21018
  { encoding: "utf-8", timeout: 1e4, cwd: this.options.projectRoot }
19849
21019
  );
19850
21020
  } catch (error) {
@@ -19941,6 +21111,7 @@ var PretrainBridge;
19941
21111
  var init_pretrain_bridge = __esm({
19942
21112
  "src/adapters/claude-flow/pretrain-bridge.ts"() {
19943
21113
  "use strict";
21114
+ init_detect();
19944
21115
  PretrainBridge = class {
19945
21116
  constructor(options) {
19946
21117
  this.options = options;
@@ -19954,20 +21125,10 @@ var init_pretrain_bridge = __esm({
19954
21125
  this.claudeFlowAvailable = await this.checkClaudeFlow();
19955
21126
  }
19956
21127
  /**
19957
- * Check if Claude Flow is available
21128
+ * Check if Claude Flow is available (no npm auto-install)
19958
21129
  */
19959
21130
  async checkClaudeFlow() {
19960
- try {
19961
- const { execSync: execSync6 } = await import("child_process");
19962
- execSync6("npx @claude-flow/cli@latest hooks pretrain --help", {
19963
- encoding: "utf-8",
19964
- timeout: 5e3,
19965
- cwd: this.options.projectRoot
19966
- });
19967
- return true;
19968
- } catch {
19969
- return false;
19970
- }
21131
+ return detectClaudeFlow(this.options.projectRoot).available;
19971
21132
  }
19972
21133
  /**
19973
21134
  * Run pretrain analysis
@@ -19981,9 +21142,9 @@ var init_pretrain_bridge = __esm({
19981
21142
  }
19982
21143
  if (this.claudeFlowAvailable) {
19983
21144
  try {
19984
- const { execSync: execSync6 } = await import("child_process");
19985
- const result = execSync6(
19986
- `npx @claude-flow/cli@latest hooks pretrain --path ${this.escapeArg(targetPath)} --depth ${depth}`,
21145
+ const { execSync: execSync7 } = await import("child_process");
21146
+ const result = execSync7(
21147
+ `npx --no-install @claude-flow/cli hooks pretrain --path ${this.escapeArg(targetPath)} --depth ${depth}`,
19987
21148
  { encoding: "utf-8", timeout: 12e4, cwd: this.options.projectRoot }
19988
21149
  );
19989
21150
  try {
@@ -20016,9 +21177,9 @@ var init_pretrain_bridge = __esm({
20016
21177
  async generateAgentConfigs(format = "yaml") {
20017
21178
  if (this.claudeFlowAvailable) {
20018
21179
  try {
20019
- const { execSync: execSync6 } = await import("child_process");
20020
- const result = execSync6(
20021
- `npx @claude-flow/cli@latest hooks build-agents --format ${format}`,
21180
+ const { execSync: execSync7 } = await import("child_process");
21181
+ const result = execSync7(
21182
+ `npx --no-install @claude-flow/cli hooks build-agents --format ${format}`,
20022
21183
  { encoding: "utf-8", timeout: 6e4, cwd: this.options.projectRoot }
20023
21184
  );
20024
21185
  try {
@@ -20039,9 +21200,9 @@ var init_pretrain_bridge = __esm({
20039
21200
  async transferPatterns(sourcePath, minConfidence = 0.7) {
20040
21201
  if (this.claudeFlowAvailable) {
20041
21202
  try {
20042
- const { execSync: execSync6 } = await import("child_process");
20043
- const result = execSync6(
20044
- `npx @claude-flow/cli@latest hooks transfer --source-path ${this.escapeArg(sourcePath)} --min-confidence ${minConfidence}`,
21203
+ const { execSync: execSync7 } = await import("child_process");
21204
+ const result = execSync7(
21205
+ `npx --no-install @claude-flow/cli hooks transfer --source-path ${this.escapeArg(sourcePath)} --min-confidence ${minConfidence}`,
20045
21206
  { encoding: "utf-8", timeout: 6e4, cwd: this.options.projectRoot }
20046
21207
  );
20047
21208
  const transferredMatch = result.match(/transferred[:\s]+(\d+)/i);
@@ -20077,8 +21238,8 @@ var init_pretrain_bridge = __esm({
20077
21238
  async localAnalyze(targetPath, depth) {
20078
21239
  try {
20079
21240
  const glob = await import("fast-glob");
20080
- const { existsSync: existsSync17, readFileSync: readFileSync14 } = await import("fs");
20081
- const { join: join25 } = await import("path");
21241
+ const { existsSync: existsSync18, readFileSync: readFileSync15 } = await import("fs");
21242
+ const { join: join26 } = await import("path");
20082
21243
  const patterns = depth === "shallow" ? ["*.ts", "*.js", "*.json"] : depth === "medium" ? ["**/*.ts", "**/*.js", "**/*.json", "**/*.py"] : ["**/*"];
20083
21244
  const ignore = ["node_modules/**", "dist/**", "coverage/**", ".git/**"];
20084
21245
  const files = await glob.default(patterns, {
@@ -20095,10 +21256,10 @@ var init_pretrain_bridge = __esm({
20095
21256
  if (file.endsWith(".go")) languages.add("go");
20096
21257
  if (file.endsWith(".rs")) languages.add("rust");
20097
21258
  }
20098
- const packageJsonPath = join25(targetPath, "package.json");
20099
- if (existsSync17(packageJsonPath)) {
21259
+ const packageJsonPath = join26(targetPath, "package.json");
21260
+ if (existsSync18(packageJsonPath)) {
20100
21261
  try {
20101
- const pkg2 = JSON.parse(readFileSync14(packageJsonPath, "utf-8"));
21262
+ const pkg2 = JSON.parse(readFileSync15(packageJsonPath, "utf-8"));
20102
21263
  const deps = { ...pkg2.dependencies, ...pkg2.devDependencies };
20103
21264
  if (deps.react) frameworks.add("react");
20104
21265
  if (deps.vue) frameworks.add("vue");
@@ -20180,6 +21341,7 @@ var init_claude_flow = __esm({
20180
21341
  init_trajectory_bridge();
20181
21342
  init_model_router_bridge();
20182
21343
  init_pretrain_bridge();
21344
+ init_detect();
20183
21345
  init_trajectory_bridge();
20184
21346
  init_model_router_bridge();
20185
21347
  init_pretrain_bridge();
@@ -23595,8 +24757,8 @@ var init_coherence_service = __esm({
23595
24757
  // src/integrations/coherence/wasm-loader.ts
23596
24758
  import { createRequire as createRequire2 } from "node:module";
23597
24759
  import { fileURLToPath as fileURLToPath2 } from "node:url";
23598
- import { dirname as dirname4, join as join17 } from "node:path";
23599
- import { readFileSync as readFileSync10, existsSync as existsSync12 } from "node:fs";
24760
+ import { dirname as dirname4, join as join18 } from "node:path";
24761
+ import { readFileSync as readFileSync11, existsSync as existsSync13 } from "node:fs";
23600
24762
  var FALLBACK_RETRY_DELAYS_MS, WasmLoader, wasmLoader;
23601
24763
  var init_wasm_loader = __esm({
23602
24764
  "src/integrations/coherence/wasm-loader.ts"() {
@@ -23859,15 +25021,15 @@ var init_wasm_loader = __esm({
23859
25021
  (() => {
23860
25022
  try {
23861
25023
  const modulePath = require3.resolve("prime-radiant-advanced-wasm");
23862
- return join17(dirname4(modulePath), "prime_radiant_advanced_wasm_bg.wasm");
25024
+ return join18(dirname4(modulePath), "prime_radiant_advanced_wasm_bg.wasm");
23863
25025
  } catch {
23864
25026
  return null;
23865
25027
  }
23866
25028
  })(),
23867
- join17(process.cwd(), "node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm")
25029
+ join18(process.cwd(), "node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm")
23868
25030
  ].filter((p74) => p74 !== null);
23869
25031
  for (const path21 of wasmPaths) {
23870
- if (existsSync12(path21)) {
25032
+ if (existsSync13(path21)) {
23871
25033
  return true;
23872
25034
  }
23873
25035
  }
@@ -24118,19 +25280,19 @@ var init_wasm_loader = __esm({
24118
25280
  (() => {
24119
25281
  try {
24120
25282
  const modulePath = require3.resolve("prime-radiant-advanced-wasm");
24121
- return join17(dirname4(modulePath), "prime_radiant_advanced_wasm_bg.wasm");
25283
+ return join18(dirname4(modulePath), "prime_radiant_advanced_wasm_bg.wasm");
24122
25284
  } catch {
24123
25285
  return null;
24124
25286
  }
24125
25287
  })(),
24126
25288
  // Direct node_modules path from current file
24127
- join17(dirname4(fileURLToPath2(import.meta.url)), "../../../../node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm"),
25289
+ join18(dirname4(fileURLToPath2(import.meta.url)), "../../../../node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm"),
24128
25290
  // Workspace root
24129
- join17(process.cwd(), "node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm")
25291
+ join18(process.cwd(), "node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm")
24130
25292
  ].filter((p74) => p74 !== null);
24131
25293
  let wasmPath = null;
24132
25294
  for (const path21 of wasmPaths) {
24133
- if (existsSync12(path21)) {
25295
+ if (existsSync13(path21)) {
24134
25296
  wasmPath = path21;
24135
25297
  break;
24136
25298
  }
@@ -24142,7 +25304,7 @@ ${wasmPaths.join("\n")}
24142
25304
  Ensure prime-radiant-advanced-wasm is installed.`
24143
25305
  );
24144
25306
  }
24145
- const wasmBytes = readFileSync10(wasmPath);
25307
+ const wasmBytes = readFileSync11(wasmPath);
24146
25308
  if (wasmModule2.initSync && typeof wasmModule2.initSync === "function") {
24147
25309
  wasmModule2.initSync({ module: wasmBytes });
24148
25310
  } else {
@@ -24918,8 +26080,8 @@ var init_aqe_learning_engine = __esm({
24918
26080
  async localAnalyze(targetPath, depth) {
24919
26081
  try {
24920
26082
  const glob = await import("fast-glob");
24921
- const { existsSync: existsSync17, readFileSync: readFileSync14 } = await import("fs");
24922
- const { join: join25 } = await import("path");
26083
+ const { existsSync: existsSync18, readFileSync: readFileSync15 } = await import("fs");
26084
+ const { join: join26 } = await import("path");
24923
26085
  const patterns = depth === "shallow" ? ["*.ts", "*.js", "*.json"] : depth === "medium" ? ["**/*.ts", "**/*.js", "**/*.json", "**/*.py"] : ["**/*"];
24924
26086
  const ignore = ["node_modules/**", "dist/**", "coverage/**", ".git/**"];
24925
26087
  const files = await glob.default(patterns, {
@@ -24936,10 +26098,10 @@ var init_aqe_learning_engine = __esm({
24936
26098
  if (file.endsWith(".go")) languages.add("go");
24937
26099
  if (file.endsWith(".rs")) languages.add("rust");
24938
26100
  }
24939
- const packageJsonPath = join25(targetPath, "package.json");
24940
- if (existsSync17(packageJsonPath)) {
26101
+ const packageJsonPath = join26(targetPath, "package.json");
26102
+ if (existsSync18(packageJsonPath)) {
24941
26103
  try {
24942
- const pkg2 = JSON.parse(readFileSync14(packageJsonPath, "utf-8"));
26104
+ const pkg2 = JSON.parse(readFileSync15(packageJsonPath, "utf-8"));
24943
26105
  const deps = { ...pkg2.dependencies, ...pkg2.devDependencies };
24944
26106
  if (deps.react) frameworks.add("react");
24945
26107
  if (deps.vue) frameworks.add("vue");
@@ -25025,6 +26187,17 @@ var init_aqe_learning_engine = __esm({
25025
26187
 
25026
26188
  // src/mcp/transport/stdio.ts
25027
26189
  import * as readline from "readline";
26190
+
26191
+ // src/cli/helpers/safe-json.ts
26192
+ var import_secure_json_parse = __toESM(require_secure_json_parse(), 1);
26193
+ function safeJsonParse(json) {
26194
+ return import_secure_json_parse.default.parse(json, void 0, {
26195
+ protoAction: "remove",
26196
+ constructorAction: "remove"
26197
+ });
26198
+ }
26199
+
26200
+ // src/mcp/transport/stdio.ts
25028
26201
  var JSON_RPC_ERRORS = {
25029
26202
  PARSE_ERROR: -32700,
25030
26203
  INVALID_REQUEST: -32600,
@@ -25145,7 +26318,7 @@ var StdioTransport = class {
25145
26318
  }
25146
26319
  let message;
25147
26320
  try {
25148
- message = JSON.parse(line);
26321
+ message = safeJsonParse(line);
25149
26322
  } catch {
25150
26323
  this.metrics.errors++;
25151
26324
  await this.sendError(null, JSON_RPC_ERRORS.PARSE_ERROR, "Parse error");
@@ -25259,6 +26432,8 @@ var DEFAULT_CONFIG = {
25259
26432
  var ConnectionManager = class {
25260
26433
  config;
25261
26434
  connections = /* @__PURE__ */ new Map();
26435
+ threadIndex = /* @__PURE__ */ new Map();
26436
+ // threadId → connection IDs
25262
26437
  closedConnections = [];
25263
26438
  // Keep closed connections for metrics
25264
26439
  keepAliveTimers = /* @__PURE__ */ new Map();
@@ -25297,6 +26472,12 @@ var ConnectionManager = class {
25297
26472
  }
25298
26473
  };
25299
26474
  this.connections.set(id, connection);
26475
+ let threadConns = this.threadIndex.get(threadId);
26476
+ if (!threadConns) {
26477
+ threadConns = /* @__PURE__ */ new Set();
26478
+ this.threadIndex.set(threadId, threadConns);
26479
+ }
26480
+ threadConns.add(id);
25300
26481
  this.startKeepAlive(id);
25301
26482
  this.startTimeout(id);
25302
26483
  return connection;
@@ -25311,11 +26492,11 @@ var ConnectionManager = class {
25311
26492
  * Get connection by thread ID
25312
26493
  */
25313
26494
  getConnectionByThreadId(threadId) {
25314
- const connections = Array.from(this.connections.values());
25315
- for (const connection of connections) {
25316
- if (connection.threadId === threadId) {
25317
- return connection;
25318
- }
26495
+ const connIds = this.threadIndex.get(threadId);
26496
+ if (!connIds) return void 0;
26497
+ for (const id of connIds) {
26498
+ const conn = this.connections.get(id);
26499
+ if (conn) return conn;
25319
26500
  }
25320
26501
  return void 0;
25321
26502
  }
@@ -25385,17 +26566,24 @@ var ConnectionManager = class {
25385
26566
  while (this.closedConnections.length > 1e3) {
25386
26567
  this.closedConnections.shift();
25387
26568
  }
26569
+ const threadConns = this.threadIndex.get(connection.threadId);
26570
+ if (threadConns) {
26571
+ threadConns.delete(id);
26572
+ if (threadConns.size === 0) {
26573
+ this.threadIndex.delete(connection.threadId);
26574
+ }
26575
+ }
25388
26576
  this.connections.delete(id);
25389
26577
  }
25390
26578
  /**
25391
26579
  * Close all connections for a thread
25392
26580
  */
25393
26581
  closeThreadConnections(threadId, reason) {
25394
- const connections = Array.from(this.connections.values());
25395
- for (const connection of connections) {
25396
- if (connection.threadId === threadId) {
25397
- this.closeConnection(connection.id, reason);
25398
- }
26582
+ const connIds = this.threadIndex.get(threadId);
26583
+ if (!connIds) return;
26584
+ const ids = Array.from(connIds);
26585
+ for (const id of ids) {
26586
+ this.closeConnection(id, reason);
25399
26587
  }
25400
26588
  }
25401
26589
  /**
@@ -25768,7 +26956,7 @@ var SSETransport = class {
25768
26956
  reject(new Error("Empty request body"));
25769
26957
  return;
25770
26958
  }
25771
- const parsed = JSON.parse(body);
26959
+ const parsed = safeJsonParse(body);
25772
26960
  resolve9(parsed);
25773
26961
  } catch (error) {
25774
26962
  reject(new Error("Invalid JSON in request body"));
@@ -26538,7 +27726,7 @@ var WebSocketTransport = class extends EventEmitter2 {
26538
27726
  }
26539
27727
  try {
26540
27728
  const messageStr = data.toString();
26541
- const message = JSON.parse(messageStr);
27729
+ const message = safeJsonParse(messageStr);
26542
27730
  if (!connectionId.startsWith("pending_")) {
26543
27731
  this.connectionManager.recordMessageReceived(connectionId, Buffer.byteLength(messageStr));
26544
27732
  }
@@ -27291,6 +28479,7 @@ var RegexSafetyValidator = class {
27291
28479
  }
27292
28480
  };
27293
28481
  var defaultValidator2 = new RegexSafetyValidator();
28482
+ var createSafeRegex = (pattern, flags, maxLength) => defaultValidator2.createSafeRegex(pattern, flags, maxLength);
27294
28483
 
27295
28484
  // src/mcp/security/validators/crypto-validator.ts
27296
28485
  import { createHash, timingSafeEqual, randomBytes } from "crypto";
@@ -43662,7 +44851,8 @@ var DeterministicGatewayIntegration = class {
43662
44851
  received: `length: ${value.length}`
43663
44852
  });
43664
44853
  }
43665
- if (schema.pattern && !new RegExp(schema.pattern).test(value)) {
44854
+ const patternRegex = schema.pattern ? createSafeRegex(schema.pattern) : null;
44855
+ if (patternRegex && !patternRegex.test(value)) {
43666
44856
  errors.push({
43667
44857
  path: path21,
43668
44858
  message: `${path21} must match pattern ${schema.pattern}`,
@@ -95970,17 +97160,14 @@ Provide:
95970
97160
  });
95971
97161
  }
95972
97162
  if (pattern) {
95973
- try {
95974
- const regex = new RegExp(pattern);
95975
- if (!regex.test(data)) {
95976
- errors.push({
95977
- path: path21,
95978
- keyword: "pattern",
95979
- message: `String must match pattern: ${pattern}`,
95980
- params: { pattern }
95981
- });
95982
- }
95983
- } catch {
97163
+ const regex = createSafeRegex(pattern);
97164
+ if (regex && !regex.test(data)) {
97165
+ errors.push({
97166
+ path: path21,
97167
+ keyword: "pattern",
97168
+ message: `String must match pattern: ${pattern}`,
97169
+ params: { pattern }
97170
+ });
95984
97171
  }
95985
97172
  }
95986
97173
  }
@@ -98461,8 +99648,8 @@ var SchemaValidatorService = class {
98461
99648
  });
98462
99649
  }
98463
99650
  if (typeof schema.pattern === "string") {
98464
- const regex = new RegExp(schema.pattern);
98465
- if (!regex.test(value)) {
99651
+ const regex = createSafeRegex(schema.pattern);
99652
+ if (regex && !regex.test(value)) {
98466
99653
  errors.push({
98467
99654
  path: path21,
98468
99655
  keyword: "pattern",
@@ -117649,7 +118836,10 @@ var MinCutCalculator = class {
117649
118836
  variance += (degree - meanDegree) ** 2;
117650
118837
  }
117651
118838
  const stdDev2 = Math.sqrt(variance / vertices.length);
117652
- const minDegree = Math.min(...degrees.values());
118839
+ let minDegree = Infinity;
118840
+ for (const d74 of degrees.values()) {
118841
+ if (d74 < minDegree) minDegree = d74;
118842
+ }
117653
118843
  const effectiveThreshold = threshold ?? meanDegree - stdDev2;
117654
118844
  for (const vertex of vertices) {
117655
118845
  const weightedDegree = degrees.get(vertex.id);
@@ -117716,23 +118906,71 @@ var MinCutCalculator = class {
117716
118906
  }
117717
118907
  /**
117718
118908
  * Analyze graph for potential partitioning points
118909
+ *
118910
+ * Uses Tarjan's algorithm to find articulation points in O(V+E) time.
118911
+ * Previous implementation cloned the entire graph per vertex — O(V*(V+E)).
117719
118912
  */
117720
118913
  findPartitioningPoints(graph) {
118914
+ if (graph.isEmpty() || graph.vertexCount < 2) {
118915
+ return [];
118916
+ }
118917
+ const articulationPoints = this.findArticulationPoints(graph);
117721
118918
  const result = [];
117722
118919
  for (const vertex of graph.getVertices()) {
117723
118920
  const localMinCut = this.getLocalMinCut(graph, vertex.id);
117724
- const graphCopy = graph.clone();
117725
- graphCopy.removeVertex(vertex.id);
117726
- const wouldDisconnect = !graphCopy.isConnected() && graph.vertexCount > 2;
117727
118921
  result.push({
117728
118922
  vertexId: vertex.id,
117729
118923
  localMinCut,
117730
- wouldDisconnect
118924
+ wouldDisconnect: articulationPoints.has(vertex.id) && graph.vertexCount > 2
117731
118925
  });
117732
118926
  }
117733
118927
  result.sort((a37, b68) => a37.localMinCut - b68.localMinCut);
117734
118928
  return result;
117735
118929
  }
118930
+ /**
118931
+ * Tarjan's algorithm for finding articulation points in O(V+E)
118932
+ */
118933
+ findArticulationPoints(graph) {
118934
+ const disc = /* @__PURE__ */ new Map();
118935
+ const low = /* @__PURE__ */ new Map();
118936
+ const parent = /* @__PURE__ */ new Map();
118937
+ const ap = /* @__PURE__ */ new Set();
118938
+ let timer = 0;
118939
+ const vertices = graph.getVertexIds();
118940
+ for (const v62 of vertices) {
118941
+ disc.set(v62, -1);
118942
+ low.set(v62, -1);
118943
+ parent.set(v62, null);
118944
+ }
118945
+ const dfs = (u73) => {
118946
+ let children6 = 0;
118947
+ disc.set(u73, timer);
118948
+ low.set(u73, timer);
118949
+ timer++;
118950
+ for (const neighborId of graph.neighborIds(u73)) {
118951
+ if (disc.get(neighborId) === -1) {
118952
+ children6++;
118953
+ parent.set(neighborId, u73);
118954
+ dfs(neighborId);
118955
+ low.set(u73, Math.min(low.get(u73), low.get(neighborId)));
118956
+ if (parent.get(u73) === null && children6 > 1) {
118957
+ ap.add(u73);
118958
+ }
118959
+ if (parent.get(u73) !== null && low.get(neighborId) >= disc.get(u73)) {
118960
+ ap.add(u73);
118961
+ }
118962
+ } else if (neighborId !== parent.get(u73)) {
118963
+ low.set(u73, Math.min(low.get(u73), disc.get(neighborId)));
118964
+ }
118965
+ }
118966
+ };
118967
+ for (const v62 of vertices) {
118968
+ if (disc.get(v62) === -1) {
118969
+ dfs(v62);
118970
+ }
118971
+ }
118972
+ return ap;
118973
+ }
117736
118974
  /**
117737
118975
  * Suggest optimal edge additions to improve min-cut
117738
118976
  */
@@ -133104,7 +134342,12 @@ function getTaskExecutor() {
133104
134342
  }
133105
134343
  function resetTaskExecutor() {
133106
134344
  taskExecutor = null;
133107
- cachedLearningEngine = null;
134345
+ if (cachedLearningEngine) {
134346
+ const engine = cachedLearningEngine;
134347
+ cachedLearningEngine = null;
134348
+ engine.dispose().catch(() => {
134349
+ });
134350
+ }
133108
134351
  }
133109
134352
  async function getLearningEngine() {
133110
134353
  if (cachedLearningEngine) {
@@ -133187,6 +134430,24 @@ async function routeDomainTask(taskDescription, domain, codeContext) {
133187
134430
  return null;
133188
134431
  }
133189
134432
  }
134433
+ async function recordPatternUsageAsync(patternHints, success, domain, durationMs) {
134434
+ if (!patternHints || patternHints.length === 0) return;
134435
+ if (!cachedLearningEngine) return;
134436
+ try {
134437
+ for (const hint of patternHints) {
134438
+ if (!hint.patternId) continue;
134439
+ await cachedLearningEngine.recordOutcome({
134440
+ patternId: hint.patternId,
134441
+ success,
134442
+ metrics: {
134443
+ executionTimeMs: durationMs
134444
+ },
134445
+ feedback: `Domain handler ${domain} execution ${success ? "succeeded" : "failed"}`
134446
+ });
134447
+ }
134448
+ } catch {
134449
+ }
134450
+ }
133190
134451
  function createDomainHandler(config) {
133191
134452
  const {
133192
134453
  domain,
@@ -133207,10 +134468,11 @@ function createDomainHandler(config) {
133207
134468
  };
133208
134469
  }
133209
134470
  const { queen } = getFleetState();
134471
+ let routingResult = null;
133210
134472
  try {
133211
134473
  const taskDescription = buildTaskDescription(params);
133212
134474
  const codeContext = includeCodeContext?.(params);
133213
- const routingResult = await routeDomainTask(taskDescription, domain, codeContext);
134475
+ routingResult = await routeDomainTask(taskDescription, domain, codeContext);
133214
134476
  const payload = mapToPayload(params, routingResult);
133215
134477
  const timeout = calculateTimeout?.(params) ?? defaultTimeout;
133216
134478
  const submitResult = await queen.submitTask({
@@ -133249,12 +134511,24 @@ function createDomainHandler(config) {
133249
134511
  result.savedFiles,
133250
134512
  params
133251
134513
  );
134514
+ recordPatternUsageAsync(
134515
+ routingResult?.patternHints,
134516
+ true,
134517
+ domain,
134518
+ result.duration
134519
+ );
133252
134520
  return {
133253
134521
  success: true,
133254
134522
  data: mappedResult
133255
134523
  };
133256
134524
  } catch (error) {
133257
134525
  const errorMessage = error instanceof Error ? error.message : String(error);
134526
+ recordPatternUsageAsync(
134527
+ routingResult?.patternHints,
134528
+ false,
134529
+ domain,
134530
+ 0
134531
+ );
133258
134532
  return {
133259
134533
  success: false,
133260
134534
  error: `Failed to ${taskType.replace(/-/g, " ")}: ${errorMessage}`
@@ -137779,8 +139053,8 @@ function generateRecommendations2(results) {
137779
139053
  }
137780
139054
 
137781
139055
  // src/domains/requirements-validation/services/quality-criteria/quality-criteria-service.ts
137782
- import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
137783
- import { join as join20 } from "path";
139056
+ import { existsSync as existsSync15, readFileSync as readFileSync12 } from "fs";
139057
+ import { join as join21 } from "path";
137784
139058
 
137785
139059
  // src/domains/requirements-validation/services/quality-criteria/types.ts
137786
139060
  var HTSM_CATEGORIES = [
@@ -137821,14 +139095,14 @@ var QualityCriteriaService = class {
137821
139095
  findTemplatePath() {
137822
139096
  const possiblePaths = [
137823
139097
  // Relative to v3 package
137824
- join20(process.cwd(), ".claude/helpers/v3/quality-criteria/quality-criteria-reference-template.html"),
139098
+ join21(process.cwd(), ".claude/helpers/v3/quality-criteria/quality-criteria-reference-template.html"),
137825
139099
  // In node_modules
137826
- join20(process.cwd(), "node_modules/@agentic-qe/v3/assets/agents/v3/helpers/quality-criteria/quality-criteria-reference-template.html"),
139100
+ join21(process.cwd(), "node_modules/@agentic-qe/v3/assets/agents/v3/helpers/quality-criteria/quality-criteria-reference-template.html"),
137827
139101
  // Development path
137828
- join20(__dirname, "../../../../../assets/agents/v3/helpers/quality-criteria/quality-criteria-reference-template.html")
139102
+ join21(__dirname, "../../../../../assets/agents/v3/helpers/quality-criteria/quality-criteria-reference-template.html")
137829
139103
  ];
137830
139104
  for (const path21 of possiblePaths) {
137831
- if (existsSync14(path21)) {
139105
+ if (existsSync15(path21)) {
137832
139106
  return path21;
137833
139107
  }
137834
139108
  }
@@ -137845,8 +139119,8 @@ var QualityCriteriaService = class {
137845
139119
  */
137846
139120
  analyze(input) {
137847
139121
  let epicContent = input.epicContent || "";
137848
- if (input.epicPath && existsSync14(input.epicPath)) {
137849
- epicContent = readFileSync11(input.epicPath, "utf-8");
139122
+ if (input.epicPath && existsSync15(input.epicPath)) {
139123
+ epicContent = readFileSync12(input.epicPath, "utf-8");
137850
139124
  }
137851
139125
  if (!epicContent && !input.epicPath) {
137852
139126
  throw new Error("Either epicPath or epicContent is required for analysis");
@@ -138012,8 +139286,8 @@ Analyze the requirements above and return the complete QualityCriteriaAnalysis.`
138012
139286
  * Generate HTML output
138013
139287
  */
138014
139288
  generateHTML(analysis) {
138015
- if (!this.templateCache && existsSync14(this.config.templatePath)) {
138016
- this.templateCache = readFileSync11(this.config.templatePath, "utf-8");
139289
+ if (!this.templateCache && existsSync15(this.config.templatePath)) {
139290
+ this.templateCache = readFileSync12(this.config.templatePath, "utf-8");
138017
139291
  }
138018
139292
  if (!this.templateCache) {
138019
139293
  return this.generateFallbackHTML(analysis);
@@ -138124,7 +139398,7 @@ function createQualityCriteriaService(config) {
138124
139398
  init_types();
138125
139399
 
138126
139400
  // src/mcp/tools/requirements-validation/quality-criteria.ts
138127
- import { existsSync as existsSync15, readFileSync as readFileSync12 } from "fs";
139401
+ import { existsSync as existsSync16, readFileSync as readFileSync13 } from "fs";
138128
139402
  var QualityCriteriaTool = class extends MCPToolBase {
138129
139403
  config = {
138130
139404
  name: "qe/requirements/quality-criteria",
@@ -138223,8 +139497,8 @@ var QualityCriteriaTool = class extends MCPToolBase {
138223
139497
  message: "Preparing agent invocation for semantic HTSM analysis"
138224
139498
  });
138225
139499
  let content = epicContent || "";
138226
- if (epicPath && existsSync15(epicPath)) {
138227
- content = readFileSync12(epicPath, "utf-8");
139500
+ if (epicPath && existsSync16(epicPath)) {
139501
+ content = readFileSync13(epicPath, "utf-8");
138228
139502
  }
138229
139503
  if (!content && !epicPath) {
138230
139504
  return {
@@ -139317,7 +140591,7 @@ var ContractValidateTool = class extends MCPToolBase {
139317
140591
  const endpoints = [];
139318
140592
  if (format === "openapi") {
139319
140593
  try {
139320
- const parsed = JSON.parse(content);
140594
+ const parsed = safeJsonParse(content);
139321
140595
  const components = parsed.components;
139322
140596
  const schemasDef = components?.schemas || {};
139323
140597
  for (const [name, schemaContent] of Object.entries(schemasDef)) {
@@ -139355,7 +140629,7 @@ var ContractValidateTool = class extends MCPToolBase {
139355
140629
  });
139356
140630
  } else if (format === "pact") {
139357
140631
  try {
139358
- const parsed = JSON.parse(content);
140632
+ const parsed = safeJsonParse(content);
139359
140633
  const interactions = parsed.interactions || [];
139360
140634
  for (const interaction of interactions) {
139361
140635
  const request = interaction.request;
@@ -145338,6 +146612,85 @@ import Database4 from "better-sqlite3";
145338
146612
 
145339
146613
  // src/learning/qe-unified-memory.ts
145340
146614
  init_hnsw_index();
146615
+ var QE_DOMAIN_HNSW_CONFIGS = {
146616
+ "test-suites": {
146617
+ dimensions: EMBEDDING_CONFIG.DIMENSIONS,
146618
+ M: 8,
146619
+ // Low connectivity for fast lookup
146620
+ efConstruction: 100,
146621
+ efSearch: 50,
146622
+ metric: "cosine",
146623
+ namespace: "test-suites-hnsw",
146624
+ maxElements: 1e5
146625
+ },
146626
+ coverage: {
146627
+ dimensions: EMBEDDING_CONFIG.DIMENSIONS,
146628
+ M: 16,
146629
+ // Balanced for gap detection
146630
+ efConstruction: 200,
146631
+ efSearch: 100,
146632
+ metric: "cosine",
146633
+ namespace: "coverage-hnsw",
146634
+ maxElements: 1e5
146635
+ },
146636
+ defects: {
146637
+ dimensions: EMBEDDING_CONFIG.DIMENSIONS,
146638
+ M: 32,
146639
+ // High connectivity for precision
146640
+ efConstruction: 400,
146641
+ efSearch: 200,
146642
+ // Higher efSearch for better recall
146643
+ metric: "cosine",
146644
+ namespace: "defects-hnsw",
146645
+ maxElements: 1e5
146646
+ },
146647
+ quality: {
146648
+ dimensions: EMBEDDING_CONFIG.DIMENSIONS,
146649
+ M: 16,
146650
+ // Balanced configuration
146651
+ efConstruction: 200,
146652
+ efSearch: 100,
146653
+ metric: "cosine",
146654
+ namespace: "quality-hnsw",
146655
+ maxElements: 1e5
146656
+ },
146657
+ learning: {
146658
+ dimensions: EMBEDDING_CONFIG.DIMENSIONS,
146659
+ M: 24,
146660
+ // Higher recall for knowledge transfer
146661
+ efConstruction: 300,
146662
+ efSearch: 150,
146663
+ metric: "cosine",
146664
+ namespace: "learning-hnsw",
146665
+ maxElements: 1e5
146666
+ },
146667
+ coordination: {
146668
+ dimensions: EMBEDDING_CONFIG.DIMENSIONS,
146669
+ M: 8,
146670
+ // Fast lookup for coordination
146671
+ efConstruction: 100,
146672
+ efSearch: 50,
146673
+ metric: "cosine",
146674
+ namespace: "coordination-hnsw",
146675
+ maxElements: 5e4
146676
+ // Fewer entries needed
146677
+ }
146678
+ };
146679
+ var DEFAULT_QE_UNIFIED_MEMORY_CONFIG = {
146680
+ enableHNSW: {
146681
+ "test-suites": true,
146682
+ "coverage": true,
146683
+ // Already has HNSW
146684
+ "defects": true,
146685
+ "quality": true,
146686
+ "learning": true,
146687
+ // Already has HNSW (ReasoningBank)
146688
+ "coordination": true
146689
+ },
146690
+ defaultNamespace: "qe-unified",
146691
+ enableCrossDomainSearch: true,
146692
+ embeddingDimension: EMBEDDING_CONFIG.DIMENSIONS
146693
+ };
145341
146694
 
145342
146695
  // src/learning/index.ts
145343
146696
  init_dream();
@@ -151486,8 +152839,8 @@ var DEFAULT_POOL_CONFIG = {
151486
152839
  };
151487
152840
  var ConnectionPoolImpl = class {
151488
152841
  connections = /* @__PURE__ */ new Map();
151489
- connectionQueue = [];
151490
- // FIFO queue for LRU-style eviction
152842
+ idleConnections = /* @__PURE__ */ new Set();
152843
+ // O(1) acquire + release
151491
152844
  config;
151492
152845
  healthCheckInterval = null;
151493
152846
  initialized = false;
@@ -151569,16 +152922,18 @@ var ConnectionPoolImpl = class {
151569
152922
  doAcquire() {
151570
152923
  const startTime = performance.now();
151571
152924
  this.totalRequests++;
151572
- for (const connId of this.connectionQueue) {
152925
+ for (const connId of this.idleConnections) {
151573
152926
  const conn = this.connections.get(connId);
151574
- if (conn && conn.isHealthy && !conn.inUse) {
152927
+ if (conn && conn.isHealthy) {
151575
152928
  conn.inUse = true;
151576
152929
  conn.lastUsedAt = Date.now();
152930
+ this.idleConnections.delete(connId);
151577
152931
  this.cacheHits++;
151578
152932
  const elapsed2 = performance.now() - startTime;
151579
152933
  this.trackAcquisitionTime(elapsed2);
151580
152934
  return conn;
151581
152935
  }
152936
+ this.idleConnections.delete(connId);
151582
152937
  }
151583
152938
  if (this.config.autoCreate && this.connections.size < this.config.maxConnections) {
151584
152939
  const newConn = this.createConnectionSync();
@@ -151604,6 +152959,9 @@ var ConnectionPoolImpl = class {
151604
152959
  }
151605
152960
  conn.inUse = false;
151606
152961
  conn.lastUsedAt = Date.now();
152962
+ if (conn.isHealthy) {
152963
+ this.idleConnections.add(connectionId);
152964
+ }
151607
152965
  }
151608
152966
  /**
151609
152967
  * Record a request completion for metrics
@@ -151670,10 +153028,7 @@ var ConnectionPoolImpl = class {
151670
153028
  }
151671
153029
  for (const id of pruned) {
151672
153030
  this.connections.delete(id);
151673
- const idx = this.connectionQueue.indexOf(id);
151674
- if (idx >= 0) {
151675
- this.connectionQueue.splice(idx, 1);
151676
- }
153031
+ this.idleConnections.delete(id);
151677
153032
  }
151678
153033
  while (this.connections.size < this.config.minConnections) {
151679
153034
  this.createConnectionSync();
@@ -151685,7 +153040,7 @@ var ConnectionPoolImpl = class {
151685
153040
  */
151686
153041
  reset() {
151687
153042
  this.connections.clear();
151688
- this.connectionQueue.length = 0;
153043
+ this.idleConnections.clear();
151689
153044
  this.totalRequests = 0;
151690
153045
  this.cacheHits = 0;
151691
153046
  this.acquisitionTimes = [];
@@ -151699,7 +153054,7 @@ var ConnectionPoolImpl = class {
151699
153054
  this.healthCheckInterval = null;
151700
153055
  }
151701
153056
  this.connections.clear();
151702
- this.connectionQueue.length = 0;
153057
+ this.idleConnections.clear();
151703
153058
  this.initialized = false;
151704
153059
  }
151705
153060
  // ============================================================================
@@ -151723,7 +153078,7 @@ var ConnectionPoolImpl = class {
151723
153078
  }
151724
153079
  };
151725
153080
  this.connections.set(id, connection);
151726
- this.connectionQueue.push(id);
153081
+ this.idleConnections.add(id);
151727
153082
  }
151728
153083
  createConnectionSync() {
151729
153084
  if (this.connections.size >= this.config.maxConnections) {
@@ -151746,7 +153101,7 @@ var ConnectionPoolImpl = class {
151746
153101
  }
151747
153102
  };
151748
153103
  this.connections.set(id, connection);
151749
- this.connectionQueue.push(id);
153104
+ this.idleConnections.add(id);
151750
153105
  return connection;
151751
153106
  }
151752
153107
  performHealthChecks() {
@@ -151759,8 +153114,16 @@ var ConnectionPoolImpl = class {
151759
153114
  health -= errorRate * 0.8;
151760
153115
  health -= Math.min(0.2, avgLatency / 100 * 0.2);
151761
153116
  conn.health = Math.max(0, Math.min(1, health));
153117
+ const wasHealthy = conn.isHealthy;
151762
153118
  conn.isHealthy = conn.health >= this.config.healthThreshold;
151763
153119
  conn.metrics.lastHealthCheck = now;
153120
+ if (!conn.inUse) {
153121
+ if (conn.isHealthy && !wasHealthy) {
153122
+ this.idleConnections.add(conn.id);
153123
+ } else if (!conn.isHealthy && wasHealthy) {
153124
+ this.idleConnections.delete(conn.id);
153125
+ }
153126
+ }
151764
153127
  }
151765
153128
  if (this.config.autoPrune) {
151766
153129
  this.prune();
@@ -152731,7 +154094,7 @@ async function quickStart(config) {
152731
154094
 
152732
154095
  // src/mcp/http-server.ts
152733
154096
  import { createServer } from "http";
152734
- import { join as join23, dirname as dirname8 } from "path";
154097
+ import { join as join24, dirname as dirname8 } from "path";
152735
154098
  import { fileURLToPath as fileURLToPath3 } from "url";
152736
154099
 
152737
154100
  // src/adapters/a2a/agent-cards/schema.ts
@@ -155808,7 +157171,7 @@ init_unified_memory();
155808
157171
 
155809
157172
  // src/adapters/a2a/agent-cards/generator.ts
155810
157173
  import { readFile as readFile10, readdir as readdir5, stat as stat5 } from "fs/promises";
155811
- import { join as join22, basename as basename4 } from "path";
157174
+ import { join as join23, basename as basename4 } from "path";
155812
157175
  var DEFAULT_GENERATOR_CONFIG = {
155813
157176
  baseUrl: "http://localhost:8080",
155814
157177
  defaultVersion: "3.0.0",
@@ -156157,7 +157520,7 @@ var AgentCardGenerator = class {
156157
157520
  const processDirectory = async (dirPath) => {
156158
157521
  const entries = await readdir5(dirPath);
156159
157522
  for (const entry of entries) {
156160
- const fullPath = join22(dirPath, entry);
157523
+ const fullPath = join23(dirPath, entry);
156161
157524
  const stats = await stat5(fullPath);
156162
157525
  if (stats.isDirectory() && recursive) {
156163
157526
  await processDirectory(fullPath);
@@ -157609,7 +158972,7 @@ var HTTPServerImpl = class {
157609
158972
  this.skipCRDTInit = config.skipCRDTInit ?? false;
157610
158973
  this.enableWebSocket = config.enableWebSocket ?? true;
157611
158974
  const currentDir = dirname8(fileURLToPath3(import.meta.url));
157612
- this.agentMarkdownDir = config.agentMarkdownDir ?? join23(currentDir, "../../assets/agents/v3");
158975
+ this.agentMarkdownDir = config.agentMarkdownDir ?? join24(currentDir, "../../assets/agents/v3");
157613
158976
  this.taskStore = createTaskStore();
157614
158977
  this.taskManager = config.taskManager ?? createTaskManager({
157615
158978
  storeConfig: {}
@@ -158117,7 +159480,7 @@ var HTTPServerImpl = class {
158117
159480
  resolve9({});
158118
159481
  return;
158119
159482
  }
158120
- resolve9(JSON.parse(body));
159483
+ resolve9(safeJsonParse(body));
158121
159484
  } catch (error) {
158122
159485
  reject(new Error("Invalid JSON in request body"));
158123
159486
  }
@@ -159485,7 +160848,7 @@ function createInfraHealingOrchestratorSync(options) {
159485
160848
  }
159486
160849
 
159487
160850
  // src/mcp/entry.ts
159488
- import { readFileSync as readFileSync13 } from "node:fs";
160851
+ import { readFileSync as readFileSync14 } from "node:fs";
159489
160852
  import { resolve as resolve8, dirname as dirname9 } from "node:path";
159490
160853
  import { fileURLToPath as fileURLToPath4 } from "node:url";
159491
160854
  var require2 = createRequire3(import.meta.url);
@@ -159544,7 +160907,7 @@ async function main() {
159544
160907
  const playbookPath = resolve8(__dirname2, "../strange-loop/infra-healing/default-playbook.yaml");
159545
160908
  let playbookContent;
159546
160909
  try {
159547
- playbookContent = readFileSync13(playbookPath, "utf-8");
160910
+ playbookContent = readFileSync14(playbookPath, "utf-8");
159548
160911
  } catch {
159549
160912
  playbookContent = "";
159550
160913
  }