agentic-qe 3.6.15 → 3.6.17

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 (113) hide show
  1. package/.claude/agents/v3/qe-queen-coordinator.md +9 -3
  2. package/.claude/skills/skills-manifest.json +1 -1
  3. package/package.json +1 -1
  4. package/v3/CHANGELOG.md +45 -0
  5. package/v3/assets/agents/v3/qe-queen-coordinator.md +9 -3
  6. package/v3/dist/cli/bundle.js +1944 -685
  7. package/v3/dist/cli/commands/sync.d.ts.map +1 -1
  8. package/v3/dist/cli/commands/sync.js +83 -1
  9. package/v3/dist/cli/commands/sync.js.map +1 -1
  10. package/v3/dist/cli/completions/index.d.ts +1 -1
  11. package/v3/dist/cli/completions/index.d.ts.map +1 -1
  12. package/v3/dist/cli/completions/index.js +1 -1
  13. package/v3/dist/cli/completions/index.js.map +1 -1
  14. package/v3/dist/cli/wizards/test-wizard.d.ts +1 -1
  15. package/v3/dist/cli/wizards/test-wizard.d.ts.map +1 -1
  16. package/v3/dist/cli/wizards/test-wizard.js +8 -1
  17. package/v3/dist/cli/wizards/test-wizard.js.map +1 -1
  18. package/v3/dist/coordination/task-executor.js.map +1 -1
  19. package/v3/dist/domains/test-generation/factories/test-generator-factory.d.ts.map +1 -1
  20. package/v3/dist/domains/test-generation/factories/test-generator-factory.js +4 -1
  21. package/v3/dist/domains/test-generation/factories/test-generator-factory.js.map +1 -1
  22. package/v3/dist/domains/test-generation/generators/base-test-generator.d.ts.map +1 -1
  23. package/v3/dist/domains/test-generation/generators/base-test-generator.js +26 -1
  24. package/v3/dist/domains/test-generation/generators/base-test-generator.js.map +1 -1
  25. package/v3/dist/domains/test-generation/generators/index.d.ts +1 -0
  26. package/v3/dist/domains/test-generation/generators/index.d.ts.map +1 -1
  27. package/v3/dist/domains/test-generation/generators/index.js +1 -0
  28. package/v3/dist/domains/test-generation/generators/index.js.map +1 -1
  29. package/v3/dist/domains/test-generation/generators/jest-vitest-generator.d.ts.map +1 -1
  30. package/v3/dist/domains/test-generation/generators/jest-vitest-generator.js +26 -2
  31. package/v3/dist/domains/test-generation/generators/jest-vitest-generator.js.map +1 -1
  32. package/v3/dist/domains/test-generation/generators/mocha-generator.d.ts.map +1 -1
  33. package/v3/dist/domains/test-generation/generators/mocha-generator.js +50 -5
  34. package/v3/dist/domains/test-generation/generators/mocha-generator.js.map +1 -1
  35. package/v3/dist/domains/test-generation/generators/node-test-generator.d.ts +54 -0
  36. package/v3/dist/domains/test-generation/generators/node-test-generator.d.ts.map +1 -0
  37. package/v3/dist/domains/test-generation/generators/node-test-generator.js +222 -0
  38. package/v3/dist/domains/test-generation/generators/node-test-generator.js.map +1 -0
  39. package/v3/dist/domains/test-generation/generators/pytest-generator.d.ts.map +1 -1
  40. package/v3/dist/domains/test-generation/generators/pytest-generator.js +47 -5
  41. package/v3/dist/domains/test-generation/generators/pytest-generator.js.map +1 -1
  42. package/v3/dist/domains/test-generation/interfaces/test-generator.interface.d.ts +1 -1
  43. package/v3/dist/domains/test-generation/interfaces/test-generator.interface.d.ts.map +1 -1
  44. package/v3/dist/domains/test-generation/interfaces.d.ts +2 -2
  45. package/v3/dist/domains/test-generation/interfaces.d.ts.map +1 -1
  46. package/v3/dist/domains/test-generation/plugin.js.map +1 -1
  47. package/v3/dist/domains/test-generation/services/pattern-matcher.js +32 -6
  48. package/v3/dist/domains/test-generation/services/pattern-matcher.js.map +1 -1
  49. package/v3/dist/domains/test-generation/services/test-generator.d.ts.map +1 -1
  50. package/v3/dist/domains/test-generation/services/test-generator.js +31 -6
  51. package/v3/dist/domains/test-generation/services/test-generator.js.map +1 -1
  52. package/v3/dist/mcp/bundle.js +666 -46
  53. package/v3/dist/mcp/handlers/agent-handlers.d.ts +3 -0
  54. package/v3/dist/mcp/handlers/agent-handlers.d.ts.map +1 -1
  55. package/v3/dist/mcp/handlers/agent-handlers.js +16 -9
  56. package/v3/dist/mcp/handlers/agent-handlers.js.map +1 -1
  57. package/v3/dist/mcp/handlers/core-handlers.d.ts +32 -0
  58. package/v3/dist/mcp/handlers/core-handlers.d.ts.map +1 -1
  59. package/v3/dist/mcp/handlers/core-handlers.js +45 -1
  60. package/v3/dist/mcp/handlers/core-handlers.js.map +1 -1
  61. package/v3/dist/mcp/handlers/handler-factory.d.ts +9 -1
  62. package/v3/dist/mcp/handlers/handler-factory.d.ts.map +1 -1
  63. package/v3/dist/mcp/handlers/handler-factory.js +94 -2
  64. package/v3/dist/mcp/handlers/handler-factory.js.map +1 -1
  65. package/v3/dist/mcp/handlers/memory-handlers.d.ts +2 -0
  66. package/v3/dist/mcp/handlers/memory-handlers.d.ts.map +1 -1
  67. package/v3/dist/mcp/handlers/memory-handlers.js +90 -1
  68. package/v3/dist/mcp/handlers/memory-handlers.js.map +1 -1
  69. package/v3/dist/mcp/protocol-server.d.ts +7 -0
  70. package/v3/dist/mcp/protocol-server.d.ts.map +1 -1
  71. package/v3/dist/mcp/protocol-server.js +56 -2
  72. package/v3/dist/mcp/protocol-server.js.map +1 -1
  73. package/v3/dist/mcp/tools/test-generation/generate.d.ts +1 -1
  74. package/v3/dist/mcp/tools/test-generation/generate.d.ts.map +1 -1
  75. package/v3/dist/mcp/tools/test-generation/generate.js.map +1 -1
  76. package/v3/dist/mcp/transport/stdio.d.ts +18 -0
  77. package/v3/dist/mcp/transport/stdio.d.ts.map +1 -1
  78. package/v3/dist/mcp/transport/stdio.js +72 -5
  79. package/v3/dist/mcp/transport/stdio.js.map +1 -1
  80. package/v3/dist/mcp/types.d.ts +2 -0
  81. package/v3/dist/mcp/types.d.ts.map +1 -1
  82. package/v3/dist/sync/cloud/index.d.ts +1 -0
  83. package/v3/dist/sync/cloud/index.d.ts.map +1 -1
  84. package/v3/dist/sync/cloud/index.js +1 -0
  85. package/v3/dist/sync/cloud/index.js.map +1 -1
  86. package/v3/dist/sync/cloud/postgres-reader.d.ts +63 -0
  87. package/v3/dist/sync/cloud/postgres-reader.d.ts.map +1 -0
  88. package/v3/dist/sync/cloud/postgres-reader.js +225 -0
  89. package/v3/dist/sync/cloud/postgres-reader.js.map +1 -0
  90. package/v3/dist/sync/index.d.ts +5 -2
  91. package/v3/dist/sync/index.d.ts.map +1 -1
  92. package/v3/dist/sync/index.js +7 -2
  93. package/v3/dist/sync/index.js.map +1 -1
  94. package/v3/dist/sync/interfaces.d.ts +49 -0
  95. package/v3/dist/sync/interfaces.d.ts.map +1 -1
  96. package/v3/dist/sync/interfaces.js +160 -0
  97. package/v3/dist/sync/interfaces.js.map +1 -1
  98. package/v3/dist/sync/pull-agent.d.ts +102 -0
  99. package/v3/dist/sync/pull-agent.d.ts.map +1 -0
  100. package/v3/dist/sync/pull-agent.js +354 -0
  101. package/v3/dist/sync/pull-agent.js.map +1 -0
  102. package/v3/dist/sync/sync-agent.d.ts.map +1 -1
  103. package/v3/dist/sync/sync-agent.js +9 -0
  104. package/v3/dist/sync/sync-agent.js.map +1 -1
  105. package/v3/dist/sync/writers/index.d.ts +7 -0
  106. package/v3/dist/sync/writers/index.d.ts.map +1 -0
  107. package/v3/dist/sync/writers/index.js +7 -0
  108. package/v3/dist/sync/writers/index.js.map +1 -0
  109. package/v3/dist/sync/writers/sqlite-writer.d.ts +69 -0
  110. package/v3/dist/sync/writers/sqlite-writer.d.ts.map +1 -0
  111. package/v3/dist/sync/writers/sqlite-writer.js +249 -0
  112. package/v3/dist/sync/writers/sqlite-writer.js.map +1 -0
  113. package/v3/package.json +1 -1
@@ -27141,6 +27141,7 @@ var StdioTransport = class {
27141
27141
  rl = null;
27142
27142
  requestHandler = null;
27143
27143
  notificationHandler = null;
27144
+ errorHandler = null;
27144
27145
  running = false;
27145
27146
  metrics = {
27146
27147
  messagesReceived: 0,
@@ -27185,22 +27186,29 @@ var StdioTransport = class {
27185
27186
  });
27186
27187
  });
27187
27188
  this.rl.on("close", () => {
27189
+ const wasRunning = this.running;
27188
27190
  this.running = false;
27191
+ if (wasRunning && this.errorHandler) {
27192
+ this.errorHandler(new Error("Transport connection closed unexpectedly"));
27193
+ }
27189
27194
  });
27190
27195
  this.rl.on("error", (err4) => {
27191
27196
  this.metrics.errors++;
27192
27197
  console.error("[StdioTransport] Readline error:", err4);
27198
+ if (this.errorHandler) {
27199
+ this.errorHandler(err4);
27200
+ }
27193
27201
  });
27194
27202
  }
27195
27203
  /**
27196
27204
  * Stop listening
27197
27205
  */
27198
27206
  stop() {
27207
+ this.running = false;
27199
27208
  if (this.rl) {
27200
27209
  this.rl.close();
27201
27210
  this.rl = null;
27202
27211
  }
27203
- this.running = false;
27204
27212
  }
27205
27213
  /**
27206
27214
  * Send a response
@@ -27219,6 +27227,24 @@ var StdioTransport = class {
27219
27227
  };
27220
27228
  await this.write(JSON.stringify(notification));
27221
27229
  }
27230
+ /**
27231
+ * Set error handler for transport-level errors
27232
+ */
27233
+ onError(handler) {
27234
+ this.errorHandler = handler;
27235
+ }
27236
+ /**
27237
+ * Reconnect the transport by re-attaching to stdin/stdout.
27238
+ * Closes the existing readline interface and creates a new one.
27239
+ */
27240
+ reconnect() {
27241
+ if (this.rl) {
27242
+ this.rl.close();
27243
+ this.rl = null;
27244
+ }
27245
+ this.running = false;
27246
+ this.start();
27247
+ }
27222
27248
  /**
27223
27249
  * Get transport metrics
27224
27250
  */
@@ -27321,13 +27347,50 @@ var StdioTransport = class {
27321
27347
  };
27322
27348
  await this.sendResponse(response);
27323
27349
  }
27324
- write(data) {
27350
+ /**
27351
+ * Write with retry and backpressure handling.
27352
+ * Retries up to 3 times with exponential backoff before rejecting.
27353
+ */
27354
+ async write(data) {
27355
+ const maxAttempts = 3;
27356
+ const backoffDelays = [0, 500, 1e3];
27357
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
27358
+ try {
27359
+ await this.writeOnce(data);
27360
+ return;
27361
+ } catch (err4) {
27362
+ if (attempt < maxAttempts - 1) {
27363
+ console.error(
27364
+ `[StdioTransport] Write attempt ${attempt + 1} failed, retrying in ${backoffDelays[attempt + 1]}ms...`
27365
+ );
27366
+ await new Promise((r54) => setTimeout(r54, backoffDelays[attempt + 1]));
27367
+ } else {
27368
+ throw err4;
27369
+ }
27370
+ }
27371
+ }
27372
+ }
27373
+ /**
27374
+ * Single write attempt with 120s timeout and backpressure (drain) handling.
27375
+ */
27376
+ async writeOnce(data) {
27377
+ const message = data + "\n";
27378
+ if (this.outputStream.writableNeedDrain) {
27379
+ await new Promise((resolve9, reject) => {
27380
+ const drainTimeout = setTimeout(() => {
27381
+ reject(new Error("Transport drain timeout after 30 seconds"));
27382
+ }, 3e4);
27383
+ this.outputStream.once("drain", () => {
27384
+ clearTimeout(drainTimeout);
27385
+ resolve9();
27386
+ });
27387
+ });
27388
+ }
27325
27389
  return new Promise((resolve9, reject) => {
27326
- const message = data + "\n";
27327
27390
  const writeTimeout = setTimeout(() => {
27328
27391
  this.metrics.errors++;
27329
- reject(new Error("Transport write timeout after 30 seconds"));
27330
- }, 3e4);
27392
+ reject(new Error("Transport write timeout after 120 seconds"));
27393
+ }, 12e4);
27331
27394
  this.outputStream.write(message, "utf-8", (error) => {
27332
27395
  clearTimeout(writeTimeout);
27333
27396
  if (error) {
@@ -38683,11 +38746,27 @@ var BaseTestGenerator = class _BaseTestGenerator {
38683
38746
  const validParams = fn.parameters.map((p74) => this.generateTestValue(p74)).join(", ");
38684
38747
  const fnCall = fn.isAsync ? `await ${fn.name}(${validParams})` : `${fn.name}(${validParams})`;
38685
38748
  const isVoid = fn.returnType === "void" || fn.returnType === "Promise<void>";
38749
+ let assertion = "expect(result).toBeDefined();";
38750
+ if (!isVoid) {
38751
+ if (/^(is|has|can)[A-Z]/.test(fn.name)) {
38752
+ assertion = "expect(typeof result).toBe('boolean');";
38753
+ } else if (/^(get|fetch|find)[A-Z]/.test(fn.name)) {
38754
+ assertion = "expect(result).not.toBeUndefined();";
38755
+ } else if (/^(create|build|make)[A-Z]/.test(fn.name)) {
38756
+ assertion = "expect(result).toBeTruthy();";
38757
+ } else if (fn.returnType) {
38758
+ const rt3 = fn.returnType.toLowerCase().replace(/promise<(.+)>/, "$1");
38759
+ if (rt3.includes("boolean")) assertion = "expect(typeof result).toBe('boolean');";
38760
+ else if (rt3.includes("number")) assertion = "expect(typeof result).toBe('number');";
38761
+ else if (rt3.includes("string")) assertion = "expect(typeof result).toBe('string');";
38762
+ else if (rt3.includes("[]") || rt3.includes("array")) assertion = "expect(Array.isArray(result)).toBe(true);";
38763
+ }
38764
+ }
38686
38765
  testCases.push({
38687
38766
  description: "should handle valid input correctly",
38688
38767
  type: "happy-path",
38689
38768
  action: isVoid ? `${fnCall};` : `const result = ${fnCall};`,
38690
- assertion: isVoid ? `// void function \u2014 no return value to assert` : "expect(result).toBeDefined();"
38769
+ assertion: isVoid ? `// void function \u2014 no return value to assert` : assertion
38691
38770
  });
38692
38771
  const bodyText = fn.body || "";
38693
38772
  const hasExplicitThrow = /\bthrow\b/.test(bodyText) || /\bvalidat/i.test(bodyText);
@@ -38992,6 +39071,22 @@ ${importStatement}
38992
39071
  const methodCall = method.isAsync ? `await instance.${method.name}(${validParams})` : `instance.${method.name}(${validParams})`;
38993
39072
  const asyncPrefix = method.isAsync ? "async " : "";
38994
39073
  const isVoid = method.returnType === "void" || method.returnType === "Promise<void>";
39074
+ let methodAssertion = "expect(result).toBeDefined();";
39075
+ if (!isVoid) {
39076
+ if (/^(is|has|can)[A-Z]/.test(method.name)) {
39077
+ methodAssertion = "expect(typeof result).toBe('boolean');";
39078
+ } else if (/^(get|fetch|find)[A-Z]/.test(method.name)) {
39079
+ methodAssertion = "expect(result).not.toBeUndefined();";
39080
+ } else if (/^(create|build|make)[A-Z]/.test(method.name)) {
39081
+ methodAssertion = "expect(result).toBeTruthy();";
39082
+ } else if (method.returnType) {
39083
+ const mrt = method.returnType.toLowerCase().replace(/promise<(.+)>/, "$1");
39084
+ if (mrt.includes("boolean")) methodAssertion = "expect(typeof result).toBe('boolean');";
39085
+ else if (mrt.includes("number")) methodAssertion = "expect(typeof result).toBe('number');";
39086
+ else if (mrt.includes("string")) methodAssertion = "expect(typeof result).toBe('string');";
39087
+ else if (mrt.includes("[]") || mrt.includes("array")) methodAssertion = "expect(Array.isArray(result)).toBe(true);";
39088
+ }
39089
+ }
38995
39090
  code += ` it('should execute successfully', ${asyncPrefix}() => {
38996
39091
  `;
38997
39092
  if (isVoid) {
@@ -39002,7 +39097,7 @@ ${importStatement}
39002
39097
  } else {
39003
39098
  code += ` const result = ${methodCall};
39004
39099
  `;
39005
- code += ` expect(result).toBeDefined();
39100
+ code += ` ${methodAssertion}
39006
39101
  `;
39007
39102
  }
39008
39103
  code += ` });
@@ -39399,6 +39494,22 @@ ${stubSetup}`;
39399
39494
  const isVoid = fn.returnType === "void" || fn.returnType === "Promise<void>";
39400
39495
  let code = ` describe('${fn.name}', function() {
39401
39496
  `;
39497
+ let chaiAssertion = "expect(result).to.not.be.undefined;";
39498
+ if (!isVoid) {
39499
+ if (/^(is|has|can)[A-Z]/.test(fn.name)) {
39500
+ chaiAssertion = "expect(typeof result).to.equal('boolean');";
39501
+ } else if (/^(get|fetch|find)[A-Z]/.test(fn.name)) {
39502
+ chaiAssertion = "expect(result).to.not.be.undefined;";
39503
+ } else if (/^(create|build|make)[A-Z]/.test(fn.name)) {
39504
+ chaiAssertion = "expect(result).to.be.ok;";
39505
+ } else if (fn.returnType) {
39506
+ const rt3 = fn.returnType.toLowerCase().replace(/promise<(.+)>/, "$1");
39507
+ if (rt3.includes("boolean")) chaiAssertion = "expect(typeof result).to.equal('boolean');";
39508
+ else if (rt3.includes("number")) chaiAssertion = "expect(typeof result).to.equal('number');";
39509
+ else if (rt3.includes("string")) chaiAssertion = "expect(typeof result).to.equal('string');";
39510
+ else if (rt3.includes("[]") || rt3.includes("array")) chaiAssertion = "expect(result).to.be.an('array');";
39511
+ }
39512
+ }
39402
39513
  code += ` it('should handle valid input', ${fn.isAsync ? "async " : ""}function() {
39403
39514
  `;
39404
39515
  if (isVoid) {
@@ -39407,7 +39518,7 @@ ${stubSetup}`;
39407
39518
  } else {
39408
39519
  code += ` const result = ${fnCall};
39409
39520
  `;
39410
- code += ` expect(result).to.not.be.undefined;
39521
+ code += ` ${chaiAssertion}
39411
39522
  `;
39412
39523
  }
39413
39524
  code += ` });
@@ -39473,19 +39584,33 @@ ${stubSetup}`;
39473
39584
  code += ` });
39474
39585
  `;
39475
39586
  for (const method of cls.methods) {
39476
- if (!method.name.startsWith("_")) {
39587
+ if (!method.name.startsWith("_") && !method.name.startsWith("#")) {
39477
39588
  const methodParams = method.parameters.map((p74) => this.generateTestValue(p74)).join(", ");
39478
- const isVoid = method.returnType === "void" || method.returnType === "Promise<void>";
39589
+ const isMethodVoid = method.returnType === "void" || method.returnType === "Promise<void>";
39590
+ let methodAssertion = "expect(result).to.not.be.undefined;";
39591
+ if (!isMethodVoid) {
39592
+ if (/^(is|has|can)[A-Z]/.test(method.name)) {
39593
+ methodAssertion = "expect(typeof result).to.equal('boolean');";
39594
+ } else if (/^(create|build|make)[A-Z]/.test(method.name)) {
39595
+ methodAssertion = "expect(result).to.be.ok;";
39596
+ } else if (method.returnType) {
39597
+ const mrt = method.returnType.toLowerCase().replace(/promise<(.+)>/, "$1");
39598
+ if (mrt.includes("boolean")) methodAssertion = "expect(typeof result).to.equal('boolean');";
39599
+ else if (mrt.includes("number")) methodAssertion = "expect(typeof result).to.equal('number');";
39600
+ else if (mrt.includes("string")) methodAssertion = "expect(typeof result).to.equal('string');";
39601
+ else if (mrt.includes("[]") || mrt.includes("array")) methodAssertion = "expect(result).to.be.an('array');";
39602
+ }
39603
+ }
39479
39604
  code += `
39480
39605
  it('${method.name} should work', ${method.isAsync ? "async " : ""}function() {
39481
39606
  `;
39482
- if (isVoid) {
39607
+ if (isMethodVoid) {
39483
39608
  code += ` ${method.isAsync ? "await " : ""}instance.${method.name}(${methodParams});
39484
39609
  `;
39485
39610
  } else {
39486
39611
  code += ` const result = ${method.isAsync ? "await " : ""}instance.${method.name}(${methodParams});
39487
39612
  `;
39488
- code += ` expect(result).to.not.be.undefined;
39613
+ code += ` ${methodAssertion}
39489
39614
  `;
39490
39615
  }
39491
39616
  code += ` });
@@ -39734,6 +39859,20 @@ class Test${this.pascalCase(moduleName)}:
39734
39859
  `;
39735
39860
  code += ` """Test ${fn.name} with valid input"""
39736
39861
  `;
39862
+ let pyAssertion = "assert result is not None";
39863
+ if (!isVoid) {
39864
+ if (/^(is|has|can)[A-Z]/.test(fn.name)) {
39865
+ pyAssertion = "assert isinstance(result, bool)";
39866
+ } else if (/^(create|build|make)[A-Z]/.test(fn.name)) {
39867
+ pyAssertion = "assert result";
39868
+ } else if (fn.returnType) {
39869
+ const rt3 = fn.returnType.toLowerCase().replace(/promise<(.+)>/, "$1");
39870
+ if (rt3.includes("boolean") || rt3.includes("bool")) pyAssertion = "assert isinstance(result, bool)";
39871
+ else if (rt3.includes("number") || rt3.includes("int") || rt3.includes("float")) pyAssertion = "assert isinstance(result, (int, float))";
39872
+ else if (rt3.includes("string") || rt3.includes("str")) pyAssertion = "assert isinstance(result, str)";
39873
+ else if (rt3.includes("[]") || rt3.includes("array") || rt3.includes("list")) pyAssertion = "assert isinstance(result, list)";
39874
+ }
39875
+ }
39737
39876
  if (isVoid) {
39738
39877
  code += ` ${fn.name}(${validParams}) # void function
39739
39878
 
@@ -39741,7 +39880,7 @@ class Test${this.pascalCase(moduleName)}:
39741
39880
  } else {
39742
39881
  code += ` result = ${fn.name}(${validParams})
39743
39882
  `;
39744
- code += ` assert result is not None
39883
+ code += ` ${pyAssertion}
39745
39884
 
39746
39885
  `;
39747
39886
  }
@@ -39785,19 +39924,33 @@ class Test${cls.name}:
39785
39924
 
39786
39925
  `;
39787
39926
  for (const method of cls.methods) {
39788
- if (!method.name.startsWith("_")) {
39927
+ if (!method.name.startsWith("_") && !method.name.startsWith("#")) {
39789
39928
  const methodParams = method.parameters.map((p74) => this.generatePythonTestValue(p74)).join(", ");
39790
- const isVoid = method.returnType === "void" || method.returnType === "Promise<void>";
39929
+ const isMethodVoid = method.returnType === "void" || method.returnType === "Promise<void>";
39930
+ let mAssertion = "assert result is not None";
39931
+ if (!isMethodVoid) {
39932
+ if (/^(is|has|can)[A-Z]/.test(method.name)) {
39933
+ mAssertion = "assert isinstance(result, bool)";
39934
+ } else if (/^(create|build|make)[A-Z]/.test(method.name)) {
39935
+ mAssertion = "assert result";
39936
+ } else if (method.returnType) {
39937
+ const mrt = method.returnType.toLowerCase().replace(/promise<(.+)>/, "$1");
39938
+ if (mrt.includes("boolean") || mrt.includes("bool")) mAssertion = "assert isinstance(result, bool)";
39939
+ else if (mrt.includes("number") || mrt.includes("int") || mrt.includes("float")) mAssertion = "assert isinstance(result, (int, float))";
39940
+ else if (mrt.includes("string") || mrt.includes("str")) mAssertion = "assert isinstance(result, str)";
39941
+ else if (mrt.includes("[]") || mrt.includes("array") || mrt.includes("list")) mAssertion = "assert isinstance(result, list)";
39942
+ }
39943
+ }
39791
39944
  code += ` def test_${method.name}(self, instance):
39792
39945
  `;
39793
- if (isVoid) {
39946
+ if (isMethodVoid) {
39794
39947
  code += ` instance.${method.name}(${methodParams})
39795
39948
 
39796
39949
  `;
39797
39950
  } else {
39798
39951
  code += ` result = instance.${method.name}(${methodParams})
39799
39952
  `;
39800
- code += ` assert result is not None
39953
+ code += ` ${mAssertion}
39801
39954
 
39802
39955
  `;
39803
39956
  }
@@ -39985,12 +40138,214 @@ class Test${this.pascalCase(moduleName)}Coverage:
39985
40138
  }
39986
40139
  };
39987
40140
 
40141
+ // src/domains/test-generation/generators/node-test-generator.ts
40142
+ var NodeTestGenerator = class extends BaseTestGenerator {
40143
+ framework = "node-test";
40144
+ /**
40145
+ * Generate complete test file from analysis
40146
+ */
40147
+ generateTests(context) {
40148
+ const { moduleName, importPath, testType, patterns, analysis } = context;
40149
+ if (!analysis || analysis.functions.length === 0 && analysis.classes.length === 0) {
40150
+ return this.generateStubTests(context);
40151
+ }
40152
+ const patternComment = this.generatePatternComment(patterns);
40153
+ const exportedFunctions = analysis.functions.filter((fn) => fn.isExported);
40154
+ const exportedClasses = analysis.classes.filter((cls) => cls.isExported);
40155
+ const exports = this.extractExports(exportedFunctions, exportedClasses);
40156
+ const importStatement = this.generateImportStatement(exports, importPath, moduleName);
40157
+ let testCode = `${patternComment}import { describe, it, beforeEach } from 'node:test';
40158
+ import assert from 'node:assert';
40159
+ ${importStatement}
40160
+
40161
+ `;
40162
+ for (const fn of exportedFunctions) {
40163
+ testCode += this.generateFunctionTests(fn, testType);
40164
+ }
40165
+ for (const cls of exportedClasses) {
40166
+ testCode += this.generateClassTests(cls, testType);
40167
+ }
40168
+ return testCode;
40169
+ }
40170
+ /**
40171
+ * Generate tests for a standalone function
40172
+ */
40173
+ generateFunctionTests(fn, _testType) {
40174
+ const testCases = this.generateTestCasesForFunction(fn);
40175
+ let code = `describe('${fn.name}', () => {
40176
+ `;
40177
+ for (const testCase of testCases) {
40178
+ if (testCase.setup) {
40179
+ code += ` ${testCase.setup}
40180
+
40181
+ `;
40182
+ }
40183
+ const asyncPrefix = fn.isAsync ? "async " : "";
40184
+ code += ` it('${testCase.description}', ${asyncPrefix}() => {
40185
+ `;
40186
+ code += ` ${this.convertToAssert(testCase.action)}
40187
+ `;
40188
+ code += ` ${this.convertToAssert(testCase.assertion)}
40189
+ `;
40190
+ code += ` });
40191
+
40192
+ `;
40193
+ }
40194
+ code += `});
40195
+
40196
+ `;
40197
+ return code;
40198
+ }
40199
+ /**
40200
+ * Generate tests for a class
40201
+ */
40202
+ generateClassTests(cls, testType) {
40203
+ let code = `describe('${cls.name}', () => {
40204
+ `;
40205
+ code += ` let instance;
40206
+
40207
+ `;
40208
+ const constructorArgs = cls.constructorParams?.map((p74) => this.generateTestValue(p74)).join(", ") || "";
40209
+ code += ` beforeEach(() => {
40210
+ `;
40211
+ code += ` instance = new ${cls.name}(${constructorArgs});
40212
+ `;
40213
+ code += ` });
40214
+
40215
+ `;
40216
+ code += ` it('should instantiate correctly', () => {
40217
+ `;
40218
+ code += ` assert.ok(instance instanceof ${cls.name});
40219
+ `;
40220
+ code += ` });
40221
+
40222
+ `;
40223
+ for (const method of cls.methods) {
40224
+ if (!method.name.startsWith("_") && !method.name.startsWith("#")) {
40225
+ code += this.generateMethodTest(method);
40226
+ }
40227
+ }
40228
+ code += `});
40229
+
40230
+ `;
40231
+ return code;
40232
+ }
40233
+ /**
40234
+ * Generate test for a class method
40235
+ */
40236
+ generateMethodTest(method) {
40237
+ const validParams = method.parameters.map((p74) => this.generateTestValue(p74)).join(", ");
40238
+ const isVoid = method.returnType === "void" || method.returnType === "Promise<void>";
40239
+ const asyncPrefix = method.isAsync ? "async " : "";
40240
+ const methodCall = method.isAsync ? `await instance.${method.name}(${validParams})` : `instance.${method.name}(${validParams})`;
40241
+ let assertLine = "assert.ok(result !== undefined);";
40242
+ if (!isVoid) {
40243
+ const mLower = method.name.toLowerCase();
40244
+ if (/^(is|has|can)[A-Z]/.test(method.name)) {
40245
+ assertLine = "assert.strictEqual(typeof result, 'boolean');";
40246
+ } else if (/^(get|fetch|find)[A-Z]/.test(method.name)) {
40247
+ assertLine = "assert.ok(result !== undefined);";
40248
+ } else if (/^(create|build|make)[A-Z]/.test(method.name)) {
40249
+ assertLine = "assert.ok(result);";
40250
+ } else if (method.returnType) {
40251
+ const rt3 = method.returnType.toLowerCase().replace(/promise<(.+)>/, "$1");
40252
+ if (rt3.includes("boolean")) assertLine = "assert.strictEqual(typeof result, 'boolean');";
40253
+ else if (rt3.includes("number")) assertLine = "assert.strictEqual(typeof result, 'number');";
40254
+ else if (rt3.includes("string")) assertLine = "assert.strictEqual(typeof result, 'string');";
40255
+ else if (rt3.includes("[]") || rt3.includes("array")) assertLine = "assert.ok(Array.isArray(result));";
40256
+ }
40257
+ }
40258
+ let code = ` it('${method.name} should execute successfully', ${asyncPrefix}() => {
40259
+ `;
40260
+ if (isVoid) {
40261
+ code += ` ${methodCall};
40262
+ `;
40263
+ } else {
40264
+ code += ` const result = ${methodCall};
40265
+ `;
40266
+ code += ` ${assertLine}
40267
+ `;
40268
+ }
40269
+ code += ` });
40270
+
40271
+ `;
40272
+ return code;
40273
+ }
40274
+ /**
40275
+ * Generate stub tests when no AST analysis is available
40276
+ */
40277
+ generateStubTests(context) {
40278
+ const { moduleName, importPath, testType, patterns } = context;
40279
+ const patternComment = this.generatePatternComment(patterns);
40280
+ return `${patternComment}import { describe, it } from 'node:test';
40281
+ import assert from 'node:assert';
40282
+ import { ${moduleName} } from '${importPath}';
40283
+
40284
+ describe('${moduleName}', () => {
40285
+ describe('${testType} tests', () => {
40286
+ it('should be defined', () => {
40287
+ assert.ok(${moduleName} !== undefined);
40288
+ });
40289
+
40290
+ it('should handle basic operations', () => {
40291
+ const moduleType = typeof ${moduleName};
40292
+ assert.ok(['function', 'object'].includes(moduleType));
40293
+ });
40294
+
40295
+ it('should handle error conditions', () => {
40296
+ assert.doesNotThrow(() => {
40297
+ const instance = typeof ${moduleName} === 'function'
40298
+ ? new ${moduleName}()
40299
+ : ${moduleName};
40300
+ return instance;
40301
+ });
40302
+ });
40303
+ });
40304
+ });
40305
+ `;
40306
+ }
40307
+ /**
40308
+ * Generate coverage-focused tests for specific lines
40309
+ */
40310
+ generateCoverageTests(moduleName, importPath, lines) {
40311
+ const funcName = this.camelCase(moduleName);
40312
+ const lineRange = this.formatLineRange(lines);
40313
+ return `// Coverage test for ${lineRange} in ${moduleName}
40314
+ import { describe, it } from 'node:test';
40315
+ import assert from 'node:assert';
40316
+ import { ${funcName} } from '${importPath}';
40317
+
40318
+ describe('${moduleName} coverage', () => {
40319
+ it('should exercise code path covering ${lineRange}', () => {
40320
+ const testInput = undefined; // Replace with appropriate input
40321
+ const result = ${funcName}(testInput);
40322
+ assert.ok(result !== undefined || result === undefined);
40323
+ });
40324
+
40325
+ it('should handle edge case for ${lineRange}', () => {
40326
+ assert.doesNotThrow(() => ${funcName}(null));
40327
+ });
40328
+ });
40329
+ `;
40330
+ }
40331
+ // ============================================================================
40332
+ // Helpers
40333
+ // ============================================================================
40334
+ /**
40335
+ * Convert expect() style assertions to node:assert
40336
+ */
40337
+ convertToAssert(assertion) {
40338
+ return assertion.replace(/expect\(typeof ([^)]+)\)\.toBe\('([^']+)'\);?/g, "assert.strictEqual(typeof $1, '$2');").replace(/expect\(Array\.isArray\(([^)]+)\)\)\.toBe\(true\);?/g, "assert.ok(Array.isArray($1));").replace(/expect\(([^)]+)\)\.toThrow\(\);?/g, "assert.throws($1);").replace(/expect\(([^)]+)\)\.not\.toThrow\(\);?/g, "assert.doesNotThrow($1);").replace(/expect\(([^)]+)\)\.toBeInstanceOf\(([^)]+)\);?/g, "assert.ok($1 instanceof $2);").replace(/expect\(([^)]+)\)\.toBeDefined\(\);?/g, "assert.ok($1 !== undefined);").replace(/expect\(([^)]+)\)\.not\.toBeUndefined\(\);?/g, "assert.ok($1 !== undefined);").replace(/expect\(([^)]+)\)\.toBeUndefined\(\);?/g, "assert.strictEqual($1, undefined);").replace(/expect\(([^)]+)\)\.toBeTruthy\(\);?/g, "assert.ok($1);").replace(/expect\(([^)]+)\)\.toBeFalsy\(\);?/g, "assert.ok(!$1);").replace(/expect\(([^)]+)\)\.toBe\(([^)]+)\);?/g, "assert.strictEqual($1, $2);").replace(/expect\(([^)]+)\)\.toEqual\(([^)]+)\);?/g, "assert.deepStrictEqual($1, $2);");
40339
+ }
40340
+ };
40341
+
39988
40342
  // src/domains/test-generation/factories/test-generator-factory.ts
39989
40343
  var SUPPORTED_FRAMEWORKS = [
39990
40344
  "jest",
39991
40345
  "vitest",
39992
40346
  "mocha",
39993
- "pytest"
40347
+ "pytest",
40348
+ "node-test"
39994
40349
  ];
39995
40350
  var DEFAULT_FRAMEWORK = "vitest";
39996
40351
  var TestGeneratorFactory = class {
@@ -40052,6 +40407,8 @@ var TestGeneratorFactory = class {
40052
40407
  return new MochaGenerator();
40053
40408
  case "pytest":
40054
40409
  return new PytestGenerator();
40410
+ case "node-test":
40411
+ return new NodeTestGenerator();
40055
40412
  default:
40056
40413
  throw new Error(`Unsupported test framework: ${framework}`);
40057
40414
  }
@@ -41399,12 +41756,32 @@ ${sourceCode}
41399
41756
  };
41400
41757
  }
41401
41758
  extractParameters(params, sourceFile) {
41402
- return params.map((param) => ({
41403
- name: param.name.getText(sourceFile),
41404
- type: param.type?.getText(sourceFile),
41405
- optional: param.questionToken !== void 0,
41406
- defaultValue: param.initializer?.getText(sourceFile)
41407
- }));
41759
+ let objectDestructureCount = 0;
41760
+ let arrayDestructureCount = 0;
41761
+ return params.map((param) => {
41762
+ let name = param.name.getText(sourceFile);
41763
+ let type = param.type?.getText(sourceFile);
41764
+ if (ts.isObjectBindingPattern(param.name)) {
41765
+ objectDestructureCount++;
41766
+ name = objectDestructureCount > 1 ? `options${objectDestructureCount}` : "options";
41767
+ if (!type) {
41768
+ const props = param.name.elements.map((el) => `${el.name.getText(sourceFile)}: unknown`).join(", ");
41769
+ type = `{ ${props} }`;
41770
+ }
41771
+ } else if (ts.isArrayBindingPattern(param.name)) {
41772
+ arrayDestructureCount++;
41773
+ name = arrayDestructureCount > 1 ? `items${arrayDestructureCount}` : "items";
41774
+ if (!type) {
41775
+ type = "unknown[]";
41776
+ }
41777
+ }
41778
+ return {
41779
+ name,
41780
+ type,
41781
+ optional: param.questionToken !== void 0,
41782
+ defaultValue: param.initializer?.getText(sourceFile)
41783
+ };
41784
+ });
41408
41785
  }
41409
41786
  calculateComplexity(node) {
41410
41787
  let complexity = 1;
@@ -43419,12 +43796,32 @@ var TypeScriptASTParser = class {
43419
43796
  * Extract parameter information
43420
43797
  */
43421
43798
  extractParameters(params, sourceFile) {
43422
- return params.map((param) => ({
43423
- name: param.name.getText(sourceFile),
43424
- type: param.type?.getText(sourceFile),
43425
- optional: param.questionToken !== void 0,
43426
- defaultValue: param.initializer?.getText(sourceFile)
43427
- }));
43799
+ let objectDestructureCount = 0;
43800
+ let arrayDestructureCount = 0;
43801
+ return params.map((param) => {
43802
+ let name = param.name.getText(sourceFile);
43803
+ let type = param.type?.getText(sourceFile);
43804
+ if (ts2.isObjectBindingPattern(param.name)) {
43805
+ objectDestructureCount++;
43806
+ name = objectDestructureCount > 1 ? `options${objectDestructureCount}` : "options";
43807
+ if (!type) {
43808
+ const props = param.name.elements.map((el) => `${el.name.getText(sourceFile)}: unknown`).join(", ");
43809
+ type = `{ ${props} }`;
43810
+ }
43811
+ } else if (ts2.isArrayBindingPattern(param.name)) {
43812
+ arrayDestructureCount++;
43813
+ name = arrayDestructureCount > 1 ? `items${arrayDestructureCount}` : "items";
43814
+ if (!type) {
43815
+ type = "unknown[]";
43816
+ }
43817
+ }
43818
+ return {
43819
+ name,
43820
+ type,
43821
+ optional: param.questionToken !== void 0,
43822
+ defaultValue: param.initializer?.getText(sourceFile)
43823
+ };
43824
+ });
43428
43825
  }
43429
43826
  /**
43430
43827
  * Calculate cyclomatic complexity of a node
@@ -137639,8 +138036,83 @@ function generateV2LearningFeedback(agentType) {
137639
138036
  return {
137640
138037
  enabled: true,
137641
138038
  agentId: generateAgentId(agentType),
137642
- message: "Agent learned from this execution - patterns and Q-values updated"
138039
+ message: "Experience captured asynchronously via learning pipeline"
138040
+ };
138041
+ }
138042
+ async function captureExecutionLearning(agentType, toolName, params, result, durationMs) {
138043
+ const agentId = generateAgentId(agentType);
138044
+ try {
138045
+ const { kernel } = getFleetState();
138046
+ if (!kernel) {
138047
+ return { enabled: false, agentId, message: "Learning engine not available - kernel not initialized" };
138048
+ }
138049
+ const engine = await getLearningEngineForCapture();
138050
+ if (!engine) {
138051
+ return { enabled: false, agentId, message: "Learning engine not available" };
138052
+ }
138053
+ const captureService = engine.getExperienceCaptureService();
138054
+ if (!captureService) {
138055
+ return { enabled: false, agentId, message: "Experience capture service not available" };
138056
+ }
138057
+ const domain = toolNameToDomain(toolName);
138058
+ const experienceId = captureService.startCapture(
138059
+ `${toolName}: ${JSON.stringify(params).slice(0, 200)}`,
138060
+ {
138061
+ agent: agentType,
138062
+ domain: domain || void 0,
138063
+ metadata: {
138064
+ tool: toolName,
138065
+ durationMs
138066
+ }
138067
+ }
138068
+ );
138069
+ captureService.recordStep(experienceId, {
138070
+ action: `execute-${toolName}`,
138071
+ result: typeof result === "object" ? JSON.stringify(result).slice(0, 500) : String(result).slice(0, 500),
138072
+ quality: 0.7
138073
+ // Default quality for successful tool execution
138074
+ });
138075
+ const captureResult = await captureService.completeCapture(experienceId, {
138076
+ success: true,
138077
+ quality: 0.7
138078
+ });
138079
+ if (captureResult.success) {
138080
+ const experience = captureResult.value;
138081
+ return {
138082
+ enabled: true,
138083
+ agentId,
138084
+ message: `Experience captured: ${experience.id} (domain: ${domain || "general"}, quality: ${experience.quality})`,
138085
+ experienceId: experience.id,
138086
+ domain: domain || "general"
138087
+ };
138088
+ }
138089
+ return { enabled: true, agentId, message: "Experience capture completed (no pattern extracted)" };
138090
+ } catch (error) {
138091
+ return {
138092
+ enabled: false,
138093
+ agentId,
138094
+ message: `Learning capture failed: ${toErrorMessage(error)}`
138095
+ };
138096
+ }
138097
+ }
138098
+ function toolNameToDomain(toolName) {
138099
+ const mapping = {
138100
+ "test_generate_enhanced": "test-generation",
138101
+ "test_execute_parallel": "test-execution",
138102
+ "coverage_analyze_sublinear": "coverage-analysis",
138103
+ "quality_assess": "quality-assessment",
138104
+ "security_scan_comprehensive": "security-compliance",
138105
+ "contract_validate": "contract-testing",
138106
+ "accessibility_test": "visual-accessibility",
138107
+ "chaos_test": "chaos-resilience",
138108
+ "defect_predict": "defect-intelligence",
138109
+ "requirements_validate": "requirements-validation",
138110
+ "code_index": "code-intelligence"
137643
138111
  };
138112
+ return mapping[toolName] || null;
138113
+ }
138114
+ async function getLearningEngineForCapture() {
138115
+ return getLearningEngine();
137644
138116
  }
137645
138117
  function analyzeComplexity(sourceCode) {
137646
138118
  const lines = sourceCode.split("\n").length;
@@ -137946,6 +138418,14 @@ function createDomainHandler(config) {
137946
138418
  domain,
137947
138419
  result.duration
137948
138420
  );
138421
+ captureExecutionLearning(
138422
+ `qe-${domain}`,
138423
+ taskType,
138424
+ params,
138425
+ data,
138426
+ result.duration
138427
+ ).catch(() => {
138428
+ });
137949
138429
  return {
137950
138430
  success: true,
137951
138431
  data: mappedResult
@@ -153615,7 +154095,9 @@ var state = {
153615
154095
  router: null,
153616
154096
  workflowOrchestrator: null,
153617
154097
  initialized: false,
153618
- initTime: null
154098
+ initTime: null,
154099
+ topology: "hierarchical",
154100
+ agentLevels: /* @__PURE__ */ new Map()
153619
154101
  };
153620
154102
  function getFleetState() {
153621
154103
  return state;
@@ -153623,6 +154105,23 @@ function getFleetState() {
153623
154105
  function isFleetInitialized() {
153624
154106
  return state.initialized && state.kernel !== null && state.queen !== null;
153625
154107
  }
154108
+ function assignAgentLevel(agentId, domain) {
154109
+ if (state.topology !== "hierarchical") {
154110
+ const info2 = { agentId, domain, level: "worker", spawnedAt: /* @__PURE__ */ new Date() };
154111
+ state.agentLevels.set(agentId, info2);
154112
+ return "worker";
154113
+ }
154114
+ const existingLead = Array.from(state.agentLevels.values()).find(
154115
+ (a37) => a37.domain === domain && a37.level === "lead"
154116
+ );
154117
+ const level = existingLead ? "worker" : "lead";
154118
+ const info = { agentId, domain, level, spawnedAt: /* @__PURE__ */ new Date() };
154119
+ state.agentLevels.set(agentId, info);
154120
+ return level;
154121
+ }
154122
+ function getAgentLevel(agentId) {
154123
+ return state.agentLevels.get(agentId);
154124
+ }
153626
154125
  async function handleFleetInit(params) {
153627
154126
  try {
153628
154127
  if (state.initialized && state.kernel && state.queen) {
@@ -153687,11 +154186,13 @@ async function handleFleetInit(params) {
153687
154186
  registerDomainWorkflowActions(state.kernel, state.workflowOrchestrator);
153688
154187
  state.initialized = true;
153689
154188
  state.initTime = /* @__PURE__ */ new Date();
154189
+ state.topology = params.topology || "hierarchical";
154190
+ state.agentLevels.clear();
153690
154191
  return {
153691
154192
  success: true,
153692
154193
  data: {
153693
154194
  fleetId: state.fleetId,
153694
- topology: params.topology || "hierarchical",
154195
+ topology: state.topology,
153695
154196
  maxAgents: params.maxAgents || 15,
153696
154197
  // Return user-facing domains (12) - coordination is internal
153697
154198
  enabledDomains: userFacingDomains,
@@ -153851,6 +154352,8 @@ async function disposeFleet() {
153851
154352
  state.initialized = false;
153852
154353
  state.fleetId = null;
153853
154354
  state.initTime = null;
154355
+ state.topology = "hierarchical";
154356
+ state.agentLevels.clear();
153854
154357
  }
153855
154358
  function registerDomainWorkflowActions(kernel, orchestrator) {
153856
154359
  const reqValAPI = kernel.getDomainAPI("requirements-validation");
@@ -155124,14 +155627,18 @@ async function handleAgentList(params) {
155124
155627
  if (typeof params.limit === "number") {
155125
155628
  agents = agents.slice(0, params.limit);
155126
155629
  }
155127
- const result = agents.map((agent) => ({
155128
- id: agent.id,
155129
- domain: agent.domain,
155130
- type: agent.type,
155131
- status: agent.status,
155132
- name: agent.name,
155133
- startedAt: agent.startedAt?.toISOString()
155134
- }));
155630
+ const result = agents.map((agent) => {
155631
+ const levelInfo = getAgentLevel(agent.id);
155632
+ return {
155633
+ id: agent.id,
155634
+ domain: agent.domain,
155635
+ type: agent.type,
155636
+ status: agent.status,
155637
+ name: agent.name,
155638
+ startedAt: agent.startedAt?.toISOString(),
155639
+ level: levelInfo?.level
155640
+ };
155641
+ });
155135
155642
  return {
155136
155643
  success: true,
155137
155644
  data: result
@@ -155165,6 +155672,7 @@ async function handleAgentSpawn(params) {
155165
155672
  }
155166
155673
  const balancer = getLoadBalancer();
155167
155674
  balancer.registerAgent(result.value);
155675
+ const level = assignAgentLevel(result.value, params.domain);
155168
155676
  return {
155169
155677
  success: true,
155170
155678
  data: {
@@ -155172,7 +155680,8 @@ async function handleAgentSpawn(params) {
155172
155680
  domain: params.domain,
155173
155681
  type: params.type || "worker",
155174
155682
  status: "spawned",
155175
- capabilities: params.capabilities || ["general"]
155683
+ capabilities: params.capabilities || ["general"],
155684
+ level
155176
155685
  }
155177
155686
  };
155178
155687
  } catch (error) {
@@ -155732,6 +156241,17 @@ async function handleMemoryStore(params) {
155732
156241
  await kernel.memory.set(fullKey, params.value, {
155733
156242
  ttl: params.ttl
155734
156243
  });
156244
+ try {
156245
+ const textForEmbedding = `${params.key} ${JSON.stringify(params.value)}`;
156246
+ const embedding = textToSimpleEmbedding(textForEmbedding);
156247
+ await kernel.memory.storeVector(fullKey, embedding, {
156248
+ key: params.key,
156249
+ namespace,
156250
+ storedAt: Date.now()
156251
+ });
156252
+ } catch (vecErr) {
156253
+ console.warn(`[MemoryHandler] Vector indexing failed for ${params.key}: ${toErrorMessage(vecErr)}`);
156254
+ }
155735
156255
  if (isMemoryWriteGateEnabled()) {
155736
156256
  memoryWriteGateIntegration.registerPattern(
155737
156257
  createMemoryPattern(params.key, params.value, namespace)
@@ -155795,6 +156315,9 @@ async function handleMemoryRetrieve(params) {
155795
156315
  };
155796
156316
  }
155797
156317
  }
156318
+ function isNaturalLanguageQuery(pattern) {
156319
+ return pattern.includes(" ") && !pattern.includes("*") && !pattern.includes("?");
156320
+ }
155798
156321
  async function handleMemoryQuery(params) {
155799
156322
  if (!isFleetInitialized()) {
155800
156323
  return {
@@ -155807,6 +156330,34 @@ async function handleMemoryQuery(params) {
155807
156330
  const namespace = params.namespace || "default";
155808
156331
  const limit = params.limit || 100;
155809
156332
  const offset = params.offset || 0;
156333
+ const useSemantic = params.semantic === true || params.semantic !== false && params.pattern && isNaturalLanguageQuery(params.pattern);
156334
+ if (useSemantic && params.pattern) {
156335
+ try {
156336
+ const embedding = textToSimpleEmbedding(params.pattern);
156337
+ const vectorResults = await kernel.memory.vectorSearch(embedding, limit + offset);
156338
+ const filtered = namespace !== "default" ? vectorResults.filter((r54) => r54.key.startsWith(`${namespace}:`)) : vectorResults;
156339
+ const paginatedResults = filtered.slice(offset, offset + limit);
156340
+ const entries2 = paginatedResults.map((r54) => {
156341
+ const parts = r54.key.split(":");
156342
+ return {
156343
+ key: parts.length > 1 ? parts.slice(1).join(":") : r54.key,
156344
+ namespace: parts.length > 1 ? parts[0] : namespace,
156345
+ score: r54.score
156346
+ };
156347
+ });
156348
+ return {
156349
+ success: true,
156350
+ data: {
156351
+ entries: entries2,
156352
+ total: filtered.length,
156353
+ hasMore: offset + limit < filtered.length,
156354
+ searchType: "semantic"
156355
+ }
156356
+ };
156357
+ } catch (vectorError) {
156358
+ console.error(`[MemoryHandler] Semantic search failed, falling back to pattern: ${toErrorMessage(vectorError)}`);
156359
+ }
156360
+ }
155810
156361
  const pattern = params.pattern ? `${namespace}:${params.pattern}` : `${namespace}:*`;
155811
156362
  const keys = await kernel.memory.search(pattern, limit + offset);
155812
156363
  const paginatedKeys = keys.slice(offset, offset + limit);
@@ -155823,7 +156374,8 @@ async function handleMemoryQuery(params) {
155823
156374
  data: {
155824
156375
  entries,
155825
156376
  total: keys.length,
155826
- hasMore: offset + limit < keys.length
156377
+ hasMore: offset + limit < keys.length,
156378
+ searchType: "pattern"
155827
156379
  }
155828
156380
  };
155829
156381
  } catch (error) {
@@ -155833,6 +156385,26 @@ async function handleMemoryQuery(params) {
155833
156385
  };
155834
156386
  }
155835
156387
  }
156388
+ function textToSimpleEmbedding(text2) {
156389
+ const dimension = 768;
156390
+ const embedding = new Array(dimension).fill(0);
156391
+ const words = text2.toLowerCase().split(/\s+/);
156392
+ for (const word of words) {
156393
+ let hash = 0;
156394
+ for (let i58 = 0; i58 < word.length; i58++) {
156395
+ hash = (hash << 5) - hash + word.charCodeAt(i58) | 0;
156396
+ }
156397
+ const idx = Math.abs(hash) % dimension;
156398
+ embedding[idx] += 1;
156399
+ }
156400
+ const magnitude2 = Math.sqrt(embedding.reduce((sum, v62) => sum + v62 * v62, 0));
156401
+ if (magnitude2 > 0) {
156402
+ for (let i58 = 0; i58 < dimension; i58++) {
156403
+ embedding[i58] /= magnitude2;
156404
+ }
156405
+ }
156406
+ return embedding;
156407
+ }
155836
156408
  async function handleMemoryDelete(params) {
155837
156409
  if (!isFleetInitialized()) {
155838
156410
  return {
@@ -156562,6 +157134,9 @@ var MCPProtocolServer = class {
156562
157134
  monitor = getPerformanceMonitor();
156563
157135
  // AG-UI EventAdapter for streaming events to HTTP clients
156564
157136
  eventAdapter;
157137
+ // Connection recovery state
157138
+ reconnecting = false;
157139
+ pendingRequests = [];
156565
157140
  constructor(config = {}) {
156566
157141
  this.config = {
156567
157142
  name: config.name ?? "agentic-qe-v3",
@@ -156604,9 +157179,53 @@ var MCPProtocolServer = class {
156604
157179
  this.transport.onNotification(async (notification) => {
156605
157180
  await this.handleNotification(notification);
156606
157181
  });
157182
+ this.transport.onError(async (error) => {
157183
+ console.error(`[MCP] Transport error: ${error.message}`);
157184
+ await this.attemptReconnect();
157185
+ });
156607
157186
  this.transport.start();
156608
157187
  console.error(`[MCP] ${this.config.name} v${this.config.version} started`);
156609
157188
  }
157189
+ /**
157190
+ * Attempt to reconnect the transport with exponential backoff.
157191
+ * Buffers requests during the reconnection window and replays them after success.
157192
+ */
157193
+ async attemptReconnect() {
157194
+ if (this.reconnecting) return;
157195
+ this.reconnecting = true;
157196
+ const maxAttempts = 3;
157197
+ const baseDelay = 1e3;
157198
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
157199
+ const delay = baseDelay * Math.pow(2, attempt);
157200
+ console.error(`[MCP] Reconnect attempt ${attempt + 1}/${maxAttempts} in ${delay}ms...`);
157201
+ await new Promise((r54) => setTimeout(r54, delay));
157202
+ try {
157203
+ this.transport.reconnect();
157204
+ console.error(`[MCP] Reconnected after ${attempt + 1} attempt(s)`);
157205
+ this.reconnecting = false;
157206
+ const buffered2 = [...this.pendingRequests];
157207
+ this.pendingRequests = [];
157208
+ for (const { resolve: resolve9, request } of buffered2) {
157209
+ try {
157210
+ const result = await this.handleRequest(request);
157211
+ resolve9(result);
157212
+ } catch (err4) {
157213
+ console.error(`[MCP] Failed to replay buffered request: ${request.method}`);
157214
+ }
157215
+ }
157216
+ return;
157217
+ } catch (err4) {
157218
+ console.error(`[MCP] Reconnect attempt ${attempt + 1} failed: ${err4 instanceof Error ? err4.message : err4}`);
157219
+ }
157220
+ }
157221
+ this.reconnecting = false;
157222
+ console.error("[MCP] All reconnect attempts failed. Tools unavailable until transport is restored.");
157223
+ const buffered = [...this.pendingRequests];
157224
+ this.pendingRequests = [];
157225
+ for (const { reject } of buffered) {
157226
+ reject(new Error("MCP connection lost and reconnect failed"));
157227
+ }
157228
+ }
156610
157229
  /**
156611
157230
  * Stop the MCP server
156612
157231
  */
@@ -157092,11 +157711,12 @@ var MCPProtocolServer = class {
157092
157711
  this.registerTool({
157093
157712
  definition: {
157094
157713
  name: "memory_query",
157095
- description: "Query memory with pattern matching",
157714
+ description: "Query memory with pattern matching or HNSW semantic search",
157096
157715
  category: "memory",
157097
157716
  parameters: [
157098
- { name: "pattern", type: "string", description: "Key pattern" },
157099
- { name: "namespace", type: "string", description: "Memory namespace" }
157717
+ { name: "pattern", type: "string", description: "Key pattern (glob) or natural language query (for semantic search)" },
157718
+ { name: "namespace", type: "string", description: "Memory namespace" },
157719
+ { name: "semantic", type: "boolean", description: "Use HNSW vector search instead of pattern matching. Auto-detected when pattern contains spaces and no wildcards." }
157100
157720
  ]
157101
157721
  },
157102
157722
  handler: (params) => handleMemoryQuery(params)