agentic-qe 3.6.14 → 3.6.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/.claude/skills/skills-manifest.json +1 -1
  2. package/package.json +3 -2
  3. package/v3/CHANGELOG.md +42 -0
  4. package/v3/dist/cli/bundle.js +911 -354
  5. package/v3/dist/cli/commands/test.d.ts.map +1 -1
  6. package/v3/dist/cli/commands/test.js +6 -3
  7. package/v3/dist/cli/commands/test.js.map +1 -1
  8. package/v3/dist/cli/completions/index.d.ts +1 -1
  9. package/v3/dist/cli/completions/index.d.ts.map +1 -1
  10. package/v3/dist/cli/completions/index.js +1 -1
  11. package/v3/dist/cli/completions/index.js.map +1 -1
  12. package/v3/dist/cli/wizards/test-wizard.d.ts +1 -1
  13. package/v3/dist/cli/wizards/test-wizard.d.ts.map +1 -1
  14. package/v3/dist/cli/wizards/test-wizard.js +8 -1
  15. package/v3/dist/cli/wizards/test-wizard.js.map +1 -1
  16. package/v3/dist/coordination/task-executor.js.map +1 -1
  17. package/v3/dist/domains/test-generation/factories/test-generator-factory.d.ts.map +1 -1
  18. package/v3/dist/domains/test-generation/factories/test-generator-factory.js +4 -1
  19. package/v3/dist/domains/test-generation/factories/test-generator-factory.js.map +1 -1
  20. package/v3/dist/domains/test-generation/generators/base-test-generator.d.ts.map +1 -1
  21. package/v3/dist/domains/test-generation/generators/base-test-generator.js +74 -27
  22. package/v3/dist/domains/test-generation/generators/base-test-generator.js.map +1 -1
  23. package/v3/dist/domains/test-generation/generators/index.d.ts +1 -0
  24. package/v3/dist/domains/test-generation/generators/index.d.ts.map +1 -1
  25. package/v3/dist/domains/test-generation/generators/index.js +1 -0
  26. package/v3/dist/domains/test-generation/generators/index.js.map +1 -1
  27. package/v3/dist/domains/test-generation/generators/jest-vitest-generator.d.ts.map +1 -1
  28. package/v3/dist/domains/test-generation/generators/jest-vitest-generator.js +77 -21
  29. package/v3/dist/domains/test-generation/generators/jest-vitest-generator.js.map +1 -1
  30. package/v3/dist/domains/test-generation/generators/mocha-generator.d.ts.map +1 -1
  31. package/v3/dist/domains/test-generation/generators/mocha-generator.js +92 -17
  32. package/v3/dist/domains/test-generation/generators/mocha-generator.js.map +1 -1
  33. package/v3/dist/domains/test-generation/generators/node-test-generator.d.ts +54 -0
  34. package/v3/dist/domains/test-generation/generators/node-test-generator.d.ts.map +1 -0
  35. package/v3/dist/domains/test-generation/generators/node-test-generator.js +222 -0
  36. package/v3/dist/domains/test-generation/generators/node-test-generator.js.map +1 -0
  37. package/v3/dist/domains/test-generation/generators/pytest-generator.d.ts.map +1 -1
  38. package/v3/dist/domains/test-generation/generators/pytest-generator.js +74 -15
  39. package/v3/dist/domains/test-generation/generators/pytest-generator.js.map +1 -1
  40. package/v3/dist/domains/test-generation/interfaces/test-generator.interface.d.ts +1 -1
  41. package/v3/dist/domains/test-generation/interfaces/test-generator.interface.d.ts.map +1 -1
  42. package/v3/dist/domains/test-generation/interfaces.d.ts +2 -2
  43. package/v3/dist/domains/test-generation/interfaces.d.ts.map +1 -1
  44. package/v3/dist/domains/test-generation/plugin.js.map +1 -1
  45. package/v3/dist/domains/test-generation/services/pattern-matcher.d.ts.map +1 -1
  46. package/v3/dist/domains/test-generation/services/pattern-matcher.js +34 -7
  47. package/v3/dist/domains/test-generation/services/pattern-matcher.js.map +1 -1
  48. package/v3/dist/domains/test-generation/services/test-generator.d.ts.map +1 -1
  49. package/v3/dist/domains/test-generation/services/test-generator.js +42 -9
  50. package/v3/dist/domains/test-generation/services/test-generator.js.map +1 -1
  51. package/v3/dist/mcp/bundle.js +550 -78
  52. package/v3/dist/mcp/tools/test-generation/generate.d.ts +1 -1
  53. package/v3/dist/mcp/tools/test-generation/generate.d.ts.map +1 -1
  54. package/v3/dist/mcp/tools/test-generation/generate.js.map +1 -1
  55. package/v3/dist/shared/sql-safety.d.ts +3 -0
  56. package/v3/dist/shared/sql-safety.d.ts.map +1 -1
  57. package/v3/dist/shared/sql-safety.js +12 -2
  58. package/v3/dist/shared/sql-safety.js.map +1 -1
  59. package/v3/dist/sync/cloud/postgres-writer.d.ts +6 -1
  60. package/v3/dist/sync/cloud/postgres-writer.d.ts.map +1 -1
  61. package/v3/dist/sync/cloud/postgres-writer.js +121 -46
  62. package/v3/dist/sync/cloud/postgres-writer.js.map +1 -1
  63. package/v3/dist/sync/interfaces.d.ts.map +1 -1
  64. package/v3/dist/sync/interfaces.js +97 -32
  65. package/v3/dist/sync/interfaces.js.map +1 -1
  66. package/v3/dist/sync/sync-agent.d.ts.map +1 -1
  67. package/v3/dist/sync/sync-agent.js +8 -24
  68. package/v3/dist/sync/sync-agent.js.map +1 -1
  69. package/v3/package.json +1 -1
@@ -14,7 +14,7 @@ var __require = /* @__PURE__ */ ((x67) => typeof require !== "undefined" ? requi
14
14
  var __esm = (fn, res) => function __init() {
15
15
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
16
16
  };
17
- var __commonJS = (cb, mod) => function __require10() {
17
+ var __commonJS = (cb, mod) => function __require9() {
18
18
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
19
19
  };
20
20
  var __export = (target, all) => {
@@ -1082,11 +1082,19 @@ function validateTableName(tableName) {
1082
1082
  return tableName;
1083
1083
  }
1084
1084
  function validateIdentifier(name) {
1085
- if (!IDENTIFIER_REGEX.test(name)) {
1085
+ const parts = name.split(".");
1086
+ if (parts.length > 2) {
1086
1087
  throw new Error(
1087
- `Invalid SQL identifier: "${name}" does not match pattern ${IDENTIFIER_REGEX}`
1088
+ `Invalid SQL identifier: "${name}" has too many parts (max: schema.table)`
1088
1089
  );
1089
1090
  }
1091
+ for (const part of parts) {
1092
+ if (!IDENTIFIER_REGEX.test(part)) {
1093
+ throw new Error(
1094
+ `Invalid SQL identifier: "${name}" \u2014 part "${part}" does not match pattern ${IDENTIFIER_REGEX}`
1095
+ );
1096
+ }
1097
+ }
1090
1098
  return name;
1091
1099
  }
1092
1100
  var ALLOWED_TABLE_NAMES, IDENTIFIER_REGEX;
@@ -16856,63 +16864,6 @@ var init_hnswlib_node = __esm({
16856
16864
  }
16857
16865
  });
16858
16866
 
16859
- // native-require:pg
16860
- var pg_exports = {};
16861
- __export(pg_exports, {
16862
- DotProductAttention: () => DotProductAttention7,
16863
- FlashAttention: () => FlashAttention7,
16864
- HyperbolicAttention: () => HyperbolicAttention7,
16865
- LinearAttention: () => LinearAttention7,
16866
- MoEAttention: () => MoEAttention7,
16867
- MultiHeadAttention: () => MultiHeadAttention7,
16868
- RuvectorLayer: () => RuvectorLayer7,
16869
- SonaEngine: () => SonaEngine7,
16870
- TensorCompress: () => TensorCompress7,
16871
- default: () => pg_default,
16872
- differentiableSearch: () => differentiableSearch7,
16873
- getCompressionLevel: () => getCompressionLevel7,
16874
- hierarchicalForward: () => hierarchicalForward7,
16875
- init: () => init7,
16876
- pipeline: () => pipeline8
16877
- });
16878
- import { createRequire as createRequire7 } from "module";
16879
- var __require8, __mod7, pg_default, RuvectorLayer7, TensorCompress7, differentiableSearch7, hierarchicalForward7, getCompressionLevel7, init7, FlashAttention7, DotProductAttention7, MultiHeadAttention7, HyperbolicAttention7, LinearAttention7, MoEAttention7, SonaEngine7, pipeline8;
16880
- var init_pg = __esm({
16881
- "native-require:pg"() {
16882
- __require8 = createRequire7(import.meta.url);
16883
- __mod7 = __require8("pg");
16884
- pg_default = __mod7;
16885
- ({
16886
- RuvectorLayer: (
16887
- // @ruvector/gnn
16888
- RuvectorLayer7
16889
- ),
16890
- TensorCompress: TensorCompress7,
16891
- differentiableSearch: differentiableSearch7,
16892
- hierarchicalForward: hierarchicalForward7,
16893
- getCompressionLevel: getCompressionLevel7,
16894
- init: init7,
16895
- FlashAttention: (
16896
- // @ruvector/attention
16897
- FlashAttention7
16898
- ),
16899
- DotProductAttention: DotProductAttention7,
16900
- MultiHeadAttention: MultiHeadAttention7,
16901
- HyperbolicAttention: HyperbolicAttention7,
16902
- LinearAttention: LinearAttention7,
16903
- MoEAttention: MoEAttention7,
16904
- SonaEngine: (
16905
- // @ruvector/sona
16906
- SonaEngine7
16907
- ),
16908
- pipeline: (
16909
- // @xenova/transformers
16910
- pipeline8
16911
- )
16912
- } = __mod7 || {});
16913
- }
16914
- });
16915
-
16916
16867
  // src/learning/qe-reasoning-bank.ts
16917
16868
  var qe_reasoning_bank_exports = {};
16918
16869
  __export(qe_reasoning_bank_exports, {
@@ -18314,57 +18265,57 @@ On promotion:
18314
18265
  // native-require:prime-radiant-advanced-wasm
18315
18266
  var prime_radiant_advanced_wasm_exports = {};
18316
18267
  __export(prime_radiant_advanced_wasm_exports, {
18317
- DotProductAttention: () => DotProductAttention8,
18318
- FlashAttention: () => FlashAttention8,
18319
- HyperbolicAttention: () => HyperbolicAttention8,
18320
- LinearAttention: () => LinearAttention8,
18321
- MoEAttention: () => MoEAttention8,
18322
- MultiHeadAttention: () => MultiHeadAttention8,
18323
- RuvectorLayer: () => RuvectorLayer8,
18324
- SonaEngine: () => SonaEngine8,
18325
- TensorCompress: () => TensorCompress8,
18268
+ DotProductAttention: () => DotProductAttention7,
18269
+ FlashAttention: () => FlashAttention7,
18270
+ HyperbolicAttention: () => HyperbolicAttention7,
18271
+ LinearAttention: () => LinearAttention7,
18272
+ MoEAttention: () => MoEAttention7,
18273
+ MultiHeadAttention: () => MultiHeadAttention7,
18274
+ RuvectorLayer: () => RuvectorLayer7,
18275
+ SonaEngine: () => SonaEngine7,
18276
+ TensorCompress: () => TensorCompress7,
18326
18277
  default: () => prime_radiant_advanced_wasm_default,
18327
- differentiableSearch: () => differentiableSearch8,
18328
- getCompressionLevel: () => getCompressionLevel8,
18329
- hierarchicalForward: () => hierarchicalForward8,
18330
- init: () => init8,
18331
- pipeline: () => pipeline9
18278
+ differentiableSearch: () => differentiableSearch7,
18279
+ getCompressionLevel: () => getCompressionLevel7,
18280
+ hierarchicalForward: () => hierarchicalForward7,
18281
+ init: () => init7,
18282
+ pipeline: () => pipeline8
18332
18283
  });
18333
18284
  import { createRequire as createRequire8 } from "module";
18334
- var __require9, __mod8, prime_radiant_advanced_wasm_default, RuvectorLayer8, TensorCompress8, differentiableSearch8, hierarchicalForward8, getCompressionLevel8, init8, FlashAttention8, DotProductAttention8, MultiHeadAttention8, HyperbolicAttention8, LinearAttention8, MoEAttention8, SonaEngine8, pipeline9;
18285
+ var __require8, __mod7, prime_radiant_advanced_wasm_default, RuvectorLayer7, TensorCompress7, differentiableSearch7, hierarchicalForward7, getCompressionLevel7, init7, FlashAttention7, DotProductAttention7, MultiHeadAttention7, HyperbolicAttention7, LinearAttention7, MoEAttention7, SonaEngine7, pipeline8;
18335
18286
  var init_prime_radiant_advanced_wasm = __esm({
18336
18287
  "native-require:prime-radiant-advanced-wasm"() {
18337
- __require9 = createRequire8(import.meta.url);
18338
- __mod8 = __require9("prime-radiant-advanced-wasm");
18339
- prime_radiant_advanced_wasm_default = __mod8;
18288
+ __require8 = createRequire8(import.meta.url);
18289
+ __mod7 = __require8("prime-radiant-advanced-wasm");
18290
+ prime_radiant_advanced_wasm_default = __mod7;
18340
18291
  ({
18341
18292
  RuvectorLayer: (
18342
18293
  // @ruvector/gnn
18343
- RuvectorLayer8
18294
+ RuvectorLayer7
18344
18295
  ),
18345
- TensorCompress: TensorCompress8,
18346
- differentiableSearch: differentiableSearch8,
18347
- hierarchicalForward: hierarchicalForward8,
18348
- getCompressionLevel: getCompressionLevel8,
18349
- init: init8,
18296
+ TensorCompress: TensorCompress7,
18297
+ differentiableSearch: differentiableSearch7,
18298
+ hierarchicalForward: hierarchicalForward7,
18299
+ getCompressionLevel: getCompressionLevel7,
18300
+ init: init7,
18350
18301
  FlashAttention: (
18351
18302
  // @ruvector/attention
18352
- FlashAttention8
18303
+ FlashAttention7
18353
18304
  ),
18354
- DotProductAttention: DotProductAttention8,
18355
- MultiHeadAttention: MultiHeadAttention8,
18356
- HyperbolicAttention: HyperbolicAttention8,
18357
- LinearAttention: LinearAttention8,
18358
- MoEAttention: MoEAttention8,
18305
+ DotProductAttention: DotProductAttention7,
18306
+ MultiHeadAttention: MultiHeadAttention7,
18307
+ HyperbolicAttention: HyperbolicAttention7,
18308
+ LinearAttention: LinearAttention7,
18309
+ MoEAttention: MoEAttention7,
18359
18310
  SonaEngine: (
18360
18311
  // @ruvector/sona
18361
- SonaEngine8
18312
+ SonaEngine7
18362
18313
  ),
18363
18314
  pipeline: (
18364
18315
  // @xenova/transformers
18365
- pipeline9
18316
+ pipeline8
18366
18317
  )
18367
- } = __mod8 || {});
18318
+ } = __mod7 || {});
18368
18319
  }
18369
18320
  });
18370
18321
 
@@ -25357,7 +25308,7 @@ var BaseTestGenerator = class _BaseTestGenerator {
25357
25308
  for (const [typeKey, generator] of _BaseTestGenerator.TYPE_VALUE_TABLE) {
25358
25309
  if (type.includes(typeKey)) return generator();
25359
25310
  }
25360
- return `mock${param.name.charAt(0).toUpperCase() + param.name.slice(1)}`;
25311
+ return `{} /* TODO: provide ${param.name}: ${param.type || "unknown"} */`;
25361
25312
  }
25362
25313
  /**
25363
25314
  * Generate test cases for a function based on its signature
@@ -25370,21 +25321,62 @@ var BaseTestGenerator = class _BaseTestGenerator {
25370
25321
  const testCases = [];
25371
25322
  const validParams = fn.parameters.map((p74) => this.generateTestValue(p74)).join(", ");
25372
25323
  const fnCall = fn.isAsync ? `await ${fn.name}(${validParams})` : `${fn.name}(${validParams})`;
25324
+ const isVoid = fn.returnType === "void" || fn.returnType === "Promise<void>";
25325
+ let assertion = "expect(result).toBeDefined();";
25326
+ if (!isVoid) {
25327
+ if (/^(is|has|can)[A-Z]/.test(fn.name)) {
25328
+ assertion = "expect(typeof result).toBe('boolean');";
25329
+ } else if (/^(get|fetch|find)[A-Z]/.test(fn.name)) {
25330
+ assertion = "expect(result).not.toBeUndefined();";
25331
+ } else if (/^(create|build|make)[A-Z]/.test(fn.name)) {
25332
+ assertion = "expect(result).toBeTruthy();";
25333
+ } else if (fn.returnType) {
25334
+ const rt3 = fn.returnType.toLowerCase().replace(/promise<(.+)>/, "$1");
25335
+ if (rt3.includes("boolean")) assertion = "expect(typeof result).toBe('boolean');";
25336
+ else if (rt3.includes("number")) assertion = "expect(typeof result).toBe('number');";
25337
+ else if (rt3.includes("string")) assertion = "expect(typeof result).toBe('string');";
25338
+ else if (rt3.includes("[]") || rt3.includes("array")) assertion = "expect(Array.isArray(result)).toBe(true);";
25339
+ }
25340
+ }
25373
25341
  testCases.push({
25374
25342
  description: "should handle valid input correctly",
25375
25343
  type: "happy-path",
25376
- action: `const result = ${fnCall};`,
25377
- assertion: "expect(result).toBeDefined();"
25344
+ action: isVoid ? `${fnCall};` : `const result = ${fnCall};`,
25345
+ assertion: isVoid ? `// void function \u2014 no return value to assert` : assertion
25378
25346
  });
25347
+ const bodyText = fn.body || "";
25348
+ const hasExplicitThrow = /\bthrow\b/.test(bodyText) || /\bvalidat/i.test(bodyText);
25379
25349
  for (const param of fn.parameters) {
25380
25350
  if (!param.optional) {
25381
25351
  const paramsWithUndefined = fn.parameters.map((p74) => p74.name === param.name ? "undefined" : this.generateTestValue(p74)).join(", ");
25382
- testCases.push({
25383
- description: `should handle undefined ${param.name}`,
25384
- type: "error-handling",
25385
- action: fn.isAsync ? `const action = async () => await ${fn.name}(${paramsWithUndefined});` : `const action = () => ${fn.name}(${paramsWithUndefined});`,
25386
- assertion: "expect(action).toThrow();"
25387
- });
25352
+ if (hasExplicitThrow) {
25353
+ testCases.push({
25354
+ description: `should handle undefined ${param.name}`,
25355
+ type: "error-handling",
25356
+ action: fn.isAsync ? `const action = async () => await ${fn.name}(${paramsWithUndefined});` : `const action = () => ${fn.name}(${paramsWithUndefined});`,
25357
+ assertion: "expect(action).toThrow();"
25358
+ });
25359
+ } else {
25360
+ const undefinedCall = fn.isAsync ? `await ${fn.name}(${paramsWithUndefined})` : `${fn.name}(${paramsWithUndefined})`;
25361
+ testCases.push({
25362
+ description: `should handle undefined ${param.name}`,
25363
+ type: "edge-case",
25364
+ action: fn.isAsync ? `let threw = false;
25365
+ try {
25366
+ await ${fn.name}(${paramsWithUndefined});
25367
+ } catch (e) {
25368
+ threw = true;
25369
+ expect(e).toBeInstanceOf(Error);
25370
+ }` : `let threw = false;
25371
+ try {
25372
+ ${fn.name}(${paramsWithUndefined});
25373
+ } catch (e) {
25374
+ threw = true;
25375
+ expect(e).toBeInstanceOf(Error);
25376
+ }`,
25377
+ assertion: `expect(true).toBe(true); // function either handles undefined or throws TypeError`
25378
+ });
25379
+ }
25388
25380
  }
25389
25381
  testCases.push(...this.generateBoundaryTestCases(fn, param));
25390
25382
  }
@@ -25404,32 +25396,48 @@ var BaseTestGenerator = class _BaseTestGenerator {
25404
25396
  generateBoundaryTestCases(fn, param) {
25405
25397
  const testCases = [];
25406
25398
  const type = param.type?.toLowerCase() || "";
25399
+ const wrapBoundaryAction = (call, isAsync) => {
25400
+ if (isAsync) {
25401
+ return `try {
25402
+ const result = await ${call};
25403
+ expect(result).toBeDefined();
25404
+ } catch (e) {
25405
+ expect(e).toBeInstanceOf(Error);
25406
+ }`;
25407
+ }
25408
+ return `try {
25409
+ const result = ${call};
25410
+ expect(result).toBeDefined();
25411
+ } catch (e) {
25412
+ expect(e).toBeInstanceOf(Error);
25413
+ }`;
25414
+ };
25407
25415
  if (type.includes("string")) {
25408
25416
  const paramsWithEmpty = fn.parameters.map((p74) => p74.name === param.name ? "''" : this.generateTestValue(p74)).join(", ");
25409
- const emptyCall = fn.isAsync ? `await ${fn.name}(${paramsWithEmpty})` : `${fn.name}(${paramsWithEmpty})`;
25417
+ const emptyCall = `${fn.name}(${paramsWithEmpty})`;
25410
25418
  testCases.push({
25411
25419
  description: `should handle empty string for ${param.name}`,
25412
25420
  type: "boundary",
25413
- action: `const result = ${emptyCall};`,
25414
- assertion: "expect(result).toBeDefined();"
25421
+ action: wrapBoundaryAction(emptyCall, fn.isAsync),
25422
+ assertion: ""
25415
25423
  });
25416
25424
  }
25417
25425
  if (type.includes("number")) {
25418
25426
  const paramsWithZero = fn.parameters.map((p74) => p74.name === param.name ? "0" : this.generateTestValue(p74)).join(", ");
25419
- const zeroCall = fn.isAsync ? `await ${fn.name}(${paramsWithZero})` : `${fn.name}(${paramsWithZero})`;
25427
+ const zeroCall = `${fn.name}(${paramsWithZero})`;
25420
25428
  testCases.push({
25421
25429
  description: `should handle zero for ${param.name}`,
25422
25430
  type: "boundary",
25423
- action: `const result = ${zeroCall};`,
25424
- assertion: "expect(result).toBeDefined();"
25431
+ action: wrapBoundaryAction(zeroCall, fn.isAsync),
25432
+ assertion: ""
25425
25433
  });
25426
25434
  const paramsWithNegative = fn.parameters.map((p74) => p74.name === param.name ? "-1" : this.generateTestValue(p74)).join(", ");
25427
- const negativeCall = fn.isAsync ? `await ${fn.name}(${paramsWithNegative})` : `${fn.name}(${paramsWithNegative})`;
25435
+ const negativeCall = `${fn.name}(${paramsWithNegative})`;
25428
25436
  testCases.push({
25429
25437
  description: `should handle negative value for ${param.name}`,
25430
25438
  type: "edge-case",
25431
- action: `const result = ${negativeCall};`,
25432
- assertion: "expect(result).toBeDefined();"
25439
+ action: wrapBoundaryAction(negativeCall, fn.isAsync),
25440
+ assertion: ""
25433
25441
  });
25434
25442
  }
25435
25443
  if (type.includes("[]") || type.includes("array")) {
@@ -25527,24 +25535,31 @@ ${importStatement}
25527
25535
  `;
25528
25536
  if (dependencies && dependencies.imports.length > 0) {
25529
25537
  const mockFn = this.framework === "vitest" ? "vi.fn()" : "jest.fn()";
25530
- testCode += `
25538
+ const externalDeps = dependencies.imports.filter((dep) => !dep.startsWith("."));
25539
+ if (externalDeps.length > 0) {
25540
+ testCode += `
25531
25541
  // Auto-generated mocks from Knowledge Graph dependency analysis
25532
25542
  `;
25533
- for (const dep of dependencies.imports.slice(0, 10)) {
25534
- const depName = dep.split("/").pop()?.replace(/[^a-zA-Z0-9_]/g, "_") || dep;
25535
- testCode += `${this.framework === "vitest" ? "vi" : "jest"}.mock('${dep}', () => ({ default: ${mockFn} }));
25543
+ for (const dep of externalDeps.slice(0, 10)) {
25544
+ testCode += `${this.framework === "vitest" ? "vi" : "jest"}.mock('${dep}', () => ({ default: ${mockFn} }));
25536
25545
  `;
25537
- }
25538
- testCode += `
25546
+ }
25547
+ testCode += `
25548
+ `;
25549
+ } else {
25550
+ testCode += `
25539
25551
  `;
25552
+ }
25540
25553
  } else {
25541
25554
  testCode += `
25542
25555
  `;
25543
25556
  }
25544
- for (const fn of analysis.functions) {
25557
+ const exportedFns = analysis.functions.filter((fn) => fn.isExported);
25558
+ const exportedClasses = analysis.classes.filter((cls) => cls.isExported);
25559
+ for (const fn of exportedFns) {
25545
25560
  testCode += this.generateFunctionTests(fn, testType);
25546
25561
  }
25547
- for (const cls of analysis.classes) {
25562
+ for (const cls of exportedClasses) {
25548
25563
  testCode += this.generateClassTests(cls, testType);
25549
25564
  }
25550
25565
  return testCode;
@@ -25631,24 +25646,68 @@ ${importStatement}
25631
25646
  const validParams = method.parameters.map((p74) => this.generateTestValue(p74)).join(", ");
25632
25647
  const methodCall = method.isAsync ? `await instance.${method.name}(${validParams})` : `instance.${method.name}(${validParams})`;
25633
25648
  const asyncPrefix = method.isAsync ? "async " : "";
25649
+ const isVoid = method.returnType === "void" || method.returnType === "Promise<void>";
25650
+ let methodAssertion = "expect(result).toBeDefined();";
25651
+ if (!isVoid) {
25652
+ if (/^(is|has|can)[A-Z]/.test(method.name)) {
25653
+ methodAssertion = "expect(typeof result).toBe('boolean');";
25654
+ } else if (/^(get|fetch|find)[A-Z]/.test(method.name)) {
25655
+ methodAssertion = "expect(result).not.toBeUndefined();";
25656
+ } else if (/^(create|build|make)[A-Z]/.test(method.name)) {
25657
+ methodAssertion = "expect(result).toBeTruthy();";
25658
+ } else if (method.returnType) {
25659
+ const mrt = method.returnType.toLowerCase().replace(/promise<(.+)>/, "$1");
25660
+ if (mrt.includes("boolean")) methodAssertion = "expect(typeof result).toBe('boolean');";
25661
+ else if (mrt.includes("number")) methodAssertion = "expect(typeof result).toBe('number');";
25662
+ else if (mrt.includes("string")) methodAssertion = "expect(typeof result).toBe('string');";
25663
+ else if (mrt.includes("[]") || mrt.includes("array")) methodAssertion = "expect(Array.isArray(result)).toBe(true);";
25664
+ }
25665
+ }
25634
25666
  code += ` it('should execute successfully', ${asyncPrefix}() => {
25635
25667
  `;
25636
- code += ` const result = ${methodCall};
25668
+ if (isVoid) {
25669
+ code += ` ${methodCall};
25637
25670
  `;
25638
- code += ` expect(result).toBeDefined();
25671
+ code += ` // void return \u2014 no assertion on result needed
25639
25672
  `;
25673
+ } else {
25674
+ code += ` const result = ${methodCall};
25675
+ `;
25676
+ code += ` ${methodAssertion}
25677
+ `;
25678
+ }
25640
25679
  code += ` });
25641
25680
  `;
25681
+ const methodBody = method.body || "";
25682
+ const methodThrows = /\bthrow\b/.test(methodBody) || /\bvalidat/i.test(methodBody);
25642
25683
  for (const param of method.parameters) {
25643
25684
  if (!param.optional) {
25644
25685
  const paramsWithUndefined = method.parameters.map((p74) => p74.name === param.name ? "undefined as any" : this.generateTestValue(p74)).join(", ");
25645
- code += `
25646
- it('should handle invalid ${param.name}', () => {
25686
+ if (methodThrows) {
25687
+ code += `
25688
+ it('should handle invalid ${param.name}', ${asyncPrefix}() => {
25647
25689
  `;
25648
- code += ` expect(() => instance.${method.name}(${paramsWithUndefined})).toThrow();
25690
+ code += ` expect(() => instance.${method.name}(${paramsWithUndefined})).toThrow();
25649
25691
  `;
25650
- code += ` });
25692
+ code += ` });
25651
25693
  `;
25694
+ } else {
25695
+ code += `
25696
+ it('should handle undefined ${param.name}', ${asyncPrefix}() => {
25697
+ `;
25698
+ code += ` try {
25699
+ `;
25700
+ code += ` ${method.isAsync ? "await " : ""}instance.${method.name}(${paramsWithUndefined});
25701
+ `;
25702
+ code += ` } catch (e) {
25703
+ `;
25704
+ code += ` expect(e).toBeInstanceOf(Error);
25705
+ `;
25706
+ code += ` }
25707
+ `;
25708
+ code += ` });
25709
+ `;
25710
+ }
25652
25711
  }
25653
25712
  }
25654
25713
  code += ` });
@@ -25668,12 +25727,15 @@ ${importStatement}
25668
25727
  let mockDeclarations = "";
25669
25728
  if (dependencies && dependencies.imports.length > 0) {
25670
25729
  const mockFn = this.framework === "vitest" ? "vi.fn()" : "jest.fn()";
25671
- mockDeclarations += `
25730
+ const externalDeps = dependencies.imports.filter((dep) => !dep.startsWith("."));
25731
+ if (externalDeps.length > 0) {
25732
+ mockDeclarations += `
25672
25733
  // Auto-generated mocks from Knowledge Graph dependency analysis
25673
25734
  `;
25674
- for (const dep of dependencies.imports.slice(0, 10)) {
25675
- mockDeclarations += `${this.mockUtil}.mock('${dep}', () => ({ default: ${mockFn} }));
25735
+ for (const dep of externalDeps.slice(0, 10)) {
25736
+ mockDeclarations += `${this.mockUtil}.mock('${dep}', () => ({ default: ${mockFn} }));
25676
25737
  `;
25738
+ }
25677
25739
  }
25678
25740
  }
25679
25741
  let similarityComment = "";
@@ -25950,10 +26012,11 @@ var MochaGenerator = class extends BaseTestGenerator {
25950
26012
  const importStatement = this.generateImportStatement(exports, importPath, moduleName);
25951
26013
  let sinonImport = "";
25952
26014
  let stubSetup = "";
25953
- if (dependencies && dependencies.imports.length > 0) {
26015
+ const externalDeps = dependencies?.imports.filter((dep) => !dep.startsWith(".")) || [];
26016
+ if (externalDeps.length > 0) {
25954
26017
  sinonImport = `import sinon from 'sinon';
25955
26018
  `;
25956
- const depsToMock = dependencies.imports.slice(0, 5);
26019
+ const depsToMock = externalDeps.slice(0, 5);
25957
26020
  stubSetup += ` // Auto-generated stubs from Knowledge Graph dependency analysis
25958
26021
  `;
25959
26022
  stubSetup += ` let stubs;
@@ -25986,10 +26049,12 @@ ${sinonImport}${importStatement}
25986
26049
 
25987
26050
  describe('${moduleName} - ${testType} tests', function() {
25988
26051
  ${stubSetup}`;
25989
- for (const fn of analysis.functions) {
26052
+ const exportedFns = analysis.functions.filter((fn) => fn.isExported);
26053
+ const exportedClasses = analysis.classes.filter((cls) => cls.isExported);
26054
+ for (const fn of exportedFns) {
25990
26055
  code += this.generateFunctionTests(fn, testType);
25991
26056
  }
25992
- for (const cls of analysis.classes) {
26057
+ for (const cls of exportedClasses) {
25993
26058
  code += this.generateClassTests(cls, testType);
25994
26059
  }
25995
26060
  code += `});
@@ -26002,26 +26067,68 @@ ${stubSetup}`;
26002
26067
  generateFunctionTests(fn, _testType) {
26003
26068
  const validParams = fn.parameters.map((p74) => this.generateTestValue(p74)).join(", ");
26004
26069
  const fnCall = fn.isAsync ? `await ${fn.name}(${validParams})` : `${fn.name}(${validParams})`;
26070
+ const isVoid = fn.returnType === "void" || fn.returnType === "Promise<void>";
26005
26071
  let code = ` describe('${fn.name}', function() {
26006
26072
  `;
26073
+ let chaiAssertion = "expect(result).to.not.be.undefined;";
26074
+ if (!isVoid) {
26075
+ if (/^(is|has|can)[A-Z]/.test(fn.name)) {
26076
+ chaiAssertion = "expect(typeof result).to.equal('boolean');";
26077
+ } else if (/^(get|fetch|find)[A-Z]/.test(fn.name)) {
26078
+ chaiAssertion = "expect(result).to.not.be.undefined;";
26079
+ } else if (/^(create|build|make)[A-Z]/.test(fn.name)) {
26080
+ chaiAssertion = "expect(result).to.be.ok;";
26081
+ } else if (fn.returnType) {
26082
+ const rt3 = fn.returnType.toLowerCase().replace(/promise<(.+)>/, "$1");
26083
+ if (rt3.includes("boolean")) chaiAssertion = "expect(typeof result).to.equal('boolean');";
26084
+ else if (rt3.includes("number")) chaiAssertion = "expect(typeof result).to.equal('number');";
26085
+ else if (rt3.includes("string")) chaiAssertion = "expect(typeof result).to.equal('string');";
26086
+ else if (rt3.includes("[]") || rt3.includes("array")) chaiAssertion = "expect(result).to.be.an('array');";
26087
+ }
26088
+ }
26007
26089
  code += ` it('should handle valid input', ${fn.isAsync ? "async " : ""}function() {
26008
26090
  `;
26009
- code += ` const result = ${fnCall};
26091
+ if (isVoid) {
26092
+ code += ` ${fnCall};
26093
+ `;
26094
+ } else {
26095
+ code += ` const result = ${fnCall};
26010
26096
  `;
26011
- code += ` expect(result).to.not.be.undefined;
26097
+ code += ` ${chaiAssertion}
26012
26098
  `;
26099
+ }
26013
26100
  code += ` });
26014
26101
  `;
26102
+ const bodyText = fn.body || "";
26103
+ const hasExplicitThrow = /\bthrow\b/.test(bodyText) || /\bvalidat/i.test(bodyText);
26015
26104
  for (const param of fn.parameters) {
26016
26105
  if (!param.optional) {
26017
26106
  const paramsWithUndefined = fn.parameters.map((p74) => p74.name === param.name ? "undefined" : this.generateTestValue(p74)).join(", ");
26018
- code += `
26107
+ if (hasExplicitThrow) {
26108
+ code += `
26019
26109
  it('should handle undefined ${param.name}', function() {
26020
26110
  `;
26021
- code += ` expect(function() { ${fn.name}(${paramsWithUndefined}); }).to.throw();
26111
+ code += ` expect(function() { ${fn.name}(${paramsWithUndefined}); }).to.throw();
26022
26112
  `;
26023
- code += ` });
26113
+ code += ` });
26114
+ `;
26115
+ } else {
26116
+ code += `
26117
+ it('should handle undefined ${param.name}', function() {
26118
+ `;
26119
+ code += ` try {
26120
+ `;
26121
+ code += ` ${fn.name}(${paramsWithUndefined});
26122
+ `;
26123
+ code += ` } catch (e) {
26124
+ `;
26125
+ code += ` expect(e).to.be.instanceOf(Error);
26024
26126
  `;
26127
+ code += ` }
26128
+ `;
26129
+ code += ` });
26130
+ `;
26131
+ }
26025
26132
  }
26026
26133
  }
26027
26134
  code += ` });
@@ -26053,15 +26160,35 @@ ${stubSetup}`;
26053
26160
  code += ` });
26054
26161
  `;
26055
26162
  for (const method of cls.methods) {
26056
- if (!method.name.startsWith("_")) {
26163
+ if (!method.name.startsWith("_") && !method.name.startsWith("#")) {
26057
26164
  const methodParams = method.parameters.map((p74) => this.generateTestValue(p74)).join(", ");
26165
+ const isMethodVoid = method.returnType === "void" || method.returnType === "Promise<void>";
26166
+ let methodAssertion = "expect(result).to.not.be.undefined;";
26167
+ if (!isMethodVoid) {
26168
+ if (/^(is|has|can)[A-Z]/.test(method.name)) {
26169
+ methodAssertion = "expect(typeof result).to.equal('boolean');";
26170
+ } else if (/^(create|build|make)[A-Z]/.test(method.name)) {
26171
+ methodAssertion = "expect(result).to.be.ok;";
26172
+ } else if (method.returnType) {
26173
+ const mrt = method.returnType.toLowerCase().replace(/promise<(.+)>/, "$1");
26174
+ if (mrt.includes("boolean")) methodAssertion = "expect(typeof result).to.equal('boolean');";
26175
+ else if (mrt.includes("number")) methodAssertion = "expect(typeof result).to.equal('number');";
26176
+ else if (mrt.includes("string")) methodAssertion = "expect(typeof result).to.equal('string');";
26177
+ else if (mrt.includes("[]") || mrt.includes("array")) methodAssertion = "expect(result).to.be.an('array');";
26178
+ }
26179
+ }
26058
26180
  code += `
26059
26181
  it('${method.name} should work', ${method.isAsync ? "async " : ""}function() {
26060
26182
  `;
26061
- code += ` const result = ${method.isAsync ? "await " : ""}instance.${method.name}(${methodParams});
26183
+ if (isMethodVoid) {
26184
+ code += ` ${method.isAsync ? "await " : ""}instance.${method.name}(${methodParams});
26062
26185
  `;
26063
- code += ` expect(result).to.not.be.undefined;
26186
+ } else {
26187
+ code += ` const result = ${method.isAsync ? "await " : ""}instance.${method.name}(${methodParams});
26188
+ `;
26189
+ code += ` ${methodAssertion}
26064
26190
  `;
26191
+ }
26065
26192
  code += ` });
26066
26193
  `;
26067
26194
  }
@@ -26084,10 +26211,11 @@ ${stubSetup}`;
26084
26211
  let sinonImport = "";
26085
26212
  let stubSetup = "";
26086
26213
  let stubTeardown = "";
26087
- if (dependencies && dependencies.imports.length > 0) {
26214
+ const stubExternalDeps = dependencies?.imports.filter((dep) => !dep.startsWith(".")) || [];
26215
+ if (stubExternalDeps.length > 0) {
26088
26216
  sinonImport = `import sinon from 'sinon';
26089
26217
  `;
26090
- const depsToMock = dependencies.imports.slice(0, 5);
26218
+ const depsToMock = stubExternalDeps.slice(0, 5);
26091
26219
  stubSetup += `
26092
26220
  // Auto-generated stubs from Knowledge Graph dependency analysis
26093
26221
  `;
@@ -26258,12 +26386,13 @@ var PytestGenerator = class extends BaseTestGenerator {
26258
26386
  const exports = this.extractExports(analysis.functions, analysis.classes);
26259
26387
  const pythonImport = importPath.replace(/\//g, ".").replace(/\.(ts|js)$/, "");
26260
26388
  const importStatement = exports.length > 0 ? `from ${pythonImport} import ${exports.join(", ")}` : `import ${pythonImport} as ${moduleName}`;
26389
+ const externalDeps = dependencies?.imports.filter((dep) => !dep.startsWith(".")) || [];
26261
26390
  let mockImport = "";
26262
- if (dependencies && dependencies.imports.length > 0) {
26391
+ if (externalDeps.length > 0) {
26263
26392
  mockImport = `from unittest.mock import patch, MagicMock
26264
26393
  `;
26265
26394
  }
26266
- const depsToMock = dependencies?.imports.slice(0, 5) || [];
26395
+ const depsToMock = externalDeps.slice(0, 5);
26267
26396
  const patchDecorators = depsToMock.map((dep) => {
26268
26397
  const depModule = dep.replace(/\//g, ".").replace(/\.py$/, "");
26269
26398
  return `@patch('${depModule}')`;
@@ -26276,10 +26405,12 @@ class Test${this.pascalCase(moduleName)}:
26276
26405
  """${testType} tests for ${moduleName}"""
26277
26406
 
26278
26407
  `;
26279
- for (const fn of analysis.functions) {
26408
+ const exportedFns = analysis.functions.filter((fn) => fn.isExported);
26409
+ const exportedClasses = analysis.classes.filter((cls) => cls.isExported);
26410
+ for (const fn of exportedFns) {
26280
26411
  code += this.generateFunctionTestsWithPatches(fn, testType, patchDecorators);
26281
26412
  }
26282
- for (const cls of analysis.classes) {
26413
+ for (const cls of exportedClasses) {
26283
26414
  code += this.generateClassTests(cls, testType);
26284
26415
  }
26285
26416
  return code;
@@ -26299,15 +26430,36 @@ class Test${this.pascalCase(moduleName)}:
26299
26430
  const allParams = mockParams ? `self, ${mockParams}` : "self";
26300
26431
  const patchPrefix = patchDecorators.map((d74) => ` ${d74}
26301
26432
  `).join("");
26433
+ const isVoid = fn.returnType === "void" || fn.returnType === "Promise<void>" || fn.returnType === "None";
26302
26434
  let code = `${patchPrefix} def test_${fn.name}_valid_input(${allParams}):
26303
26435
  `;
26304
26436
  code += ` """Test ${fn.name} with valid input"""
26305
26437
  `;
26306
- code += ` result = ${fn.name}(${validParams})
26438
+ let pyAssertion = "assert result is not None";
26439
+ if (!isVoid) {
26440
+ if (/^(is|has|can)[A-Z]/.test(fn.name)) {
26441
+ pyAssertion = "assert isinstance(result, bool)";
26442
+ } else if (/^(create|build|make)[A-Z]/.test(fn.name)) {
26443
+ pyAssertion = "assert result";
26444
+ } else if (fn.returnType) {
26445
+ const rt3 = fn.returnType.toLowerCase().replace(/promise<(.+)>/, "$1");
26446
+ if (rt3.includes("boolean") || rt3.includes("bool")) pyAssertion = "assert isinstance(result, bool)";
26447
+ else if (rt3.includes("number") || rt3.includes("int") || rt3.includes("float")) pyAssertion = "assert isinstance(result, (int, float))";
26448
+ else if (rt3.includes("string") || rt3.includes("str")) pyAssertion = "assert isinstance(result, str)";
26449
+ else if (rt3.includes("[]") || rt3.includes("array") || rt3.includes("list")) pyAssertion = "assert isinstance(result, list)";
26450
+ }
26451
+ }
26452
+ if (isVoid) {
26453
+ code += ` ${fn.name}(${validParams}) # void function
26454
+
26455
+ `;
26456
+ } else {
26457
+ code += ` result = ${fn.name}(${validParams})
26307
26458
  `;
26308
- code += ` assert result is not None
26459
+ code += ` ${pyAssertion}
26309
26460
 
26310
26461
  `;
26462
+ }
26311
26463
  for (const param of fn.parameters) {
26312
26464
  if (!param.optional && param.type?.includes("str")) {
26313
26465
  code += `${patchPrefix} def test_${fn.name}_empty_${param.name}(${allParams}):
@@ -26348,15 +26500,36 @@ class Test${cls.name}:
26348
26500
 
26349
26501
  `;
26350
26502
  for (const method of cls.methods) {
26351
- if (!method.name.startsWith("_")) {
26503
+ if (!method.name.startsWith("_") && !method.name.startsWith("#")) {
26352
26504
  const methodParams = method.parameters.map((p74) => this.generatePythonTestValue(p74)).join(", ");
26505
+ const isMethodVoid = method.returnType === "void" || method.returnType === "Promise<void>";
26506
+ let mAssertion = "assert result is not None";
26507
+ if (!isMethodVoid) {
26508
+ if (/^(is|has|can)[A-Z]/.test(method.name)) {
26509
+ mAssertion = "assert isinstance(result, bool)";
26510
+ } else if (/^(create|build|make)[A-Z]/.test(method.name)) {
26511
+ mAssertion = "assert result";
26512
+ } else if (method.returnType) {
26513
+ const mrt = method.returnType.toLowerCase().replace(/promise<(.+)>/, "$1");
26514
+ if (mrt.includes("boolean") || mrt.includes("bool")) mAssertion = "assert isinstance(result, bool)";
26515
+ else if (mrt.includes("number") || mrt.includes("int") || mrt.includes("float")) mAssertion = "assert isinstance(result, (int, float))";
26516
+ else if (mrt.includes("string") || mrt.includes("str")) mAssertion = "assert isinstance(result, str)";
26517
+ else if (mrt.includes("[]") || mrt.includes("array") || mrt.includes("list")) mAssertion = "assert isinstance(result, list)";
26518
+ }
26519
+ }
26353
26520
  code += ` def test_${method.name}(self, instance):
26354
26521
  `;
26355
- code += ` result = instance.${method.name}(${methodParams})
26522
+ if (isMethodVoid) {
26523
+ code += ` instance.${method.name}(${methodParams})
26524
+
26356
26525
  `;
26357
- code += ` assert result is not None
26526
+ } else {
26527
+ code += ` result = instance.${method.name}(${methodParams})
26528
+ `;
26529
+ code += ` ${mAssertion}
26358
26530
 
26359
26531
  `;
26532
+ }
26360
26533
  }
26361
26534
  }
26362
26535
  return code;
@@ -26374,11 +26547,11 @@ class Test${cls.name}:
26374
26547
  const asyncDef = isAsync ? "async def" : "def";
26375
26548
  let mockImports = "";
26376
26549
  let mockPatches = "";
26377
- if (dependencies && dependencies.imports.length > 0) {
26550
+ const stubExternalDeps = dependencies?.imports.filter((dep) => !dep.startsWith(".")) || [];
26551
+ if (stubExternalDeps.length > 0) {
26378
26552
  mockImports = `from unittest.mock import patch, MagicMock
26379
26553
  `;
26380
- const depsToMock = dependencies.imports.slice(0, 5);
26381
- for (const dep of depsToMock) {
26554
+ for (const dep of stubExternalDeps.slice(0, 5)) {
26382
26555
  const depModule = dep.replace(/\//g, ".").replace(/\.py$/, "");
26383
26556
  mockPatches += ` @patch('${depModule}')
26384
26557
  `;
@@ -26541,12 +26714,214 @@ class Test${this.pascalCase(moduleName)}Coverage:
26541
26714
  }
26542
26715
  };
26543
26716
 
26717
+ // src/domains/test-generation/generators/node-test-generator.ts
26718
+ var NodeTestGenerator = class extends BaseTestGenerator {
26719
+ framework = "node-test";
26720
+ /**
26721
+ * Generate complete test file from analysis
26722
+ */
26723
+ generateTests(context2) {
26724
+ const { moduleName, importPath, testType, patterns, analysis } = context2;
26725
+ if (!analysis || analysis.functions.length === 0 && analysis.classes.length === 0) {
26726
+ return this.generateStubTests(context2);
26727
+ }
26728
+ const patternComment = this.generatePatternComment(patterns);
26729
+ const exportedFunctions = analysis.functions.filter((fn) => fn.isExported);
26730
+ const exportedClasses = analysis.classes.filter((cls) => cls.isExported);
26731
+ const exports = this.extractExports(exportedFunctions, exportedClasses);
26732
+ const importStatement = this.generateImportStatement(exports, importPath, moduleName);
26733
+ let testCode = `${patternComment}import { describe, it, beforeEach } from 'node:test';
26734
+ import assert from 'node:assert';
26735
+ ${importStatement}
26736
+
26737
+ `;
26738
+ for (const fn of exportedFunctions) {
26739
+ testCode += this.generateFunctionTests(fn, testType);
26740
+ }
26741
+ for (const cls of exportedClasses) {
26742
+ testCode += this.generateClassTests(cls, testType);
26743
+ }
26744
+ return testCode;
26745
+ }
26746
+ /**
26747
+ * Generate tests for a standalone function
26748
+ */
26749
+ generateFunctionTests(fn, _testType) {
26750
+ const testCases = this.generateTestCasesForFunction(fn);
26751
+ let code = `describe('${fn.name}', () => {
26752
+ `;
26753
+ for (const testCase of testCases) {
26754
+ if (testCase.setup) {
26755
+ code += ` ${testCase.setup}
26756
+
26757
+ `;
26758
+ }
26759
+ const asyncPrefix = fn.isAsync ? "async " : "";
26760
+ code += ` it('${testCase.description}', ${asyncPrefix}() => {
26761
+ `;
26762
+ code += ` ${this.convertToAssert(testCase.action)}
26763
+ `;
26764
+ code += ` ${this.convertToAssert(testCase.assertion)}
26765
+ `;
26766
+ code += ` });
26767
+
26768
+ `;
26769
+ }
26770
+ code += `});
26771
+
26772
+ `;
26773
+ return code;
26774
+ }
26775
+ /**
26776
+ * Generate tests for a class
26777
+ */
26778
+ generateClassTests(cls, testType) {
26779
+ let code = `describe('${cls.name}', () => {
26780
+ `;
26781
+ code += ` let instance;
26782
+
26783
+ `;
26784
+ const constructorArgs = cls.constructorParams?.map((p74) => this.generateTestValue(p74)).join(", ") || "";
26785
+ code += ` beforeEach(() => {
26786
+ `;
26787
+ code += ` instance = new ${cls.name}(${constructorArgs});
26788
+ `;
26789
+ code += ` });
26790
+
26791
+ `;
26792
+ code += ` it('should instantiate correctly', () => {
26793
+ `;
26794
+ code += ` assert.ok(instance instanceof ${cls.name});
26795
+ `;
26796
+ code += ` });
26797
+
26798
+ `;
26799
+ for (const method of cls.methods) {
26800
+ if (!method.name.startsWith("_") && !method.name.startsWith("#")) {
26801
+ code += this.generateMethodTest(method);
26802
+ }
26803
+ }
26804
+ code += `});
26805
+
26806
+ `;
26807
+ return code;
26808
+ }
26809
+ /**
26810
+ * Generate test for a class method
26811
+ */
26812
+ generateMethodTest(method) {
26813
+ const validParams = method.parameters.map((p74) => this.generateTestValue(p74)).join(", ");
26814
+ const isVoid = method.returnType === "void" || method.returnType === "Promise<void>";
26815
+ const asyncPrefix = method.isAsync ? "async " : "";
26816
+ const methodCall = method.isAsync ? `await instance.${method.name}(${validParams})` : `instance.${method.name}(${validParams})`;
26817
+ let assertLine = "assert.ok(result !== undefined);";
26818
+ if (!isVoid) {
26819
+ const mLower = method.name.toLowerCase();
26820
+ if (/^(is|has|can)[A-Z]/.test(method.name)) {
26821
+ assertLine = "assert.strictEqual(typeof result, 'boolean');";
26822
+ } else if (/^(get|fetch|find)[A-Z]/.test(method.name)) {
26823
+ assertLine = "assert.ok(result !== undefined);";
26824
+ } else if (/^(create|build|make)[A-Z]/.test(method.name)) {
26825
+ assertLine = "assert.ok(result);";
26826
+ } else if (method.returnType) {
26827
+ const rt3 = method.returnType.toLowerCase().replace(/promise<(.+)>/, "$1");
26828
+ if (rt3.includes("boolean")) assertLine = "assert.strictEqual(typeof result, 'boolean');";
26829
+ else if (rt3.includes("number")) assertLine = "assert.strictEqual(typeof result, 'number');";
26830
+ else if (rt3.includes("string")) assertLine = "assert.strictEqual(typeof result, 'string');";
26831
+ else if (rt3.includes("[]") || rt3.includes("array")) assertLine = "assert.ok(Array.isArray(result));";
26832
+ }
26833
+ }
26834
+ let code = ` it('${method.name} should execute successfully', ${asyncPrefix}() => {
26835
+ `;
26836
+ if (isVoid) {
26837
+ code += ` ${methodCall};
26838
+ `;
26839
+ } else {
26840
+ code += ` const result = ${methodCall};
26841
+ `;
26842
+ code += ` ${assertLine}
26843
+ `;
26844
+ }
26845
+ code += ` });
26846
+
26847
+ `;
26848
+ return code;
26849
+ }
26850
+ /**
26851
+ * Generate stub tests when no AST analysis is available
26852
+ */
26853
+ generateStubTests(context2) {
26854
+ const { moduleName, importPath, testType, patterns } = context2;
26855
+ const patternComment = this.generatePatternComment(patterns);
26856
+ return `${patternComment}import { describe, it } from 'node:test';
26857
+ import assert from 'node:assert';
26858
+ import { ${moduleName} } from '${importPath}';
26859
+
26860
+ describe('${moduleName}', () => {
26861
+ describe('${testType} tests', () => {
26862
+ it('should be defined', () => {
26863
+ assert.ok(${moduleName} !== undefined);
26864
+ });
26865
+
26866
+ it('should handle basic operations', () => {
26867
+ const moduleType = typeof ${moduleName};
26868
+ assert.ok(['function', 'object'].includes(moduleType));
26869
+ });
26870
+
26871
+ it('should handle error conditions', () => {
26872
+ assert.doesNotThrow(() => {
26873
+ const instance = typeof ${moduleName} === 'function'
26874
+ ? new ${moduleName}()
26875
+ : ${moduleName};
26876
+ return instance;
26877
+ });
26878
+ });
26879
+ });
26880
+ });
26881
+ `;
26882
+ }
26883
+ /**
26884
+ * Generate coverage-focused tests for specific lines
26885
+ */
26886
+ generateCoverageTests(moduleName, importPath, lines) {
26887
+ const funcName = this.camelCase(moduleName);
26888
+ const lineRange = this.formatLineRange(lines);
26889
+ return `// Coverage test for ${lineRange} in ${moduleName}
26890
+ import { describe, it } from 'node:test';
26891
+ import assert from 'node:assert';
26892
+ import { ${funcName} } from '${importPath}';
26893
+
26894
+ describe('${moduleName} coverage', () => {
26895
+ it('should exercise code path covering ${lineRange}', () => {
26896
+ const testInput = undefined; // Replace with appropriate input
26897
+ const result = ${funcName}(testInput);
26898
+ assert.ok(result !== undefined || result === undefined);
26899
+ });
26900
+
26901
+ it('should handle edge case for ${lineRange}', () => {
26902
+ assert.doesNotThrow(() => ${funcName}(null));
26903
+ });
26904
+ });
26905
+ `;
26906
+ }
26907
+ // ============================================================================
26908
+ // Helpers
26909
+ // ============================================================================
26910
+ /**
26911
+ * Convert expect() style assertions to node:assert
26912
+ */
26913
+ convertToAssert(assertion) {
26914
+ 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);");
26915
+ }
26916
+ };
26917
+
26544
26918
  // src/domains/test-generation/factories/test-generator-factory.ts
26545
26919
  var SUPPORTED_FRAMEWORKS = [
26546
26920
  "jest",
26547
26921
  "vitest",
26548
26922
  "mocha",
26549
- "pytest"
26923
+ "pytest",
26924
+ "node-test"
26550
26925
  ];
26551
26926
  var DEFAULT_FRAMEWORK = "vitest";
26552
26927
  var TestGeneratorFactory = class {
@@ -26608,6 +26983,8 @@ var TestGeneratorFactory = class {
26608
26983
  return new MochaGenerator();
26609
26984
  case "pytest":
26610
26985
  return new PytestGenerator();
26986
+ case "node-test":
26987
+ return new NodeTestGenerator();
26611
26988
  default:
26612
26989
  throw new Error(`Unsupported test framework: ${framework}`);
26613
26990
  }
@@ -27955,12 +28332,32 @@ ${sourceCode}
27955
28332
  };
27956
28333
  }
27957
28334
  extractParameters(params, sourceFile) {
27958
- return params.map((param) => ({
27959
- name: param.name.getText(sourceFile),
27960
- type: param.type?.getText(sourceFile),
27961
- optional: param.questionToken !== void 0,
27962
- defaultValue: param.initializer?.getText(sourceFile)
27963
- }));
28335
+ let objectDestructureCount = 0;
28336
+ let arrayDestructureCount = 0;
28337
+ return params.map((param) => {
28338
+ let name = param.name.getText(sourceFile);
28339
+ let type = param.type?.getText(sourceFile);
28340
+ if (ts.isObjectBindingPattern(param.name)) {
28341
+ objectDestructureCount++;
28342
+ name = objectDestructureCount > 1 ? `options${objectDestructureCount}` : "options";
28343
+ if (!type) {
28344
+ const props = param.name.elements.map((el) => `${el.name.getText(sourceFile)}: unknown`).join(", ");
28345
+ type = `{ ${props} }`;
28346
+ }
28347
+ } else if (ts.isArrayBindingPattern(param.name)) {
28348
+ arrayDestructureCount++;
28349
+ name = arrayDestructureCount > 1 ? `items${arrayDestructureCount}` : "items";
28350
+ if (!type) {
28351
+ type = "unknown[]";
28352
+ }
28353
+ }
28354
+ return {
28355
+ name,
28356
+ type,
28357
+ optional: param.questionToken !== void 0,
28358
+ defaultValue: param.initializer?.getText(sourceFile)
28359
+ };
28360
+ });
27964
28361
  }
27965
28362
  calculateComplexity(node) {
27966
28363
  let complexity = 1;
@@ -28019,12 +28416,18 @@ ${sourceCode}
28019
28416
  const callees = [];
28020
28417
  const callers = [];
28021
28418
  const tsImports = sourceContent.matchAll(/(?:import|from)\s+['"]([^'"]+)['"]/g);
28022
- const pyImports = sourceContent.matchAll(/(?:^|\n)\s*(?:from\s+(\S+)\s+import|import\s+(\S+))/g);
28023
28419
  for (const match of tsImports) {
28024
28420
  imports.push(match[1]);
28025
28421
  }
28026
- for (const match of pyImports) {
28027
- imports.push(match[1] || match[2]);
28422
+ const isPython = filePath.endsWith(".py");
28423
+ if (isPython) {
28424
+ const pyImports = sourceContent.matchAll(/(?:^|\n)\s*(?:from\s+(\S+)\s+import|import\s+(\S+))/g);
28425
+ for (const match of pyImports) {
28426
+ const mod = match[1] || match[2];
28427
+ if (mod && /^[a-zA-Z_][\w.]*$/.test(mod)) {
28428
+ imports.push(mod);
28429
+ }
28430
+ }
28028
28431
  }
28029
28432
  const normalizedPath = filePath.replace(/\\/g, "/");
28030
28433
  const baseName = normalizedPath.split("/").pop()?.replace(/\.(ts|js|tsx|jsx|py)$/, "") || "";
@@ -28486,7 +28889,7 @@ var PatternMatcherService = class _PatternMatcherService {
28486
28889
  return template.replace("{{name}}", param.name);
28487
28890
  }
28488
28891
  }
28489
- return `mock${param.name.charAt(0).toUpperCase() + param.name.slice(1)}`;
28892
+ return `{} /* TODO: provide ${param.name}: ${param.type || "unknown"} */`;
28490
28893
  }
28491
28894
  /**
28492
28895
  * Estimate number of branches from cyclomatic complexity
@@ -29402,12 +29805,32 @@ var TypeScriptASTParser = class {
29402
29805
  * Extract parameter information
29403
29806
  */
29404
29807
  extractParameters(params, sourceFile) {
29405
- return params.map((param) => ({
29406
- name: param.name.getText(sourceFile),
29407
- type: param.type?.getText(sourceFile),
29408
- optional: param.questionToken !== void 0,
29409
- defaultValue: param.initializer?.getText(sourceFile)
29410
- }));
29808
+ let objectDestructureCount = 0;
29809
+ let arrayDestructureCount = 0;
29810
+ return params.map((param) => {
29811
+ let name = param.name.getText(sourceFile);
29812
+ let type = param.type?.getText(sourceFile);
29813
+ if (ts2.isObjectBindingPattern(param.name)) {
29814
+ objectDestructureCount++;
29815
+ name = objectDestructureCount > 1 ? `options${objectDestructureCount}` : "options";
29816
+ if (!type) {
29817
+ const props = param.name.elements.map((el) => `${el.name.getText(sourceFile)}: unknown`).join(", ");
29818
+ type = `{ ${props} }`;
29819
+ }
29820
+ } else if (ts2.isArrayBindingPattern(param.name)) {
29821
+ arrayDestructureCount++;
29822
+ name = arrayDestructureCount > 1 ? `items${arrayDestructureCount}` : "items";
29823
+ if (!type) {
29824
+ type = "unknown[]";
29825
+ }
29826
+ }
29827
+ return {
29828
+ name,
29829
+ type,
29830
+ optional: param.questionToken !== void 0,
29831
+ defaultValue: param.initializer?.getText(sourceFile)
29832
+ };
29833
+ });
29411
29834
  }
29412
29835
  /**
29413
29836
  * Calculate cyclomatic complexity of a node
@@ -114551,7 +114974,7 @@ function parsePipelineContent(content, sourcePath) {
114551
114974
  if (errors.length > 0) {
114552
114975
  return { success: false, errors };
114553
114976
  }
114554
- const pipeline11 = {
114977
+ const pipeline10 = {
114555
114978
  name: parsed.name,
114556
114979
  description: parsed.description,
114557
114980
  version: parsed.version || "1.0.0",
@@ -114573,26 +114996,26 @@ function parsePipelineContent(content, sourcePath) {
114573
114996
  tags: parsed.tags,
114574
114997
  timeout: parsed.timeout
114575
114998
  };
114576
- for (let i58 = 0; i58 < pipeline11.stages.length; i58++) {
114577
- const stage = pipeline11.stages[i58];
114999
+ for (let i58 = 0; i58 < pipeline10.stages.length; i58++) {
115000
+ const stage = pipeline10.stages[i58];
114578
115001
  if (!stage.command) {
114579
115002
  errors.push(`Stage ${i58 + 1} (${stage.name}) must have a "command" field`);
114580
115003
  }
114581
115004
  }
114582
115005
  if (errors.length > 0) {
114583
- return { success: false, pipeline: pipeline11, errors };
115006
+ return { success: false, pipeline: pipeline10, errors };
114584
115007
  }
114585
- const workflow = convertToWorkflowDefinition(pipeline11, sourcePath);
115008
+ const workflow = convertToWorkflowDefinition(pipeline10, sourcePath);
114586
115009
  return {
114587
115010
  success: true,
114588
- pipeline: pipeline11,
115011
+ pipeline: pipeline10,
114589
115012
  workflow,
114590
115013
  errors: []
114591
115014
  };
114592
115015
  }
114593
- function convertToWorkflowDefinition(pipeline11, sourcePath) {
114594
- const workflowId = `pipeline-${pipeline11.name.replace(/\s+/g, "-").toLowerCase()}`;
114595
- const steps = pipeline11.stages.map((stage, index) => {
115016
+ function convertToWorkflowDefinition(pipeline10, sourcePath) {
115017
+ const workflowId = `pipeline-${pipeline10.name.replace(/\s+/g, "-").toLowerCase()}`;
115018
+ const steps = pipeline10.stages.map((stage, index) => {
114596
115019
  const domainAction = mapCommandToDomainAction(stage.command);
114597
115020
  const inputMapping = {};
114598
115021
  if (stage.params) {
@@ -114626,7 +115049,7 @@ function convertToWorkflowDefinition(pipeline11, sourcePath) {
114626
115049
  }
114627
115050
  return step;
114628
115051
  });
114629
- const triggers = pipeline11.triggers?.map((trigger) => {
115052
+ const triggers = pipeline10.triggers?.map((trigger) => {
114630
115053
  const workflowTrigger = {
114631
115054
  eventType: mapTriggerEventType(trigger),
114632
115055
  sourceDomain: trigger.source_domain
@@ -114642,13 +115065,13 @@ function convertToWorkflowDefinition(pipeline11, sourcePath) {
114642
115065
  });
114643
115066
  return {
114644
115067
  id: workflowId,
114645
- name: pipeline11.name,
114646
- description: pipeline11.description || `Pipeline from ${sourcePath || "inline YAML"}`,
114647
- version: pipeline11.version || "1.0.0",
115068
+ name: pipeline10.name,
115069
+ description: pipeline10.description || `Pipeline from ${sourcePath || "inline YAML"}`,
115070
+ version: pipeline10.version || "1.0.0",
114648
115071
  steps,
114649
115072
  triggers,
114650
- tags: pipeline11.tags,
114651
- timeout: pipeline11.timeout ? pipeline11.timeout * 1e3 : void 0
115073
+ tags: pipeline10.tags,
115074
+ timeout: pipeline10.timeout ? pipeline10.timeout * 1e3 : void 0
114652
115075
  };
114653
115076
  }
114654
115077
  function mapCommandToDomainAction(command) {
@@ -114697,17 +115120,17 @@ function mapTriggerEventType(trigger) {
114697
115120
  }
114698
115121
  return event;
114699
115122
  }
114700
- function validatePipeline(pipeline11) {
115123
+ function validatePipeline(pipeline10) {
114701
115124
  const errors = [];
114702
115125
  const warnings = [];
114703
- if (!pipeline11.name) {
115126
+ if (!pipeline10.name) {
114704
115127
  errors.push({
114705
115128
  path: "name",
114706
115129
  message: "Pipeline name is required",
114707
115130
  severity: "error"
114708
115131
  });
114709
115132
  }
114710
- if (!pipeline11.stages || pipeline11.stages.length === 0) {
115133
+ if (!pipeline10.stages || pipeline10.stages.length === 0) {
114711
115134
  errors.push({
114712
115135
  path: "stages",
114713
115136
  message: "Pipeline must have at least one stage",
@@ -114715,8 +115138,8 @@ function validatePipeline(pipeline11) {
114715
115138
  });
114716
115139
  } else {
114717
115140
  const stageNames = /* @__PURE__ */ new Set();
114718
- for (let i58 = 0; i58 < pipeline11.stages.length; i58++) {
114719
- const stage = pipeline11.stages[i58];
115141
+ for (let i58 = 0; i58 < pipeline10.stages.length; i58++) {
115142
+ const stage = pipeline10.stages[i58];
114720
115143
  const stagePath = `stages[${i58}]`;
114721
115144
  if (stageNames.has(stage.name)) {
114722
115145
  errors.push({
@@ -114744,7 +115167,7 @@ function validatePipeline(pipeline11) {
114744
115167
  }
114745
115168
  if (stage.depends_on) {
114746
115169
  for (const dep of stage.depends_on) {
114747
- if (!pipeline11.stages.some((s70) => s70.name === dep)) {
115170
+ if (!pipeline10.stages.some((s70) => s70.name === dep)) {
114748
115171
  errors.push({
114749
115172
  path: `${stagePath}.depends_on`,
114750
115173
  message: `Unknown dependency: ${dep}`,
@@ -114770,7 +115193,7 @@ function validatePipeline(pipeline11) {
114770
115193
  }
114771
115194
  }
114772
115195
  }
114773
- const circular = detectCircularDependencies(pipeline11.stages);
115196
+ const circular = detectCircularDependencies(pipeline10.stages);
114774
115197
  if (circular) {
114775
115198
  errors.push({
114776
115199
  path: "stages",
@@ -114779,18 +115202,18 @@ function validatePipeline(pipeline11) {
114779
115202
  });
114780
115203
  }
114781
115204
  }
114782
- if (pipeline11.schedule) {
114783
- if (!isValidCronExpression(pipeline11.schedule)) {
115205
+ if (pipeline10.schedule) {
115206
+ if (!isValidCronExpression(pipeline10.schedule)) {
114784
115207
  errors.push({
114785
115208
  path: "schedule",
114786
- message: `Invalid cron expression: ${pipeline11.schedule}`,
115209
+ message: `Invalid cron expression: ${pipeline10.schedule}`,
114787
115210
  severity: "error"
114788
115211
  });
114789
115212
  }
114790
115213
  }
114791
- if (pipeline11.triggers) {
114792
- for (let i58 = 0; i58 < pipeline11.triggers.length; i58++) {
114793
- const trigger = pipeline11.triggers[i58];
115214
+ if (pipeline10.triggers) {
115215
+ for (let i58 = 0; i58 < pipeline10.triggers.length; i58++) {
115216
+ const trigger = pipeline10.triggers[i58];
114794
115217
  const triggerPath = `triggers[${i58}]`;
114795
115218
  if (!trigger.event) {
114796
115219
  errors.push({
@@ -115449,7 +115872,7 @@ var ALL_DOMAINS2 = [
115449
115872
  "enterprise-integration"
115450
115873
  ];
115451
115874
  function getAQEVersion() {
115452
- return true ? "3.6.14" : "3.0.0";
115875
+ return true ? "3.6.16" : "3.0.0";
115453
115876
  }
115454
115877
  function createDefaultConfig(projectName, projectRoot) {
115455
115878
  return {
@@ -123549,11 +123972,11 @@ function createTestCommand(context2, cleanupAndExit2, ensureInitialized2) {
123549
123972
  console.log(chalk9.gray(` Assertions: ${test.assertions}`));
123550
123973
  if (test.testCode) {
123551
123974
  console.log(chalk9.gray(` Test File: ${test.testFile}`));
123552
- console.log(`
123553
- --- Generated Code ---`);
123554
- console.log(test.testCode);
123555
- console.log(`--- End Generated Code ---
123556
- `);
123975
+ const fs23 = await import("fs");
123976
+ const testDir = path26.dirname(test.testFile);
123977
+ fs23.mkdirSync(testDir, { recursive: true });
123978
+ fs23.writeFileSync(test.testFile, test.testCode, "utf-8");
123979
+ console.log(chalk9.green(` Written to: ${test.testFile}`));
123557
123980
  }
123558
123981
  }
123559
123982
  if (generated.tests.length > 10) {
@@ -125641,7 +126064,7 @@ var TASK_TYPES = [
125641
126064
  ];
125642
126065
  var PRIORITIES = ["p0", "p1", "p2", "p3"];
125643
126066
  var STATUSES = ["pending", "running", "completed", "failed", "cancelled"];
125644
- var FRAMEWORKS = ["jest", "vitest", "pytest", "junit", "playwright", "cypress", "go-test"];
126067
+ var FRAMEWORKS = ["jest", "vitest", "pytest", "junit", "playwright", "cypress", "go-test", "node-test"];
125645
126068
  var TEST_TYPES = ["unit", "integration", "e2e"];
125646
126069
  var MEMORY_BACKENDS = ["sqlite", "agentdb", "hybrid"];
125647
126070
  function generateBashCompletion() {
@@ -132588,16 +133011,15 @@ import ora2 from "ora";
132588
133011
  var DEFAULT_SYNC_CONFIG = {
132589
133012
  local: {
132590
133013
  // PRIMARY: Root database (consolidated, MCP-active)
132591
- v3MemoryDb: "../.agentic-qe/memory.db",
132592
- // Now points to root (consolidated)
132593
- rootMemoryDb: "../.agentic-qe/memory.db",
132594
- // Same as above
132595
- claudeFlowMemory: "../.claude-flow/memory/store.json",
132596
- claudeFlowDaemon: "../.claude-flow/daemon-state.json",
132597
- claudeFlowMetrics: "../.claude-flow/metrics/",
132598
- intelligenceJson: "../v3/.ruvector/intelligence.json",
132599
- swarmMemoryDb: "../.swarm/memory.db",
132600
- v2PatternsDb: "../v2/data/ruvector-patterns.db"
133014
+ // Paths relative to process.cwd() which is the project root
133015
+ v3MemoryDb: "./.agentic-qe/memory.db",
133016
+ rootMemoryDb: "./.agentic-qe/memory.db",
133017
+ claudeFlowMemory: "./.claude-flow/memory/store.json",
133018
+ claudeFlowDaemon: "./.claude-flow/daemon-state.json",
133019
+ claudeFlowMetrics: "./.claude-flow/metrics/",
133020
+ intelligenceJson: "./v3/.ruvector/intelligence.json",
133021
+ swarmMemoryDb: "./.swarm/memory.db",
133022
+ v2PatternsDb: "./v2/data/ruvector-patterns.db"
132601
133023
  },
132602
133024
  cloud: {
132603
133025
  project: process.env.GCP_PROJECT || "",
@@ -132613,82 +133035,150 @@ var DEFAULT_SYNC_CONFIG = {
132613
133035
  batchSize: 1e3,
132614
133036
  conflictResolution: "newer-wins",
132615
133037
  sourcePriority: {
132616
- rootMemory: 1,
132617
- // Root is now PRIMARY (consolidated)
132618
- claudeFlowMemory: 2,
132619
- intelligenceJson: 3,
132620
- legacy: 4
133038
+ qePatterns: 1,
133039
+ // Primary QE learning data (12K+ records)
133040
+ sonaPatterns: 2,
133041
+ // Neural backbone patterns
133042
+ goapActions: 3,
133043
+ // Planning primitives
133044
+ kvStore: 4,
133045
+ // Key-value memory entries
133046
+ experiences: 5,
133047
+ // Captured RL experiences
133048
+ claudeFlowMemory: 6,
133049
+ intelligenceJson: 7
132621
133050
  },
132622
133051
  sources: [
132623
133052
  // ============================================================
132624
- // ROOT Memory - PRIMARY (Consolidated from V3 + Historical)
132625
- // All tables now in single database: .agentic-qe/memory.db
133053
+ // ROOT Memory - PRIMARY (Consolidated database)
133054
+ // All tables in single database: .agentic-qe/memory.db
133055
+ //
133056
+ // NOTE (2026-02-20): Post-consolidation table mapping:
133057
+ // OLD v2 tables (removed) → NEW v3 tables (actual)
133058
+ // memory_entries → kv_store
133059
+ // learning_experiences → captured_experiences
133060
+ // patterns → qe_patterns (absorbed)
133061
+ // events → (removed, use dream_cycles/routing_outcomes)
132626
133062
  // ============================================================
133063
+ // QE Patterns - PRIMARY learning data (12,150+ records)
133064
+ // Explicit columns to match cloud schema exactly
133065
+ {
133066
+ name: "root-qe-patterns",
133067
+ type: "sqlite",
133068
+ path: "./.agentic-qe/memory.db",
133069
+ targetTable: "aqe.qe_patterns",
133070
+ priority: "high",
133071
+ mode: "incremental",
133072
+ query: "SELECT id, pattern_type, qe_domain, domain, name, description, confidence, usage_count, success_rate, quality_score, tier, template_json, context_json, successful_uses, created_at, updated_at, last_used_at, tokens_used, input_tokens, output_tokens, latency_ms, reusable, reuse_count, average_token_savings, total_tokens_saved FROM qe_patterns",
133073
+ enabled: true
133074
+ },
133075
+ // SONA neural patterns (731+ records)
132627
133076
  {
132628
133077
  name: "root-sona-patterns",
132629
133078
  type: "sqlite",
132630
- path: "../.agentic-qe/memory.db",
133079
+ path: "./.agentic-qe/memory.db",
132631
133080
  targetTable: "aqe.sona_patterns",
132632
133081
  priority: "high",
132633
133082
  mode: "incremental",
132634
133083
  query: "SELECT * FROM sona_patterns",
132635
133084
  enabled: true
132636
133085
  },
133086
+ // GOAP actions (2,243+ records)
132637
133087
  {
132638
133088
  name: "root-goap-actions",
132639
133089
  type: "sqlite",
132640
- path: "../.agentic-qe/memory.db",
133090
+ path: "./.agentic-qe/memory.db",
132641
133091
  targetTable: "aqe.goap_actions",
132642
133092
  priority: "high",
132643
133093
  mode: "incremental",
132644
133094
  query: "SELECT * FROM goap_actions",
132645
133095
  enabled: true
132646
133096
  },
133097
+ // KV Store → cloud memory_entries (1,619+ records)
133098
+ // Only sync entries with valid JSON values (skip corrupt/HTML-embedded data)
132647
133099
  {
132648
- name: "root-memory-entries",
133100
+ name: "root-kv-store",
132649
133101
  type: "sqlite",
132650
- path: "../.agentic-qe/memory.db",
133102
+ path: "./.agentic-qe/memory.db",
132651
133103
  targetTable: "aqe.memory_entries",
132652
133104
  priority: "high",
132653
133105
  mode: "incremental",
132654
- query: "SELECT * FROM memory_entries",
133106
+ query: "SELECT key, namespace as partition, CASE WHEN json_valid(value) THEN value ELSE json_quote(value) END as value, created_at, expires_at FROM kv_store WHERE json_valid(value) OR json_valid(json_quote(value))",
132655
133107
  enabled: true
132656
133108
  },
133109
+ // Captured experiences → cloud learning_experiences (854+ records)
133110
+ // Cloud id is SERIAL (auto-increment) — omit local UUID id
132657
133111
  {
132658
- name: "root-learning-experiences",
133112
+ name: "root-captured-experiences",
132659
133113
  type: "sqlite",
132660
- path: "../.agentic-qe/memory.db",
133114
+ path: "./.agentic-qe/memory.db",
132661
133115
  targetTable: "aqe.learning_experiences",
132662
133116
  priority: "high",
132663
133117
  mode: "append",
132664
- query: "SELECT * FROM learning_experiences",
133118
+ query: "SELECT agent as agent_id, task as task_id, domain as task_type, COALESCE(result_json, '{}') as state, COALESCE(steps_json, '{}') as action, quality as reward, COALESCE(routing_json, '{}') as next_state, tags as episode_id, started_at as created_at FROM captured_experiences",
132665
133119
  enabled: true
132666
133120
  },
133121
+ // GOAP plans (91+ records)
132667
133122
  {
132668
- name: "root-patterns",
133123
+ name: "root-goap-plans",
132669
133124
  type: "sqlite",
132670
- path: "../.agentic-qe/memory.db",
132671
- targetTable: "aqe.patterns",
133125
+ path: "./.agentic-qe/memory.db",
133126
+ targetTable: "aqe.goap_plans",
132672
133127
  priority: "medium",
132673
133128
  mode: "incremental",
132674
- query: "SELECT * FROM patterns",
133129
+ query: "SELECT id, goal_id, action_sequence as sequence, initial_state, goal_state, action_sequence, total_cost, estimated_duration_ms as estimated_duration, status, created_at, completed_at FROM goap_plans",
132675
133130
  enabled: true
132676
133131
  },
133132
+ // RL Q-values (from SQLite, not JSON)
133133
+ // Use DISTINCT to avoid duplicate (state, action) pairs in same batch
132677
133134
  {
132678
- name: "root-events",
133135
+ name: "root-rl-q-values",
132679
133136
  type: "sqlite",
132680
- path: "../.agentic-qe/memory.db",
132681
- targetTable: "aqe.events",
133137
+ path: "./.agentic-qe/memory.db",
133138
+ targetTable: "aqe.qlearning_patterns",
133139
+ priority: "medium",
133140
+ mode: "incremental",
133141
+ query: "SELECT DISTINCT state_key as state, action_key as action, q_value, visits, updated_at as last_update, created_at FROM rl_q_values GROUP BY state_key, action_key",
133142
+ enabled: true
133143
+ },
133144
+ // Routing outcomes (184+ records) - model routing decisions
133145
+ {
133146
+ name: "root-routing-outcomes",
133147
+ type: "sqlite",
133148
+ path: "./.agentic-qe/memory.db",
133149
+ targetTable: "aqe.routing_outcomes",
133150
+ priority: "medium",
133151
+ mode: "append",
133152
+ query: "SELECT * FROM routing_outcomes",
133153
+ enabled: true
133154
+ },
133155
+ // QE trajectories (320+ records) - execution traces
133156
+ {
133157
+ name: "root-qe-trajectories",
133158
+ type: "sqlite",
133159
+ path: "./.agentic-qe/memory.db",
133160
+ targetTable: "aqe.qe_trajectories",
133161
+ priority: "medium",
133162
+ mode: "append",
133163
+ query: "SELECT * FROM qe_trajectories",
133164
+ enabled: true
133165
+ },
133166
+ // Dream insights (660+ records) - consolidation results
133167
+ {
133168
+ name: "root-dream-insights",
133169
+ type: "sqlite",
133170
+ path: "./.agentic-qe/memory.db",
133171
+ targetTable: "aqe.dream_insights",
132682
133172
  priority: "low",
132683
133173
  mode: "append",
132684
- query: "SELECT * FROM events",
133174
+ query: "SELECT * FROM dream_insights",
132685
133175
  enabled: true
132686
133176
  },
132687
133177
  // Claude-Flow Memory (JSON)
132688
133178
  {
132689
133179
  name: "claude-flow-memory",
132690
133180
  type: "json",
132691
- path: "../.claude-flow/memory/store.json",
133181
+ path: "./.claude-flow/memory/store.json",
132692
133182
  targetTable: "aqe.claude_flow_memory",
132693
133183
  priority: "medium",
132694
133184
  mode: "full",
@@ -132698,7 +133188,7 @@ var DEFAULT_SYNC_CONFIG = {
132698
133188
  {
132699
133189
  name: "intelligence-qlearning",
132700
133190
  type: "json",
132701
- path: "../v3/.ruvector/intelligence.json",
133191
+ path: "./v3/.ruvector/intelligence.json",
132702
133192
  targetTable: "aqe.qlearning_patterns",
132703
133193
  priority: "low",
132704
133194
  mode: "full",
@@ -133450,7 +133940,9 @@ function createConnectionManager(config) {
133450
133940
  init_sql_safety();
133451
133941
  init_error_utils();
133452
133942
  init_logging();
133943
+ import { createRequire as createRequire7 } from "module";
133453
133944
  var logger14 = LoggerFactory.create("postgres-writer");
133945
+ var requirePg = createRequire7(import.meta.url);
133454
133946
  var PostgresWriter = class {
133455
133947
  client = null;
133456
133948
  config;
@@ -133471,31 +133963,36 @@ var PostgresWriter = class {
133471
133963
  if (!connection) {
133472
133964
  throw new Error("No tunnel connection available");
133473
133965
  }
133966
+ let pg;
133474
133967
  try {
133475
- const pg = await Promise.resolve().then(() => (init_pg(), pg_exports));
133476
- const Client = pg.Client || pg.default?.Client;
133477
- if (Client) {
133478
- const connectionConfig = {
133479
- host: connection.host,
133480
- port: connection.port,
133481
- database: this.config.cloud.database,
133482
- user: this.config.cloud.user,
133483
- password: process.env.PGPASSWORD || "",
133484
- connectionTimeoutMillis: this.config.connectionTimeout || 1e4
133485
- };
133486
- this.client = new Client(connectionConfig);
133487
- await this.client.connect();
133488
- this.connected = true;
133489
- console.log(`[PostgresWriter] Connected to ${connection.host}:${connection.port}/${this.config.cloud.database}`);
133490
- } else {
133491
- throw new Error("pg Client not found");
133492
- }
133968
+ pg = requirePg("pg");
133493
133969
  } catch (e20) {
133494
- logger14.debug("pg module not available, using mock mode", { error: e20 instanceof Error ? e20.message : String(e20) });
133495
- console.warn("[PostgresWriter] pg module not available, running in mock mode");
133970
+ logger14.debug("pg module not installed, using mock mode", { error: e20 instanceof Error ? e20.message : String(e20) });
133971
+ console.warn("[PostgresWriter] pg module not installed, running in mock mode");
133496
133972
  this.client = this.createMockClient();
133497
133973
  this.connected = true;
133974
+ return;
133498
133975
  }
133976
+ const pgDefault = pg.default;
133977
+ const Client = pg.Client || pgDefault?.Client;
133978
+ if (!Client) {
133979
+ console.warn("[PostgresWriter] pg.Client not found in module, running in mock mode");
133980
+ this.client = this.createMockClient();
133981
+ this.connected = true;
133982
+ return;
133983
+ }
133984
+ const connectionConfig = {
133985
+ host: connection.host,
133986
+ port: connection.port,
133987
+ database: this.config.cloud.database,
133988
+ user: this.config.cloud.user,
133989
+ password: process.env.PGPASSWORD || "",
133990
+ connectionTimeoutMillis: this.config.connectionTimeout || 1e4
133991
+ };
133992
+ this.client = new Client(connectionConfig);
133993
+ await this.client.connect();
133994
+ this.connected = true;
133995
+ console.log(`[PostgresWriter] Connected to ${connection.host}:${connection.port}/${this.config.cloud.database}`);
133499
133996
  }
133500
133997
  /**
133501
133998
  * Begin a transaction
@@ -133545,8 +134042,28 @@ var PostgresWriter = class {
133545
134042
  const batchSize = 100;
133546
134043
  for (let i58 = 0; i58 < records.length; i58 += batchSize) {
133547
134044
  const batch = records.slice(i58, i58 + batchSize);
133548
- const inserted = await this.upsertBatch(table, batch, columns, conflictColumns, updateColumns, options?.skipIfExists);
133549
- totalInserted += inserted;
134045
+ try {
134046
+ const inserted = await this.upsertBatch(table, batch, columns, conflictColumns, updateColumns, options?.skipIfExists);
134047
+ totalInserted += inserted;
134048
+ } catch (error) {
134049
+ const batchNum = Math.floor(i58 / batchSize) + 1;
134050
+ const totalBatches = Math.ceil(records.length / batchSize);
134051
+ logger14.debug(`Batch ${batchNum}/${totalBatches} failed for ${table}, retrying individually`, { error: toErrorMessage(error) });
134052
+ let recovered = 0;
134053
+ for (const record of batch) {
134054
+ try {
134055
+ const inserted = await this.upsertBatch(table, [record], columns, conflictColumns, updateColumns, options?.skipIfExists);
134056
+ recovered += inserted;
134057
+ } catch (retryError) {
134058
+ const recordId = record["id"] || record["key"] || "?";
134059
+ logger14.debug(`Skipped record ${String(recordId).slice(0, 50)} in ${table}`, { error: toErrorMessage(retryError) });
134060
+ }
134061
+ }
134062
+ totalInserted += recovered;
134063
+ if (recovered < batch.length) {
134064
+ console.warn(`[PostgresWriter] Batch ${batchNum}/${totalBatches} for ${table}: ${recovered}/${batch.length} recovered (${batch.length - recovered} skipped)`);
134065
+ }
134066
+ }
133550
134067
  }
133551
134068
  return totalInserted;
133552
134069
  }
@@ -133589,7 +134106,7 @@ var PostgresWriter = class {
133589
134106
  const result = await this.client.query(sql, params);
133590
134107
  return result.rowCount || 0;
133591
134108
  } catch (error) {
133592
- console.error(`[PostgresWriter] Upsert failed: ${toErrorMessage(error)}`);
134109
+ logger14.debug(`Upsert failed for ${table}`, { error: toErrorMessage(error) });
133593
134110
  throw error;
133594
134111
  }
133595
134112
  }
@@ -133660,9 +134177,33 @@ var PostgresWriter = class {
133660
134177
  return JSON.stringify(value);
133661
134178
  }
133662
134179
  if (typeof value === "object") {
133663
- return JSON.stringify(value);
134180
+ let jsonStr = JSON.stringify(value);
134181
+ if (columnName && this.isJsonbColumn(columnName)) {
134182
+ jsonStr = jsonStr.replace(/\u0000/g, "");
134183
+ try {
134184
+ JSON.parse(jsonStr);
134185
+ } catch {
134186
+ return JSON.stringify(String(value));
134187
+ }
134188
+ }
134189
+ return jsonStr;
133664
134190
  }
133665
134191
  if (typeof value === "string") {
134192
+ if (value === "") {
134193
+ const timestampColumns = [
134194
+ "created_at",
134195
+ "updated_at",
134196
+ "last_used_at",
134197
+ "started_at",
134198
+ "ended_at",
134199
+ "completed_at",
134200
+ "expires_at",
134201
+ "last_update"
134202
+ ];
134203
+ if (columnName && timestampColumns.includes(columnName)) {
134204
+ return null;
134205
+ }
134206
+ }
133666
134207
  if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value)) {
133667
134208
  return value;
133668
134209
  }
@@ -133670,53 +134211,83 @@ var PostgresWriter = class {
133670
134211
  if (!isNaN(numVal) && numVal > 9466848e5 && numVal < 41024448e5) {
133671
134212
  return new Date(numVal).toISOString();
133672
134213
  }
133673
- const jsonbColumns = [
133674
- "action_value",
133675
- "state",
133676
- "action",
133677
- "next_state",
133678
- "preconditions",
133679
- "effects",
133680
- "metadata",
133681
- "value",
133682
- "payload",
133683
- "context_json",
133684
- "template_json",
133685
- "execution_trace",
133686
- "action_sequence",
133687
- "initial_state",
133688
- "goal_state",
133689
- "sequence"
133690
- ];
133691
- if (columnName && jsonbColumns.includes(columnName)) {
133692
- if (!value.startsWith("{") && !value.startsWith("[") && !value.startsWith('"')) {
133693
- return JSON.stringify(value);
134214
+ if (columnName && this.isJsonbColumn(columnName)) {
134215
+ const sanitized = value.replace(/\u0000/g, "");
134216
+ try {
134217
+ JSON.parse(sanitized);
134218
+ return sanitized;
134219
+ } catch {
134220
+ return JSON.stringify(sanitized);
133694
134221
  }
133695
134222
  }
133696
134223
  }
133697
134224
  return value;
133698
134225
  }
133699
134226
  /**
133700
- * Infer conflict columns from table name
134227
+ * Check if a column is a JSONB column
134228
+ */
134229
+ isJsonbColumn(columnName) {
134230
+ const jsonbColumns = [
134231
+ "action_value",
134232
+ "state",
134233
+ "action",
134234
+ "next_state",
134235
+ "preconditions",
134236
+ "effects",
134237
+ "metadata",
134238
+ "value",
134239
+ "payload",
134240
+ "context_json",
134241
+ "template_json",
134242
+ "execution_trace",
134243
+ "action_sequence",
134244
+ "initial_state",
134245
+ "goal_state",
134246
+ "sequence",
134247
+ "task_json",
134248
+ "decision_json",
134249
+ "steps_json",
134250
+ "metadata_json"
134251
+ ];
134252
+ return jsonbColumns.includes(columnName);
134253
+ }
134254
+ /**
134255
+ * Infer conflict columns from table name and available columns.
134256
+ * Only returns columns if the target table is known to have a matching unique constraint.
133701
134257
  */
133702
134258
  inferConflictColumns(table, columns) {
133703
134259
  const tableName = table.includes(".") ? table.split(".")[1] : table;
133704
- if (columns.includes("id")) {
134260
+ const tablesWithIdPK = [
134261
+ "qe_patterns",
134262
+ "sona_patterns",
134263
+ "goap_actions",
134264
+ "goap_plans",
134265
+ "patterns",
134266
+ "events",
134267
+ "routing_outcomes",
134268
+ "qe_trajectories",
134269
+ "dream_insights",
134270
+ "intelligence_memories"
134271
+ ];
134272
+ if (columns.includes("id") && tablesWithIdPK.includes(tableName)) {
133705
134273
  return ["id"];
133706
134274
  }
133707
- if (columns.includes("key") && columns.includes("source_env")) {
134275
+ if (tableName === "memory_entries" && columns.includes("key") && columns.includes("source_env")) {
133708
134276
  if (columns.includes("partition")) {
133709
134277
  return ["key", "partition", "source_env"];
133710
134278
  }
133711
134279
  return ["key", "source_env"];
133712
134280
  }
133713
- if (columns.includes("state") && columns.includes("action") && columns.includes("source_env")) {
134281
+ if (tableName === "claude_flow_memory" && columns.includes("key") && columns.includes("source_env")) {
134282
+ return ["key", "source_env"];
134283
+ }
134284
+ if (tableName === "qlearning_patterns" && columns.includes("state") && columns.includes("action") && columns.includes("source_env")) {
133714
134285
  return ["state", "action", "source_env"];
133715
134286
  }
133716
- if (columns.includes("worker_type") && columns.includes("source_env")) {
134287
+ if (tableName === "claude_flow_workers" && columns.includes("worker_type") && columns.includes("source_env")) {
133717
134288
  return ["worker_type", "source_env"];
133718
134289
  }
133719
- return columns.includes("id") ? ["id"] : [];
134290
+ return [];
133720
134291
  }
133721
134292
  /**
133722
134293
  * Create mock client for testing without pg installed
@@ -133869,17 +134440,10 @@ var CloudSyncAgent = class {
133869
134440
  return result;
133870
134441
  }
133871
134442
  if (this.writer && !this.config.sync.dryRun) {
133872
- await this.writer.beginTransaction();
133873
- try {
133874
- const written = await this.writer.upsert(source.targetTable, records, {
133875
- skipIfExists: source.mode === "append"
133876
- });
133877
- result.recordsSynced = written;
133878
- await this.writer.commit();
133879
- } catch (error) {
133880
- await this.writer.rollback();
133881
- throw error;
133882
- }
134443
+ const written = await this.writer.upsert(source.targetTable, records, {
134444
+ skipIfExists: source.mode === "append"
134445
+ });
134446
+ result.recordsSynced = written;
133883
134447
  } else {
133884
134448
  result.recordsSynced = records.length;
133885
134449
  this.log(`[DRY RUN] Would sync ${records.length} records to ${source.targetTable}`);
@@ -133919,15 +134483,8 @@ var CloudSyncAgent = class {
133919
134483
  return result;
133920
134484
  }
133921
134485
  if (this.writer && !this.config.sync.dryRun) {
133922
- await this.writer.beginTransaction();
133923
- try {
133924
- const written = await this.writer.upsert(source.targetTable, records);
133925
- result.recordsSynced = written;
133926
- await this.writer.commit();
133927
- } catch (error) {
133928
- await this.writer.rollback();
133929
- throw error;
133930
- }
134486
+ const written = await this.writer.upsert(source.targetTable, records);
134487
+ result.recordsSynced = written;
133931
134488
  } else {
133932
134489
  result.recordsSynced = records.length;
133933
134490
  }
@@ -135653,22 +136210,22 @@ var CategoryAdapter = class {
135653
136210
  * @param pipeline - The pipeline to verify
135654
136211
  * @returns Type verification result
135655
136212
  */
135656
- verifyPipeline(pipeline11) {
136213
+ verifyPipeline(pipeline10) {
135657
136214
  const startTime = Date.now();
135658
136215
  this.clear();
135659
- this.addType(pipeline11.inputType, this.inferSchema(pipeline11.inputType));
135660
- this.addType(pipeline11.outputType, this.inferSchema(pipeline11.outputType));
135661
- for (const element of pipeline11.elements) {
136216
+ this.addType(pipeline10.inputType, this.inferSchema(pipeline10.inputType));
136217
+ this.addType(pipeline10.outputType, this.inferSchema(pipeline10.outputType));
136218
+ for (const element of pipeline10.elements) {
135662
136219
  this.addType(element.inputType, this.inferSchema(element.inputType));
135663
136220
  this.addType(element.outputType, this.inferSchema(element.outputType));
135664
136221
  }
135665
- for (const element of pipeline11.elements) {
136222
+ for (const element of pipeline10.elements) {
135666
136223
  this.addMorphism(element.inputType, element.outputType, element.name);
135667
136224
  }
135668
- const path26 = this.buildCompositionPath(pipeline11);
136225
+ const path26 = this.buildCompositionPath(pipeline10);
135669
136226
  const compositionValid = this.verifyComposition(path26);
135670
136227
  const mismatches = this.checkTypeConsistency();
135671
- const warnings = this.generateWarnings(pipeline11, compositionValid, mismatches);
136228
+ const warnings = this.generateWarnings(pipeline10, compositionValid, mismatches);
135672
136229
  const durationMs = Date.now() - startTime;
135673
136230
  const result = {
135674
136231
  isValid: compositionValid && mismatches.length === 0,
@@ -135678,7 +136235,7 @@ var CategoryAdapter = class {
135678
136235
  usedFallback: false
135679
136236
  };
135680
136237
  this.logger.info("Verified pipeline", {
135681
- pipelineId: pipeline11.id,
136238
+ pipelineId: pipeline10.id,
135682
136239
  isValid: result.isValid,
135683
136240
  mismatchCount: mismatches.length,
135684
136241
  warningCount: warnings.length,
@@ -135689,16 +136246,16 @@ var CategoryAdapter = class {
135689
136246
  /**
135690
136247
  * Build a composition path from a pipeline
135691
136248
  */
135692
- buildCompositionPath(pipeline11) {
135693
- const path26 = [pipeline11.inputType];
135694
- for (const element of pipeline11.elements) {
136249
+ buildCompositionPath(pipeline10) {
136250
+ const path26 = [pipeline10.inputType];
136251
+ for (const element of pipeline10.elements) {
135695
136252
  if (element.inputType !== path26[path26.length - 1]) {
135696
136253
  path26.push(element.inputType);
135697
136254
  }
135698
136255
  path26.push(element.outputType);
135699
136256
  }
135700
- if (path26[path26.length - 1] !== pipeline11.outputType) {
135701
- path26.push(pipeline11.outputType);
136257
+ if (path26[path26.length - 1] !== pipeline10.outputType) {
136258
+ path26.push(pipeline10.outputType);
135702
136259
  }
135703
136260
  return path26;
135704
136261
  }
@@ -135744,21 +136301,21 @@ var CategoryAdapter = class {
135744
136301
  /**
135745
136302
  * Generate warnings for potential issues
135746
136303
  */
135747
- generateWarnings(pipeline11, compositionValid, mismatches) {
136304
+ generateWarnings(pipeline10, compositionValid, mismatches) {
135748
136305
  const warnings = [];
135749
136306
  if (!compositionValid) {
135750
136307
  warnings.push(
135751
- `Pipeline '${pipeline11.id}' has an invalid composition chain. Types do not connect properly from input to output.`
136308
+ `Pipeline '${pipeline10.id}' has an invalid composition chain. Types do not connect properly from input to output.`
135752
136309
  );
135753
136310
  }
135754
- for (const element of pipeline11.elements) {
136311
+ for (const element of pipeline10.elements) {
135755
136312
  if (element.inputType === "any" || element.outputType === "any") {
135756
136313
  warnings.push(
135757
136314
  `Element '${element.name}' uses 'any' type, which bypasses type safety.`
135758
136315
  );
135759
136316
  }
135760
136317
  }
135761
- for (const element of pipeline11.elements) {
136318
+ for (const element of pipeline10.elements) {
135762
136319
  if (element.inputType.includes("<T>") || element.outputType.includes("<T>")) {
135763
136320
  warnings.push(
135764
136321
  `Element '${element.name}' has unconstrained generic types.`
@@ -136668,21 +137225,21 @@ var CoherenceService = class {
136668
137225
  /**
136669
137226
  * Verify type consistency in a pipeline
136670
137227
  */
136671
- async verifyTypes(pipeline11) {
137228
+ async verifyTypes(pipeline10) {
136672
137229
  this.ensureInitialized();
136673
137230
  if (this.categoryAdapter?.isInitialized()) {
136674
- return this.categoryAdapter.verifyPipeline(pipeline11);
137231
+ return this.categoryAdapter.verifyPipeline(pipeline10);
136675
137232
  }
136676
- return this.verifyTypesWithFallback(pipeline11);
137233
+ return this.verifyTypesWithFallback(pipeline10);
136677
137234
  }
136678
137235
  /**
136679
137236
  * Fallback type verification using simple matching
136680
137237
  */
136681
- verifyTypesWithFallback(pipeline11) {
137238
+ verifyTypesWithFallback(pipeline10) {
136682
137239
  const startTime = Date.now();
136683
137240
  const mismatches = [];
136684
- let currentType = pipeline11.inputType;
136685
- for (const element of pipeline11.elements) {
137241
+ let currentType = pipeline10.inputType;
137242
+ for (const element of pipeline10.elements) {
136686
137243
  if (element.inputType !== currentType && currentType !== "any") {
136687
137244
  mismatches.push({
136688
137245
  location: element.name,
@@ -136693,10 +137250,10 @@ var CoherenceService = class {
136693
137250
  }
136694
137251
  currentType = element.outputType;
136695
137252
  }
136696
- if (currentType !== pipeline11.outputType && currentType !== "any") {
137253
+ if (currentType !== pipeline10.outputType && currentType !== "any") {
136697
137254
  mismatches.push({
136698
137255
  location: "pipeline output",
136699
- expected: pipeline11.outputType,
137256
+ expected: pipeline10.outputType,
136700
137257
  actual: currentType,
136701
137258
  severity: "critical"
136702
137259
  });
@@ -139196,7 +139753,7 @@ import chalk28 from "chalk";
139196
139753
  import path24 from "node:path";
139197
139754
  import { createReadStream, createWriteStream } from "node:fs";
139198
139755
  import { createGzip, createGunzip } from "node:zlib";
139199
- import { pipeline as pipeline10 } from "node:stream/promises";
139756
+ import { pipeline as pipeline9 } from "node:stream/promises";
139200
139757
  init_qe_patterns();
139201
139758
  var state2 = {
139202
139759
  reasoningBank: null,
@@ -139324,7 +139881,7 @@ function getDbPath() {
139324
139881
  }
139325
139882
  async function compressFile(inputPath, outputPath) {
139326
139883
  const gzPath = outputPath || `${inputPath}.gz`;
139327
- await pipeline10(
139884
+ await pipeline9(
139328
139885
  createReadStream(inputPath),
139329
139886
  createGzip(),
139330
139887
  createWriteStream(gzPath)
@@ -139332,7 +139889,7 @@ async function compressFile(inputPath, outputPath) {
139332
139889
  return gzPath;
139333
139890
  }
139334
139891
  async function decompressFile(gzPath, outputPath) {
139335
- await pipeline10(
139892
+ await pipeline9(
139336
139893
  createReadStream(gzPath),
139337
139894
  createGunzip(),
139338
139895
  createWriteStream(outputPath)
@@ -140544,7 +141101,7 @@ async function cleanupAndExit(code = 0) {
140544
141101
  process.exit(code);
140545
141102
  }
140546
141103
  var program = new Command18();
140547
- var VERSION = true ? "3.6.14" : "0.0.0-dev";
141104
+ var VERSION = true ? "3.6.16" : "0.0.0-dev";
140548
141105
  program.name("aqe").description("Agentic QE - Domain-Driven Quality Engineering").version(VERSION);
140549
141106
  var registry = createCommandRegistry(context, cleanupAndExit, ensureInitialized);
140550
141107
  registry.registerAll(program);
@@ -140828,22 +141385,22 @@ Validating pipeline: ${file}
140828
141385
  console.log("");
140829
141386
  }
140830
141387
  if (options.verbose && parseResult.pipeline) {
140831
- const pipeline11 = parseResult.pipeline;
141388
+ const pipeline10 = parseResult.pipeline;
140832
141389
  console.log(chalk30.cyan("Pipeline Details:\n"));
140833
- console.log(chalk30.gray(` Name: ${pipeline11.name}`));
140834
- console.log(chalk30.gray(` Version: ${pipeline11.version || "1.0.0"}`));
140835
- if (pipeline11.description) {
140836
- console.log(chalk30.gray(` Description: ${pipeline11.description}`));
141390
+ console.log(chalk30.gray(` Name: ${pipeline10.name}`));
141391
+ console.log(chalk30.gray(` Version: ${pipeline10.version || "1.0.0"}`));
141392
+ if (pipeline10.description) {
141393
+ console.log(chalk30.gray(` Description: ${pipeline10.description}`));
140837
141394
  }
140838
- if (pipeline11.schedule) {
140839
- console.log(chalk30.gray(` Schedule: ${pipeline11.schedule} (${describeCronSchedule(pipeline11.schedule)})`));
141395
+ if (pipeline10.schedule) {
141396
+ console.log(chalk30.gray(` Schedule: ${pipeline10.schedule} (${describeCronSchedule(pipeline10.schedule)})`));
140840
141397
  }
140841
- if (pipeline11.tags && pipeline11.tags.length > 0) {
140842
- console.log(chalk30.gray(` Tags: ${pipeline11.tags.join(", ")}`));
141398
+ if (pipeline10.tags && pipeline10.tags.length > 0) {
141399
+ console.log(chalk30.gray(` Tags: ${pipeline10.tags.join(", ")}`));
140843
141400
  }
140844
141401
  console.log(chalk30.cyan("\n Stages:"));
140845
- for (let i58 = 0; i58 < pipeline11.stages.length; i58++) {
140846
- const stage = pipeline11.stages[i58];
141402
+ for (let i58 = 0; i58 < pipeline10.stages.length; i58++) {
141403
+ const stage = pipeline10.stages[i58];
140847
141404
  console.log(` ${i58 + 1}. ${chalk30.white(stage.name)}`);
140848
141405
  console.log(chalk30.gray(` Command: ${stage.command}`));
140849
141406
  if (stage.params) {
@@ -140856,9 +141413,9 @@ Validating pipeline: ${file}
140856
141413
  console.log(chalk30.gray(` Timeout: ${stage.timeout}s`));
140857
141414
  }
140858
141415
  }
140859
- if (pipeline11.triggers && pipeline11.triggers.length > 0) {
141416
+ if (pipeline10.triggers && pipeline10.triggers.length > 0) {
140860
141417
  console.log(chalk30.cyan("\n Triggers:"));
140861
- for (const trigger of pipeline11.triggers) {
141418
+ for (const trigger of pipeline10.triggers) {
140862
141419
  console.log(chalk30.gray(` * ${trigger.event}`));
140863
141420
  if (trigger.branches) {
140864
141421
  console.log(chalk30.gray(` Branches: ${trigger.branches.join(", ")}`));