agentic-qe 3.6.16 → 3.6.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/v3/qe-queen-coordinator.md +9 -3
- package/.claude/skills/skills-manifest.json +1 -1
- package/package.json +1 -1
- package/v3/CHANGELOG.md +22 -0
- package/v3/assets/agents/v3/qe-queen-coordinator.md +9 -3
- package/v3/dist/cli/bundle.js +1584 -659
- package/v3/dist/cli/commands/sync.d.ts.map +1 -1
- package/v3/dist/cli/commands/sync.js +83 -1
- package/v3/dist/cli/commands/sync.js.map +1 -1
- package/v3/dist/mcp/bundle.js +307 -21
- package/v3/dist/mcp/handlers/agent-handlers.d.ts +3 -0
- package/v3/dist/mcp/handlers/agent-handlers.d.ts.map +1 -1
- package/v3/dist/mcp/handlers/agent-handlers.js +16 -9
- package/v3/dist/mcp/handlers/agent-handlers.js.map +1 -1
- package/v3/dist/mcp/handlers/core-handlers.d.ts +32 -0
- package/v3/dist/mcp/handlers/core-handlers.d.ts.map +1 -1
- package/v3/dist/mcp/handlers/core-handlers.js +45 -1
- package/v3/dist/mcp/handlers/core-handlers.js.map +1 -1
- package/v3/dist/mcp/handlers/handler-factory.d.ts +9 -1
- package/v3/dist/mcp/handlers/handler-factory.d.ts.map +1 -1
- package/v3/dist/mcp/handlers/handler-factory.js +94 -2
- package/v3/dist/mcp/handlers/handler-factory.js.map +1 -1
- package/v3/dist/mcp/handlers/memory-handlers.d.ts +2 -0
- package/v3/dist/mcp/handlers/memory-handlers.d.ts.map +1 -1
- package/v3/dist/mcp/handlers/memory-handlers.js +90 -1
- package/v3/dist/mcp/handlers/memory-handlers.js.map +1 -1
- package/v3/dist/mcp/protocol-server.d.ts +7 -0
- package/v3/dist/mcp/protocol-server.d.ts.map +1 -1
- package/v3/dist/mcp/protocol-server.js +56 -2
- package/v3/dist/mcp/protocol-server.js.map +1 -1
- package/v3/dist/mcp/transport/stdio.d.ts +18 -0
- package/v3/dist/mcp/transport/stdio.d.ts.map +1 -1
- package/v3/dist/mcp/transport/stdio.js +72 -5
- package/v3/dist/mcp/transport/stdio.js.map +1 -1
- package/v3/dist/mcp/types.d.ts +2 -0
- package/v3/dist/mcp/types.d.ts.map +1 -1
- package/v3/dist/sync/cloud/index.d.ts +1 -0
- package/v3/dist/sync/cloud/index.d.ts.map +1 -1
- package/v3/dist/sync/cloud/index.js +1 -0
- package/v3/dist/sync/cloud/index.js.map +1 -1
- package/v3/dist/sync/cloud/postgres-reader.d.ts +63 -0
- package/v3/dist/sync/cloud/postgres-reader.d.ts.map +1 -0
- package/v3/dist/sync/cloud/postgres-reader.js +225 -0
- package/v3/dist/sync/cloud/postgres-reader.js.map +1 -0
- package/v3/dist/sync/index.d.ts +5 -2
- package/v3/dist/sync/index.d.ts.map +1 -1
- package/v3/dist/sync/index.js +7 -2
- package/v3/dist/sync/index.js.map +1 -1
- package/v3/dist/sync/interfaces.d.ts +49 -0
- package/v3/dist/sync/interfaces.d.ts.map +1 -1
- package/v3/dist/sync/interfaces.js +160 -0
- package/v3/dist/sync/interfaces.js.map +1 -1
- package/v3/dist/sync/pull-agent.d.ts +102 -0
- package/v3/dist/sync/pull-agent.d.ts.map +1 -0
- package/v3/dist/sync/pull-agent.js +354 -0
- package/v3/dist/sync/pull-agent.js.map +1 -0
- package/v3/dist/sync/sync-agent.d.ts.map +1 -1
- package/v3/dist/sync/sync-agent.js +9 -0
- package/v3/dist/sync/sync-agent.js.map +1 -1
- package/v3/dist/sync/writers/index.d.ts +7 -0
- package/v3/dist/sync/writers/index.d.ts.map +1 -0
- package/v3/dist/sync/writers/index.js +7 -0
- package/v3/dist/sync/writers/index.js.map +1 -0
- package/v3/dist/sync/writers/sqlite-writer.d.ts +69 -0
- package/v3/dist/sync/writers/sqlite-writer.d.ts.map +1 -0
- package/v3/dist/sync/writers/sqlite-writer.js +249 -0
- package/v3/dist/sync/writers/sqlite-writer.js.map +1 -0
- package/v3/package.json +1 -1
package/v3/dist/cli/bundle.js
CHANGED
|
@@ -617,18 +617,18 @@ var init_logger_factory = __esm({
|
|
|
617
617
|
return this.instances.get(domain);
|
|
618
618
|
}
|
|
619
619
|
const level = this.getDomainLevel(domain);
|
|
620
|
-
let
|
|
620
|
+
let logger22;
|
|
621
621
|
if (this.config.silent) {
|
|
622
|
-
|
|
622
|
+
logger22 = new NullLogger(domain);
|
|
623
623
|
} else if (this.customProvider) {
|
|
624
|
-
|
|
624
|
+
logger22 = this.customProvider(domain, level, context2);
|
|
625
625
|
} else {
|
|
626
|
-
|
|
626
|
+
logger22 = new ConsoleLogger(domain, level, this.config.consoleConfig, context2);
|
|
627
627
|
}
|
|
628
628
|
if (!context2) {
|
|
629
|
-
this.instances.set(domain,
|
|
629
|
+
this.instances.set(domain, logger22);
|
|
630
630
|
}
|
|
631
|
-
return
|
|
631
|
+
return logger22;
|
|
632
632
|
}
|
|
633
633
|
/**
|
|
634
634
|
* Get a logger (alias for create)
|
|
@@ -4409,7 +4409,7 @@ var init_ollama_client = __esm({
|
|
|
4409
4409
|
* Sleep utility for retry delays
|
|
4410
4410
|
*/
|
|
4411
4411
|
sleep(ms) {
|
|
4412
|
-
return new Promise((
|
|
4412
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
4413
4413
|
}
|
|
4414
4414
|
/**
|
|
4415
4415
|
* Get Ollama server info
|
|
@@ -5618,7 +5618,7 @@ Focus on accuracy over speed. It's better to mark something as "INCONCLUSIVE" if
|
|
|
5618
5618
|
* Sleep for specified milliseconds
|
|
5619
5619
|
*/
|
|
5620
5620
|
sleep(ms) {
|
|
5621
|
-
return new Promise((
|
|
5621
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
5622
5622
|
}
|
|
5623
5623
|
/**
|
|
5624
5624
|
* Get cost per token for current model
|
|
@@ -5944,7 +5944,7 @@ Focus on accuracy over speed. It's better to mark something as "INCONCLUSIVE" if
|
|
|
5944
5944
|
* Sleep for specified milliseconds
|
|
5945
5945
|
*/
|
|
5946
5946
|
sleep(ms) {
|
|
5947
|
-
return new Promise((
|
|
5947
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
5948
5948
|
}
|
|
5949
5949
|
/**
|
|
5950
5950
|
* Get cost per token for current model
|
|
@@ -6228,7 +6228,7 @@ Focus on accuracy over speed. It's better to mark something as "INCONCLUSIVE" if
|
|
|
6228
6228
|
* Sleep for specified milliseconds
|
|
6229
6229
|
*/
|
|
6230
6230
|
sleep(ms) {
|
|
6231
|
-
return new Promise((
|
|
6231
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
6232
6232
|
}
|
|
6233
6233
|
/**
|
|
6234
6234
|
* Get cost per token for current model
|
|
@@ -6514,7 +6514,7 @@ var init_openrouter_provider = __esm({
|
|
|
6514
6514
|
* Sleep for a given duration
|
|
6515
6515
|
*/
|
|
6516
6516
|
sleep(ms) {
|
|
6517
|
-
return new Promise((
|
|
6517
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
6518
6518
|
}
|
|
6519
6519
|
/**
|
|
6520
6520
|
* Get default system prompt for security verification
|
|
@@ -6797,7 +6797,7 @@ var init_ollama_provider = __esm({
|
|
|
6797
6797
|
* Sleep for a given duration
|
|
6798
6798
|
*/
|
|
6799
6799
|
sleep(ms) {
|
|
6800
|
-
return new Promise((
|
|
6800
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
6801
6801
|
}
|
|
6802
6802
|
/**
|
|
6803
6803
|
* Get default system prompt for security verification
|
|
@@ -8495,7 +8495,7 @@ var init_gnn_wrapper = __esm({
|
|
|
8495
8495
|
* Save index to file
|
|
8496
8496
|
* Note: @ruvector/gnn uses JSON serialization for layers
|
|
8497
8497
|
*/
|
|
8498
|
-
async saveIndex(namespace,
|
|
8498
|
+
async saveIndex(namespace, path27) {
|
|
8499
8499
|
const index = this.indexes.get(namespace);
|
|
8500
8500
|
if (!index) {
|
|
8501
8501
|
throw new Error(`Namespace ${namespace} not initialized`);
|
|
@@ -8505,15 +8505,15 @@ var init_gnn_wrapper = __esm({
|
|
|
8505
8505
|
vector: Array.from(emb.vector),
|
|
8506
8506
|
metadata: emb.metadata
|
|
8507
8507
|
}));
|
|
8508
|
-
const
|
|
8509
|
-
await
|
|
8508
|
+
const fs25 = await import("fs/promises");
|
|
8509
|
+
await fs25.writeFile(path27, JSON.stringify(data, null, 2));
|
|
8510
8510
|
}
|
|
8511
8511
|
/**
|
|
8512
8512
|
* Load index from file
|
|
8513
8513
|
*/
|
|
8514
|
-
async loadIndex(namespace,
|
|
8515
|
-
const
|
|
8516
|
-
const content = await
|
|
8514
|
+
async loadIndex(namespace, path27) {
|
|
8515
|
+
const fs25 = await import("fs/promises");
|
|
8516
|
+
const content = await fs25.readFile(path27, "utf-8");
|
|
8517
8517
|
const data = safeJsonParse(content);
|
|
8518
8518
|
this.initializeIndex(namespace);
|
|
8519
8519
|
for (const item of data) {
|
|
@@ -9693,7 +9693,7 @@ var init_path_traversal_validator = __esm({
|
|
|
9693
9693
|
/**
|
|
9694
9694
|
* Validate a file path against traversal attacks
|
|
9695
9695
|
*/
|
|
9696
|
-
validate(
|
|
9696
|
+
validate(path27, options = {}) {
|
|
9697
9697
|
const {
|
|
9698
9698
|
basePath = "",
|
|
9699
9699
|
allowAbsolute = false,
|
|
@@ -9702,7 +9702,7 @@ var init_path_traversal_validator = __esm({
|
|
|
9702
9702
|
maxDepth = 10,
|
|
9703
9703
|
maxLength = 4096
|
|
9704
9704
|
} = options;
|
|
9705
|
-
if (
|
|
9705
|
+
if (path27.length > maxLength) {
|
|
9706
9706
|
return {
|
|
9707
9707
|
valid: false,
|
|
9708
9708
|
error: `Path exceeds maximum length of ${maxLength}`,
|
|
@@ -9710,7 +9710,7 @@ var init_path_traversal_validator = __esm({
|
|
|
9710
9710
|
};
|
|
9711
9711
|
}
|
|
9712
9712
|
for (const pattern of PATH_TRAVERSAL_PATTERNS) {
|
|
9713
|
-
if (pattern.test(
|
|
9713
|
+
if (pattern.test(path27)) {
|
|
9714
9714
|
return {
|
|
9715
9715
|
valid: false,
|
|
9716
9716
|
error: "Path traversal attempt detected",
|
|
@@ -9718,7 +9718,7 @@ var init_path_traversal_validator = __esm({
|
|
|
9718
9718
|
};
|
|
9719
9719
|
}
|
|
9720
9720
|
}
|
|
9721
|
-
if (!allowAbsolute && (
|
|
9721
|
+
if (!allowAbsolute && (path27.startsWith("/") || /^[A-Z]:/i.test(path27))) {
|
|
9722
9722
|
return {
|
|
9723
9723
|
valid: false,
|
|
9724
9724
|
error: "Absolute paths are not allowed",
|
|
@@ -9726,7 +9726,7 @@ var init_path_traversal_validator = __esm({
|
|
|
9726
9726
|
};
|
|
9727
9727
|
}
|
|
9728
9728
|
for (const pattern of DANGEROUS_PATH_COMPONENTS) {
|
|
9729
|
-
if (pattern.test(
|
|
9729
|
+
if (pattern.test(path27)) {
|
|
9730
9730
|
return {
|
|
9731
9731
|
valid: false,
|
|
9732
9732
|
error: "Access to system paths is not allowed",
|
|
@@ -9734,7 +9734,7 @@ var init_path_traversal_validator = __esm({
|
|
|
9734
9734
|
};
|
|
9735
9735
|
}
|
|
9736
9736
|
}
|
|
9737
|
-
const normalizedPath = this.normalizePath(
|
|
9737
|
+
const normalizedPath = this.normalizePath(path27);
|
|
9738
9738
|
if (normalizedPath.includes("..")) {
|
|
9739
9739
|
return {
|
|
9740
9740
|
valid: false,
|
|
@@ -9797,8 +9797,8 @@ var init_path_traversal_validator = __esm({
|
|
|
9797
9797
|
/**
|
|
9798
9798
|
* Normalize a path by resolving . and .. components
|
|
9799
9799
|
*/
|
|
9800
|
-
normalizePath(
|
|
9801
|
-
let normalized =
|
|
9800
|
+
normalizePath(path27) {
|
|
9801
|
+
let normalized = path27.replace(/\\/g, "/");
|
|
9802
9802
|
normalized = normalized.replace(/\/+/g, "/");
|
|
9803
9803
|
const parts = normalized.split("/");
|
|
9804
9804
|
const result = [];
|
|
@@ -9839,13 +9839,13 @@ var init_path_traversal_validator = __esm({
|
|
|
9839
9839
|
/**
|
|
9840
9840
|
* Get file extension from path
|
|
9841
9841
|
*/
|
|
9842
|
-
getExtension(
|
|
9843
|
-
const match =
|
|
9842
|
+
getExtension(path27) {
|
|
9843
|
+
const match = path27.match(/\.([^./\\]+)$/);
|
|
9844
9844
|
return match ? match[1] : null;
|
|
9845
9845
|
}
|
|
9846
9846
|
};
|
|
9847
9847
|
defaultValidator2 = new PathTraversalValidator();
|
|
9848
|
-
validatePath = (
|
|
9848
|
+
validatePath = (path27, options) => defaultValidator2.validate(path27, options);
|
|
9849
9849
|
}
|
|
9850
9850
|
});
|
|
9851
9851
|
|
|
@@ -10692,23 +10692,23 @@ var init_knowledge_graph = __esm({
|
|
|
10692
10692
|
if (!incremental) {
|
|
10693
10693
|
await this.clear();
|
|
10694
10694
|
}
|
|
10695
|
-
for (const
|
|
10695
|
+
for (const path27 of paths) {
|
|
10696
10696
|
try {
|
|
10697
10697
|
if (languages && languages.length > 0) {
|
|
10698
|
-
const ext = this.getFileExtension(
|
|
10698
|
+
const ext = this.getFileExtension(path27);
|
|
10699
10699
|
if (!this.matchesLanguage(ext, languages)) {
|
|
10700
10700
|
continue;
|
|
10701
10701
|
}
|
|
10702
10702
|
}
|
|
10703
|
-
if (!includeTests && this.isTestFile(
|
|
10703
|
+
if (!includeTests && this.isTestFile(path27)) {
|
|
10704
10704
|
continue;
|
|
10705
10705
|
}
|
|
10706
|
-
const result = await this.indexFile(
|
|
10706
|
+
const result = await this.indexFile(path27);
|
|
10707
10707
|
nodesCreated += result.nodes;
|
|
10708
10708
|
edgesCreated += result.edges;
|
|
10709
10709
|
} catch (fileError) {
|
|
10710
10710
|
errors.push({
|
|
10711
|
-
file:
|
|
10711
|
+
file: path27,
|
|
10712
10712
|
error: toErrorMessage(fileError)
|
|
10713
10713
|
});
|
|
10714
10714
|
}
|
|
@@ -11422,16 +11422,16 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
|
|
|
11422
11422
|
}
|
|
11423
11423
|
});
|
|
11424
11424
|
}
|
|
11425
|
-
async traverseDependencies(file, direction, depth, visited, nodes, edges,
|
|
11425
|
+
async traverseDependencies(file, direction, depth, visited, nodes, edges, path27, cycles) {
|
|
11426
11426
|
if (depth <= 0 || visited.has(file)) {
|
|
11427
|
-
const cycleStart =
|
|
11427
|
+
const cycleStart = path27.indexOf(file);
|
|
11428
11428
|
if (cycleStart >= 0) {
|
|
11429
|
-
cycles.push([...
|
|
11429
|
+
cycles.push([...path27.slice(cycleStart), file]);
|
|
11430
11430
|
}
|
|
11431
11431
|
return;
|
|
11432
11432
|
}
|
|
11433
11433
|
visited.add(file);
|
|
11434
|
-
|
|
11434
|
+
path27.push(file);
|
|
11435
11435
|
const nodeId = this.pathToNodeId(file);
|
|
11436
11436
|
const fileEdges = await this.getEdges(nodeId, direction);
|
|
11437
11437
|
const inDegree = fileEdges.filter((e20) => e20.target === nodeId).length;
|
|
@@ -11461,12 +11461,12 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
|
|
|
11461
11461
|
visited,
|
|
11462
11462
|
nodes,
|
|
11463
11463
|
edges,
|
|
11464
|
-
|
|
11464
|
+
path27,
|
|
11465
11465
|
cycles
|
|
11466
11466
|
);
|
|
11467
11467
|
}
|
|
11468
11468
|
}
|
|
11469
|
-
|
|
11469
|
+
path27.pop();
|
|
11470
11470
|
}
|
|
11471
11471
|
calculateDependencyMetrics(nodes, edges) {
|
|
11472
11472
|
const totalNodes = nodes.length;
|
|
@@ -11551,23 +11551,23 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
|
|
|
11551
11551
|
const magnitude2 = Math.sqrt(embedding.reduce((sum, v62) => sum + v62 * v62, 0)) || 1;
|
|
11552
11552
|
return embedding.map((v62) => v62 / magnitude2);
|
|
11553
11553
|
}
|
|
11554
|
-
pathToNodeId(
|
|
11555
|
-
return
|
|
11554
|
+
pathToNodeId(path27) {
|
|
11555
|
+
return path27.replace(/[/\\]/g, ":").replace(/\./g, "_");
|
|
11556
11556
|
}
|
|
11557
11557
|
nodeIdToPath(nodeId) {
|
|
11558
|
-
const
|
|
11559
|
-
return
|
|
11558
|
+
const path27 = nodeId.replace(/:/g, "/").replace(/_(?=[^_]*$)/, ".");
|
|
11559
|
+
return path27.includes("/") ? path27 : null;
|
|
11560
11560
|
}
|
|
11561
|
-
getFileName(
|
|
11562
|
-
return
|
|
11561
|
+
getFileName(path27) {
|
|
11562
|
+
return path27.split(/[/\\]/).pop() || path27;
|
|
11563
11563
|
}
|
|
11564
|
-
getFileExtension(
|
|
11565
|
-
const name = this.getFileName(
|
|
11564
|
+
getFileExtension(path27) {
|
|
11565
|
+
const name = this.getFileName(path27);
|
|
11566
11566
|
const parts = name.split(".");
|
|
11567
11567
|
return parts.length > 1 ? parts.pop() : "";
|
|
11568
11568
|
}
|
|
11569
|
-
getFileType(
|
|
11570
|
-
const ext = this.getFileExtension(
|
|
11569
|
+
getFileType(path27) {
|
|
11570
|
+
const ext = this.getFileExtension(path27);
|
|
11571
11571
|
const typeMap = {
|
|
11572
11572
|
ts: "typescript",
|
|
11573
11573
|
tsx: "typescript-react",
|
|
@@ -11596,7 +11596,7 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
|
|
|
11596
11596
|
return exts.includes(ext);
|
|
11597
11597
|
});
|
|
11598
11598
|
}
|
|
11599
|
-
isTestFile(
|
|
11599
|
+
isTestFile(path27) {
|
|
11600
11600
|
const testPatterns = [
|
|
11601
11601
|
/\.test\.[tj]sx?$/,
|
|
11602
11602
|
/\.spec\.[tj]sx?$/,
|
|
@@ -11605,7 +11605,7 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
|
|
|
11605
11605
|
/.*_test\.py$/,
|
|
11606
11606
|
/.*_test\.go$/
|
|
11607
11607
|
];
|
|
11608
|
-
return testPatterns.some((pattern) => pattern.test(
|
|
11608
|
+
return testPatterns.some((pattern) => pattern.test(path27));
|
|
11609
11609
|
}
|
|
11610
11610
|
/**
|
|
11611
11611
|
* Dispose of all resources and clear caches.
|
|
@@ -12718,7 +12718,7 @@ var init_spreading_activation = __esm({
|
|
|
12718
12718
|
* Helper to sleep for a duration
|
|
12719
12719
|
*/
|
|
12720
12720
|
sleep(ms) {
|
|
12721
|
-
return new Promise((
|
|
12721
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
12722
12722
|
}
|
|
12723
12723
|
};
|
|
12724
12724
|
}
|
|
@@ -15645,11 +15645,11 @@ var init_sqlite_persistence = __esm({
|
|
|
15645
15645
|
this.db = this.unifiedMemory.getDatabase();
|
|
15646
15646
|
console.log(`[SQLitePatternStore] Using unified storage: ${this.unifiedMemory.getDbPath()}`);
|
|
15647
15647
|
} else {
|
|
15648
|
-
const
|
|
15649
|
-
const
|
|
15650
|
-
const dir =
|
|
15651
|
-
if (!
|
|
15652
|
-
|
|
15648
|
+
const path27 = await import("path");
|
|
15649
|
+
const fs25 = await import("fs");
|
|
15650
|
+
const dir = path27.dirname(this.config.dbPath);
|
|
15651
|
+
if (!fs25.existsSync(dir)) {
|
|
15652
|
+
fs25.mkdirSync(dir, { recursive: true });
|
|
15653
15653
|
}
|
|
15654
15654
|
this.db = openDatabase(this.config.dbPath);
|
|
15655
15655
|
this.db.pragma(`mmap_size = ${this.config.mmapSize}`);
|
|
@@ -16881,7 +16881,7 @@ __export(qe_reasoning_bank_exports, {
|
|
|
16881
16881
|
function createQEReasoningBank(memory, eventBus, config, coherenceService) {
|
|
16882
16882
|
return new QEReasoningBank(memory, eventBus, config, coherenceService);
|
|
16883
16883
|
}
|
|
16884
|
-
var
|
|
16884
|
+
var logger20, DEFAULT_QE_REASONING_BANK_CONFIG, QEReasoningBank;
|
|
16885
16885
|
var init_qe_reasoning_bank = __esm({
|
|
16886
16886
|
"src/learning/qe-reasoning-bank.ts"() {
|
|
16887
16887
|
"use strict";
|
|
@@ -16894,7 +16894,7 @@ var init_qe_reasoning_bank = __esm({
|
|
|
16894
16894
|
init_sqlite_persistence();
|
|
16895
16895
|
init_qe_patterns();
|
|
16896
16896
|
init_qe_guidance();
|
|
16897
|
-
|
|
16897
|
+
logger20 = LoggerFactory.create("QEReasoningBank");
|
|
16898
16898
|
DEFAULT_QE_REASONING_BANK_CONFIG = {
|
|
16899
16899
|
enableLearning: true,
|
|
16900
16900
|
enableGuidance: true,
|
|
@@ -16934,7 +16934,7 @@ var init_qe_reasoning_bank = __esm({
|
|
|
16934
16934
|
if (!this.sqliteStore) {
|
|
16935
16935
|
this.sqliteStore = createSQLitePatternStore();
|
|
16936
16936
|
this.sqliteStore.initialize().catch((e20) => {
|
|
16937
|
-
|
|
16937
|
+
logger20.warn("SQLitePatternStore init failed", { error: toErrorMessage(e20) });
|
|
16938
16938
|
});
|
|
16939
16939
|
}
|
|
16940
16940
|
return this.sqliteStore;
|
|
@@ -17015,7 +17015,7 @@ var init_qe_reasoning_bank = __esm({
|
|
|
17015
17015
|
await store.initialize();
|
|
17016
17016
|
this.patternStore.setSqliteStore(store);
|
|
17017
17017
|
} catch (e20) {
|
|
17018
|
-
|
|
17018
|
+
logger20.warn("Failed to wire SQLitePatternStore into PatternStore", { error: toErrorMessage(e20) });
|
|
17019
17019
|
}
|
|
17020
17020
|
await this.loadPretrainedPatterns();
|
|
17021
17021
|
this.initialized = true;
|
|
@@ -17027,12 +17027,12 @@ var init_qe_reasoning_bank = __esm({
|
|
|
17027
17027
|
await this.seedCrossDomainPatterns();
|
|
17028
17028
|
} else {
|
|
17029
17029
|
const stats = await this.patternStore.getStats();
|
|
17030
|
-
|
|
17030
|
+
logger20.info("Cross-domain transfer already complete", { totalPatterns: stats.totalPatterns });
|
|
17031
17031
|
}
|
|
17032
17032
|
} catch (error) {
|
|
17033
|
-
|
|
17033
|
+
logger20.warn("Cross-domain seeding failed (non-fatal)", { error });
|
|
17034
17034
|
}
|
|
17035
|
-
|
|
17035
|
+
logger20.info("Initialized");
|
|
17036
17036
|
}
|
|
17037
17037
|
/**
|
|
17038
17038
|
* Load pre-trained patterns for common QE scenarios
|
|
@@ -17040,7 +17040,7 @@ var init_qe_reasoning_bank = __esm({
|
|
|
17040
17040
|
async loadPretrainedPatterns() {
|
|
17041
17041
|
const stats = await this.patternStore.getStats();
|
|
17042
17042
|
if (stats.totalPatterns > 0) {
|
|
17043
|
-
|
|
17043
|
+
logger20.info("Found existing patterns", { totalPatterns: stats.totalPatterns });
|
|
17044
17044
|
return;
|
|
17045
17045
|
}
|
|
17046
17046
|
const foundationalPatterns = [
|
|
@@ -17758,10 +17758,10 @@ On promotion:
|
|
|
17758
17758
|
try {
|
|
17759
17759
|
await this.patternStore.create(options);
|
|
17760
17760
|
} catch (error) {
|
|
17761
|
-
|
|
17761
|
+
logger20.warn("Failed to load pattern", { name: options.name, error });
|
|
17762
17762
|
}
|
|
17763
17763
|
}
|
|
17764
|
-
|
|
17764
|
+
logger20.info("Loaded foundational patterns", { count: foundationalPatterns.length });
|
|
17765
17765
|
}
|
|
17766
17766
|
/**
|
|
17767
17767
|
* Seed cross-domain patterns by transferring generalizable patterns
|
|
@@ -17844,7 +17844,7 @@ On promotion:
|
|
|
17844
17844
|
}
|
|
17845
17845
|
}
|
|
17846
17846
|
}
|
|
17847
|
-
|
|
17847
|
+
logger20.info("Cross-domain transfer complete", { transferred, skipped });
|
|
17848
17848
|
return { transferred, skipped };
|
|
17849
17849
|
}
|
|
17850
17850
|
/**
|
|
@@ -17923,7 +17923,7 @@ On promotion:
|
|
|
17923
17923
|
outcome.feedback
|
|
17924
17924
|
);
|
|
17925
17925
|
} catch (persistError) {
|
|
17926
|
-
|
|
17926
|
+
logger20.warn("SQLite pattern usage persist failed", { error: toErrorMessage(persistError) });
|
|
17927
17927
|
}
|
|
17928
17928
|
if (result.success) {
|
|
17929
17929
|
this.stats.learningOutcomes++;
|
|
@@ -17933,7 +17933,7 @@ On promotion:
|
|
|
17933
17933
|
const pattern = await this.getPattern(outcome.patternId);
|
|
17934
17934
|
if (pattern && await this.checkPatternPromotionWithCoherence(pattern)) {
|
|
17935
17935
|
await this.promotePattern(outcome.patternId);
|
|
17936
|
-
|
|
17936
|
+
logger20.info("Pattern promoted to long-term", { name: pattern.name });
|
|
17937
17937
|
}
|
|
17938
17938
|
}
|
|
17939
17939
|
return result;
|
|
@@ -17980,7 +17980,7 @@ On promotion:
|
|
|
17980
17980
|
payload: event
|
|
17981
17981
|
});
|
|
17982
17982
|
}
|
|
17983
|
-
|
|
17983
|
+
logger20.info("Pattern promotion blocked due to coherence violation", {
|
|
17984
17984
|
name: pattern.name,
|
|
17985
17985
|
energy: coherenceResult.energy
|
|
17986
17986
|
});
|
|
@@ -18009,9 +18009,9 @@ On promotion:
|
|
|
18009
18009
|
try {
|
|
18010
18010
|
this.getSqliteStore().promotePattern(patternId);
|
|
18011
18011
|
} catch (e20) {
|
|
18012
|
-
|
|
18012
|
+
logger20.warn("SQLite pattern promotion persist failed", { error: toErrorMessage(e20) });
|
|
18013
18013
|
}
|
|
18014
|
-
|
|
18014
|
+
logger20.info("Promoted pattern to long-term", { patternId });
|
|
18015
18015
|
if (this.eventBus) {
|
|
18016
18016
|
await this.eventBus.publish({
|
|
18017
18017
|
id: `pattern-promoted-${patternId}`,
|
|
@@ -18022,7 +18022,7 @@ On promotion:
|
|
|
18022
18022
|
});
|
|
18023
18023
|
}
|
|
18024
18024
|
} else {
|
|
18025
|
-
|
|
18025
|
+
logger20.error("Failed to promote pattern", result.error, { patternId });
|
|
18026
18026
|
}
|
|
18027
18027
|
}
|
|
18028
18028
|
/**
|
|
@@ -18148,7 +18148,7 @@ On promotion:
|
|
|
18148
18148
|
return embedding;
|
|
18149
18149
|
} catch (error) {
|
|
18150
18150
|
if (process.env.DEBUG) {
|
|
18151
|
-
|
|
18151
|
+
logger20.warn("ONNX embeddings unavailable, using hash fallback", {
|
|
18152
18152
|
error: toErrorMessage(error)
|
|
18153
18153
|
});
|
|
18154
18154
|
}
|
|
@@ -33348,12 +33348,12 @@ var DeterministicGatewayIntegration = class {
|
|
|
33348
33348
|
/**
|
|
33349
33349
|
* Validate a single value against its schema
|
|
33350
33350
|
*/
|
|
33351
|
-
validateValue(value, schema,
|
|
33351
|
+
validateValue(value, schema, path27) {
|
|
33352
33352
|
const errors = [];
|
|
33353
33353
|
if (schema.required && (value === void 0 || value === null)) {
|
|
33354
33354
|
errors.push({
|
|
33355
|
-
path:
|
|
33356
|
-
message: `${
|
|
33355
|
+
path: path27,
|
|
33356
|
+
message: `${path27} is required`,
|
|
33357
33357
|
expected: schema.type,
|
|
33358
33358
|
received: "undefined"
|
|
33359
33359
|
});
|
|
@@ -33365,8 +33365,8 @@ var DeterministicGatewayIntegration = class {
|
|
|
33365
33365
|
const actualType = Array.isArray(value) ? "array" : typeof value;
|
|
33366
33366
|
if (actualType !== schema.type) {
|
|
33367
33367
|
errors.push({
|
|
33368
|
-
path:
|
|
33369
|
-
message: `${
|
|
33368
|
+
path: path27,
|
|
33369
|
+
message: `${path27} must be of type ${schema.type}`,
|
|
33370
33370
|
expected: schema.type,
|
|
33371
33371
|
received: actualType
|
|
33372
33372
|
});
|
|
@@ -33375,16 +33375,16 @@ var DeterministicGatewayIntegration = class {
|
|
|
33375
33375
|
if (schema.type === "string" && typeof value === "string") {
|
|
33376
33376
|
if (schema.minLength !== void 0 && value.length < schema.minLength) {
|
|
33377
33377
|
errors.push({
|
|
33378
|
-
path:
|
|
33379
|
-
message: `${
|
|
33378
|
+
path: path27,
|
|
33379
|
+
message: `${path27} must be at least ${schema.minLength} characters`,
|
|
33380
33380
|
expected: `minLength: ${schema.minLength}`,
|
|
33381
33381
|
received: `length: ${value.length}`
|
|
33382
33382
|
});
|
|
33383
33383
|
}
|
|
33384
33384
|
if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
|
|
33385
33385
|
errors.push({
|
|
33386
|
-
path:
|
|
33387
|
-
message: `${
|
|
33386
|
+
path: path27,
|
|
33387
|
+
message: `${path27} must be at most ${schema.maxLength} characters`,
|
|
33388
33388
|
expected: `maxLength: ${schema.maxLength}`,
|
|
33389
33389
|
received: `length: ${value.length}`
|
|
33390
33390
|
});
|
|
@@ -33392,8 +33392,8 @@ var DeterministicGatewayIntegration = class {
|
|
|
33392
33392
|
const patternRegex = schema.pattern ? createSafeRegex(schema.pattern) : null;
|
|
33393
33393
|
if (patternRegex && !patternRegex.test(value)) {
|
|
33394
33394
|
errors.push({
|
|
33395
|
-
path:
|
|
33396
|
-
message: `${
|
|
33395
|
+
path: path27,
|
|
33396
|
+
message: `${path27} must match pattern ${schema.pattern}`,
|
|
33397
33397
|
expected: `pattern: ${schema.pattern}`,
|
|
33398
33398
|
received: value
|
|
33399
33399
|
});
|
|
@@ -33402,16 +33402,16 @@ var DeterministicGatewayIntegration = class {
|
|
|
33402
33402
|
if (schema.type === "number" && typeof value === "number") {
|
|
33403
33403
|
if (schema.min !== void 0 && value < schema.min) {
|
|
33404
33404
|
errors.push({
|
|
33405
|
-
path:
|
|
33406
|
-
message: `${
|
|
33405
|
+
path: path27,
|
|
33406
|
+
message: `${path27} must be at least ${schema.min}`,
|
|
33407
33407
|
expected: `min: ${schema.min}`,
|
|
33408
33408
|
received: `${value}`
|
|
33409
33409
|
});
|
|
33410
33410
|
}
|
|
33411
33411
|
if (schema.max !== void 0 && value > schema.max) {
|
|
33412
33412
|
errors.push({
|
|
33413
|
-
path:
|
|
33414
|
-
message: `${
|
|
33413
|
+
path: path27,
|
|
33414
|
+
message: `${path27} must be at most ${schema.max}`,
|
|
33415
33415
|
expected: `max: ${schema.max}`,
|
|
33416
33416
|
received: `${value}`
|
|
33417
33417
|
});
|
|
@@ -33419,22 +33419,22 @@ var DeterministicGatewayIntegration = class {
|
|
|
33419
33419
|
}
|
|
33420
33420
|
if (schema.enum && !schema.enum.includes(value)) {
|
|
33421
33421
|
errors.push({
|
|
33422
|
-
path:
|
|
33423
|
-
message: `${
|
|
33422
|
+
path: path27,
|
|
33423
|
+
message: `${path27} must be one of: ${schema.enum.join(", ")}`,
|
|
33424
33424
|
expected: `enum: [${schema.enum.join(", ")}]`,
|
|
33425
33425
|
received: String(value)
|
|
33426
33426
|
});
|
|
33427
33427
|
}
|
|
33428
33428
|
if (schema.type === "array" && Array.isArray(value) && schema.items) {
|
|
33429
33429
|
value.forEach((item, index) => {
|
|
33430
|
-
const itemErrors = this.validateValue(item, schema.items, `${
|
|
33430
|
+
const itemErrors = this.validateValue(item, schema.items, `${path27}[${index}]`);
|
|
33431
33431
|
errors.push(...itemErrors);
|
|
33432
33432
|
});
|
|
33433
33433
|
}
|
|
33434
33434
|
if (schema.type === "object" && typeof value === "object" && schema.properties) {
|
|
33435
33435
|
const objValue = value;
|
|
33436
33436
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
33437
|
-
const propErrors = this.validateValue(objValue[propName], propSchema, `${
|
|
33437
|
+
const propErrors = this.validateValue(objValue[propName], propSchema, `${path27}.${propName}`);
|
|
33438
33438
|
errors.push(...propErrors);
|
|
33439
33439
|
}
|
|
33440
33440
|
}
|
|
@@ -44951,7 +44951,7 @@ Provide:
|
|
|
44951
44951
|
return err(new Error(`Test file not found: ${file}`));
|
|
44952
44952
|
}
|
|
44953
44953
|
const { command, args } = this.buildTestCommand(file, framework);
|
|
44954
|
-
return new Promise((
|
|
44954
|
+
return new Promise((resolve15) => {
|
|
44955
44955
|
let stdout = "";
|
|
44956
44956
|
let stderr = "";
|
|
44957
44957
|
let killed = false;
|
|
@@ -44968,7 +44968,7 @@ Provide:
|
|
|
44968
44968
|
const timeoutId = setTimeout(() => {
|
|
44969
44969
|
killed = true;
|
|
44970
44970
|
proc.kill("SIGTERM");
|
|
44971
|
-
|
|
44971
|
+
resolve15(err(new Error(`Test execution timed out after ${timeout}ms for file: ${file}`)));
|
|
44972
44972
|
}, timeout);
|
|
44973
44973
|
proc.stdout?.on("data", (data) => {
|
|
44974
44974
|
stdout += data.toString();
|
|
@@ -44982,11 +44982,11 @@ Provide:
|
|
|
44982
44982
|
return;
|
|
44983
44983
|
}
|
|
44984
44984
|
const parseResult = this.parseTestOutput(stdout, stderr, file, framework, code);
|
|
44985
|
-
|
|
44985
|
+
resolve15(parseResult);
|
|
44986
44986
|
});
|
|
44987
44987
|
proc.on("error", (error) => {
|
|
44988
44988
|
clearTimeout(timeoutId);
|
|
44989
|
-
|
|
44989
|
+
resolve15(err(new Error(`Failed to spawn test runner: ${error.message}. Is '${command}' installed?`)));
|
|
44990
44990
|
});
|
|
44991
44991
|
});
|
|
44992
44992
|
}
|
|
@@ -45573,7 +45573,7 @@ var FlakyDetectorService = class {
|
|
|
45573
45573
|
const results = /* @__PURE__ */ new Map();
|
|
45574
45574
|
const runId = v4_default();
|
|
45575
45575
|
const startTime = Date.now();
|
|
45576
|
-
return new Promise((
|
|
45576
|
+
return new Promise((resolve15, reject) => {
|
|
45577
45577
|
const args = [...this.config.testRunnerArgs, file];
|
|
45578
45578
|
const cwd = this.config.cwd ?? process.cwd();
|
|
45579
45579
|
const child = spawn2(this.config.testRunner, args, {
|
|
@@ -45638,7 +45638,7 @@ var FlakyDetectorService = class {
|
|
|
45638
45638
|
results.set(testId, records);
|
|
45639
45639
|
}
|
|
45640
45640
|
}
|
|
45641
|
-
|
|
45641
|
+
resolve15(results);
|
|
45642
45642
|
} catch (parseError) {
|
|
45643
45643
|
const testId = this.generateTestId(file, "main");
|
|
45644
45644
|
results.set(testId, [
|
|
@@ -45654,7 +45654,7 @@ var FlakyDetectorService = class {
|
|
|
45654
45654
|
}
|
|
45655
45655
|
}
|
|
45656
45656
|
]);
|
|
45657
|
-
|
|
45657
|
+
resolve15(results);
|
|
45658
45658
|
}
|
|
45659
45659
|
});
|
|
45660
45660
|
});
|
|
@@ -46529,7 +46529,7 @@ var RetryHandlerService = class {
|
|
|
46529
46529
|
* Spawn a test process and parse the result
|
|
46530
46530
|
*/
|
|
46531
46531
|
spawnTestProcess(command, args, cwd) {
|
|
46532
|
-
return new Promise((
|
|
46532
|
+
return new Promise((resolve15, reject) => {
|
|
46533
46533
|
const timeout = this.config.testTimeout;
|
|
46534
46534
|
let stdout = "";
|
|
46535
46535
|
let stderr = "";
|
|
@@ -46558,7 +46558,7 @@ var RetryHandlerService = class {
|
|
|
46558
46558
|
return;
|
|
46559
46559
|
}
|
|
46560
46560
|
const result = this.parseTestResult(code, stdout, stderr);
|
|
46561
|
-
|
|
46561
|
+
resolve15(result);
|
|
46562
46562
|
});
|
|
46563
46563
|
proc.on("error", (err3) => {
|
|
46564
46564
|
clearTimeout(timeoutHandle);
|
|
@@ -46647,7 +46647,7 @@ var RetryHandlerService = class {
|
|
|
46647
46647
|
return Math.min(delay, maxDelay);
|
|
46648
46648
|
}
|
|
46649
46649
|
sleep(ms) {
|
|
46650
|
-
return new Promise((
|
|
46650
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
46651
46651
|
}
|
|
46652
46652
|
async recordRetry(testId, result) {
|
|
46653
46653
|
const history = this.retryHistory.get(testId) ?? [];
|
|
@@ -47314,7 +47314,7 @@ var AgentBrowserCommandExecutor = class {
|
|
|
47314
47314
|
* Execute a command asynchronously (for long-running ops)
|
|
47315
47315
|
*/
|
|
47316
47316
|
async executeAsync(command, args = []) {
|
|
47317
|
-
return new Promise((
|
|
47317
|
+
return new Promise((resolve15) => {
|
|
47318
47318
|
const fullArgs = this.buildArgs(command, args);
|
|
47319
47319
|
if (this.config.debug) {
|
|
47320
47320
|
console.log(`[agent-browser] Executing async: npx agent-browser ${fullArgs.join(" ")}`);
|
|
@@ -47334,16 +47334,16 @@ var AgentBrowserCommandExecutor = class {
|
|
|
47334
47334
|
if (code === 0) {
|
|
47335
47335
|
try {
|
|
47336
47336
|
const parsed = safeJsonParse(stdout.trim());
|
|
47337
|
-
|
|
47337
|
+
resolve15({ success: true, data: parsed });
|
|
47338
47338
|
} catch {
|
|
47339
|
-
|
|
47339
|
+
resolve15({ success: true, data: stdout.trim() });
|
|
47340
47340
|
}
|
|
47341
47341
|
} else {
|
|
47342
|
-
|
|
47342
|
+
resolve15({ success: false, error: stderr || `Exit code: ${code}` });
|
|
47343
47343
|
}
|
|
47344
47344
|
});
|
|
47345
47345
|
process2.on("error", (error) => {
|
|
47346
|
-
|
|
47346
|
+
resolve15({ success: false, error: error.message });
|
|
47347
47347
|
});
|
|
47348
47348
|
});
|
|
47349
47349
|
}
|
|
@@ -47457,11 +47457,11 @@ var AgentBrowserCommandExecutor = class {
|
|
|
47457
47457
|
/**
|
|
47458
47458
|
* Take screenshot
|
|
47459
47459
|
*/
|
|
47460
|
-
screenshot(
|
|
47460
|
+
screenshot(path27, fullPage) {
|
|
47461
47461
|
const args = [];
|
|
47462
|
-
if (
|
|
47462
|
+
if (path27) args.push(path27);
|
|
47463
47463
|
if (fullPage) args.push("--full");
|
|
47464
|
-
if (!
|
|
47464
|
+
if (!path27) args.push("--json");
|
|
47465
47465
|
return this.execute("screenshot", args);
|
|
47466
47466
|
}
|
|
47467
47467
|
// ========================================================================
|
|
@@ -47539,14 +47539,14 @@ var AgentBrowserCommandExecutor = class {
|
|
|
47539
47539
|
/**
|
|
47540
47540
|
* Save browser state (cookies, storage)
|
|
47541
47541
|
*/
|
|
47542
|
-
saveState(
|
|
47543
|
-
return this.execute("state", ["save",
|
|
47542
|
+
saveState(path27) {
|
|
47543
|
+
return this.execute("state", ["save", path27]);
|
|
47544
47544
|
}
|
|
47545
47545
|
/**
|
|
47546
47546
|
* Load browser state
|
|
47547
47547
|
*/
|
|
47548
|
-
loadState(
|
|
47549
|
-
return this.execute("state", ["load",
|
|
47548
|
+
loadState(path27) {
|
|
47549
|
+
return this.execute("state", ["load", path27]);
|
|
47550
47550
|
}
|
|
47551
47551
|
// ========================================================================
|
|
47552
47552
|
// Trace recording
|
|
@@ -48823,9 +48823,9 @@ var AgentBrowserClient = class {
|
|
|
48823
48823
|
/**
|
|
48824
48824
|
* Save browser state (cookies, storage, etc.)
|
|
48825
48825
|
*/
|
|
48826
|
-
async saveState(
|
|
48826
|
+
async saveState(path27) {
|
|
48827
48827
|
try {
|
|
48828
|
-
const result = this.executor.saveState(
|
|
48828
|
+
const result = this.executor.saveState(path27);
|
|
48829
48829
|
if (!result.success) {
|
|
48830
48830
|
return err2(new BrowserError(result.error ?? "Save state failed", "SAVE_STATE_FAILED", "agent-browser"));
|
|
48831
48831
|
}
|
|
@@ -48844,9 +48844,9 @@ var AgentBrowserClient = class {
|
|
|
48844
48844
|
/**
|
|
48845
48845
|
* Load previously saved browser state
|
|
48846
48846
|
*/
|
|
48847
|
-
async loadState(
|
|
48847
|
+
async loadState(path27) {
|
|
48848
48848
|
try {
|
|
48849
|
-
const result = this.executor.loadState(
|
|
48849
|
+
const result = this.executor.loadState(path27);
|
|
48850
48850
|
if (!result.success) {
|
|
48851
48851
|
return err2(new BrowserError(result.error ?? "Load state failed", "LOAD_STATE_FAILED", "agent-browser"));
|
|
48852
48852
|
}
|
|
@@ -49220,10 +49220,10 @@ var BrowserOrchestrator = class {
|
|
|
49220
49220
|
useAgentBrowser;
|
|
49221
49221
|
config;
|
|
49222
49222
|
log;
|
|
49223
|
-
constructor(client, config,
|
|
49223
|
+
constructor(client, config, logger22) {
|
|
49224
49224
|
this.client = client;
|
|
49225
49225
|
this.config = config;
|
|
49226
|
-
this.log =
|
|
49226
|
+
this.log = logger22;
|
|
49227
49227
|
this.unifiedClient = config.browserClient ?? client;
|
|
49228
49228
|
this.useAgentBrowser = isAgentBrowserClient(this.unifiedClient);
|
|
49229
49229
|
}
|
|
@@ -49414,17 +49414,17 @@ var BrowserOrchestrator = class {
|
|
|
49414
49414
|
return options;
|
|
49415
49415
|
}
|
|
49416
49416
|
};
|
|
49417
|
-
function createBrowserOrchestrator(client, config,
|
|
49418
|
-
return new BrowserOrchestrator(client, config,
|
|
49417
|
+
function createBrowserOrchestrator(client, config, logger22) {
|
|
49418
|
+
return new BrowserOrchestrator(client, config, logger22);
|
|
49419
49419
|
}
|
|
49420
49420
|
|
|
49421
49421
|
// src/domains/test-execution/services/e2e/assertion-handlers.ts
|
|
49422
49422
|
var AssertionHandlers = class {
|
|
49423
49423
|
orchestrator;
|
|
49424
49424
|
log;
|
|
49425
|
-
constructor(orchestrator,
|
|
49425
|
+
constructor(orchestrator, logger22) {
|
|
49426
49426
|
this.orchestrator = orchestrator;
|
|
49427
|
-
this.log =
|
|
49427
|
+
this.log = logger22;
|
|
49428
49428
|
}
|
|
49429
49429
|
// ==========================================================================
|
|
49430
49430
|
// Unified Browser Client Assertions
|
|
@@ -49837,8 +49837,8 @@ var AssertionHandlers = class {
|
|
|
49837
49837
|
this.assertCondition(matches, step, expected, actual);
|
|
49838
49838
|
}
|
|
49839
49839
|
};
|
|
49840
|
-
function createAssertionHandlers(orchestrator,
|
|
49841
|
-
return new AssertionHandlers(orchestrator,
|
|
49840
|
+
function createAssertionHandlers(orchestrator, logger22) {
|
|
49841
|
+
return new AssertionHandlers(orchestrator, logger22);
|
|
49842
49842
|
}
|
|
49843
49843
|
|
|
49844
49844
|
// src/domains/test-execution/services/e2e/wait-condition-handler.ts
|
|
@@ -49936,7 +49936,7 @@ var WaitConditionHandler = class {
|
|
|
49936
49936
|
* Delay execution
|
|
49937
49937
|
*/
|
|
49938
49938
|
delay(ms) {
|
|
49939
|
-
return new Promise((
|
|
49939
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
49940
49940
|
}
|
|
49941
49941
|
};
|
|
49942
49942
|
function createWaitConditionHandler(orchestrator) {
|
|
@@ -49951,12 +49951,12 @@ var StepExecutors = class {
|
|
|
49951
49951
|
assertionHandlers;
|
|
49952
49952
|
waitConditionHandler;
|
|
49953
49953
|
log;
|
|
49954
|
-
constructor(config, orchestrator,
|
|
49954
|
+
constructor(config, orchestrator, logger22) {
|
|
49955
49955
|
this.config = config;
|
|
49956
49956
|
this.orchestrator = orchestrator;
|
|
49957
|
-
this.assertionHandlers = createAssertionHandlers(orchestrator,
|
|
49957
|
+
this.assertionHandlers = createAssertionHandlers(orchestrator, logger22);
|
|
49958
49958
|
this.waitConditionHandler = createWaitConditionHandler(orchestrator);
|
|
49959
|
-
this.log =
|
|
49959
|
+
this.log = logger22;
|
|
49960
49960
|
}
|
|
49961
49961
|
/**
|
|
49962
49962
|
* Execute a single step based on its type
|
|
@@ -50361,11 +50361,11 @@ var StepExecutors = class {
|
|
|
50361
50361
|
return new URL(url, baseUrl).toString();
|
|
50362
50362
|
}
|
|
50363
50363
|
delay(ms) {
|
|
50364
|
-
return new Promise((
|
|
50364
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
50365
50365
|
}
|
|
50366
50366
|
};
|
|
50367
|
-
function createStepExecutors(config, orchestrator,
|
|
50368
|
-
return new StepExecutors(config, orchestrator,
|
|
50367
|
+
function createStepExecutors(config, orchestrator, logger22) {
|
|
50368
|
+
return new StepExecutors(config, orchestrator, logger22);
|
|
50369
50369
|
}
|
|
50370
50370
|
|
|
50371
50371
|
// src/shared/utils/safe-expression-evaluator.ts
|
|
@@ -50678,10 +50678,10 @@ var StepRetryHandler = class {
|
|
|
50678
50678
|
config;
|
|
50679
50679
|
stepExecutors;
|
|
50680
50680
|
log;
|
|
50681
|
-
constructor(config, stepExecutors,
|
|
50681
|
+
constructor(config, stepExecutors, logger22) {
|
|
50682
50682
|
this.config = config;
|
|
50683
50683
|
this.stepExecutors = stepExecutors;
|
|
50684
|
-
this.log =
|
|
50684
|
+
this.log = logger22;
|
|
50685
50685
|
}
|
|
50686
50686
|
/**
|
|
50687
50687
|
* Execute a step with retry logic
|
|
@@ -50771,13 +50771,13 @@ var StepRetryHandler = class {
|
|
|
50771
50771
|
* Wrap promise with timeout
|
|
50772
50772
|
*/
|
|
50773
50773
|
async withTimeout(promise, timeout, stepId) {
|
|
50774
|
-
return new Promise((
|
|
50774
|
+
return new Promise((resolve15, reject) => {
|
|
50775
50775
|
const timer = setTimeout(() => {
|
|
50776
50776
|
reject(new StepTimeoutError(stepId, timeout));
|
|
50777
50777
|
}, timeout);
|
|
50778
50778
|
promise.then((result) => {
|
|
50779
50779
|
clearTimeout(timer);
|
|
50780
|
-
|
|
50780
|
+
resolve15(result);
|
|
50781
50781
|
}).catch((error) => {
|
|
50782
50782
|
clearTimeout(timer);
|
|
50783
50783
|
reject(error);
|
|
@@ -50788,11 +50788,11 @@ var StepRetryHandler = class {
|
|
|
50788
50788
|
* Delay execution
|
|
50789
50789
|
*/
|
|
50790
50790
|
delay(ms) {
|
|
50791
|
-
return new Promise((
|
|
50791
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
50792
50792
|
}
|
|
50793
50793
|
};
|
|
50794
|
-
function createStepRetryHandler(config, stepExecutors,
|
|
50795
|
-
return new StepRetryHandler(config, stepExecutors,
|
|
50794
|
+
function createStepRetryHandler(config, stepExecutors, logger22) {
|
|
50795
|
+
return new StepRetryHandler(config, stepExecutors, logger22);
|
|
50796
50796
|
}
|
|
50797
50797
|
|
|
50798
50798
|
// src/domains/test-execution/services/e2e/result-collector.ts
|
|
@@ -50918,10 +50918,10 @@ var E2ETestRunnerService = class {
|
|
|
50918
50918
|
constructor(client, config = {}) {
|
|
50919
50919
|
this.client = client;
|
|
50920
50920
|
this.config = { ...DEFAULT_E2E_RUNNER_CONFIG, ...config };
|
|
50921
|
-
const
|
|
50922
|
-
this.orchestrator = createBrowserOrchestrator(client, this.config,
|
|
50923
|
-
this.stepExecutors = createStepExecutors(this.config, this.orchestrator,
|
|
50924
|
-
this.retryHandler = createStepRetryHandler(this.config, this.stepExecutors,
|
|
50921
|
+
const logger22 = (message) => this.log(message);
|
|
50922
|
+
this.orchestrator = createBrowserOrchestrator(client, this.config, logger22);
|
|
50923
|
+
this.stepExecutors = createStepExecutors(this.config, this.orchestrator, logger22);
|
|
50924
|
+
this.retryHandler = createStepRetryHandler(this.config, this.stepExecutors, logger22);
|
|
50925
50925
|
this.resultCollector = createResultCollector();
|
|
50926
50926
|
this.log(
|
|
50927
50927
|
`E2E Runner initialized with ${this.orchestrator.isUsingAgentBrowser() ? "agent-browser" : "vibium"} client`
|
|
@@ -51133,7 +51133,7 @@ var E2ETestRunnerService = class {
|
|
|
51133
51133
|
* Delay execution
|
|
51134
51134
|
*/
|
|
51135
51135
|
delay(ms) {
|
|
51136
|
-
return new Promise((
|
|
51136
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
51137
51137
|
}
|
|
51138
51138
|
/**
|
|
51139
51139
|
* Log message if verbose mode is enabled
|
|
@@ -54095,16 +54095,16 @@ var CoverageEmbedder = class {
|
|
|
54095
54095
|
const idealRegions = Math.ceil(coverage.uncoveredLines.length / 5);
|
|
54096
54096
|
return regions > 0 ? Math.min(1, idealRegions / regions) : 0;
|
|
54097
54097
|
}
|
|
54098
|
-
extractPathFeatures(
|
|
54099
|
-
const parts =
|
|
54100
|
-
const extension =
|
|
54098
|
+
extractPathFeatures(path27) {
|
|
54099
|
+
const parts = path27.split("/").filter(Boolean);
|
|
54100
|
+
const extension = path27.split(".").pop() || "";
|
|
54101
54101
|
const fileName = parts[parts.length - 1] || "";
|
|
54102
54102
|
return {
|
|
54103
54103
|
depth: parts.length,
|
|
54104
54104
|
extension,
|
|
54105
|
-
hashNormalized: this.hashString(
|
|
54106
|
-
isTest: /\.(test|spec)\.(ts|js|tsx|jsx)$/.test(
|
|
54107
|
-
isConfig: /\.(config|rc)\.(ts|js|json|yaml|yml)$/.test(
|
|
54105
|
+
hashNormalized: this.hashString(path27) / 1e6,
|
|
54106
|
+
isTest: /\.(test|spec)\.(ts|js|tsx|jsx)$/.test(path27) || parts.includes("tests") || parts.includes("__tests__"),
|
|
54107
|
+
isConfig: /\.(config|rc)\.(ts|js|json|yaml|yml)$/.test(path27),
|
|
54108
54108
|
isIndex: fileName.startsWith("index."),
|
|
54109
54109
|
inSrc: parts.includes("src"),
|
|
54110
54110
|
inLib: parts.includes("lib"),
|
|
@@ -54422,12 +54422,12 @@ var GhostCoverageAnalyzerService = class _GhostCoverageAnalyzerService {
|
|
|
54422
54422
|
ratio(n61, d74) {
|
|
54423
54423
|
return d74 > 0 ? n61 / d74 : 0;
|
|
54424
54424
|
}
|
|
54425
|
-
gapId(
|
|
54426
|
-
const h66 = `${
|
|
54425
|
+
gapId(path27, cat) {
|
|
54426
|
+
const h66 = `${path27}:${cat}`.split("").reduce((a37, c70) => (a37 << 5) - a37 + c70.charCodeAt(0) | 0, 0);
|
|
54427
54427
|
return `phantom-${Math.abs(h66).toString(16)}`;
|
|
54428
54428
|
}
|
|
54429
|
-
gapDescription(
|
|
54430
|
-
const n61 =
|
|
54429
|
+
gapDescription(path27, cat, dist) {
|
|
54430
|
+
const n61 = path27.split("/").pop() || path27;
|
|
54431
54431
|
const s70 = dist > 0.7 ? "significant" : dist > 0.4 ? "moderate" : "minor";
|
|
54432
54432
|
const m74 = {
|
|
54433
54433
|
"missing-error-handler": `${n61}: ${s70} missing error handler tests. Cover error paths and failure recovery.`,
|
|
@@ -57474,10 +57474,10 @@ ${codeContext.slice(0, 2e3)}
|
|
|
57474
57474
|
const coverage = await this.memory.get(key);
|
|
57475
57475
|
return coverage ?? null;
|
|
57476
57476
|
}
|
|
57477
|
-
hashFilePath(
|
|
57477
|
+
hashFilePath(path27) {
|
|
57478
57478
|
let hash = 0;
|
|
57479
|
-
for (let i58 = 0; i58 <
|
|
57480
|
-
hash = (hash << 5) - hash +
|
|
57479
|
+
for (let i58 = 0; i58 < path27.length; i58++) {
|
|
57480
|
+
hash = (hash << 5) - hash + path27.charCodeAt(i58);
|
|
57481
57481
|
hash = hash & hash;
|
|
57482
57482
|
}
|
|
57483
57483
|
return hash.toString(16);
|
|
@@ -71227,7 +71227,7 @@ var ImpactAnalyzerService = class {
|
|
|
71227
71227
|
// ============================================================================
|
|
71228
71228
|
// Private Helper Methods
|
|
71229
71229
|
// ============================================================================
|
|
71230
|
-
isTestFile(
|
|
71230
|
+
isTestFile(path27) {
|
|
71231
71231
|
const testPatterns = [
|
|
71232
71232
|
/\.test\.[tj]sx?$/,
|
|
71233
71233
|
/\.spec\.[tj]sx?$/,
|
|
@@ -71236,15 +71236,15 @@ var ImpactAnalyzerService = class {
|
|
|
71236
71236
|
/.*_test\.py$/,
|
|
71237
71237
|
/.*_test\.go$/
|
|
71238
71238
|
];
|
|
71239
|
-
return testPatterns.some((pattern) => pattern.test(
|
|
71239
|
+
return testPatterns.some((pattern) => pattern.test(path27));
|
|
71240
71240
|
}
|
|
71241
|
-
isCriticalPath(
|
|
71241
|
+
isCriticalPath(path27) {
|
|
71242
71242
|
const criticalPatterns = this.config.criticalPaths.map(
|
|
71243
71243
|
(p74) => p74.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*")
|
|
71244
71244
|
);
|
|
71245
|
-
return criticalPatterns.some((pattern) => new RegExp(pattern).test(
|
|
71245
|
+
return criticalPatterns.some((pattern) => new RegExp(pattern).test(path27));
|
|
71246
71246
|
}
|
|
71247
|
-
isEntryPoint(
|
|
71247
|
+
isEntryPoint(path27) {
|
|
71248
71248
|
const entryPatterns = [
|
|
71249
71249
|
/\/index\.[tj]sx?$/,
|
|
71250
71250
|
/\/main\.[tj]sx?$/,
|
|
@@ -71254,14 +71254,14 @@ var ImpactAnalyzerService = class {
|
|
|
71254
71254
|
/\/__init__\.py$/,
|
|
71255
71255
|
/\/main\.go$/
|
|
71256
71256
|
];
|
|
71257
|
-
return entryPatterns.some((pattern) => pattern.test(
|
|
71257
|
+
return entryPatterns.some((pattern) => pattern.test(path27));
|
|
71258
71258
|
}
|
|
71259
|
-
getBaseName(
|
|
71260
|
-
const fileName = this.getFileName(
|
|
71259
|
+
getBaseName(path27) {
|
|
71260
|
+
const fileName = this.getFileName(path27);
|
|
71261
71261
|
return fileName.replace(/\.[^.]+$/, "");
|
|
71262
71262
|
}
|
|
71263
|
-
getFileName(
|
|
71264
|
-
return
|
|
71263
|
+
getFileName(path27) {
|
|
71264
|
+
return path27.split(/[/\\]/).pop() || path27;
|
|
71265
71265
|
}
|
|
71266
71266
|
deduplicateImpact(impact) {
|
|
71267
71267
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -72041,10 +72041,10 @@ function countTestsByFilePattern(projectPath, config) {
|
|
|
72041
72041
|
fileTests = countTestsInGoFile(fullPath);
|
|
72042
72042
|
}
|
|
72043
72043
|
total += fileTests;
|
|
72044
|
-
const
|
|
72045
|
-
if (
|
|
72044
|
+
const path27 = fullPath.toLowerCase();
|
|
72045
|
+
if (path27.includes("e2e") || path27.includes("end-to-end")) {
|
|
72046
72046
|
e2e += fileTests;
|
|
72047
|
-
} else if (
|
|
72047
|
+
} else if (path27.includes("integration")) {
|
|
72048
72048
|
integration += fileTests;
|
|
72049
72049
|
} else {
|
|
72050
72050
|
unit += fileTests;
|
|
@@ -72867,7 +72867,7 @@ var HypergraphEngine = class {
|
|
|
72867
72867
|
];
|
|
72868
72868
|
const effectiveMaxDepth = Math.min(maxDepth, this.config.maxTraversalDepth);
|
|
72869
72869
|
while (queue.length > 0) {
|
|
72870
|
-
const { nodeId, depth, path:
|
|
72870
|
+
const { nodeId, depth, path: path27 } = queue.shift();
|
|
72871
72871
|
if (!visitedNodes.has(nodeId)) {
|
|
72872
72872
|
const node = await this.getNode(nodeId);
|
|
72873
72873
|
if (node) {
|
|
@@ -72876,7 +72876,7 @@ var HypergraphEngine = class {
|
|
|
72876
72876
|
}
|
|
72877
72877
|
maxDepthReached = Math.max(maxDepthReached, depth);
|
|
72878
72878
|
if (depth >= effectiveMaxDepth) {
|
|
72879
|
-
paths.push(
|
|
72879
|
+
paths.push(path27);
|
|
72880
72880
|
continue;
|
|
72881
72881
|
}
|
|
72882
72882
|
const edgeCriteria = { sourceId: nodeId };
|
|
@@ -72885,15 +72885,15 @@ var HypergraphEngine = class {
|
|
|
72885
72885
|
}
|
|
72886
72886
|
const edges = await this.findEdges(edgeCriteria);
|
|
72887
72887
|
if (edges.length === 0) {
|
|
72888
|
-
paths.push(
|
|
72888
|
+
paths.push(path27);
|
|
72889
72889
|
continue;
|
|
72890
72890
|
}
|
|
72891
72891
|
for (const edge of edges) {
|
|
72892
72892
|
if (!visitedEdges.has(edge.id)) {
|
|
72893
72893
|
visitedEdges.set(edge.id, edge);
|
|
72894
72894
|
const newPath = {
|
|
72895
|
-
nodes: [...
|
|
72896
|
-
edges: [...
|
|
72895
|
+
nodes: [...path27.nodes, edge.targetId],
|
|
72896
|
+
edges: [...path27.edges, edge.id]
|
|
72897
72897
|
};
|
|
72898
72898
|
queue.push({
|
|
72899
72899
|
nodeId: edge.targetId,
|
|
@@ -73274,11 +73274,11 @@ async function createHypergraphEngine(config) {
|
|
|
73274
73274
|
init_wrappers();
|
|
73275
73275
|
async function indexCodeEmbeddings(gnnIndex, fileReader, paths) {
|
|
73276
73276
|
try {
|
|
73277
|
-
for (const
|
|
73277
|
+
for (const path27 of paths) {
|
|
73278
73278
|
try {
|
|
73279
|
-
const result = await fileReader.readFile(
|
|
73279
|
+
const result = await fileReader.readFile(path27);
|
|
73280
73280
|
if (result.success && result.value) {
|
|
73281
|
-
const embedding = await generateCodeEmbedding(
|
|
73281
|
+
const embedding = await generateCodeEmbedding(path27, result.value);
|
|
73282
73282
|
const embeddingObj = {
|
|
73283
73283
|
vector: embedding,
|
|
73284
73284
|
dimension: 384,
|
|
@@ -73286,12 +73286,12 @@ async function indexCodeEmbeddings(gnnIndex, fileReader, paths) {
|
|
|
73286
73286
|
text: result.value.slice(0, 1e3),
|
|
73287
73287
|
timestamp: Date.now(),
|
|
73288
73288
|
quantization: "none",
|
|
73289
|
-
metadata: { path:
|
|
73289
|
+
metadata: { path: path27 }
|
|
73290
73290
|
};
|
|
73291
73291
|
gnnIndex.addEmbedding(embeddingObj);
|
|
73292
73292
|
}
|
|
73293
73293
|
} catch (error) {
|
|
73294
|
-
console.error(`Failed to index ${
|
|
73294
|
+
console.error(`Failed to index ${path27}:`, error);
|
|
73295
73295
|
}
|
|
73296
73296
|
}
|
|
73297
73297
|
console.log(`[GNN] Indexed ${paths.length} code embeddings`);
|
|
@@ -73299,9 +73299,9 @@ async function indexCodeEmbeddings(gnnIndex, fileReader, paths) {
|
|
|
73299
73299
|
console.error("Failed to index code embeddings:", error);
|
|
73300
73300
|
}
|
|
73301
73301
|
}
|
|
73302
|
-
async function generateCodeEmbedding(
|
|
73302
|
+
async function generateCodeEmbedding(path27, content) {
|
|
73303
73303
|
const features = [];
|
|
73304
|
-
const ext =
|
|
73304
|
+
const ext = path27.split(".").pop();
|
|
73305
73305
|
const typeHash = hashCode(ext || "");
|
|
73306
73306
|
features.push(typeHash % 1e3 / 1e3);
|
|
73307
73307
|
features.push(Math.min(1, content.length / 1e4));
|
|
@@ -73722,14 +73722,14 @@ var CodeIntelligenceCoordinator = class extends BaseDomainCoordinator {
|
|
|
73722
73722
|
async initializeHypergraph() {
|
|
73723
73723
|
try {
|
|
73724
73724
|
const { openDatabase: openDatabase2 } = await Promise.resolve().then(() => (init_safe_db(), safe_db_exports));
|
|
73725
|
-
const
|
|
73726
|
-
const
|
|
73725
|
+
const fs25 = await import("fs");
|
|
73726
|
+
const path27 = await import("path");
|
|
73727
73727
|
const { findProjectRoot: findProjectRoot2 } = await Promise.resolve().then(() => (init_unified_memory(), unified_memory_exports));
|
|
73728
73728
|
const projectRoot = findProjectRoot2();
|
|
73729
|
-
const dbPath = this.config.hypergraphDbPath ||
|
|
73730
|
-
const dir =
|
|
73731
|
-
if (!
|
|
73732
|
-
|
|
73729
|
+
const dbPath = this.config.hypergraphDbPath || path27.join(projectRoot, ".agentic-qe", "hypergraph.db");
|
|
73730
|
+
const dir = path27.dirname(dbPath);
|
|
73731
|
+
if (!fs25.existsSync(dir)) {
|
|
73732
|
+
fs25.mkdirSync(dir, { recursive: true });
|
|
73733
73733
|
}
|
|
73734
73734
|
this.hypergraphDb = openDatabase2(dbPath);
|
|
73735
73735
|
this.hypergraph = await createHypergraphEngine({
|
|
@@ -74257,11 +74257,11 @@ var CodeIntelligenceCoordinator = class extends BaseDomainCoordinator {
|
|
|
74257
74257
|
// ============================================================================
|
|
74258
74258
|
async indexForSemanticSearch(paths) {
|
|
74259
74259
|
const filesToIndex = paths.slice(0, 100);
|
|
74260
|
-
for (const
|
|
74260
|
+
for (const path27 of filesToIndex) {
|
|
74261
74261
|
try {
|
|
74262
|
-
const result = await this.fileReader.readFile(
|
|
74262
|
+
const result = await this.fileReader.readFile(path27);
|
|
74263
74263
|
if (result.success && result.value) {
|
|
74264
|
-
await this.semanticAnalyzer.indexCode(
|
|
74264
|
+
await this.semanticAnalyzer.indexCode(path27, result.value);
|
|
74265
74265
|
}
|
|
74266
74266
|
} catch {
|
|
74267
74267
|
}
|
|
@@ -74469,8 +74469,8 @@ var CodeIntelligenceCoordinator = class extends BaseDomainCoordinator {
|
|
|
74469
74469
|
for (const marker of markers) {
|
|
74470
74470
|
try {
|
|
74471
74471
|
const markerPath = `${currentPath}/${marker}`;
|
|
74472
|
-
const
|
|
74473
|
-
if (
|
|
74472
|
+
const fs25 = __require("fs");
|
|
74473
|
+
if (fs25.existsSync(markerPath)) {
|
|
74474
74474
|
return currentPath;
|
|
74475
74475
|
}
|
|
74476
74476
|
} catch {
|
|
@@ -74975,8 +74975,8 @@ var FilePath = class _FilePath {
|
|
|
74975
74975
|
equals(other) {
|
|
74976
74976
|
return this._value === other._value;
|
|
74977
74977
|
}
|
|
74978
|
-
static create(
|
|
74979
|
-
return new _FilePath(
|
|
74978
|
+
static create(path27) {
|
|
74979
|
+
return new _FilePath(path27);
|
|
74980
74980
|
}
|
|
74981
74981
|
};
|
|
74982
74982
|
var RiskScore = class _RiskScore {
|
|
@@ -75714,8 +75714,8 @@ var SASTScanner = class {
|
|
|
75714
75714
|
let content;
|
|
75715
75715
|
let lines;
|
|
75716
75716
|
try {
|
|
75717
|
-
const
|
|
75718
|
-
content = await
|
|
75717
|
+
const fs25 = await import("fs/promises");
|
|
75718
|
+
content = await fs25.readFile(filePath, "utf-8");
|
|
75719
75719
|
lines = content.split("\n");
|
|
75720
75720
|
} catch {
|
|
75721
75721
|
return { vulnerabilities: [], linesScanned: 0 };
|
|
@@ -76405,10 +76405,10 @@ async function extractAndCrawlLinks(html, baseUrl, currentCrawled, maxDepth, vul
|
|
|
76405
76405
|
}
|
|
76406
76406
|
}
|
|
76407
76407
|
const linksToCrawl = Array.from(discoveredLinks).slice(0, Math.min(10, maxCrawl - crawledUrls));
|
|
76408
|
-
for (const
|
|
76408
|
+
for (const path27 of linksToCrawl) {
|
|
76409
76409
|
if (crawledUrls >= maxCrawl) break;
|
|
76410
76410
|
try {
|
|
76411
|
-
const crawlUrl = new URL(
|
|
76411
|
+
const crawlUrl = new URL(path27, baseUrl.origin).toString();
|
|
76412
76412
|
const crawlResponse = await fetch(crawlUrl, {
|
|
76413
76413
|
method: "GET",
|
|
76414
76414
|
headers: { "User-Agent": "AgenticQE-DAST-Scanner/3.0" },
|
|
@@ -76417,11 +76417,11 @@ async function extractAndCrawlLinks(html, baseUrl, currentCrawled, maxDepth, vul
|
|
|
76417
76417
|
});
|
|
76418
76418
|
crawledUrls++;
|
|
76419
76419
|
if (crawlResponse.ok) {
|
|
76420
|
-
if (
|
|
76420
|
+
if (path27.includes("password") || path27.includes("token") || path27.includes("api_key")) {
|
|
76421
76421
|
vulnerabilities.push({
|
|
76422
76422
|
id: v4_default(),
|
|
76423
76423
|
title: "Sensitive Data in URL Path",
|
|
76424
|
-
description: `URL path may contain sensitive parameter names: ${
|
|
76424
|
+
description: `URL path may contain sensitive parameter names: ${path27}`,
|
|
76425
76425
|
severity: "medium",
|
|
76426
76426
|
category: "sensitive-data",
|
|
76427
76427
|
location: { file: crawlUrl },
|
|
@@ -77117,7 +77117,7 @@ var HttpClient = class {
|
|
|
77117
77117
|
* Sleep utility for retry delays
|
|
77118
77118
|
*/
|
|
77119
77119
|
sleep(ms) {
|
|
77120
|
-
return new Promise((
|
|
77120
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
77121
77121
|
}
|
|
77122
77122
|
};
|
|
77123
77123
|
function createHttpClient() {
|
|
@@ -77930,8 +77930,8 @@ var DependencyScanner = class {
|
|
|
77930
77930
|
*/
|
|
77931
77931
|
async scanPackageJson(packageJsonPath) {
|
|
77932
77932
|
try {
|
|
77933
|
-
const
|
|
77934
|
-
const content = await
|
|
77933
|
+
const fs25 = await import("fs/promises");
|
|
77934
|
+
const content = await fs25.readFile(packageJsonPath, "utf-8");
|
|
77935
77935
|
const packageJson = safeJsonParse(content);
|
|
77936
77936
|
const allDependencies = {
|
|
77937
77937
|
...packageJson.dependencies || {},
|
|
@@ -82247,17 +82247,17 @@ Provide:
|
|
|
82247
82247
|
warnings.push("No consumers defined for contract");
|
|
82248
82248
|
}
|
|
82249
82249
|
}
|
|
82250
|
-
validateServiceInfo(info,
|
|
82250
|
+
validateServiceInfo(info, path27, errors) {
|
|
82251
82251
|
if (!info.name || info.name.trim() === "") {
|
|
82252
82252
|
errors.push({
|
|
82253
|
-
path: `${
|
|
82253
|
+
path: `${path27}.name`,
|
|
82254
82254
|
message: "Service name is required",
|
|
82255
82255
|
code: "REQUIRED_FIELD"
|
|
82256
82256
|
});
|
|
82257
82257
|
}
|
|
82258
82258
|
if (!info.version || info.version.trim() === "") {
|
|
82259
82259
|
errors.push({
|
|
82260
|
-
path: `${
|
|
82260
|
+
path: `${path27}.version`,
|
|
82261
82261
|
message: "Service version is required",
|
|
82262
82262
|
code: "REQUIRED_FIELD"
|
|
82263
82263
|
});
|
|
@@ -82903,13 +82903,13 @@ Provide:
|
|
|
82903
82903
|
/**
|
|
82904
82904
|
* Validate nested field selections
|
|
82905
82905
|
*/
|
|
82906
|
-
validateGraphQLSelections(selections, typeName, schemaInfo,
|
|
82906
|
+
validateGraphQLSelections(selections, typeName, schemaInfo, path27, errors) {
|
|
82907
82907
|
const typeDef = schemaInfo.types[typeName];
|
|
82908
82908
|
if (!typeDef) {
|
|
82909
82909
|
if (["String", "Int", "Float", "Boolean", "ID"].includes(typeName)) {
|
|
82910
82910
|
if (selections.length > 0) {
|
|
82911
82911
|
errors.push({
|
|
82912
|
-
path:
|
|
82912
|
+
path: path27,
|
|
82913
82913
|
keyword: "selection",
|
|
82914
82914
|
message: `Cannot select fields on scalar type '${typeName}'`,
|
|
82915
82915
|
params: { type: typeName }
|
|
@@ -82922,7 +82922,7 @@ Provide:
|
|
|
82922
82922
|
const fieldDef = typeDef.fields[selection.name];
|
|
82923
82923
|
if (!fieldDef) {
|
|
82924
82924
|
errors.push({
|
|
82925
|
-
path: `${
|
|
82925
|
+
path: `${path27}.${selection.name}`,
|
|
82926
82926
|
keyword: "field",
|
|
82927
82927
|
message: `Field '${selection.name}' does not exist on type '${typeName}'`,
|
|
82928
82928
|
params: { field: selection.name, type: typeName }
|
|
@@ -82933,7 +82933,7 @@ Provide:
|
|
|
82933
82933
|
selection.selections,
|
|
82934
82934
|
nestedType,
|
|
82935
82935
|
schemaInfo,
|
|
82936
|
-
`${
|
|
82936
|
+
`${path27}.${selection.name}`,
|
|
82937
82937
|
errors
|
|
82938
82938
|
);
|
|
82939
82939
|
}
|
|
@@ -82942,14 +82942,14 @@ Provide:
|
|
|
82942
82942
|
/**
|
|
82943
82943
|
* Validate variable type matches expected GraphQL type
|
|
82944
82944
|
*/
|
|
82945
|
-
validateGraphQLVariableType(value, expectedType,
|
|
82945
|
+
validateGraphQLVariableType(value, expectedType, path27, errors) {
|
|
82946
82946
|
const baseType = this.unwrapGraphQLType(expectedType);
|
|
82947
82947
|
const isNonNull = expectedType.endsWith("!");
|
|
82948
82948
|
const isList = expectedType.includes("[");
|
|
82949
82949
|
if (value === null || value === void 0) {
|
|
82950
82950
|
if (isNonNull) {
|
|
82951
82951
|
errors.push({
|
|
82952
|
-
path:
|
|
82952
|
+
path: path27,
|
|
82953
82953
|
keyword: "type",
|
|
82954
82954
|
message: `Variable cannot be null (expected ${expectedType})`,
|
|
82955
82955
|
params: { expectedType }
|
|
@@ -82960,7 +82960,7 @@ Provide:
|
|
|
82960
82960
|
if (isList) {
|
|
82961
82961
|
if (!Array.isArray(value)) {
|
|
82962
82962
|
errors.push({
|
|
82963
|
-
path:
|
|
82963
|
+
path: path27,
|
|
82964
82964
|
keyword: "type",
|
|
82965
82965
|
message: `Expected array for type ${expectedType}`,
|
|
82966
82966
|
params: { expectedType, actualType: typeof value }
|
|
@@ -82973,7 +82973,7 @@ Provide:
|
|
|
82973
82973
|
case "ID":
|
|
82974
82974
|
if (typeof value !== "string") {
|
|
82975
82975
|
errors.push({
|
|
82976
|
-
path:
|
|
82976
|
+
path: path27,
|
|
82977
82977
|
keyword: "type",
|
|
82978
82978
|
message: `Expected string for type ${baseType}`,
|
|
82979
82979
|
params: { expectedType: baseType, actualType: typeof value }
|
|
@@ -82983,7 +82983,7 @@ Provide:
|
|
|
82983
82983
|
case "Int":
|
|
82984
82984
|
if (typeof value !== "number" || !Number.isInteger(value)) {
|
|
82985
82985
|
errors.push({
|
|
82986
|
-
path:
|
|
82986
|
+
path: path27,
|
|
82987
82987
|
keyword: "type",
|
|
82988
82988
|
message: `Expected integer for type Int`,
|
|
82989
82989
|
params: { expectedType: "Int", actualType: typeof value }
|
|
@@ -82993,7 +82993,7 @@ Provide:
|
|
|
82993
82993
|
case "Float":
|
|
82994
82994
|
if (typeof value !== "number") {
|
|
82995
82995
|
errors.push({
|
|
82996
|
-
path:
|
|
82996
|
+
path: path27,
|
|
82997
82997
|
keyword: "type",
|
|
82998
82998
|
message: `Expected number for type Float`,
|
|
82999
82999
|
params: { expectedType: "Float", actualType: typeof value }
|
|
@@ -83003,7 +83003,7 @@ Provide:
|
|
|
83003
83003
|
case "Boolean":
|
|
83004
83004
|
if (typeof value !== "boolean") {
|
|
83005
83005
|
errors.push({
|
|
83006
|
-
path:
|
|
83006
|
+
path: path27,
|
|
83007
83007
|
keyword: "type",
|
|
83008
83008
|
message: `Expected boolean for type Boolean`,
|
|
83009
83009
|
params: { expectedType: "Boolean", actualType: typeof value }
|
|
@@ -83014,7 +83014,7 @@ Provide:
|
|
|
83014
83014
|
default:
|
|
83015
83015
|
if (typeof value !== "object") {
|
|
83016
83016
|
errors.push({
|
|
83017
|
-
path:
|
|
83017
|
+
path: path27,
|
|
83018
83018
|
keyword: "type",
|
|
83019
83019
|
message: `Expected object for type ${baseType}`,
|
|
83020
83020
|
params: { expectedType: baseType, actualType: typeof value }
|
|
@@ -83022,10 +83022,10 @@ Provide:
|
|
|
83022
83022
|
}
|
|
83023
83023
|
}
|
|
83024
83024
|
}
|
|
83025
|
-
basicTypeValidation(data, schema,
|
|
83025
|
+
basicTypeValidation(data, schema, path27, errors, depth = 0) {
|
|
83026
83026
|
if (depth > this.config.maxSchemaDepth) {
|
|
83027
83027
|
errors.push({
|
|
83028
|
-
path:
|
|
83028
|
+
path: path27,
|
|
83029
83029
|
keyword: "maxDepth",
|
|
83030
83030
|
message: "Maximum schema depth exceeded",
|
|
83031
83031
|
params: { maxDepth: this.config.maxSchemaDepth }
|
|
@@ -83042,7 +83042,7 @@ Provide:
|
|
|
83042
83042
|
for (const prop of required) {
|
|
83043
83043
|
if (!(prop in dataObj)) {
|
|
83044
83044
|
errors.push({
|
|
83045
|
-
path:
|
|
83045
|
+
path: path27 ? `${path27}.${prop}` : prop,
|
|
83046
83046
|
keyword: "required",
|
|
83047
83047
|
message: `Required property '${prop}' is missing`,
|
|
83048
83048
|
params: { missingProperty: prop }
|
|
@@ -83054,7 +83054,7 @@ Provide:
|
|
|
83054
83054
|
this.basicTypeValidation(
|
|
83055
83055
|
dataObj[prop],
|
|
83056
83056
|
propSchema,
|
|
83057
|
-
|
|
83057
|
+
path27 ? `${path27}.${prop}` : prop,
|
|
83058
83058
|
errors,
|
|
83059
83059
|
depth + 1
|
|
83060
83060
|
);
|
|
@@ -83063,26 +83063,26 @@ Provide:
|
|
|
83063
83063
|
} else if (type === "array" && actualType === "array") {
|
|
83064
83064
|
const items = schema.items;
|
|
83065
83065
|
const dataArr = data;
|
|
83066
|
-
this.validateArrayConstraints(dataArr, schema,
|
|
83066
|
+
this.validateArrayConstraints(dataArr, schema, path27, errors);
|
|
83067
83067
|
if (items) {
|
|
83068
83068
|
for (let i58 = 0; i58 < dataArr.length; i58++) {
|
|
83069
83069
|
this.basicTypeValidation(
|
|
83070
83070
|
dataArr[i58],
|
|
83071
83071
|
items,
|
|
83072
|
-
`${
|
|
83072
|
+
`${path27}[${i58}]`,
|
|
83073
83073
|
errors,
|
|
83074
83074
|
depth + 1
|
|
83075
83075
|
);
|
|
83076
83076
|
}
|
|
83077
83077
|
}
|
|
83078
83078
|
} else if (type === "string" && actualType === "string") {
|
|
83079
|
-
this.validateStringConstraints(data, schema,
|
|
83079
|
+
this.validateStringConstraints(data, schema, path27, errors);
|
|
83080
83080
|
} else if ((type === "number" || type === "integer") && (actualType === "number" || actualType === "integer")) {
|
|
83081
|
-
this.validateNumberConstraints(data, schema,
|
|
83081
|
+
this.validateNumberConstraints(data, schema, path27, errors);
|
|
83082
83082
|
} else if (type !== actualType) {
|
|
83083
83083
|
if (!(type === "number" && actualType === "integer")) {
|
|
83084
83084
|
errors.push({
|
|
83085
|
-
path:
|
|
83085
|
+
path: path27,
|
|
83086
83086
|
keyword: "type",
|
|
83087
83087
|
message: `Expected type '${type}' but got '${actualType}'`,
|
|
83088
83088
|
params: { expectedType: type, actualType }
|
|
@@ -83093,7 +83093,7 @@ Provide:
|
|
|
83093
83093
|
const enumValues = schema.enum;
|
|
83094
83094
|
if (!enumValues.some((v62) => JSON.stringify(v62) === JSON.stringify(data))) {
|
|
83095
83095
|
errors.push({
|
|
83096
|
-
path:
|
|
83096
|
+
path: path27,
|
|
83097
83097
|
keyword: "enum",
|
|
83098
83098
|
message: `Value must be one of: ${enumValues.map((v62) => JSON.stringify(v62)).join(", ")}`,
|
|
83099
83099
|
params: { allowedValues: enumValues }
|
|
@@ -83101,13 +83101,13 @@ Provide:
|
|
|
83101
83101
|
}
|
|
83102
83102
|
}
|
|
83103
83103
|
}
|
|
83104
|
-
validateStringConstraints(data, schema,
|
|
83104
|
+
validateStringConstraints(data, schema, path27, errors) {
|
|
83105
83105
|
const minLength = schema.minLength;
|
|
83106
83106
|
const maxLength = schema.maxLength;
|
|
83107
83107
|
const pattern = schema.pattern;
|
|
83108
83108
|
if (minLength !== void 0 && data.length < minLength) {
|
|
83109
83109
|
errors.push({
|
|
83110
|
-
path:
|
|
83110
|
+
path: path27,
|
|
83111
83111
|
keyword: "minLength",
|
|
83112
83112
|
message: `String must be at least ${minLength} characters`,
|
|
83113
83113
|
params: { limit: minLength, actual: data.length }
|
|
@@ -83115,7 +83115,7 @@ Provide:
|
|
|
83115
83115
|
}
|
|
83116
83116
|
if (maxLength !== void 0 && data.length > maxLength) {
|
|
83117
83117
|
errors.push({
|
|
83118
|
-
path:
|
|
83118
|
+
path: path27,
|
|
83119
83119
|
keyword: "maxLength",
|
|
83120
83120
|
message: `String must be at most ${maxLength} characters`,
|
|
83121
83121
|
params: { limit: maxLength, actual: data.length }
|
|
@@ -83125,7 +83125,7 @@ Provide:
|
|
|
83125
83125
|
const regex = createSafeRegex(pattern);
|
|
83126
83126
|
if (regex && !regex.test(data)) {
|
|
83127
83127
|
errors.push({
|
|
83128
|
-
path:
|
|
83128
|
+
path: path27,
|
|
83129
83129
|
keyword: "pattern",
|
|
83130
83130
|
message: `String must match pattern: ${pattern}`,
|
|
83131
83131
|
params: { pattern }
|
|
@@ -83133,7 +83133,7 @@ Provide:
|
|
|
83133
83133
|
}
|
|
83134
83134
|
}
|
|
83135
83135
|
}
|
|
83136
|
-
validateNumberConstraints(data, schema,
|
|
83136
|
+
validateNumberConstraints(data, schema, path27, errors) {
|
|
83137
83137
|
const minimum = schema.minimum;
|
|
83138
83138
|
const maximum = schema.maximum;
|
|
83139
83139
|
const exclusiveMinimum = schema.exclusiveMinimum;
|
|
@@ -83141,7 +83141,7 @@ Provide:
|
|
|
83141
83141
|
const multipleOf = schema.multipleOf;
|
|
83142
83142
|
if (minimum !== void 0 && data < minimum) {
|
|
83143
83143
|
errors.push({
|
|
83144
|
-
path:
|
|
83144
|
+
path: path27,
|
|
83145
83145
|
keyword: "minimum",
|
|
83146
83146
|
message: `Number must be >= ${minimum}`,
|
|
83147
83147
|
params: { limit: minimum, actual: data }
|
|
@@ -83149,7 +83149,7 @@ Provide:
|
|
|
83149
83149
|
}
|
|
83150
83150
|
if (maximum !== void 0 && data > maximum) {
|
|
83151
83151
|
errors.push({
|
|
83152
|
-
path:
|
|
83152
|
+
path: path27,
|
|
83153
83153
|
keyword: "maximum",
|
|
83154
83154
|
message: `Number must be <= ${maximum}`,
|
|
83155
83155
|
params: { limit: maximum, actual: data }
|
|
@@ -83157,7 +83157,7 @@ Provide:
|
|
|
83157
83157
|
}
|
|
83158
83158
|
if (exclusiveMinimum !== void 0 && data <= exclusiveMinimum) {
|
|
83159
83159
|
errors.push({
|
|
83160
|
-
path:
|
|
83160
|
+
path: path27,
|
|
83161
83161
|
keyword: "exclusiveMinimum",
|
|
83162
83162
|
message: `Number must be > ${exclusiveMinimum}`,
|
|
83163
83163
|
params: { limit: exclusiveMinimum, actual: data }
|
|
@@ -83165,7 +83165,7 @@ Provide:
|
|
|
83165
83165
|
}
|
|
83166
83166
|
if (exclusiveMaximum !== void 0 && data >= exclusiveMaximum) {
|
|
83167
83167
|
errors.push({
|
|
83168
|
-
path:
|
|
83168
|
+
path: path27,
|
|
83169
83169
|
keyword: "exclusiveMaximum",
|
|
83170
83170
|
message: `Number must be < ${exclusiveMaximum}`,
|
|
83171
83171
|
params: { limit: exclusiveMaximum, actual: data }
|
|
@@ -83173,20 +83173,20 @@ Provide:
|
|
|
83173
83173
|
}
|
|
83174
83174
|
if (multipleOf !== void 0 && data % multipleOf !== 0) {
|
|
83175
83175
|
errors.push({
|
|
83176
|
-
path:
|
|
83176
|
+
path: path27,
|
|
83177
83177
|
keyword: "multipleOf",
|
|
83178
83178
|
message: `Number must be a multiple of ${multipleOf}`,
|
|
83179
83179
|
params: { multipleOf, actual: data }
|
|
83180
83180
|
});
|
|
83181
83181
|
}
|
|
83182
83182
|
}
|
|
83183
|
-
validateArrayConstraints(data, schema,
|
|
83183
|
+
validateArrayConstraints(data, schema, path27, errors) {
|
|
83184
83184
|
const minItems = schema.minItems;
|
|
83185
83185
|
const maxItems = schema.maxItems;
|
|
83186
83186
|
const uniqueItems = schema.uniqueItems;
|
|
83187
83187
|
if (minItems !== void 0 && data.length < minItems) {
|
|
83188
83188
|
errors.push({
|
|
83189
|
-
path:
|
|
83189
|
+
path: path27,
|
|
83190
83190
|
keyword: "minItems",
|
|
83191
83191
|
message: `Array must have at least ${minItems} items`,
|
|
83192
83192
|
params: { limit: minItems, actual: data.length }
|
|
@@ -83194,7 +83194,7 @@ Provide:
|
|
|
83194
83194
|
}
|
|
83195
83195
|
if (maxItems !== void 0 && data.length > maxItems) {
|
|
83196
83196
|
errors.push({
|
|
83197
|
-
path:
|
|
83197
|
+
path: path27,
|
|
83198
83198
|
keyword: "maxItems",
|
|
83199
83199
|
message: `Array must have at most ${maxItems} items`,
|
|
83200
83200
|
params: { limit: maxItems, actual: data.length }
|
|
@@ -83206,7 +83206,7 @@ Provide:
|
|
|
83206
83206
|
const serialized = JSON.stringify(data[i58]);
|
|
83207
83207
|
if (seen.has(serialized)) {
|
|
83208
83208
|
errors.push({
|
|
83209
|
-
path: `${
|
|
83209
|
+
path: `${path27}[${i58}]`,
|
|
83210
83210
|
keyword: "uniqueItems",
|
|
83211
83211
|
message: "Array items must be unique",
|
|
83212
83212
|
params: { duplicateIndex: i58 }
|
|
@@ -83702,11 +83702,11 @@ var ApiCompatibilityService = class {
|
|
|
83702
83702
|
} catch {
|
|
83703
83703
|
}
|
|
83704
83704
|
}
|
|
83705
|
-
scanObjectForDeprecations(obj,
|
|
83705
|
+
scanObjectForDeprecations(obj, path27, deprecations, version, context2) {
|
|
83706
83706
|
if (!obj || typeof obj !== "object") return;
|
|
83707
83707
|
const record = obj;
|
|
83708
83708
|
if (record.deprecated === true) {
|
|
83709
|
-
const location = context2 ? `${context2} -> ${
|
|
83709
|
+
const location = context2 ? `${context2} -> ${path27}` : path27;
|
|
83710
83710
|
deprecations.push({
|
|
83711
83711
|
location,
|
|
83712
83712
|
reason: typeof record.description === "string" ? record.description : "Field marked as deprecated",
|
|
@@ -83715,7 +83715,7 @@ var ApiCompatibilityService = class {
|
|
|
83715
83715
|
});
|
|
83716
83716
|
}
|
|
83717
83717
|
if (record["x-deprecated"] === true) {
|
|
83718
|
-
const location = context2 ? `${context2} -> ${
|
|
83718
|
+
const location = context2 ? `${context2} -> ${path27}` : path27;
|
|
83719
83719
|
deprecations.push({
|
|
83720
83720
|
location,
|
|
83721
83721
|
reason: typeof record["x-deprecated-message"] === "string" ? record["x-deprecated-message"] : "Element marked as deprecated via x-deprecated",
|
|
@@ -83727,7 +83727,7 @@ var ApiCompatibilityService = class {
|
|
|
83727
83727
|
for (const [propName, propValue] of Object.entries(props)) {
|
|
83728
83728
|
this.scanObjectForDeprecations(
|
|
83729
83729
|
propValue,
|
|
83730
|
-
`${
|
|
83730
|
+
`${path27}.${propName}`,
|
|
83731
83731
|
deprecations,
|
|
83732
83732
|
version,
|
|
83733
83733
|
context2
|
|
@@ -83737,7 +83737,7 @@ var ApiCompatibilityService = class {
|
|
|
83737
83737
|
if (record.items && typeof record.items === "object") {
|
|
83738
83738
|
this.scanObjectForDeprecations(
|
|
83739
83739
|
record.items,
|
|
83740
|
-
`${
|
|
83740
|
+
`${path27}[]`,
|
|
83741
83741
|
deprecations,
|
|
83742
83742
|
version,
|
|
83743
83743
|
context2
|
|
@@ -84486,13 +84486,13 @@ var ContractTestingCoordinator = class extends BaseDomainCoordinator {
|
|
|
84486
84486
|
}
|
|
84487
84487
|
return contracts;
|
|
84488
84488
|
}
|
|
84489
|
-
async loadContractFromPath(
|
|
84490
|
-
const content = await this.loadFileContent(
|
|
84489
|
+
async loadContractFromPath(path27) {
|
|
84490
|
+
const content = await this.loadFileContent(path27);
|
|
84491
84491
|
if (!content) {
|
|
84492
84492
|
return null;
|
|
84493
84493
|
}
|
|
84494
84494
|
try {
|
|
84495
|
-
const filePath =
|
|
84495
|
+
const filePath = path27.value.toLowerCase();
|
|
84496
84496
|
if (filePath.endsWith(".json")) {
|
|
84497
84497
|
const parsed = safeJsonParse(content);
|
|
84498
84498
|
if (parsed.openapi || parsed.swagger) {
|
|
@@ -84500,22 +84500,22 @@ var ContractTestingCoordinator = class extends BaseDomainCoordinator {
|
|
|
84500
84500
|
}
|
|
84501
84501
|
return parsed;
|
|
84502
84502
|
} else if (filePath.endsWith(".yaml") || filePath.endsWith(".yml")) {
|
|
84503
|
-
console.warn("YAML contract files not yet supported:",
|
|
84503
|
+
console.warn("YAML contract files not yet supported:", path27.value);
|
|
84504
84504
|
return null;
|
|
84505
84505
|
}
|
|
84506
84506
|
return safeJsonParse(content);
|
|
84507
84507
|
} catch (error) {
|
|
84508
84508
|
console.error(
|
|
84509
|
-
`Failed to parse contract from ${
|
|
84509
|
+
`Failed to parse contract from ${path27.value}:`,
|
|
84510
84510
|
toErrorMessage(error)
|
|
84511
84511
|
);
|
|
84512
84512
|
return null;
|
|
84513
84513
|
}
|
|
84514
84514
|
}
|
|
84515
|
-
async loadFileContent(
|
|
84516
|
-
const result = await this.fileReader.readFile(
|
|
84515
|
+
async loadFileContent(path27) {
|
|
84516
|
+
const result = await this.fileReader.readFile(path27.value);
|
|
84517
84517
|
if (!result.success) {
|
|
84518
|
-
console.error(`Failed to read file ${
|
|
84518
|
+
console.error(`Failed to read file ${path27.value}:`, result.error);
|
|
84519
84519
|
return null;
|
|
84520
84520
|
}
|
|
84521
84521
|
return result.value;
|
|
@@ -84526,13 +84526,13 @@ var ContractTestingCoordinator = class extends BaseDomainCoordinator {
|
|
|
84526
84526
|
const paths = spec.paths || {};
|
|
84527
84527
|
const endpoints = [];
|
|
84528
84528
|
const schemas = [];
|
|
84529
|
-
for (const [
|
|
84529
|
+
for (const [path27, methods] of Object.entries(paths)) {
|
|
84530
84530
|
const httpMethods = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
|
|
84531
84531
|
for (const method of httpMethods) {
|
|
84532
84532
|
const operation = methods[method.toLowerCase()];
|
|
84533
84533
|
if (operation) {
|
|
84534
84534
|
endpoints.push({
|
|
84535
|
-
path:
|
|
84535
|
+
path: path27,
|
|
84536
84536
|
method,
|
|
84537
84537
|
requestSchema: this.extractRequestSchema(operation),
|
|
84538
84538
|
responseSchema: this.extractResponseSchema(operation),
|
|
@@ -85261,10 +85261,10 @@ var SchemaValidatorService = class {
|
|
|
85261
85261
|
// ============================================================================
|
|
85262
85262
|
// Private Validation Methods
|
|
85263
85263
|
// ============================================================================
|
|
85264
|
-
validateValue(value, schema,
|
|
85264
|
+
validateValue(value, schema, path27, errors, depth) {
|
|
85265
85265
|
if (depth > this.config.maxRecursionDepth) {
|
|
85266
85266
|
errors.push({
|
|
85267
|
-
path:
|
|
85267
|
+
path: path27,
|
|
85268
85268
|
keyword: "maxDepth",
|
|
85269
85269
|
message: "Maximum recursion depth exceeded",
|
|
85270
85270
|
params: { maxDepth: this.config.maxRecursionDepth }
|
|
@@ -85277,7 +85277,7 @@ var SchemaValidatorService = class {
|
|
|
85277
85277
|
}
|
|
85278
85278
|
if (this.config.strictMode) {
|
|
85279
85279
|
errors.push({
|
|
85280
|
-
path:
|
|
85280
|
+
path: path27,
|
|
85281
85281
|
keyword: "type",
|
|
85282
85282
|
message: "Value cannot be null",
|
|
85283
85283
|
params: {}
|
|
@@ -85287,15 +85287,15 @@ var SchemaValidatorService = class {
|
|
|
85287
85287
|
}
|
|
85288
85288
|
const schemaType = schema.type;
|
|
85289
85289
|
if (schema.oneOf) {
|
|
85290
|
-
this.validateOneOf(value, schema.oneOf,
|
|
85290
|
+
this.validateOneOf(value, schema.oneOf, path27, errors, depth);
|
|
85291
85291
|
return;
|
|
85292
85292
|
}
|
|
85293
85293
|
if (schema.anyOf) {
|
|
85294
|
-
this.validateAnyOf(value, schema.anyOf,
|
|
85294
|
+
this.validateAnyOf(value, schema.anyOf, path27, errors, depth);
|
|
85295
85295
|
return;
|
|
85296
85296
|
}
|
|
85297
85297
|
if (schema.allOf) {
|
|
85298
|
-
this.validateAllOf(value, schema.allOf,
|
|
85298
|
+
this.validateAllOf(value, schema.allOf, path27, errors, depth);
|
|
85299
85299
|
return;
|
|
85300
85300
|
}
|
|
85301
85301
|
if (schemaType) {
|
|
@@ -85303,7 +85303,7 @@ var SchemaValidatorService = class {
|
|
|
85303
85303
|
const actualType = this.getJsonType(value);
|
|
85304
85304
|
if (!types.some((t50) => this.typesMatch(actualType, t50))) {
|
|
85305
85305
|
errors.push({
|
|
85306
|
-
path:
|
|
85306
|
+
path: path27,
|
|
85307
85307
|
keyword: "type",
|
|
85308
85308
|
message: `Expected type '${types.join(" | ")}' but got '${actualType}'`,
|
|
85309
85309
|
params: { expectedType: types, actualType }
|
|
@@ -85312,19 +85312,19 @@ var SchemaValidatorService = class {
|
|
|
85312
85312
|
}
|
|
85313
85313
|
}
|
|
85314
85314
|
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
85315
|
-
this.validateObject(value, schema,
|
|
85315
|
+
this.validateObject(value, schema, path27, errors, depth);
|
|
85316
85316
|
} else if (Array.isArray(value)) {
|
|
85317
|
-
this.validateArray(value, schema,
|
|
85317
|
+
this.validateArray(value, schema, path27, errors, depth);
|
|
85318
85318
|
} else if (typeof value === "string") {
|
|
85319
|
-
this.validateString(value, schema,
|
|
85319
|
+
this.validateString(value, schema, path27, errors);
|
|
85320
85320
|
} else if (typeof value === "number") {
|
|
85321
|
-
this.validateNumber(value, schema,
|
|
85321
|
+
this.validateNumber(value, schema, path27, errors);
|
|
85322
85322
|
}
|
|
85323
85323
|
if (schema.enum) {
|
|
85324
85324
|
const enumValues = schema.enum;
|
|
85325
85325
|
if (!enumValues.includes(value)) {
|
|
85326
85326
|
errors.push({
|
|
85327
|
-
path:
|
|
85327
|
+
path: path27,
|
|
85328
85328
|
keyword: "enum",
|
|
85329
85329
|
message: `Value must be one of: ${enumValues.map((v62) => JSON.stringify(v62)).join(", ")}`,
|
|
85330
85330
|
params: { allowedValues: enumValues }
|
|
@@ -85334,7 +85334,7 @@ var SchemaValidatorService = class {
|
|
|
85334
85334
|
if ("const" in schema) {
|
|
85335
85335
|
if (value !== schema.const) {
|
|
85336
85336
|
errors.push({
|
|
85337
|
-
path:
|
|
85337
|
+
path: path27,
|
|
85338
85338
|
keyword: "const",
|
|
85339
85339
|
message: `Value must be ${JSON.stringify(schema.const)}`,
|
|
85340
85340
|
params: { expected: schema.const }
|
|
@@ -85342,14 +85342,14 @@ var SchemaValidatorService = class {
|
|
|
85342
85342
|
}
|
|
85343
85343
|
}
|
|
85344
85344
|
}
|
|
85345
|
-
validateObject(value, schema,
|
|
85345
|
+
validateObject(value, schema, path27, errors, depth) {
|
|
85346
85346
|
const properties = schema.properties || {};
|
|
85347
85347
|
const required = schema.required || [];
|
|
85348
85348
|
const additionalProperties = schema.additionalProperties;
|
|
85349
85349
|
for (const prop of required) {
|
|
85350
85350
|
if (!(prop in value)) {
|
|
85351
85351
|
errors.push({
|
|
85352
|
-
path:
|
|
85352
|
+
path: path27 ? `${path27}.${prop}` : prop,
|
|
85353
85353
|
keyword: "required",
|
|
85354
85354
|
message: `Required property '${prop}' is missing`,
|
|
85355
85355
|
params: { missingProperty: prop }
|
|
@@ -85357,7 +85357,7 @@ var SchemaValidatorService = class {
|
|
|
85357
85357
|
}
|
|
85358
85358
|
}
|
|
85359
85359
|
for (const [prop, propValue] of Object.entries(value)) {
|
|
85360
|
-
const propPath =
|
|
85360
|
+
const propPath = path27 ? `${path27}.${prop}` : prop;
|
|
85361
85361
|
if (prop in properties) {
|
|
85362
85362
|
this.validateValue(propValue, properties[prop], propPath, errors, depth + 1);
|
|
85363
85363
|
} else if (this.config.strictMode && additionalProperties === false) {
|
|
@@ -85380,7 +85380,7 @@ var SchemaValidatorService = class {
|
|
|
85380
85380
|
const propCount = Object.keys(value).length;
|
|
85381
85381
|
if (typeof schema.minProperties === "number" && propCount < schema.minProperties) {
|
|
85382
85382
|
errors.push({
|
|
85383
|
-
path:
|
|
85383
|
+
path: path27,
|
|
85384
85384
|
keyword: "minProperties",
|
|
85385
85385
|
message: `Object must have at least ${schema.minProperties} properties`,
|
|
85386
85386
|
params: { limit: schema.minProperties, actual: propCount }
|
|
@@ -85388,23 +85388,23 @@ var SchemaValidatorService = class {
|
|
|
85388
85388
|
}
|
|
85389
85389
|
if (typeof schema.maxProperties === "number" && propCount > schema.maxProperties) {
|
|
85390
85390
|
errors.push({
|
|
85391
|
-
path:
|
|
85391
|
+
path: path27,
|
|
85392
85392
|
keyword: "maxProperties",
|
|
85393
85393
|
message: `Object must have at most ${schema.maxProperties} properties`,
|
|
85394
85394
|
params: { limit: schema.maxProperties, actual: propCount }
|
|
85395
85395
|
});
|
|
85396
85396
|
}
|
|
85397
85397
|
}
|
|
85398
|
-
validateArray(value, schema,
|
|
85398
|
+
validateArray(value, schema, path27, errors, depth) {
|
|
85399
85399
|
const items = schema.items;
|
|
85400
85400
|
if (items) {
|
|
85401
85401
|
for (let i58 = 0; i58 < value.length; i58++) {
|
|
85402
|
-
this.validateValue(value[i58], items, `${
|
|
85402
|
+
this.validateValue(value[i58], items, `${path27}[${i58}]`, errors, depth + 1);
|
|
85403
85403
|
}
|
|
85404
85404
|
}
|
|
85405
85405
|
if (typeof schema.minItems === "number" && value.length < schema.minItems) {
|
|
85406
85406
|
errors.push({
|
|
85407
|
-
path:
|
|
85407
|
+
path: path27,
|
|
85408
85408
|
keyword: "minItems",
|
|
85409
85409
|
message: `Array must have at least ${schema.minItems} items`,
|
|
85410
85410
|
params: { limit: schema.minItems, actual: value.length }
|
|
@@ -85412,7 +85412,7 @@ var SchemaValidatorService = class {
|
|
|
85412
85412
|
}
|
|
85413
85413
|
if (typeof schema.maxItems === "number" && value.length > schema.maxItems) {
|
|
85414
85414
|
errors.push({
|
|
85415
|
-
path:
|
|
85415
|
+
path: path27,
|
|
85416
85416
|
keyword: "maxItems",
|
|
85417
85417
|
message: `Array must have at most ${schema.maxItems} items`,
|
|
85418
85418
|
params: { limit: schema.maxItems, actual: value.length }
|
|
@@ -85424,7 +85424,7 @@ var SchemaValidatorService = class {
|
|
|
85424
85424
|
const serialized = JSON.stringify(value[i58]);
|
|
85425
85425
|
if (seen.has(serialized)) {
|
|
85426
85426
|
errors.push({
|
|
85427
|
-
path: `${
|
|
85427
|
+
path: `${path27}[${i58}]`,
|
|
85428
85428
|
keyword: "uniqueItems",
|
|
85429
85429
|
message: "Array items must be unique",
|
|
85430
85430
|
params: { duplicateIndex: i58 }
|
|
@@ -85434,10 +85434,10 @@ var SchemaValidatorService = class {
|
|
|
85434
85434
|
}
|
|
85435
85435
|
}
|
|
85436
85436
|
}
|
|
85437
|
-
validateString(value, schema,
|
|
85437
|
+
validateString(value, schema, path27, errors) {
|
|
85438
85438
|
if (typeof schema.minLength === "number" && value.length < schema.minLength) {
|
|
85439
85439
|
errors.push({
|
|
85440
|
-
path:
|
|
85440
|
+
path: path27,
|
|
85441
85441
|
keyword: "minLength",
|
|
85442
85442
|
message: `String must be at least ${schema.minLength} characters`,
|
|
85443
85443
|
params: { limit: schema.minLength, actual: value.length }
|
|
@@ -85445,7 +85445,7 @@ var SchemaValidatorService = class {
|
|
|
85445
85445
|
}
|
|
85446
85446
|
if (typeof schema.maxLength === "number" && value.length > schema.maxLength) {
|
|
85447
85447
|
errors.push({
|
|
85448
|
-
path:
|
|
85448
|
+
path: path27,
|
|
85449
85449
|
keyword: "maxLength",
|
|
85450
85450
|
message: `String must be at most ${schema.maxLength} characters`,
|
|
85451
85451
|
params: { limit: schema.maxLength, actual: value.length }
|
|
@@ -85455,7 +85455,7 @@ var SchemaValidatorService = class {
|
|
|
85455
85455
|
const regex = createSafeRegex(schema.pattern);
|
|
85456
85456
|
if (regex && !regex.test(value)) {
|
|
85457
85457
|
errors.push({
|
|
85458
|
-
path:
|
|
85458
|
+
path: path27,
|
|
85459
85459
|
keyword: "pattern",
|
|
85460
85460
|
message: `String must match pattern '${schema.pattern}'`,
|
|
85461
85461
|
params: { pattern: schema.pattern }
|
|
@@ -85463,15 +85463,15 @@ var SchemaValidatorService = class {
|
|
|
85463
85463
|
}
|
|
85464
85464
|
}
|
|
85465
85465
|
if (typeof schema.format === "string") {
|
|
85466
|
-
this.validateFormat(value, schema.format,
|
|
85466
|
+
this.validateFormat(value, schema.format, path27, errors);
|
|
85467
85467
|
}
|
|
85468
85468
|
}
|
|
85469
|
-
validateNumber(value, schema,
|
|
85469
|
+
validateNumber(value, schema, path27, errors) {
|
|
85470
85470
|
if (typeof schema.minimum === "number") {
|
|
85471
85471
|
if (schema.exclusiveMinimum === true) {
|
|
85472
85472
|
if (value <= schema.minimum) {
|
|
85473
85473
|
errors.push({
|
|
85474
|
-
path:
|
|
85474
|
+
path: path27,
|
|
85475
85475
|
keyword: "exclusiveMinimum",
|
|
85476
85476
|
message: `Number must be greater than ${schema.minimum}`,
|
|
85477
85477
|
params: { limit: schema.minimum, actual: value }
|
|
@@ -85479,7 +85479,7 @@ var SchemaValidatorService = class {
|
|
|
85479
85479
|
}
|
|
85480
85480
|
} else if (value < schema.minimum) {
|
|
85481
85481
|
errors.push({
|
|
85482
|
-
path:
|
|
85482
|
+
path: path27,
|
|
85483
85483
|
keyword: "minimum",
|
|
85484
85484
|
message: `Number must be at least ${schema.minimum}`,
|
|
85485
85485
|
params: { limit: schema.minimum, actual: value }
|
|
@@ -85490,7 +85490,7 @@ var SchemaValidatorService = class {
|
|
|
85490
85490
|
if (schema.exclusiveMaximum === true) {
|
|
85491
85491
|
if (value >= schema.maximum) {
|
|
85492
85492
|
errors.push({
|
|
85493
|
-
path:
|
|
85493
|
+
path: path27,
|
|
85494
85494
|
keyword: "exclusiveMaximum",
|
|
85495
85495
|
message: `Number must be less than ${schema.maximum}`,
|
|
85496
85496
|
params: { limit: schema.maximum, actual: value }
|
|
@@ -85498,7 +85498,7 @@ var SchemaValidatorService = class {
|
|
|
85498
85498
|
}
|
|
85499
85499
|
} else if (value > schema.maximum) {
|
|
85500
85500
|
errors.push({
|
|
85501
|
-
path:
|
|
85501
|
+
path: path27,
|
|
85502
85502
|
keyword: "maximum",
|
|
85503
85503
|
message: `Number must be at most ${schema.maximum}`,
|
|
85504
85504
|
params: { limit: schema.maximum, actual: value }
|
|
@@ -85509,7 +85509,7 @@ var SchemaValidatorService = class {
|
|
|
85509
85509
|
const remainder = value % schema.multipleOf;
|
|
85510
85510
|
if (Math.abs(remainder) > 1e-10) {
|
|
85511
85511
|
errors.push({
|
|
85512
|
-
path:
|
|
85512
|
+
path: path27,
|
|
85513
85513
|
keyword: "multipleOf",
|
|
85514
85514
|
message: `Number must be a multiple of ${schema.multipleOf}`,
|
|
85515
85515
|
params: { multipleOf: schema.multipleOf, actual: value }
|
|
@@ -85517,7 +85517,7 @@ var SchemaValidatorService = class {
|
|
|
85517
85517
|
}
|
|
85518
85518
|
}
|
|
85519
85519
|
}
|
|
85520
|
-
validateFormat(value, format,
|
|
85520
|
+
validateFormat(value, format, path27, errors) {
|
|
85521
85521
|
let isValid = true;
|
|
85522
85522
|
switch (format) {
|
|
85523
85523
|
case "email":
|
|
@@ -85554,46 +85554,46 @@ var SchemaValidatorService = class {
|
|
|
85554
85554
|
}
|
|
85555
85555
|
if (!isValid) {
|
|
85556
85556
|
errors.push({
|
|
85557
|
-
path:
|
|
85557
|
+
path: path27,
|
|
85558
85558
|
keyword: "format",
|
|
85559
85559
|
message: `String must be a valid ${format}`,
|
|
85560
85560
|
params: { format }
|
|
85561
85561
|
});
|
|
85562
85562
|
}
|
|
85563
85563
|
}
|
|
85564
|
-
validateOneOf(value, schemas,
|
|
85564
|
+
validateOneOf(value, schemas, path27, errors, depth) {
|
|
85565
85565
|
const validCount = schemas.reduce((count, schema) => {
|
|
85566
85566
|
const subErrors = [];
|
|
85567
|
-
this.validateValue(value, schema,
|
|
85567
|
+
this.validateValue(value, schema, path27, subErrors, depth + 1);
|
|
85568
85568
|
return count + (subErrors.length === 0 ? 1 : 0);
|
|
85569
85569
|
}, 0);
|
|
85570
85570
|
if (validCount !== 1) {
|
|
85571
85571
|
errors.push({
|
|
85572
|
-
path:
|
|
85572
|
+
path: path27,
|
|
85573
85573
|
keyword: "oneOf",
|
|
85574
85574
|
message: `Value must match exactly one schema (matched ${validCount})`,
|
|
85575
85575
|
params: { matched: validCount }
|
|
85576
85576
|
});
|
|
85577
85577
|
}
|
|
85578
85578
|
}
|
|
85579
|
-
validateAnyOf(value, schemas,
|
|
85579
|
+
validateAnyOf(value, schemas, path27, errors, depth) {
|
|
85580
85580
|
const hasValid = schemas.some((schema) => {
|
|
85581
85581
|
const subErrors = [];
|
|
85582
|
-
this.validateValue(value, schema,
|
|
85582
|
+
this.validateValue(value, schema, path27, subErrors, depth + 1);
|
|
85583
85583
|
return subErrors.length === 0;
|
|
85584
85584
|
});
|
|
85585
85585
|
if (!hasValid) {
|
|
85586
85586
|
errors.push({
|
|
85587
|
-
path:
|
|
85587
|
+
path: path27,
|
|
85588
85588
|
keyword: "anyOf",
|
|
85589
85589
|
message: "Value must match at least one schema",
|
|
85590
85590
|
params: {}
|
|
85591
85591
|
});
|
|
85592
85592
|
}
|
|
85593
85593
|
}
|
|
85594
|
-
validateAllOf(value, schemas,
|
|
85594
|
+
validateAllOf(value, schemas, path27, errors, depth) {
|
|
85595
85595
|
for (const schema of schemas) {
|
|
85596
|
-
this.validateValue(value, schema,
|
|
85596
|
+
this.validateValue(value, schema, path27, errors, depth + 1);
|
|
85597
85597
|
}
|
|
85598
85598
|
}
|
|
85599
85599
|
getJsonType(value) {
|
|
@@ -85626,20 +85626,20 @@ var SchemaValidatorService = class {
|
|
|
85626
85626
|
});
|
|
85627
85627
|
}
|
|
85628
85628
|
}
|
|
85629
|
-
compareSchemaObjects(oldSchema, newSchema,
|
|
85629
|
+
compareSchemaObjects(oldSchema, newSchema, path27, additions, removals, modifications) {
|
|
85630
85630
|
const oldProps = oldSchema.properties || {};
|
|
85631
85631
|
const newProps = newSchema.properties || {};
|
|
85632
85632
|
const oldRequired = new Set(oldSchema.required || []);
|
|
85633
85633
|
const newRequired = new Set(newSchema.required || []);
|
|
85634
85634
|
for (const prop of Object.keys(oldProps)) {
|
|
85635
85635
|
if (!(prop in newProps)) {
|
|
85636
|
-
const propPath =
|
|
85636
|
+
const propPath = path27 ? `${path27}.${prop}` : prop;
|
|
85637
85637
|
removals.push(propPath);
|
|
85638
85638
|
}
|
|
85639
85639
|
}
|
|
85640
85640
|
for (const prop of Object.keys(newProps)) {
|
|
85641
85641
|
if (!(prop in oldProps)) {
|
|
85642
|
-
const propPath =
|
|
85642
|
+
const propPath = path27 ? `${path27}.${prop}` : prop;
|
|
85643
85643
|
additions.push(propPath);
|
|
85644
85644
|
if (newRequired.has(prop)) {
|
|
85645
85645
|
modifications.push({
|
|
@@ -85653,7 +85653,7 @@ var SchemaValidatorService = class {
|
|
|
85653
85653
|
}
|
|
85654
85654
|
if (oldSchema.type !== newSchema.type) {
|
|
85655
85655
|
modifications.push({
|
|
85656
|
-
path:
|
|
85656
|
+
path: path27 || "root",
|
|
85657
85657
|
oldType: String(oldSchema.type || "any"),
|
|
85658
85658
|
newType: String(newSchema.type || "any"),
|
|
85659
85659
|
isBreaking: true
|
|
@@ -85662,7 +85662,7 @@ var SchemaValidatorService = class {
|
|
|
85662
85662
|
const newRequiredArray = Array.from(newRequired);
|
|
85663
85663
|
for (const prop of newRequiredArray) {
|
|
85664
85664
|
if (!oldRequired.has(prop) && prop in oldProps) {
|
|
85665
|
-
const propPath =
|
|
85665
|
+
const propPath = path27 ? `${path27}.${prop}` : prop;
|
|
85666
85666
|
modifications.push({
|
|
85667
85667
|
path: propPath,
|
|
85668
85668
|
oldType: "optional",
|
|
@@ -86538,7 +86538,7 @@ var VisualTesterService = class {
|
|
|
86538
86538
|
const timestamp = /* @__PURE__ */ new Date();
|
|
86539
86539
|
const urlHash = this.hashUrl(url);
|
|
86540
86540
|
const viewportKey = `${viewport.width}x${viewport.height}`;
|
|
86541
|
-
const
|
|
86541
|
+
const path27 = FilePath.create(
|
|
86542
86542
|
`${this.config.baselineDirectory}/${urlHash}_${viewportKey}_${screenshotId}.png`
|
|
86543
86543
|
);
|
|
86544
86544
|
const loadTime = this.estimateLoadTime(url, viewport);
|
|
@@ -86554,7 +86554,7 @@ var VisualTesterService = class {
|
|
|
86554
86554
|
url,
|
|
86555
86555
|
viewport,
|
|
86556
86556
|
timestamp,
|
|
86557
|
-
path:
|
|
86557
|
+
path: path27,
|
|
86558
86558
|
metadata
|
|
86559
86559
|
};
|
|
86560
86560
|
await this.storeScreenshotMetadata(screenshot);
|
|
@@ -86571,7 +86571,7 @@ var VisualTesterService = class {
|
|
|
86571
86571
|
const viewport = options?.viewport || this.config.defaultViewport;
|
|
86572
86572
|
const screenshotId = v4_default();
|
|
86573
86573
|
const timestamp = /* @__PURE__ */ new Date();
|
|
86574
|
-
const
|
|
86574
|
+
const path27 = FilePath.create(
|
|
86575
86575
|
`${this.config.baselineDirectory}/${screenshotId}.png`
|
|
86576
86576
|
);
|
|
86577
86577
|
const metadata = {
|
|
@@ -86586,7 +86586,7 @@ var VisualTesterService = class {
|
|
|
86586
86586
|
url,
|
|
86587
86587
|
viewport,
|
|
86588
86588
|
timestamp,
|
|
86589
|
-
path:
|
|
86589
|
+
path: path27,
|
|
86590
86590
|
metadata
|
|
86591
86591
|
};
|
|
86592
86592
|
await this.storeScreenshotMetadata(screenshot);
|
|
@@ -90797,12 +90797,12 @@ var VisualAccessibilityCoordinator = class extends BaseDomainCoordinator {
|
|
|
90797
90797
|
*/
|
|
90798
90798
|
extractPathFeatures(url) {
|
|
90799
90799
|
const features = [];
|
|
90800
|
-
const
|
|
90800
|
+
const path27 = new URL(url).pathname;
|
|
90801
90801
|
const commonPaths = ["dashboard", "checkout", "login", "profile", "settings", "api", "admin", "search"];
|
|
90802
90802
|
for (const cp of commonPaths) {
|
|
90803
|
-
features.push(
|
|
90803
|
+
features.push(path27.includes(cp) ? 1 : 0);
|
|
90804
90804
|
}
|
|
90805
|
-
const depth =
|
|
90805
|
+
const depth = path27.split("/").filter(Boolean).length;
|
|
90806
90806
|
features.push(depth / 10);
|
|
90807
90807
|
features.push(url.includes("?") ? 1 : 0);
|
|
90808
90808
|
features.push(url.startsWith("https://") ? 1 : 0);
|
|
@@ -91900,13 +91900,13 @@ Provide:
|
|
|
91900
91900
|
}
|
|
91901
91901
|
}
|
|
91902
91902
|
async executeTcpProbe(probe) {
|
|
91903
|
-
return new Promise((
|
|
91903
|
+
return new Promise((resolve15) => {
|
|
91904
91904
|
try {
|
|
91905
91905
|
const [host, portStr] = probe.target.split(":");
|
|
91906
91906
|
const port = parseInt(portStr, 10);
|
|
91907
91907
|
if (!host || isNaN(port)) {
|
|
91908
91908
|
console.log(`TCP probe invalid target: ${probe.target} (expected host:port)`);
|
|
91909
|
-
|
|
91909
|
+
resolve15(false);
|
|
91910
91910
|
return;
|
|
91911
91911
|
}
|
|
91912
91912
|
const timeout = probe.timeout ?? 5e3;
|
|
@@ -91914,22 +91914,22 @@ Provide:
|
|
|
91914
91914
|
const timer = setTimeout(() => {
|
|
91915
91915
|
socket.destroy();
|
|
91916
91916
|
console.log(`TCP probe timeout: ${probe.name} -> ${probe.target}`);
|
|
91917
|
-
|
|
91917
|
+
resolve15(false);
|
|
91918
91918
|
}, timeout);
|
|
91919
91919
|
socket.connect(port, host, () => {
|
|
91920
91920
|
clearTimeout(timer);
|
|
91921
91921
|
socket.destroy();
|
|
91922
|
-
|
|
91922
|
+
resolve15(true);
|
|
91923
91923
|
});
|
|
91924
91924
|
socket.on("error", (err3) => {
|
|
91925
91925
|
clearTimeout(timer);
|
|
91926
91926
|
socket.destroy();
|
|
91927
91927
|
console.log(`TCP probe error: ${probe.name} -> ${err3.message}`);
|
|
91928
|
-
|
|
91928
|
+
resolve15(false);
|
|
91929
91929
|
});
|
|
91930
91930
|
} catch (error) {
|
|
91931
91931
|
console.log(`TCP probe exception: ${probe.name} -> ${toErrorMessage(error)}`);
|
|
91932
|
-
|
|
91932
|
+
resolve15(false);
|
|
91933
91933
|
}
|
|
91934
91934
|
});
|
|
91935
91935
|
}
|
|
@@ -91968,13 +91968,13 @@ Provide:
|
|
|
91968
91968
|
// Node.js checks
|
|
91969
91969
|
];
|
|
91970
91970
|
async executeCommandProbe(probe) {
|
|
91971
|
-
return new Promise((
|
|
91971
|
+
return new Promise((resolve15) => {
|
|
91972
91972
|
const timeout = probe.timeout ?? 1e4;
|
|
91973
91973
|
const validation = validateCommand(probe.target, _ChaosEngineerService.ALLOWED_PROBE_COMMANDS);
|
|
91974
91974
|
if (!validation.valid) {
|
|
91975
91975
|
console.log(`Command probe ${probe.name} blocked: ${validation.error}`);
|
|
91976
91976
|
console.log(`Blocked patterns: ${validation.blockedPatterns?.join(", ") || "none"}`);
|
|
91977
|
-
|
|
91977
|
+
resolve15(false);
|
|
91978
91978
|
return;
|
|
91979
91979
|
}
|
|
91980
91980
|
const sanitizedCommand = validation.sanitizedCommand || probe.target;
|
|
@@ -91984,7 +91984,7 @@ Provide:
|
|
|
91984
91984
|
execFile(executable, args, { timeout }, (error, stdout, _stderr) => {
|
|
91985
91985
|
if (error) {
|
|
91986
91986
|
console.log(`Command probe failed: ${probe.name} -> ${error.message}`);
|
|
91987
|
-
|
|
91987
|
+
resolve15(false);
|
|
91988
91988
|
return;
|
|
91989
91989
|
}
|
|
91990
91990
|
if (probe.expectedOutput !== void 0) {
|
|
@@ -91992,10 +91992,10 @@ Provide:
|
|
|
91992
91992
|
if (!passed) {
|
|
91993
91993
|
console.log(`Command probe ${probe.name}: output did not contain expected value`);
|
|
91994
91994
|
}
|
|
91995
|
-
|
|
91995
|
+
resolve15(passed);
|
|
91996
91996
|
return;
|
|
91997
91997
|
}
|
|
91998
|
-
|
|
91998
|
+
resolve15(true);
|
|
91999
91999
|
});
|
|
92000
92000
|
});
|
|
92001
92001
|
}
|
|
@@ -92315,7 +92315,7 @@ Provide:
|
|
|
92315
92315
|
// No-op commands
|
|
92316
92316
|
];
|
|
92317
92317
|
executeCommandRollback(command, timeout) {
|
|
92318
|
-
return new Promise((
|
|
92318
|
+
return new Promise((resolve15, reject) => {
|
|
92319
92319
|
const validation = validateCommand(command, _ChaosEngineerService.ALLOWED_ROLLBACK_COMMANDS);
|
|
92320
92320
|
if (!validation.valid) {
|
|
92321
92321
|
reject(new Error(`Rollback command blocked: ${validation.error}`));
|
|
@@ -92329,7 +92329,7 @@ Provide:
|
|
|
92329
92329
|
if (error) {
|
|
92330
92330
|
reject(new Error(`Command rollback failed: ${error.message}. ${stderr}`));
|
|
92331
92331
|
} else {
|
|
92332
|
-
|
|
92332
|
+
resolve15();
|
|
92333
92333
|
}
|
|
92334
92334
|
});
|
|
92335
92335
|
});
|
|
@@ -92350,7 +92350,7 @@ Provide:
|
|
|
92350
92350
|
await this.sleep(100);
|
|
92351
92351
|
}
|
|
92352
92352
|
sleep(ms) {
|
|
92353
|
-
return new Promise((
|
|
92353
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
92354
92354
|
}
|
|
92355
92355
|
};
|
|
92356
92356
|
|
|
@@ -92900,7 +92900,7 @@ var LoadTesterService = class {
|
|
|
92900
92900
|
return result;
|
|
92901
92901
|
}
|
|
92902
92902
|
sleep(ms) {
|
|
92903
|
-
return new Promise((
|
|
92903
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
92904
92904
|
}
|
|
92905
92905
|
};
|
|
92906
92906
|
|
|
@@ -93464,7 +93464,7 @@ var PerformanceProfilerService = class {
|
|
|
93464
93464
|
);
|
|
93465
93465
|
}
|
|
93466
93466
|
sleep(ms) {
|
|
93467
|
-
return new Promise((
|
|
93467
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
93468
93468
|
}
|
|
93469
93469
|
};
|
|
93470
93470
|
|
|
@@ -94397,12 +94397,12 @@ var ChaosResilienceCoordinator = class extends BaseDomainCoordinator {
|
|
|
94397
94397
|
}
|
|
94398
94398
|
return experiments;
|
|
94399
94399
|
}
|
|
94400
|
-
generateCriticalPathExperiment(
|
|
94401
|
-
const pathName =
|
|
94400
|
+
generateCriticalPathExperiment(path27, _architecture) {
|
|
94401
|
+
const pathName = path27.join("-");
|
|
94402
94402
|
return {
|
|
94403
94403
|
id: v4_default(),
|
|
94404
94404
|
name: `critical-path-${pathName}`,
|
|
94405
|
-
description: `Test critical path: ${
|
|
94405
|
+
description: `Test critical path: ${path27.join(" -> ")}`,
|
|
94406
94406
|
hypothesis: {
|
|
94407
94407
|
statement: "System should handle partial path failure gracefully",
|
|
94408
94408
|
metrics: [
|
|
@@ -94415,7 +94415,7 @@ var ChaosResilienceCoordinator = class extends BaseDomainCoordinator {
|
|
|
94415
94415
|
},
|
|
94416
94416
|
steadyState: {
|
|
94417
94417
|
description: "All services in path are healthy",
|
|
94418
|
-
probes:
|
|
94418
|
+
probes: path27.map((service) => ({
|
|
94419
94419
|
name: `${service}-health`,
|
|
94420
94420
|
type: "http",
|
|
94421
94421
|
target: `http://${service}/health`,
|
|
@@ -94423,7 +94423,7 @@ var ChaosResilienceCoordinator = class extends BaseDomainCoordinator {
|
|
|
94423
94423
|
timeout: 5e3
|
|
94424
94424
|
}))
|
|
94425
94425
|
},
|
|
94426
|
-
faults:
|
|
94426
|
+
faults: path27.slice(0, -1).map((service) => ({
|
|
94427
94427
|
id: v4_default(),
|
|
94428
94428
|
type: "latency",
|
|
94429
94429
|
target: {
|
|
@@ -101266,8 +101266,8 @@ var WorkflowOrchestrator = class {
|
|
|
101266
101266
|
}
|
|
101267
101267
|
}
|
|
101268
101268
|
}
|
|
101269
|
-
getValueByPath(obj,
|
|
101270
|
-
const parts =
|
|
101269
|
+
getValueByPath(obj, path27) {
|
|
101270
|
+
const parts = path27.split(".");
|
|
101271
101271
|
let current = obj;
|
|
101272
101272
|
for (const part of parts) {
|
|
101273
101273
|
if (current === null || current === void 0) return void 0;
|
|
@@ -101276,8 +101276,8 @@ var WorkflowOrchestrator = class {
|
|
|
101276
101276
|
}
|
|
101277
101277
|
return current;
|
|
101278
101278
|
}
|
|
101279
|
-
setValueByPath(obj,
|
|
101280
|
-
const parts =
|
|
101279
|
+
setValueByPath(obj, path27, value) {
|
|
101280
|
+
const parts = path27.split(".");
|
|
101281
101281
|
const dangerousKeys = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
101282
101282
|
for (const part of parts) {
|
|
101283
101283
|
if (dangerousKeys.has(part)) throw new Error(`Invalid path: contains dangerous prototype key`);
|
|
@@ -101425,15 +101425,15 @@ var WorkflowOrchestrator = class {
|
|
|
101425
101425
|
detectCircularDependencies(steps) {
|
|
101426
101426
|
const visited = /* @__PURE__ */ new Set();
|
|
101427
101427
|
const recursionStack = /* @__PURE__ */ new Set();
|
|
101428
|
-
const visit = (stepId,
|
|
101429
|
-
if (recursionStack.has(stepId)) return [...
|
|
101428
|
+
const visit = (stepId, path27) => {
|
|
101429
|
+
if (recursionStack.has(stepId)) return [...path27, stepId].join(" -> ");
|
|
101430
101430
|
if (visited.has(stepId)) return null;
|
|
101431
101431
|
visited.add(stepId);
|
|
101432
101432
|
recursionStack.add(stepId);
|
|
101433
101433
|
const step = steps.find((s70) => s70.id === stepId);
|
|
101434
101434
|
if (step?.dependsOn) {
|
|
101435
101435
|
for (const dep of step.dependsOn) {
|
|
101436
|
-
const result = visit(dep, [...
|
|
101436
|
+
const result = visit(dep, [...path27, stepId]);
|
|
101437
101437
|
if (result) return result;
|
|
101438
101438
|
}
|
|
101439
101439
|
}
|
|
@@ -101531,7 +101531,7 @@ var WorkflowOrchestrator = class {
|
|
|
101531
101531
|
// Private Methods - Utilities
|
|
101532
101532
|
// ============================================================================
|
|
101533
101533
|
delay(ms) {
|
|
101534
|
-
return new Promise((
|
|
101534
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
101535
101535
|
}
|
|
101536
101536
|
};
|
|
101537
101537
|
function createWorkflowOrchestrator(eventBus, memory, agentCoordinator, config) {
|
|
@@ -110861,8 +110861,8 @@ var CrossPhaseHookExecutor = class {
|
|
|
110861
110861
|
try {
|
|
110862
110862
|
const parts = condition.split(/\s*(>|<|>=|<=|==|!=)\s*/);
|
|
110863
110863
|
if (parts.length !== 3) return false;
|
|
110864
|
-
const [
|
|
110865
|
-
const actual = this.getValueFromPath(context2,
|
|
110864
|
+
const [path27, op, value] = parts;
|
|
110865
|
+
const actual = this.getValueFromPath(context2, path27);
|
|
110866
110866
|
const expected = isNaN(Number(value)) ? value : Number(value);
|
|
110867
110867
|
const actualNum = typeof actual === "number" ? actual : Number(actual);
|
|
110868
110868
|
const expectedNum = typeof expected === "number" ? expected : Number(expected);
|
|
@@ -110886,8 +110886,8 @@ var CrossPhaseHookExecutor = class {
|
|
|
110886
110886
|
return false;
|
|
110887
110887
|
}
|
|
110888
110888
|
}
|
|
110889
|
-
getValueFromPath(obj,
|
|
110890
|
-
return
|
|
110889
|
+
getValueFromPath(obj, path27) {
|
|
110890
|
+
return path27.split(".").reduce((curr, key) => {
|
|
110891
110891
|
if (curr && typeof curr === "object" && key in curr) {
|
|
110892
110892
|
return curr[key];
|
|
110893
110893
|
}
|
|
@@ -110896,8 +110896,8 @@ var CrossPhaseHookExecutor = class {
|
|
|
110896
110896
|
}
|
|
110897
110897
|
extractFromContext(extract, context2) {
|
|
110898
110898
|
const result = {};
|
|
110899
|
-
for (const [key,
|
|
110900
|
-
result[key] = this.getValueFromPath(context2,
|
|
110899
|
+
for (const [key, path27] of Object.entries(extract)) {
|
|
110900
|
+
result[key] = this.getValueFromPath(context2, path27);
|
|
110901
110901
|
}
|
|
110902
110902
|
return result;
|
|
110903
110903
|
}
|
|
@@ -111537,7 +111537,7 @@ function startWorkStealingTimer(config, doStealing) {
|
|
|
111537
111537
|
clearInterval(timer);
|
|
111538
111538
|
return;
|
|
111539
111539
|
}
|
|
111540
|
-
await new Promise((
|
|
111540
|
+
await new Promise((resolve15) => setTimeout(resolve15, backoffMs));
|
|
111541
111541
|
}
|
|
111542
111542
|
}, config.workStealing.checkInterval);
|
|
111543
111543
|
return timer;
|
|
@@ -113260,7 +113260,7 @@ var DefaultProtocolExecutor = class {
|
|
|
113260
113260
|
* Sleep helper
|
|
113261
113261
|
*/
|
|
113262
113262
|
sleep(ms) {
|
|
113263
|
-
return new Promise((
|
|
113263
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
113264
113264
|
}
|
|
113265
113265
|
};
|
|
113266
113266
|
|
|
@@ -114039,8 +114039,8 @@ var TokenMetricsCollectorImpl = class _TokenMetricsCollectorImpl {
|
|
|
114039
114039
|
* Save metrics to persistent storage
|
|
114040
114040
|
*/
|
|
114041
114041
|
async save() {
|
|
114042
|
-
const
|
|
114043
|
-
const
|
|
114042
|
+
const fs25 = await import("fs");
|
|
114043
|
+
const path27 = await import("path");
|
|
114044
114044
|
const data = {
|
|
114045
114045
|
version: "1.0.0",
|
|
114046
114046
|
sessionId: this.sessionId,
|
|
@@ -114054,26 +114054,26 @@ var TokenMetricsCollectorImpl = class _TokenMetricsCollectorImpl {
|
|
|
114054
114054
|
},
|
|
114055
114055
|
lastSavedAt: Date.now()
|
|
114056
114056
|
};
|
|
114057
|
-
const filePath =
|
|
114058
|
-
const dirPath =
|
|
114059
|
-
if (!
|
|
114060
|
-
|
|
114057
|
+
const filePath = path27.resolve(this.persistenceConfig.filePath);
|
|
114058
|
+
const dirPath = path27.dirname(filePath);
|
|
114059
|
+
if (!fs25.existsSync(dirPath)) {
|
|
114060
|
+
fs25.mkdirSync(dirPath, { recursive: true });
|
|
114061
114061
|
}
|
|
114062
|
-
|
|
114062
|
+
fs25.writeFileSync(filePath, JSON.stringify(data, null, 2));
|
|
114063
114063
|
this.isDirty = false;
|
|
114064
114064
|
}
|
|
114065
114065
|
/**
|
|
114066
114066
|
* Load metrics from persistent storage
|
|
114067
114067
|
*/
|
|
114068
114068
|
async load() {
|
|
114069
|
-
const
|
|
114070
|
-
const
|
|
114071
|
-
const filePath =
|
|
114072
|
-
if (!
|
|
114069
|
+
const fs25 = await import("fs");
|
|
114070
|
+
const path27 = await import("path");
|
|
114071
|
+
const filePath = path27.resolve(this.persistenceConfig.filePath);
|
|
114072
|
+
if (!fs25.existsSync(filePath)) {
|
|
114073
114073
|
return false;
|
|
114074
114074
|
}
|
|
114075
114075
|
try {
|
|
114076
|
-
const content =
|
|
114076
|
+
const content = fs25.readFileSync(filePath, "utf-8");
|
|
114077
114077
|
const data = safeJsonParse(content);
|
|
114078
114078
|
if (!data.version || !data.version.startsWith("1.")) {
|
|
114079
114079
|
console.warn("[TokenMetricsCollector] Incompatible data version, skipping load");
|
|
@@ -115240,9 +115240,9 @@ function validatePipeline(pipeline10) {
|
|
|
115240
115240
|
function detectCircularDependencies(stages) {
|
|
115241
115241
|
const visited = /* @__PURE__ */ new Set();
|
|
115242
115242
|
const recursionStack = /* @__PURE__ */ new Set();
|
|
115243
|
-
const visit = (stageName,
|
|
115243
|
+
const visit = (stageName, path27) => {
|
|
115244
115244
|
if (recursionStack.has(stageName)) {
|
|
115245
|
-
return [...
|
|
115245
|
+
return [...path27, stageName].join(" -> ");
|
|
115246
115246
|
}
|
|
115247
115247
|
if (visited.has(stageName)) {
|
|
115248
115248
|
return null;
|
|
@@ -115252,7 +115252,7 @@ function detectCircularDependencies(stages) {
|
|
|
115252
115252
|
const stage = stages.find((s70) => s70.name === stageName);
|
|
115253
115253
|
if (stage?.depends_on) {
|
|
115254
115254
|
for (const dep of stage.depends_on) {
|
|
115255
|
-
const result = visit(dep, [...
|
|
115255
|
+
const result = visit(dep, [...path27, stageName]);
|
|
115256
115256
|
if (result) return result;
|
|
115257
115257
|
}
|
|
115258
115258
|
}
|
|
@@ -115722,7 +115722,7 @@ var PersistentScheduler = class {
|
|
|
115722
115722
|
* Sleep for specified milliseconds
|
|
115723
115723
|
*/
|
|
115724
115724
|
sleep(ms) {
|
|
115725
|
-
return new Promise((
|
|
115725
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
115726
115726
|
}
|
|
115727
115727
|
/**
|
|
115728
115728
|
* Log debug message if debug mode is enabled
|
|
@@ -115872,7 +115872,7 @@ var ALL_DOMAINS2 = [
|
|
|
115872
115872
|
"enterprise-integration"
|
|
115873
115873
|
];
|
|
115874
115874
|
function getAQEVersion() {
|
|
115875
|
-
return true ? "3.6.
|
|
115875
|
+
return true ? "3.6.17" : "3.0.0";
|
|
115876
115876
|
}
|
|
115877
115877
|
function createDefaultConfig(projectName, projectRoot) {
|
|
115878
115878
|
return {
|
|
@@ -118664,9 +118664,9 @@ var N8nInstaller = class {
|
|
|
118664
118664
|
// Monorepo location
|
|
118665
118665
|
join21(process.cwd(), "../.claude/agents/n8n")
|
|
118666
118666
|
];
|
|
118667
|
-
for (const
|
|
118668
|
-
if (existsSync19(
|
|
118669
|
-
return
|
|
118667
|
+
for (const path27 of possiblePaths) {
|
|
118668
|
+
if (existsSync19(path27)) {
|
|
118669
|
+
return path27;
|
|
118670
118670
|
}
|
|
118671
118671
|
}
|
|
118672
118672
|
return join21(process.cwd(), ".claude/agents/n8n");
|
|
@@ -118681,9 +118681,9 @@ var N8nInstaller = class {
|
|
|
118681
118681
|
join21(process.cwd(), ".claude/skills"),
|
|
118682
118682
|
join21(__dirname2, "../../assets/skills")
|
|
118683
118683
|
];
|
|
118684
|
-
for (const
|
|
118685
|
-
if (existsSync19(
|
|
118686
|
-
return
|
|
118684
|
+
for (const path27 of possiblePaths) {
|
|
118685
|
+
if (existsSync19(path27)) {
|
|
118686
|
+
return path27;
|
|
118687
118687
|
}
|
|
118688
118688
|
}
|
|
118689
118689
|
return join21(process.cwd(), ".claude/skills");
|
|
@@ -120442,8 +120442,8 @@ var HooksPhase = class extends BasePhase {
|
|
|
120442
120442
|
let installed = false;
|
|
120443
120443
|
for (const src of assetPaths) {
|
|
120444
120444
|
if (existsSync25(src)) {
|
|
120445
|
-
const { copyFileSync:
|
|
120446
|
-
|
|
120445
|
+
const { copyFileSync: copyFileSync10 } = __require("fs");
|
|
120446
|
+
copyFileSync10(src, crossPhasePath);
|
|
120447
120447
|
context2.services.log(" Installed cross-phase memory config");
|
|
120448
120448
|
installed = true;
|
|
120449
120449
|
break;
|
|
@@ -121022,7 +121022,7 @@ try {
|
|
|
121022
121022
|
error: "aqe-mcp not found. Install globally with: npm install -g agentic-qe"
|
|
121023
121023
|
};
|
|
121024
121024
|
}
|
|
121025
|
-
return new Promise((
|
|
121025
|
+
return new Promise((resolve15) => {
|
|
121026
121026
|
try {
|
|
121027
121027
|
const env = {
|
|
121028
121028
|
...process.env,
|
|
@@ -121043,7 +121043,7 @@ try {
|
|
|
121043
121043
|
errorOutput += data.toString();
|
|
121044
121044
|
});
|
|
121045
121045
|
child.on("error", (error) => {
|
|
121046
|
-
|
|
121046
|
+
resolve15({
|
|
121047
121047
|
started: false,
|
|
121048
121048
|
pid: null,
|
|
121049
121049
|
error: error.message
|
|
@@ -121058,12 +121058,12 @@ try {
|
|
|
121058
121058
|
`;
|
|
121059
121059
|
writeFileSync11(logFile, logEntry, { flag: "a" });
|
|
121060
121060
|
child.unref();
|
|
121061
|
-
|
|
121061
|
+
resolve15({
|
|
121062
121062
|
started: true,
|
|
121063
121063
|
pid: child.pid
|
|
121064
121064
|
});
|
|
121065
121065
|
} else {
|
|
121066
|
-
|
|
121066
|
+
resolve15({
|
|
121067
121067
|
started: false,
|
|
121068
121068
|
pid: null,
|
|
121069
121069
|
error: errorOutput || "No PID assigned"
|
|
@@ -121071,7 +121071,7 @@ try {
|
|
|
121071
121071
|
}
|
|
121072
121072
|
} catch {
|
|
121073
121073
|
const errMsg = errorOutput.includes("ERR_MODULE_NOT_FOUND") ? "Missing dependencies. Run: npm install agentic-qe" : errorOutput || "Process exited immediately";
|
|
121074
|
-
|
|
121074
|
+
resolve15({
|
|
121075
121075
|
started: false,
|
|
121076
121076
|
pid: null,
|
|
121077
121077
|
error: errMsg
|
|
@@ -121079,7 +121079,7 @@ try {
|
|
|
121079
121079
|
}
|
|
121080
121080
|
}, 1500);
|
|
121081
121081
|
} catch (error) {
|
|
121082
|
-
|
|
121082
|
+
resolve15({
|
|
121083
121083
|
started: false,
|
|
121084
121084
|
pid: null,
|
|
121085
121085
|
error: error instanceof Error ? error.message : "Spawn failed"
|
|
@@ -123310,7 +123310,7 @@ var TaskHandler14 = class {
|
|
|
123310
123310
|
}
|
|
123311
123311
|
}
|
|
123312
123312
|
if (!completed) {
|
|
123313
|
-
await new Promise((
|
|
123313
|
+
await new Promise((resolve15) => setTimeout(resolve15, 500));
|
|
123314
123314
|
}
|
|
123315
123315
|
}
|
|
123316
123316
|
if (!completed) {
|
|
@@ -123946,8 +123946,8 @@ function createTestCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
123946
123946
|
console.log(chalk9.red("Test generation domain not available"));
|
|
123947
123947
|
return;
|
|
123948
123948
|
}
|
|
123949
|
-
const
|
|
123950
|
-
const targetPath =
|
|
123949
|
+
const path27 = await import("path");
|
|
123950
|
+
const targetPath = path27.resolve(target || ".");
|
|
123951
123951
|
const sourceFiles = walkSourceFiles(targetPath, { includeTests: false });
|
|
123952
123952
|
if (sourceFiles.length === 0) {
|
|
123953
123953
|
console.log(chalk9.yellow("No source files found"));
|
|
@@ -123968,14 +123968,14 @@ function createTestCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
123968
123968
|
console.log(chalk9.cyan(" Tests:"));
|
|
123969
123969
|
for (const test of generated.tests.slice(0, 10)) {
|
|
123970
123970
|
console.log(` ${chalk9.white(test.name)}`);
|
|
123971
|
-
console.log(chalk9.gray(` Source: ${
|
|
123971
|
+
console.log(chalk9.gray(` Source: ${path27.basename(test.sourceFile)}`));
|
|
123972
123972
|
console.log(chalk9.gray(` Assertions: ${test.assertions}`));
|
|
123973
123973
|
if (test.testCode) {
|
|
123974
123974
|
console.log(chalk9.gray(` Test File: ${test.testFile}`));
|
|
123975
|
-
const
|
|
123976
|
-
const testDir =
|
|
123977
|
-
|
|
123978
|
-
|
|
123975
|
+
const fs25 = await import("fs");
|
|
123976
|
+
const testDir = path27.dirname(test.testFile);
|
|
123977
|
+
fs25.mkdirSync(testDir, { recursive: true });
|
|
123978
|
+
fs25.writeFileSync(test.testFile, test.testCode, "utf-8");
|
|
123979
123979
|
console.log(chalk9.green(` Written to: ${test.testFile}`));
|
|
123980
123980
|
}
|
|
123981
123981
|
}
|
|
@@ -123999,8 +123999,8 @@ function createTestCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
123999
123999
|
console.log(chalk9.red("Test execution domain not available"));
|
|
124000
124000
|
return;
|
|
124001
124001
|
}
|
|
124002
|
-
const
|
|
124003
|
-
const targetPath =
|
|
124002
|
+
const path27 = await import("path");
|
|
124003
|
+
const targetPath = path27.resolve(target || ".");
|
|
124004
124004
|
const testFiles = walkSourceFiles(targetPath, { testsOnly: true });
|
|
124005
124005
|
if (testFiles.length === 0) {
|
|
124006
124006
|
console.log(chalk9.yellow("No test files found"));
|
|
@@ -124090,9 +124090,9 @@ var WizardPrompt = class {
|
|
|
124090
124090
|
* Generic prompt helper - wraps readline.question in a Promise
|
|
124091
124091
|
*/
|
|
124092
124092
|
static prompt(rl, question) {
|
|
124093
|
-
return new Promise((
|
|
124093
|
+
return new Promise((resolve15) => {
|
|
124094
124094
|
rl.question(question, (answer) => {
|
|
124095
|
-
|
|
124095
|
+
resolve15(answer);
|
|
124096
124096
|
});
|
|
124097
124097
|
});
|
|
124098
124098
|
}
|
|
@@ -124261,8 +124261,8 @@ var WizardFormat = class {
|
|
|
124261
124261
|
/**
|
|
124262
124262
|
* Format a path relative to cwd
|
|
124263
124263
|
*/
|
|
124264
|
-
static relativePath(
|
|
124265
|
-
return relative6(cwd,
|
|
124264
|
+
static relativePath(path27, cwd) {
|
|
124265
|
+
return relative6(cwd, path27) || ".";
|
|
124266
124266
|
}
|
|
124267
124267
|
/**
|
|
124268
124268
|
* Format a boolean as Yes/No
|
|
@@ -124903,9 +124903,9 @@ function createCoverageCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
124903
124903
|
console.log(chalk13.red("Coverage analysis domain not available"));
|
|
124904
124904
|
return;
|
|
124905
124905
|
}
|
|
124906
|
-
const
|
|
124907
|
-
const
|
|
124908
|
-
const targetPath =
|
|
124906
|
+
const fs25 = await import("fs");
|
|
124907
|
+
const path27 = await import("path");
|
|
124908
|
+
const targetPath = path27.resolve(analyzeTarget);
|
|
124909
124909
|
const sourceFiles = walkSourceFiles(targetPath, { includeTests: false });
|
|
124910
124910
|
if (sourceFiles.length === 0) {
|
|
124911
124911
|
console.log(chalk13.yellow("No source files found"));
|
|
@@ -124914,11 +124914,11 @@ function createCoverageCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
124914
124914
|
console.log(chalk13.gray(` Analyzing ${sourceFiles.length} files...
|
|
124915
124915
|
`));
|
|
124916
124916
|
const files = sourceFiles.map((filePath) => {
|
|
124917
|
-
const content =
|
|
124917
|
+
const content = fs25.readFileSync(filePath, "utf-8");
|
|
124918
124918
|
const lines = content.split("\n");
|
|
124919
124919
|
const totalLines2 = lines.length;
|
|
124920
124920
|
const testFile = filePath.replace(".ts", ".test.ts").replace("/src/", "/tests/");
|
|
124921
|
-
const hasTest =
|
|
124921
|
+
const hasTest = fs25.existsSync(testFile);
|
|
124922
124922
|
const coverageRate = hasTest ? 0.75 + Math.random() * 0.2 : 0.2 + Math.random() * 0.3;
|
|
124923
124923
|
const coveredLines2 = Math.floor(totalLines2 * coverageRate);
|
|
124924
124924
|
const uncoveredLines = Array.from({ length: totalLines2 - coveredLines2 }, (_56, i58) => i58 + coveredLines2 + 1);
|
|
@@ -125092,8 +125092,8 @@ function createSecurityCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125092
125092
|
console.log(chalk15.red("Security domain not available"));
|
|
125093
125093
|
return;
|
|
125094
125094
|
}
|
|
125095
|
-
const
|
|
125096
|
-
const targetPath =
|
|
125095
|
+
const path27 = await import("path");
|
|
125096
|
+
const targetPath = path27.resolve(options.target);
|
|
125097
125097
|
const files = walkSourceFiles(targetPath, { includeTests: true });
|
|
125098
125098
|
if (files.length === 0) {
|
|
125099
125099
|
console.log(chalk15.yellow("No files found to scan"));
|
|
@@ -125169,12 +125169,12 @@ function createCodeCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125169
125169
|
console.log(chalk16.red("Code intelligence domain not available"));
|
|
125170
125170
|
return;
|
|
125171
125171
|
}
|
|
125172
|
-
const
|
|
125172
|
+
const path27 = await import("path");
|
|
125173
125173
|
if (action === "index") {
|
|
125174
125174
|
console.log(chalk16.blue(`
|
|
125175
125175
|
Indexing codebase at ${target || "."}...
|
|
125176
125176
|
`));
|
|
125177
|
-
const targetPath =
|
|
125177
|
+
const targetPath = path27.resolve(target || ".");
|
|
125178
125178
|
const paths = walkSourceFiles(targetPath, {
|
|
125179
125179
|
includeTests: options.includeTests || false
|
|
125180
125180
|
});
|
|
@@ -125235,7 +125235,7 @@ function createCodeCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125235
125235
|
console.log(chalk16.blue(`
|
|
125236
125236
|
Analyzing impact for ${target || "recent changes"}...
|
|
125237
125237
|
`));
|
|
125238
|
-
const targetPath =
|
|
125238
|
+
const targetPath = path27.resolve(target || ".");
|
|
125239
125239
|
const changedFiles = walkSourceFiles(targetPath, { maxDepth: 2 }).slice(0, 10);
|
|
125240
125240
|
const result = await codeAPI.analyzeImpact({
|
|
125241
125241
|
changedFiles,
|
|
@@ -125281,7 +125281,7 @@ function createCodeCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125281
125281
|
console.log(chalk16.blue(`
|
|
125282
125282
|
Mapping dependencies for ${target || "."}...
|
|
125283
125283
|
`));
|
|
125284
|
-
const targetPath =
|
|
125284
|
+
const targetPath = path27.resolve(target || ".");
|
|
125285
125285
|
const files = walkSourceFiles(targetPath, { maxDepth: 2 }).slice(0, 50);
|
|
125286
125286
|
const result = await codeAPI.mapDependencies({
|
|
125287
125287
|
files,
|
|
@@ -125433,32 +125433,32 @@ var v3Agents = [
|
|
|
125433
125433
|
function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
125434
125434
|
const migrateCmd = new Command6("migrate").description("V2-to-V3 migration tools with agent compatibility (ADR-048)");
|
|
125435
125435
|
migrateCmd.command("run").description("Run full migration from v2 to v3").option("--dry-run", "Preview migration without making changes").option("--backup", "Create backup before migration (recommended)", true).option("--skip-memory", "Skip memory database migration").option("--skip-patterns", "Skip pattern migration").option("--skip-config", "Skip configuration migration").option("--skip-agents", "Skip agent name migration").option("--target <component>", "Migrate specific component (agents, skills, config, memory)").option("--force", "Force migration even if v3 already exists").action(async (options) => {
|
|
125436
|
-
const
|
|
125437
|
-
const
|
|
125436
|
+
const fs25 = await import("fs");
|
|
125437
|
+
const path27 = await import("path");
|
|
125438
125438
|
console.log(chalk17.blue("\n V2 to V3 Migration (ADR-048)\n"));
|
|
125439
125439
|
const cwd = process.cwd();
|
|
125440
|
-
const v2Dir =
|
|
125441
|
-
const v3Dir =
|
|
125442
|
-
const claudeAgentDir =
|
|
125440
|
+
const v2Dir = path27.join(cwd, ".agentic-qe");
|
|
125441
|
+
const v3Dir = path27.join(cwd, ".aqe");
|
|
125442
|
+
const claudeAgentDir = path27.join(cwd, ".claude", "agents");
|
|
125443
125443
|
console.log(chalk17.white("1. Detecting v2 installation..."));
|
|
125444
|
-
const hasV2Dir =
|
|
125445
|
-
const hasClaudeAgents =
|
|
125444
|
+
const hasV2Dir = fs25.existsSync(v2Dir);
|
|
125445
|
+
const hasClaudeAgents = fs25.existsSync(claudeAgentDir);
|
|
125446
125446
|
if (!hasV2Dir && !hasClaudeAgents) {
|
|
125447
125447
|
console.log(chalk17.yellow(" ! No v2 installation found"));
|
|
125448
125448
|
console.log(chalk17.gray(" This might be a fresh project. Use `aqe init` instead."));
|
|
125449
125449
|
await cleanupAndExit2(0);
|
|
125450
125450
|
}
|
|
125451
125451
|
const v2Files = {
|
|
125452
|
-
memoryDb:
|
|
125453
|
-
config:
|
|
125454
|
-
patterns:
|
|
125452
|
+
memoryDb: path27.join(v2Dir, "memory.db"),
|
|
125453
|
+
config: path27.join(v2Dir, "config.json"),
|
|
125454
|
+
patterns: path27.join(v2Dir, "patterns")
|
|
125455
125455
|
};
|
|
125456
|
-
const hasMemory = hasV2Dir &&
|
|
125457
|
-
const hasConfig = hasV2Dir &&
|
|
125458
|
-
const hasPatterns = hasV2Dir &&
|
|
125456
|
+
const hasMemory = hasV2Dir && fs25.existsSync(v2Files.memoryDb);
|
|
125457
|
+
const hasConfig = hasV2Dir && fs25.existsSync(v2Files.config);
|
|
125458
|
+
const hasPatterns = hasV2Dir && fs25.existsSync(v2Files.patterns);
|
|
125459
125459
|
const agentsToMigrate = [];
|
|
125460
125460
|
if (hasClaudeAgents) {
|
|
125461
|
-
const files =
|
|
125461
|
+
const files = fs25.readdirSync(claudeAgentDir);
|
|
125462
125462
|
for (const file of files) {
|
|
125463
125463
|
if (file.endsWith(".md") && file.startsWith("qe-")) {
|
|
125464
125464
|
const agentName = file.replace(".md", "");
|
|
@@ -125475,7 +125475,7 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125475
125475
|
console.log(chalk17.gray(` Agents to migrate: ${agentsToMigrate.length}
|
|
125476
125476
|
`));
|
|
125477
125477
|
console.log(chalk17.white("2. Checking v3 status..."));
|
|
125478
|
-
if (
|
|
125478
|
+
if (fs25.existsSync(v3Dir) && !options.force) {
|
|
125479
125479
|
console.log(chalk17.yellow(" ! v3 directory already exists at .aqe/"));
|
|
125480
125480
|
console.log(chalk17.gray(" Use --force to overwrite existing v3 installation."));
|
|
125481
125481
|
await cleanupAndExit2(1);
|
|
@@ -125484,14 +125484,14 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125484
125484
|
if (options.dryRun) {
|
|
125485
125485
|
console.log(chalk17.blue(" Dry Run - Migration Plan:\n"));
|
|
125486
125486
|
if (!options.skipMemory && hasMemory) {
|
|
125487
|
-
const stats =
|
|
125487
|
+
const stats = fs25.statSync(v2Files.memoryDb);
|
|
125488
125488
|
console.log(chalk17.gray(` - Migrate memory.db (${(stats.size / 1024).toFixed(1)} KB)`));
|
|
125489
125489
|
}
|
|
125490
125490
|
if (!options.skipConfig && hasConfig) {
|
|
125491
125491
|
console.log(chalk17.gray(" - Convert config.json to v3 format"));
|
|
125492
125492
|
}
|
|
125493
125493
|
if (!options.skipPatterns && hasPatterns) {
|
|
125494
|
-
const patternFiles =
|
|
125494
|
+
const patternFiles = fs25.readdirSync(v2Files.patterns);
|
|
125495
125495
|
console.log(chalk17.gray(` - Migrate ${patternFiles.length} pattern files`));
|
|
125496
125496
|
}
|
|
125497
125497
|
if (!options.skipAgents && agentsToMigrate.length > 0) {
|
|
@@ -125506,22 +125506,22 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125506
125506
|
}
|
|
125507
125507
|
if (options.backup) {
|
|
125508
125508
|
console.log(chalk17.white("3. Creating backup..."));
|
|
125509
|
-
const backupDir =
|
|
125509
|
+
const backupDir = path27.join(cwd, ".aqe-backup", `backup-${Date.now()}`);
|
|
125510
125510
|
try {
|
|
125511
|
-
|
|
125511
|
+
fs25.mkdirSync(backupDir, { recursive: true });
|
|
125512
125512
|
const copyDir = (src, dest) => {
|
|
125513
|
-
if (!
|
|
125514
|
-
if (
|
|
125515
|
-
|
|
125516
|
-
for (const file of
|
|
125517
|
-
copyDir(
|
|
125513
|
+
if (!fs25.existsSync(src)) return;
|
|
125514
|
+
if (fs25.statSync(src).isDirectory()) {
|
|
125515
|
+
fs25.mkdirSync(dest, { recursive: true });
|
|
125516
|
+
for (const file of fs25.readdirSync(src)) {
|
|
125517
|
+
copyDir(path27.join(src, file), path27.join(dest, file));
|
|
125518
125518
|
}
|
|
125519
125519
|
} else {
|
|
125520
|
-
|
|
125520
|
+
fs25.copyFileSync(src, dest);
|
|
125521
125521
|
}
|
|
125522
125522
|
};
|
|
125523
|
-
if (hasV2Dir) copyDir(v2Dir,
|
|
125524
|
-
if (hasClaudeAgents) copyDir(claudeAgentDir,
|
|
125523
|
+
if (hasV2Dir) copyDir(v2Dir, path27.join(backupDir, ".agentic-qe"));
|
|
125524
|
+
if (hasClaudeAgents) copyDir(claudeAgentDir, path27.join(backupDir, ".claude", "agents"));
|
|
125525
125525
|
console.log(chalk17.green(` * Backup created at .aqe-backup/
|
|
125526
125526
|
`));
|
|
125527
125527
|
} catch (err3) {
|
|
@@ -125534,11 +125534,11 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125534
125534
|
if (!options.target || options.target === "config" || options.target === "memory") {
|
|
125535
125535
|
console.log(chalk17.white("4. Creating v3 directory structure..."));
|
|
125536
125536
|
try {
|
|
125537
|
-
|
|
125538
|
-
|
|
125539
|
-
|
|
125540
|
-
|
|
125541
|
-
|
|
125537
|
+
fs25.mkdirSync(v3Dir, { recursive: true });
|
|
125538
|
+
fs25.mkdirSync(path27.join(v3Dir, "agentdb"), { recursive: true });
|
|
125539
|
+
fs25.mkdirSync(path27.join(v3Dir, "reasoning-bank"), { recursive: true });
|
|
125540
|
+
fs25.mkdirSync(path27.join(v3Dir, "cache"), { recursive: true });
|
|
125541
|
+
fs25.mkdirSync(path27.join(v3Dir, "logs"), { recursive: true });
|
|
125542
125542
|
console.log(chalk17.green(" * Directory structure created\n"));
|
|
125543
125543
|
} catch (err3) {
|
|
125544
125544
|
console.log(chalk17.red(` x Failed: ${err3}
|
|
@@ -125549,17 +125549,17 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125549
125549
|
if ((!options.target || options.target === "memory") && !options.skipMemory && hasMemory) {
|
|
125550
125550
|
console.log(chalk17.white("5. Migrating memory database..."));
|
|
125551
125551
|
try {
|
|
125552
|
-
const destDb =
|
|
125553
|
-
|
|
125554
|
-
const indexFile =
|
|
125555
|
-
|
|
125552
|
+
const destDb = path27.join(v3Dir, "agentdb", "memory.db");
|
|
125553
|
+
fs25.copyFileSync(v2Files.memoryDb, destDb);
|
|
125554
|
+
const indexFile = path27.join(v3Dir, "agentdb", "index.json");
|
|
125555
|
+
fs25.writeFileSync(indexFile, JSON.stringify({
|
|
125556
125556
|
version: "3.0.0",
|
|
125557
125557
|
migratedFrom: "v2",
|
|
125558
125558
|
migratedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
125559
125559
|
hnswEnabled: true,
|
|
125560
125560
|
vectorDimensions: 768
|
|
125561
125561
|
}, null, 2));
|
|
125562
|
-
const stats =
|
|
125562
|
+
const stats = fs25.statSync(v2Files.memoryDb);
|
|
125563
125563
|
console.log(chalk17.green(` * Memory database migrated (${(stats.size / 1024).toFixed(1)} KB)
|
|
125564
125564
|
`));
|
|
125565
125565
|
} catch (err3) {
|
|
@@ -125576,7 +125576,7 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125576
125576
|
if ((!options.target || options.target === "config") && !options.skipConfig && hasConfig) {
|
|
125577
125577
|
console.log(chalk17.white("6. Migrating configuration..."));
|
|
125578
125578
|
try {
|
|
125579
|
-
const v2ConfigRaw =
|
|
125579
|
+
const v2ConfigRaw = fs25.readFileSync(v2Files.config, "utf-8");
|
|
125580
125580
|
const v2Config = parseJsonFile(v2ConfigRaw, v2Files.config);
|
|
125581
125581
|
const v3Config = {
|
|
125582
125582
|
version: "3.0.0",
|
|
@@ -125612,8 +125612,8 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125612
125612
|
migrationDate: (/* @__PURE__ */ new Date()).toISOString()
|
|
125613
125613
|
}
|
|
125614
125614
|
};
|
|
125615
|
-
const destConfig =
|
|
125616
|
-
|
|
125615
|
+
const destConfig = path27.join(v3Dir, "config.json");
|
|
125616
|
+
fs25.writeFileSync(destConfig, JSON.stringify(v3Config, null, 2));
|
|
125617
125617
|
console.log(chalk17.green(" * Configuration migrated\n"));
|
|
125618
125618
|
} catch (err3) {
|
|
125619
125619
|
console.log(chalk17.red(` x Config migration failed: ${err3}
|
|
@@ -125629,18 +125629,18 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125629
125629
|
if ((!options.target || options.target === "memory") && !options.skipPatterns && hasPatterns) {
|
|
125630
125630
|
console.log(chalk17.white("7. Migrating patterns to ReasoningBank..."));
|
|
125631
125631
|
try {
|
|
125632
|
-
const patternFiles =
|
|
125632
|
+
const patternFiles = fs25.readdirSync(v2Files.patterns);
|
|
125633
125633
|
let migratedCount = 0;
|
|
125634
125634
|
for (const file of patternFiles) {
|
|
125635
|
-
const srcPath =
|
|
125636
|
-
const destPath =
|
|
125637
|
-
if (
|
|
125638
|
-
|
|
125635
|
+
const srcPath = path27.join(v2Files.patterns, file);
|
|
125636
|
+
const destPath = path27.join(v3Dir, "reasoning-bank", file);
|
|
125637
|
+
if (fs25.statSync(srcPath).isFile()) {
|
|
125638
|
+
fs25.copyFileSync(srcPath, destPath);
|
|
125639
125639
|
migratedCount++;
|
|
125640
125640
|
}
|
|
125641
125641
|
}
|
|
125642
|
-
const indexPath =
|
|
125643
|
-
|
|
125642
|
+
const indexPath = path27.join(v3Dir, "reasoning-bank", "index.json");
|
|
125643
|
+
fs25.writeFileSync(indexPath, JSON.stringify({
|
|
125644
125644
|
version: "3.0.0",
|
|
125645
125645
|
migratedFrom: "v2",
|
|
125646
125646
|
migratedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -125661,17 +125661,17 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125661
125661
|
if ((!options.target || options.target === "agents") && !options.skipAgents && agentsToMigrate.length > 0) {
|
|
125662
125662
|
console.log(chalk17.white("8. Migrating agent names (ADR-048)..."));
|
|
125663
125663
|
let migratedAgents = 0;
|
|
125664
|
-
const deprecatedDir =
|
|
125665
|
-
if (!
|
|
125666
|
-
|
|
125664
|
+
const deprecatedDir = path27.join(claudeAgentDir, "deprecated");
|
|
125665
|
+
if (!fs25.existsSync(deprecatedDir)) {
|
|
125666
|
+
fs25.mkdirSync(deprecatedDir, { recursive: true });
|
|
125667
125667
|
}
|
|
125668
125668
|
for (const v2Name of agentsToMigrate) {
|
|
125669
125669
|
const v3Name = resolveAgentName(v2Name);
|
|
125670
|
-
const v2FilePath =
|
|
125671
|
-
const v3FilePath =
|
|
125672
|
-
const deprecatedPath =
|
|
125670
|
+
const v2FilePath = path27.join(claudeAgentDir, `${v2Name}.md`);
|
|
125671
|
+
const v3FilePath = path27.join(claudeAgentDir, `${v3Name}.md`);
|
|
125672
|
+
const deprecatedPath = path27.join(deprecatedDir, `${v2Name}.md.v2`);
|
|
125673
125673
|
try {
|
|
125674
|
-
const content =
|
|
125674
|
+
const content = fs25.readFileSync(v2FilePath, "utf-8");
|
|
125675
125675
|
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
125676
125676
|
if (!frontmatterMatch) {
|
|
125677
125677
|
console.log(chalk17.yellow(` ! ${v2Name}: No frontmatter found, skipping`));
|
|
@@ -125699,8 +125699,8 @@ v2_compat:
|
|
|
125699
125699
|
const newContent = `---
|
|
125700
125700
|
${newFrontmatter}
|
|
125701
125701
|
---${body}`;
|
|
125702
|
-
|
|
125703
|
-
|
|
125702
|
+
fs25.writeFileSync(v3FilePath, newContent, "utf-8");
|
|
125703
|
+
fs25.renameSync(v2FilePath, deprecatedPath);
|
|
125704
125704
|
console.log(chalk17.gray(` ${v2Name} -> ${v3Name}`));
|
|
125705
125705
|
migratedAgents++;
|
|
125706
125706
|
} catch (err3) {
|
|
@@ -125721,10 +125721,10 @@ ${newFrontmatter}
|
|
|
125721
125721
|
}
|
|
125722
125722
|
console.log(chalk17.white("9. Validating migration..."));
|
|
125723
125723
|
const validationResults = {
|
|
125724
|
-
v3DirExists:
|
|
125725
|
-
configExists:
|
|
125726
|
-
agentdbExists:
|
|
125727
|
-
reasoningBankExists:
|
|
125724
|
+
v3DirExists: fs25.existsSync(v3Dir),
|
|
125725
|
+
configExists: fs25.existsSync(path27.join(v3Dir, "config.json")),
|
|
125726
|
+
agentdbExists: fs25.existsSync(path27.join(v3Dir, "agentdb")),
|
|
125727
|
+
reasoningBankExists: fs25.existsSync(path27.join(v3Dir, "reasoning-bank"))
|
|
125728
125728
|
};
|
|
125729
125729
|
const allValid = Object.values(validationResults).every((v62) => v62);
|
|
125730
125730
|
if (allValid) {
|
|
@@ -125744,18 +125744,18 @@ ${newFrontmatter}
|
|
|
125744
125744
|
await cleanupAndExit2(0);
|
|
125745
125745
|
});
|
|
125746
125746
|
migrateCmd.command("status").description("Check migration status of current project").option("--json", "Output as JSON").action(async (options) => {
|
|
125747
|
-
const
|
|
125748
|
-
const
|
|
125747
|
+
const fs25 = await import("fs");
|
|
125748
|
+
const path27 = await import("path");
|
|
125749
125749
|
const cwd = process.cwd();
|
|
125750
|
-
const v2Dir =
|
|
125751
|
-
const v3Dir =
|
|
125752
|
-
const claudeAgentDir =
|
|
125753
|
-
const isV2Project =
|
|
125754
|
-
const isV3Project =
|
|
125750
|
+
const v2Dir = path27.join(cwd, ".agentic-qe");
|
|
125751
|
+
const v3Dir = path27.join(cwd, ".aqe");
|
|
125752
|
+
const claudeAgentDir = path27.join(cwd, ".claude", "agents");
|
|
125753
|
+
const isV2Project = fs25.existsSync(v2Dir);
|
|
125754
|
+
const isV3Project = fs25.existsSync(v3Dir);
|
|
125755
125755
|
const agentsToMigrate = [];
|
|
125756
125756
|
const agentsMigrated = [];
|
|
125757
|
-
if (
|
|
125758
|
-
const files =
|
|
125757
|
+
if (fs25.existsSync(claudeAgentDir)) {
|
|
125758
|
+
const files = fs25.readdirSync(claudeAgentDir);
|
|
125759
125759
|
for (const file of files) {
|
|
125760
125760
|
if (file.endsWith(".md") && file.startsWith("qe-")) {
|
|
125761
125761
|
const agentName = file.replace(".md", "");
|
|
@@ -125804,15 +125804,15 @@ ${newFrontmatter}
|
|
|
125804
125804
|
await cleanupAndExit2(0);
|
|
125805
125805
|
});
|
|
125806
125806
|
migrateCmd.command("verify").description("Verify migration integrity").option("--fix", "Attempt to fix issues automatically").action(async (options) => {
|
|
125807
|
-
const
|
|
125808
|
-
const
|
|
125807
|
+
const fs25 = await import("fs");
|
|
125808
|
+
const path27 = await import("path");
|
|
125809
125809
|
console.log(chalk17.bold("\n Verifying Migration...\n"));
|
|
125810
125810
|
const cwd = process.cwd();
|
|
125811
|
-
const v3Dir =
|
|
125812
|
-
const claudeAgentDir =
|
|
125811
|
+
const v3Dir = path27.join(cwd, ".aqe");
|
|
125812
|
+
const claudeAgentDir = path27.join(cwd, ".claude", "agents");
|
|
125813
125813
|
const deprecatedInUse = [];
|
|
125814
|
-
if (
|
|
125815
|
-
const files =
|
|
125814
|
+
if (fs25.existsSync(claudeAgentDir)) {
|
|
125815
|
+
const files = fs25.readdirSync(claudeAgentDir);
|
|
125816
125816
|
for (const file of files) {
|
|
125817
125817
|
if (file.endsWith(".md") && file.startsWith("qe-")) {
|
|
125818
125818
|
const agentName = file.replace(".md", "");
|
|
@@ -125825,8 +125825,8 @@ ${newFrontmatter}
|
|
|
125825
125825
|
const checks = [
|
|
125826
125826
|
{
|
|
125827
125827
|
name: "V3 Directory",
|
|
125828
|
-
passed:
|
|
125829
|
-
message:
|
|
125828
|
+
passed: fs25.existsSync(v3Dir),
|
|
125829
|
+
message: fs25.existsSync(v3Dir) ? "Exists" : "Missing .aqe/"
|
|
125830
125830
|
},
|
|
125831
125831
|
{
|
|
125832
125832
|
name: "Agent Compatibility",
|
|
@@ -125835,7 +125835,7 @@ ${newFrontmatter}
|
|
|
125835
125835
|
},
|
|
125836
125836
|
{
|
|
125837
125837
|
name: "Config Format",
|
|
125838
|
-
passed:
|
|
125838
|
+
passed: fs25.existsSync(path27.join(v3Dir, "config.json")),
|
|
125839
125839
|
message: "Valid v3 config"
|
|
125840
125840
|
}
|
|
125841
125841
|
];
|
|
@@ -125860,15 +125860,15 @@ ${newFrontmatter}
|
|
|
125860
125860
|
await cleanupAndExit2(0);
|
|
125861
125861
|
});
|
|
125862
125862
|
migrateCmd.command("rollback").description("Rollback to previous version from backup").option("--backup-id <id>", "Specific backup to restore").option("--force", "Skip confirmation").action(async (options) => {
|
|
125863
|
-
const
|
|
125864
|
-
const
|
|
125863
|
+
const fs25 = await import("fs");
|
|
125864
|
+
const path27 = await import("path");
|
|
125865
125865
|
const cwd = process.cwd();
|
|
125866
|
-
const backupRoot =
|
|
125867
|
-
if (!
|
|
125866
|
+
const backupRoot = path27.join(cwd, ".aqe-backup");
|
|
125867
|
+
if (!fs25.existsSync(backupRoot)) {
|
|
125868
125868
|
console.log(chalk17.yellow("\n! No backups found.\n"));
|
|
125869
125869
|
return;
|
|
125870
125870
|
}
|
|
125871
|
-
const backups =
|
|
125871
|
+
const backups = fs25.readdirSync(backupRoot).filter((f74) => f74.startsWith("backup-")).sort().reverse();
|
|
125872
125872
|
if (backups.length === 0) {
|
|
125873
125873
|
console.log(chalk17.yellow("\n! No backups found.\n"));
|
|
125874
125874
|
return;
|
|
@@ -125880,8 +125880,8 @@ ${newFrontmatter}
|
|
|
125880
125880
|
console.log(` ${chalk17.cyan(backup)} - ${date.toLocaleString()}`);
|
|
125881
125881
|
}
|
|
125882
125882
|
const targetBackup = options.backupId || backups[0];
|
|
125883
|
-
const backupPath =
|
|
125884
|
-
if (!
|
|
125883
|
+
const backupPath = path27.join(backupRoot, targetBackup);
|
|
125884
|
+
if (!fs25.existsSync(backupPath)) {
|
|
125885
125885
|
console.log(chalk17.red(`
|
|
125886
125886
|
Backup not found: ${targetBackup}
|
|
125887
125887
|
`));
|
|
@@ -125896,21 +125896,21 @@ ${newFrontmatter}
|
|
|
125896
125896
|
console.log(chalk17.bold(`
|
|
125897
125897
|
Rolling back to ${targetBackup}...
|
|
125898
125898
|
`));
|
|
125899
|
-
const v2Backup =
|
|
125900
|
-
const agentsBackup =
|
|
125901
|
-
if (
|
|
125902
|
-
const v2Dir =
|
|
125903
|
-
|
|
125899
|
+
const v2Backup = path27.join(backupPath, ".agentic-qe");
|
|
125900
|
+
const agentsBackup = path27.join(backupPath, ".claude", "agents");
|
|
125901
|
+
if (fs25.existsSync(v2Backup)) {
|
|
125902
|
+
const v2Dir = path27.join(cwd, ".agentic-qe");
|
|
125903
|
+
fs25.cpSync(v2Backup, v2Dir, { recursive: true });
|
|
125904
125904
|
console.log(chalk17.dim(" Restored .agentic-qe/"));
|
|
125905
125905
|
}
|
|
125906
|
-
if (
|
|
125907
|
-
const agentsDir =
|
|
125908
|
-
|
|
125906
|
+
if (fs25.existsSync(agentsBackup)) {
|
|
125907
|
+
const agentsDir = path27.join(cwd, ".claude", "agents");
|
|
125908
|
+
fs25.cpSync(agentsBackup, agentsDir, { recursive: true });
|
|
125909
125909
|
console.log(chalk17.dim(" Restored .claude/agents/"));
|
|
125910
125910
|
}
|
|
125911
|
-
const v3Dir =
|
|
125912
|
-
if (
|
|
125913
|
-
|
|
125911
|
+
const v3Dir = path27.join(cwd, ".aqe");
|
|
125912
|
+
if (fs25.existsSync(v3Dir)) {
|
|
125913
|
+
fs25.rmSync(v3Dir, { recursive: true, force: true });
|
|
125914
125914
|
console.log(chalk17.dim(" Removed .aqe/"));
|
|
125915
125915
|
}
|
|
125916
125916
|
console.log(chalk17.green("\n Rollback complete!\n"));
|
|
@@ -127468,8 +127468,8 @@ function createCompletionsCommand(cleanupAndExit2) {
|
|
|
127468
127468
|
console.log(generateCompletion("powershell"));
|
|
127469
127469
|
});
|
|
127470
127470
|
completionsCmd.command("install").description("Auto-install completions for current shell").option("-s, --shell <shell>", "Target shell (bash|zsh|fish|powershell)").action(async (options) => {
|
|
127471
|
-
const
|
|
127472
|
-
const
|
|
127471
|
+
const fs25 = await import("fs");
|
|
127472
|
+
const path27 = await import("path");
|
|
127473
127473
|
const shellInfo = options.shell ? { name: options.shell, configFile: null, detected: false } : detectShell();
|
|
127474
127474
|
if (shellInfo.name === "unknown") {
|
|
127475
127475
|
console.log(chalk18.red("Could not detect shell. Please specify with --shell option.\n"));
|
|
@@ -127483,11 +127483,11 @@ Installing completions for ${shellInfo.name}...
|
|
|
127483
127483
|
const script = generateCompletion(shellInfo.name);
|
|
127484
127484
|
if (shellInfo.name === "fish") {
|
|
127485
127485
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
127486
|
-
const fishCompletionsDir =
|
|
127486
|
+
const fishCompletionsDir = path27.join(homeDir, ".config", "fish", "completions");
|
|
127487
127487
|
try {
|
|
127488
|
-
|
|
127489
|
-
const completionFile =
|
|
127490
|
-
|
|
127488
|
+
fs25.mkdirSync(fishCompletionsDir, { recursive: true });
|
|
127489
|
+
const completionFile = path27.join(fishCompletionsDir, "aqe.fish");
|
|
127490
|
+
fs25.writeFileSync(completionFile, script);
|
|
127491
127491
|
console.log(chalk18.green(`Completions installed to: ${completionFile}`));
|
|
127492
127492
|
console.log(chalk18.gray("\nRestart your shell or run: source ~/.config/fish/completions/aqe.fish\n"));
|
|
127493
127493
|
} catch (err3) {
|
|
@@ -127719,13 +127719,13 @@ var FleetInitEnhancer = class {
|
|
|
127719
127719
|
input: process.stdin,
|
|
127720
127720
|
output: process.stdout
|
|
127721
127721
|
});
|
|
127722
|
-
return new Promise((
|
|
127722
|
+
return new Promise((resolve15) => {
|
|
127723
127723
|
rl.question(
|
|
127724
127724
|
chalk19.white(" Run code intelligence scan now? [Y/n]: "),
|
|
127725
127725
|
(answer) => {
|
|
127726
127726
|
rl.close();
|
|
127727
127727
|
const normalized = answer.trim().toLowerCase();
|
|
127728
|
-
|
|
127728
|
+
resolve15(normalized === "" || normalized === "y" || normalized === "yes");
|
|
127729
127729
|
}
|
|
127730
127730
|
);
|
|
127731
127731
|
});
|
|
@@ -128227,11 +128227,11 @@ function createFleetCommand(context2, cleanupAndExit2, ensureInitialized2, regis
|
|
|
128227
128227
|
}
|
|
128228
128228
|
const results = await Promise.all(
|
|
128229
128229
|
agentOperations.map(async (op, index) => {
|
|
128230
|
-
await new Promise((
|
|
128230
|
+
await new Promise((resolve15) => setTimeout(resolve15, index * 200));
|
|
128231
128231
|
progress.updateAgent(op.id, 0, { status: "running" });
|
|
128232
128232
|
try {
|
|
128233
128233
|
for (let p74 = 10; p74 <= 90; p74 += 20) {
|
|
128234
|
-
await new Promise((
|
|
128234
|
+
await new Promise((resolve15) => setTimeout(resolve15, 300 + Math.random() * 200));
|
|
128235
128235
|
progress.updateAgent(op.id, p74, {
|
|
128236
128236
|
eta: Math.round((100 - p74) * 50)
|
|
128237
128237
|
});
|
|
@@ -128654,7 +128654,7 @@ var SwarmSkillValidator = class {
|
|
|
128654
128654
|
* Helper to delay execution
|
|
128655
128655
|
*/
|
|
128656
128656
|
delay(ms) {
|
|
128657
|
-
return new Promise((
|
|
128657
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
128658
128658
|
}
|
|
128659
128659
|
/**
|
|
128660
128660
|
* Get current configuration
|
|
@@ -128740,7 +128740,7 @@ var DEFAULT_PARALLEL_EVAL_CONFIG = {
|
|
|
128740
128740
|
var MockLLMExecutor = class {
|
|
128741
128741
|
async execute(prompt, model, options) {
|
|
128742
128742
|
const delay = Math.random() * MOCK_LLM_MAX_DELAY_MS + MOCK_LLM_MIN_DELAY_MS;
|
|
128743
|
-
await new Promise((
|
|
128743
|
+
await new Promise((resolve15) => setTimeout(resolve15, delay));
|
|
128744
128744
|
const output = this.generateMockResponse(prompt);
|
|
128745
128745
|
return {
|
|
128746
128746
|
output,
|
|
@@ -133008,6 +133008,160 @@ import chalk26 from "chalk";
|
|
|
133008
133008
|
import ora2 from "ora";
|
|
133009
133009
|
|
|
133010
133010
|
// src/sync/interfaces.ts
|
|
133011
|
+
var DEFAULT_PULL_CONFIG = {
|
|
133012
|
+
cloud: {
|
|
133013
|
+
project: process.env.GCP_PROJECT || "",
|
|
133014
|
+
zone: process.env.GCP_ZONE || "",
|
|
133015
|
+
instance: process.env.GCP_INSTANCE || "",
|
|
133016
|
+
database: process.env.GCP_DATABASE || "",
|
|
133017
|
+
user: process.env.GCP_USER || "",
|
|
133018
|
+
tunnelPort: parseInt(process.env.GCP_TUNNEL_PORT || "15432", 10)
|
|
133019
|
+
},
|
|
133020
|
+
environment: process.env.AQE_ENV || "all",
|
|
133021
|
+
batchSize: 1e3,
|
|
133022
|
+
sources: [
|
|
133023
|
+
// QE Patterns (cloud 0 records, but may grow)
|
|
133024
|
+
{
|
|
133025
|
+
name: "qe-patterns",
|
|
133026
|
+
cloudTable: "aqe.qe_patterns",
|
|
133027
|
+
localTable: "qe_patterns",
|
|
133028
|
+
enabled: true,
|
|
133029
|
+
priority: "high",
|
|
133030
|
+
mode: "incremental",
|
|
133031
|
+
dropColumns: ["source_env", "embedding", "sync_version"],
|
|
133032
|
+
transforms: { reusable: "boolean-to-int" }
|
|
133033
|
+
},
|
|
133034
|
+
// SONA patterns (873 records)
|
|
133035
|
+
{
|
|
133036
|
+
name: "sona-patterns",
|
|
133037
|
+
cloudTable: "aqe.sona_patterns",
|
|
133038
|
+
localTable: "sona_patterns",
|
|
133039
|
+
enabled: true,
|
|
133040
|
+
priority: "high",
|
|
133041
|
+
mode: "incremental",
|
|
133042
|
+
dropColumns: ["source_env", "sync_version"],
|
|
133043
|
+
transforms: {
|
|
133044
|
+
is_active: "boolean-to-int",
|
|
133045
|
+
requires_fine_tuning: "boolean-to-int"
|
|
133046
|
+
}
|
|
133047
|
+
},
|
|
133048
|
+
// GOAP actions (2,335 records)
|
|
133049
|
+
{
|
|
133050
|
+
name: "goap-actions",
|
|
133051
|
+
cloudTable: "aqe.goap_actions",
|
|
133052
|
+
localTable: "goap_actions",
|
|
133053
|
+
enabled: true,
|
|
133054
|
+
priority: "high",
|
|
133055
|
+
mode: "incremental",
|
|
133056
|
+
dropColumns: ["source_env", "sync_version"],
|
|
133057
|
+
columnMap: { duration_estimate: "estimated_duration_ms" }
|
|
133058
|
+
},
|
|
133059
|
+
// GOAP plans (91 records)
|
|
133060
|
+
{
|
|
133061
|
+
name: "goap-plans",
|
|
133062
|
+
cloudTable: "aqe.goap_plans",
|
|
133063
|
+
localTable: "goap_plans",
|
|
133064
|
+
enabled: true,
|
|
133065
|
+
priority: "medium",
|
|
133066
|
+
mode: "incremental",
|
|
133067
|
+
dropColumns: ["source_env", "sync_version"],
|
|
133068
|
+
columnMap: { estimated_duration: "estimated_duration_ms" }
|
|
133069
|
+
},
|
|
133070
|
+
// Memory entries → kv_store (0 records in cloud currently)
|
|
133071
|
+
{
|
|
133072
|
+
name: "memory-entries",
|
|
133073
|
+
cloudTable: "aqe.memory_entries",
|
|
133074
|
+
localTable: "kv_store",
|
|
133075
|
+
enabled: true,
|
|
133076
|
+
priority: "high",
|
|
133077
|
+
mode: "incremental",
|
|
133078
|
+
dropColumns: ["source_env", "sync_version"],
|
|
133079
|
+
columnMap: { partition: "namespace" }
|
|
133080
|
+
},
|
|
133081
|
+
// Learning experiences → captured_experiences (7,702 records)
|
|
133082
|
+
// Drop 'id' because cloud uses SERIAL auto-increment, local uses UUID
|
|
133083
|
+
// Map 'created_at' → 'started_at' since push mapped started_at → created_at
|
|
133084
|
+
{
|
|
133085
|
+
name: "learning-experiences",
|
|
133086
|
+
cloudTable: "aqe.learning_experiences",
|
|
133087
|
+
localTable: "captured_experiences",
|
|
133088
|
+
enabled: true,
|
|
133089
|
+
priority: "high",
|
|
133090
|
+
mode: "append",
|
|
133091
|
+
dropColumns: ["id", "source_env", "sync_version"],
|
|
133092
|
+
columnMap: {
|
|
133093
|
+
agent_id: "agent",
|
|
133094
|
+
task_id: "task",
|
|
133095
|
+
task_type: "domain",
|
|
133096
|
+
state: "result_json",
|
|
133097
|
+
action: "steps_json",
|
|
133098
|
+
reward: "quality",
|
|
133099
|
+
next_state: "routing_json",
|
|
133100
|
+
episode_id: "tags",
|
|
133101
|
+
created_at: "started_at"
|
|
133102
|
+
}
|
|
133103
|
+
},
|
|
133104
|
+
// Q-learning patterns → rl_q_values (3 records)
|
|
133105
|
+
{
|
|
133106
|
+
name: "qlearning-patterns",
|
|
133107
|
+
cloudTable: "aqe.qlearning_patterns",
|
|
133108
|
+
localTable: "rl_q_values",
|
|
133109
|
+
enabled: true,
|
|
133110
|
+
priority: "medium",
|
|
133111
|
+
mode: "incremental",
|
|
133112
|
+
dropColumns: ["source_env", "sync_version"],
|
|
133113
|
+
columnMap: {
|
|
133114
|
+
state: "state_key",
|
|
133115
|
+
action: "action_key",
|
|
133116
|
+
last_update: "updated_at"
|
|
133117
|
+
}
|
|
133118
|
+
},
|
|
133119
|
+
// Routing outcomes (186 records)
|
|
133120
|
+
{
|
|
133121
|
+
name: "routing-outcomes",
|
|
133122
|
+
cloudTable: "aqe.routing_outcomes",
|
|
133123
|
+
localTable: "routing_outcomes",
|
|
133124
|
+
enabled: true,
|
|
133125
|
+
priority: "medium",
|
|
133126
|
+
mode: "append",
|
|
133127
|
+
dropColumns: ["source_env", "sync_version"]
|
|
133128
|
+
},
|
|
133129
|
+
// QE trajectories (0 records in cloud currently)
|
|
133130
|
+
{
|
|
133131
|
+
name: "qe-trajectories",
|
|
133132
|
+
cloudTable: "aqe.qe_trajectories",
|
|
133133
|
+
localTable: "qe_trajectories",
|
|
133134
|
+
enabled: true,
|
|
133135
|
+
priority: "medium",
|
|
133136
|
+
mode: "append",
|
|
133137
|
+
dropColumns: ["source_env", "sync_version", "embedding"]
|
|
133138
|
+
},
|
|
133139
|
+
// Dream insights (680 records)
|
|
133140
|
+
{
|
|
133141
|
+
name: "dream-insights",
|
|
133142
|
+
cloudTable: "aqe.dream_insights",
|
|
133143
|
+
localTable: "dream_insights",
|
|
133144
|
+
enabled: true,
|
|
133145
|
+
priority: "low",
|
|
133146
|
+
mode: "append",
|
|
133147
|
+
dropColumns: ["source_env", "sync_version"]
|
|
133148
|
+
},
|
|
133149
|
+
// Claude-Flow memory (2 records in cloud)
|
|
133150
|
+
// Push syncs from JSON file; pull writes to kv_store since local has no dedicated table
|
|
133151
|
+
{
|
|
133152
|
+
name: "claude-flow-memory",
|
|
133153
|
+
cloudTable: "aqe.claude_flow_memory",
|
|
133154
|
+
localTable: "kv_store",
|
|
133155
|
+
enabled: true,
|
|
133156
|
+
priority: "low",
|
|
133157
|
+
mode: "incremental",
|
|
133158
|
+
dropColumns: ["source_env", "sync_version"],
|
|
133159
|
+
columnMap: { partition: "namespace" }
|
|
133160
|
+
}
|
|
133161
|
+
// NOTE: intelligence-qlearning (JSON push source) is NOT pulled back —
|
|
133162
|
+
// the cloud qlearning_patterns table is already pulled via the qlearning-patterns source above.
|
|
133163
|
+
]
|
|
133164
|
+
};
|
|
133011
133165
|
var DEFAULT_SYNC_CONFIG = {
|
|
133012
133166
|
local: {
|
|
133013
133167
|
// PRIMARY: Root database (consolidated, MCP-active)
|
|
@@ -133730,21 +133884,21 @@ var IAPTunnelManager = class {
|
|
|
133730
133884
|
* Check if a port is accepting connections
|
|
133731
133885
|
*/
|
|
133732
133886
|
checkPort(host, port, timeout = 2e3) {
|
|
133733
|
-
return new Promise((
|
|
133887
|
+
return new Promise((resolve15) => {
|
|
133734
133888
|
const socket = createConnection({ host, port });
|
|
133735
133889
|
const timer = setTimeout(() => {
|
|
133736
133890
|
socket.destroy();
|
|
133737
|
-
|
|
133891
|
+
resolve15(false);
|
|
133738
133892
|
}, timeout);
|
|
133739
133893
|
socket.on("connect", () => {
|
|
133740
133894
|
clearTimeout(timer);
|
|
133741
133895
|
socket.destroy();
|
|
133742
|
-
|
|
133896
|
+
resolve15(true);
|
|
133743
133897
|
});
|
|
133744
133898
|
socket.on("error", () => {
|
|
133745
133899
|
clearTimeout(timer);
|
|
133746
133900
|
socket.destroy();
|
|
133747
|
-
|
|
133901
|
+
resolve15(false);
|
|
133748
133902
|
});
|
|
133749
133903
|
});
|
|
133750
133904
|
}
|
|
@@ -133766,7 +133920,7 @@ var IAPTunnelManager = class {
|
|
|
133766
133920
|
};
|
|
133767
133921
|
return this.connection;
|
|
133768
133922
|
}
|
|
133769
|
-
return new Promise((
|
|
133923
|
+
return new Promise((resolve15, reject) => {
|
|
133770
133924
|
const args = [
|
|
133771
133925
|
"compute",
|
|
133772
133926
|
"start-iap-tunnel",
|
|
@@ -133810,7 +133964,7 @@ var IAPTunnelManager = class {
|
|
|
133810
133964
|
startedAt: /* @__PURE__ */ new Date()
|
|
133811
133965
|
};
|
|
133812
133966
|
console.log(`[TunnelManager] Tunnel ready on port ${this.config.tunnelPort}`);
|
|
133813
|
-
|
|
133967
|
+
resolve15(this.connection);
|
|
133814
133968
|
return;
|
|
133815
133969
|
}
|
|
133816
133970
|
await new Promise((r54) => setTimeout(r54, 1e3));
|
|
@@ -133853,7 +134007,7 @@ var IAPTunnelManager = class {
|
|
|
133853
134007
|
if (this.process) {
|
|
133854
134008
|
console.log("[TunnelManager] Stopping tunnel");
|
|
133855
134009
|
this.process.kill("SIGTERM");
|
|
133856
|
-
await new Promise((
|
|
134010
|
+
await new Promise((resolve15) => setTimeout(resolve15, 1e3));
|
|
133857
134011
|
if (this.process) {
|
|
133858
134012
|
this.process.kill("SIGKILL");
|
|
133859
134013
|
}
|
|
@@ -134312,11 +134466,410 @@ function createPostgresWriter(config) {
|
|
|
134312
134466
|
return new PostgresWriter(config);
|
|
134313
134467
|
}
|
|
134314
134468
|
|
|
134469
|
+
// src/sync/cloud/postgres-reader.ts
|
|
134470
|
+
init_sql_safety();
|
|
134471
|
+
init_error_utils();
|
|
134472
|
+
init_logging();
|
|
134473
|
+
var logger15 = LoggerFactory.create("postgres-reader");
|
|
134474
|
+
var PostgresReader = class {
|
|
134475
|
+
writer;
|
|
134476
|
+
environment;
|
|
134477
|
+
constructor(config) {
|
|
134478
|
+
this.writer = config.writer;
|
|
134479
|
+
this.environment = config.environment;
|
|
134480
|
+
}
|
|
134481
|
+
/**
|
|
134482
|
+
* Validate and sanitize a 'schema.table' cloud table reference.
|
|
134483
|
+
* Throws if the format is invalid (must contain exactly one dot).
|
|
134484
|
+
*/
|
|
134485
|
+
sanitizeCloudTable(cloudTable) {
|
|
134486
|
+
const dotIndex = cloudTable.indexOf(".");
|
|
134487
|
+
if (dotIndex === -1 || dotIndex === 0 || dotIndex === cloudTable.length - 1) {
|
|
134488
|
+
throw new Error(
|
|
134489
|
+
`Invalid cloud table format '${cloudTable}': expected 'schema.table' (e.g., 'aqe.qe_patterns')`
|
|
134490
|
+
);
|
|
134491
|
+
}
|
|
134492
|
+
const schema = cloudTable.substring(0, dotIndex);
|
|
134493
|
+
const table = cloudTable.substring(dotIndex + 1);
|
|
134494
|
+
return `${validateIdentifier(schema)}.${validateIdentifier(table)}`;
|
|
134495
|
+
}
|
|
134496
|
+
/**
|
|
134497
|
+
* Read all records from a cloud table
|
|
134498
|
+
*/
|
|
134499
|
+
async readAll(source) {
|
|
134500
|
+
const safeTable = this.sanitizeCloudTable(source.cloudTable);
|
|
134501
|
+
let sql;
|
|
134502
|
+
let params;
|
|
134503
|
+
if (this.environment !== "all") {
|
|
134504
|
+
sql = `SELECT * FROM ${safeTable} WHERE source_env = $1`;
|
|
134505
|
+
params = [this.environment];
|
|
134506
|
+
} else {
|
|
134507
|
+
sql = `SELECT * FROM ${safeTable}`;
|
|
134508
|
+
params = [];
|
|
134509
|
+
}
|
|
134510
|
+
try {
|
|
134511
|
+
const rows = await this.writer.query(sql, params);
|
|
134512
|
+
logger15.debug(`Read ${rows.length} records from ${source.cloudTable}`, {
|
|
134513
|
+
env: this.environment
|
|
134514
|
+
});
|
|
134515
|
+
return rows.map((row) => this.transformRecord(row, source));
|
|
134516
|
+
} catch (error) {
|
|
134517
|
+
throw new Error(
|
|
134518
|
+
`Failed to read from ${source.cloudTable}: ${toErrorMessage(error)}`
|
|
134519
|
+
);
|
|
134520
|
+
}
|
|
134521
|
+
}
|
|
134522
|
+
/**
|
|
134523
|
+
* Read records changed since a timestamp
|
|
134524
|
+
*/
|
|
134525
|
+
async readChanged(source, since) {
|
|
134526
|
+
const safeTable = this.sanitizeCloudTable(source.cloudTable);
|
|
134527
|
+
const timestampCol = await this.findTimestampColumn(safeTable);
|
|
134528
|
+
if (!timestampCol) {
|
|
134529
|
+
logger15.debug(`No timestamp column found for ${source.cloudTable}, falling back to readAll`);
|
|
134530
|
+
return this.readAll(source);
|
|
134531
|
+
}
|
|
134532
|
+
let sql;
|
|
134533
|
+
let params;
|
|
134534
|
+
if (this.environment !== "all") {
|
|
134535
|
+
sql = `SELECT * FROM ${safeTable} WHERE ${validateIdentifier(timestampCol)} > $1 AND source_env = $2`;
|
|
134536
|
+
params = [since.toISOString(), this.environment];
|
|
134537
|
+
} else {
|
|
134538
|
+
sql = `SELECT * FROM ${safeTable} WHERE ${validateIdentifier(timestampCol)} > $1`;
|
|
134539
|
+
params = [since.toISOString()];
|
|
134540
|
+
}
|
|
134541
|
+
try {
|
|
134542
|
+
const rows = await this.writer.query(sql, params);
|
|
134543
|
+
return rows.map((row) => this.transformRecord(row, source));
|
|
134544
|
+
} catch (error) {
|
|
134545
|
+
logger15.debug(`Changed query failed for ${source.cloudTable}, falling back to readAll`, {
|
|
134546
|
+
error: toErrorMessage(error)
|
|
134547
|
+
});
|
|
134548
|
+
return this.readAll(source);
|
|
134549
|
+
}
|
|
134550
|
+
}
|
|
134551
|
+
/**
|
|
134552
|
+
* Get record count from a cloud table
|
|
134553
|
+
*/
|
|
134554
|
+
async count(source) {
|
|
134555
|
+
const safeTable = this.sanitizeCloudTable(source.cloudTable);
|
|
134556
|
+
let sql;
|
|
134557
|
+
let params;
|
|
134558
|
+
if (this.environment !== "all") {
|
|
134559
|
+
sql = `SELECT COUNT(*) as count FROM ${safeTable} WHERE source_env = $1`;
|
|
134560
|
+
params = [this.environment];
|
|
134561
|
+
} else {
|
|
134562
|
+
sql = `SELECT COUNT(*) as count FROM ${safeTable}`;
|
|
134563
|
+
params = [];
|
|
134564
|
+
}
|
|
134565
|
+
try {
|
|
134566
|
+
await this.writer.beginTransaction();
|
|
134567
|
+
await this.writer.execute("SET LOCAL enable_indexonlyscan = off");
|
|
134568
|
+
const rows = await this.writer.query(sql, params);
|
|
134569
|
+
await this.writer.commit();
|
|
134570
|
+
return typeof rows[0]?.count === "string" ? parseInt(rows[0].count, 10) : rows[0]?.count || 0;
|
|
134571
|
+
} catch (error) {
|
|
134572
|
+
try {
|
|
134573
|
+
await this.writer.rollback();
|
|
134574
|
+
} catch {
|
|
134575
|
+
}
|
|
134576
|
+
logger15.debug(`Count query failed for ${source.cloudTable}`, {
|
|
134577
|
+
error: toErrorMessage(error)
|
|
134578
|
+
});
|
|
134579
|
+
return -1;
|
|
134580
|
+
}
|
|
134581
|
+
}
|
|
134582
|
+
/**
|
|
134583
|
+
* Transform a cloud record for local insertion.
|
|
134584
|
+
* - Drops specified columns (source_env, embedding, sync_version)
|
|
134585
|
+
* - Renames columns per columnMap
|
|
134586
|
+
* - Applies type transforms (boolean→int, jsonb→text, etc.)
|
|
134587
|
+
*/
|
|
134588
|
+
transformRecord(row, source) {
|
|
134589
|
+
const result = {};
|
|
134590
|
+
for (const [key, value] of Object.entries(row)) {
|
|
134591
|
+
if (source.dropColumns?.includes(key)) {
|
|
134592
|
+
continue;
|
|
134593
|
+
}
|
|
134594
|
+
const localKey = source.columnMap?.[key] || key;
|
|
134595
|
+
result[localKey] = this.transformValue(value, key, source.transforms);
|
|
134596
|
+
}
|
|
134597
|
+
return result;
|
|
134598
|
+
}
|
|
134599
|
+
/**
|
|
134600
|
+
* Transform a single value based on configured transforms
|
|
134601
|
+
*/
|
|
134602
|
+
transformValue(value, columnName, transforms) {
|
|
134603
|
+
if (value === null || value === void 0) {
|
|
134604
|
+
return null;
|
|
134605
|
+
}
|
|
134606
|
+
const transform = transforms?.[columnName];
|
|
134607
|
+
if (transform === "boolean-to-int") {
|
|
134608
|
+
if (typeof value === "boolean") return value ? 1 : 0;
|
|
134609
|
+
if (value === "true" || value === "t") return 1;
|
|
134610
|
+
if (value === "false" || value === "f") return 0;
|
|
134611
|
+
return value;
|
|
134612
|
+
}
|
|
134613
|
+
if (transform === "jsonb-to-text") {
|
|
134614
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
134615
|
+
return value;
|
|
134616
|
+
}
|
|
134617
|
+
if (transform === "timestamptz-to-text") {
|
|
134618
|
+
if (value instanceof Date) return value.toISOString();
|
|
134619
|
+
return value;
|
|
134620
|
+
}
|
|
134621
|
+
if (typeof value === "object" && !Buffer.isBuffer(value)) {
|
|
134622
|
+
return JSON.stringify(value);
|
|
134623
|
+
}
|
|
134624
|
+
if (value instanceof Date) {
|
|
134625
|
+
return value.toISOString();
|
|
134626
|
+
}
|
|
134627
|
+
if (typeof value === "boolean") {
|
|
134628
|
+
return value ? 1 : 0;
|
|
134629
|
+
}
|
|
134630
|
+
return value;
|
|
134631
|
+
}
|
|
134632
|
+
/**
|
|
134633
|
+
* Find a timestamp column in a cloud table
|
|
134634
|
+
*/
|
|
134635
|
+
async findTimestampColumn(safeTable) {
|
|
134636
|
+
const candidates = ["updated_at", "created_at", "last_update", "last_used_at"];
|
|
134637
|
+
try {
|
|
134638
|
+
const schema = safeTable.split(".")[0];
|
|
134639
|
+
const table = safeTable.split(".")[1];
|
|
134640
|
+
const rows = await this.writer.query(
|
|
134641
|
+
`SELECT column_name FROM information_schema.columns
|
|
134642
|
+
WHERE table_schema = $1 AND table_name = $2
|
|
134643
|
+
AND data_type IN ('timestamp with time zone', 'timestamp without time zone')`,
|
|
134644
|
+
[schema, table]
|
|
134645
|
+
);
|
|
134646
|
+
const columnNames = rows.map((r54) => r54.column_name);
|
|
134647
|
+
for (const candidate of candidates) {
|
|
134648
|
+
if (columnNames.includes(candidate)) {
|
|
134649
|
+
return candidate;
|
|
134650
|
+
}
|
|
134651
|
+
}
|
|
134652
|
+
return columnNames[0] || null;
|
|
134653
|
+
} catch {
|
|
134654
|
+
return null;
|
|
134655
|
+
}
|
|
134656
|
+
}
|
|
134657
|
+
};
|
|
134658
|
+
function createPostgresReader(config) {
|
|
134659
|
+
return new PostgresReader(config);
|
|
134660
|
+
}
|
|
134661
|
+
|
|
134662
|
+
// src/sync/writers/sqlite-writer.ts
|
|
134663
|
+
init_safe_db();
|
|
134664
|
+
init_sql_safety();
|
|
134665
|
+
init_error_utils();
|
|
134666
|
+
init_logging();
|
|
134667
|
+
import * as fs22 from "fs";
|
|
134668
|
+
var logger16 = LoggerFactory.create("sqlite-writer");
|
|
134669
|
+
var SQLiteWriter = class {
|
|
134670
|
+
db = null;
|
|
134671
|
+
dbPath;
|
|
134672
|
+
batchSize;
|
|
134673
|
+
constructor(config) {
|
|
134674
|
+
this.dbPath = config.dbPath;
|
|
134675
|
+
this.batchSize = config.batchSize || 500;
|
|
134676
|
+
}
|
|
134677
|
+
/**
|
|
134678
|
+
* Connect to (open) the local SQLite database
|
|
134679
|
+
*/
|
|
134680
|
+
async connect() {
|
|
134681
|
+
if (this.db) return;
|
|
134682
|
+
if (!fs22.existsSync(this.dbPath)) {
|
|
134683
|
+
throw new Error(`SQLite database not found: ${this.dbPath}. Run 'aqe init' to create it.`);
|
|
134684
|
+
}
|
|
134685
|
+
try {
|
|
134686
|
+
this.db = openDatabase(this.dbPath);
|
|
134687
|
+
this.db.pragma("journal_mode = WAL");
|
|
134688
|
+
this.db.pragma("synchronous = NORMAL");
|
|
134689
|
+
logger16.debug(`Opened SQLite database: ${this.dbPath}`);
|
|
134690
|
+
} catch (error) {
|
|
134691
|
+
throw new Error(`Failed to open SQLite database ${this.dbPath}: ${toErrorMessage(error)}`);
|
|
134692
|
+
}
|
|
134693
|
+
}
|
|
134694
|
+
/**
|
|
134695
|
+
* Upsert records into a local table using INSERT OR REPLACE.
|
|
134696
|
+
* Returns the number of records written.
|
|
134697
|
+
*/
|
|
134698
|
+
async upsert(table, records) {
|
|
134699
|
+
if (!this.db) throw new Error("Not connected");
|
|
134700
|
+
if (records.length === 0) return 0;
|
|
134701
|
+
const safeTable = validateTableName(table);
|
|
134702
|
+
if (!this.tableExists(table)) {
|
|
134703
|
+
console.warn(`[SQLiteWriter] Table '${table}' does not exist in local database \u2014 ${records.length} records skipped. Run 'aqe init' to create schema.`);
|
|
134704
|
+
return 0;
|
|
134705
|
+
}
|
|
134706
|
+
const localColumns = this.getTableColumns(table);
|
|
134707
|
+
if (localColumns.length === 0) {
|
|
134708
|
+
logger16.debug(`No columns found for table ${table}`);
|
|
134709
|
+
return 0;
|
|
134710
|
+
}
|
|
134711
|
+
const localColumnSet = new Set(localColumns);
|
|
134712
|
+
let totalWritten = 0;
|
|
134713
|
+
for (let i58 = 0; i58 < records.length; i58 += this.batchSize) {
|
|
134714
|
+
const batch = records.slice(i58, i58 + this.batchSize);
|
|
134715
|
+
try {
|
|
134716
|
+
const written = this.upsertBatch(safeTable, batch, localColumnSet);
|
|
134717
|
+
totalWritten += written;
|
|
134718
|
+
} catch (error) {
|
|
134719
|
+
const batchNum = Math.floor(i58 / this.batchSize) + 1;
|
|
134720
|
+
logger16.debug(`Batch ${batchNum} failed for ${table}, retrying individually`, {
|
|
134721
|
+
error: toErrorMessage(error)
|
|
134722
|
+
});
|
|
134723
|
+
let recovered = 0;
|
|
134724
|
+
for (const record of batch) {
|
|
134725
|
+
try {
|
|
134726
|
+
recovered += this.upsertBatch(safeTable, [record], localColumnSet);
|
|
134727
|
+
} catch (retryError) {
|
|
134728
|
+
const recordId = record["id"] || record["key"] || "?";
|
|
134729
|
+
logger16.debug(`Skipped record ${String(recordId).slice(0, 50)} in ${table}`, {
|
|
134730
|
+
error: toErrorMessage(retryError)
|
|
134731
|
+
});
|
|
134732
|
+
}
|
|
134733
|
+
}
|
|
134734
|
+
totalWritten += recovered;
|
|
134735
|
+
}
|
|
134736
|
+
}
|
|
134737
|
+
return totalWritten;
|
|
134738
|
+
}
|
|
134739
|
+
/**
|
|
134740
|
+
* Get the record count for a table
|
|
134741
|
+
*/
|
|
134742
|
+
async count(table) {
|
|
134743
|
+
if (!this.db) throw new Error("Not connected");
|
|
134744
|
+
if (!this.tableExists(table)) return 0;
|
|
134745
|
+
try {
|
|
134746
|
+
const safeTable = validateTableName(table);
|
|
134747
|
+
const row = this.db.prepare(`SELECT COUNT(*) as count FROM ${safeTable}`).get();
|
|
134748
|
+
return row.count;
|
|
134749
|
+
} catch {
|
|
134750
|
+
return 0;
|
|
134751
|
+
}
|
|
134752
|
+
}
|
|
134753
|
+
/**
|
|
134754
|
+
* Close the database connection
|
|
134755
|
+
*/
|
|
134756
|
+
async close() {
|
|
134757
|
+
if (this.db) {
|
|
134758
|
+
this.db.close();
|
|
134759
|
+
this.db = null;
|
|
134760
|
+
logger16.debug("SQLite writer closed");
|
|
134761
|
+
}
|
|
134762
|
+
}
|
|
134763
|
+
/**
|
|
134764
|
+
* Check if a table exists
|
|
134765
|
+
*/
|
|
134766
|
+
tableExists(table) {
|
|
134767
|
+
if (!this.db) return false;
|
|
134768
|
+
try {
|
|
134769
|
+
const result = this.db.prepare(
|
|
134770
|
+
`SELECT name FROM sqlite_master WHERE type='table' AND name=?`
|
|
134771
|
+
).get(table);
|
|
134772
|
+
return !!result;
|
|
134773
|
+
} catch {
|
|
134774
|
+
return false;
|
|
134775
|
+
}
|
|
134776
|
+
}
|
|
134777
|
+
/**
|
|
134778
|
+
* Get column names for a table
|
|
134779
|
+
*/
|
|
134780
|
+
getTableColumns(table) {
|
|
134781
|
+
if (!this.db) return [];
|
|
134782
|
+
try {
|
|
134783
|
+
const safeTable = validateTableName(table);
|
|
134784
|
+
const columns = this.db.prepare(`PRAGMA table_info(${safeTable})`).all();
|
|
134785
|
+
return columns.map((c70) => c70.name);
|
|
134786
|
+
} catch {
|
|
134787
|
+
return [];
|
|
134788
|
+
}
|
|
134789
|
+
}
|
|
134790
|
+
/**
|
|
134791
|
+
* Get the primary key column(s) for a table
|
|
134792
|
+
*/
|
|
134793
|
+
getPrimaryKeyColumns(table) {
|
|
134794
|
+
if (!this.db) return [];
|
|
134795
|
+
try {
|
|
134796
|
+
const safeTable = validateTableName(table);
|
|
134797
|
+
const columns = this.db.prepare(`PRAGMA table_info(${safeTable})`).all();
|
|
134798
|
+
const pkCols = columns.filter((c70) => c70.pk > 0).sort((a37, b68) => a37.pk - b68.pk).map((c70) => c70.name);
|
|
134799
|
+
return pkCols;
|
|
134800
|
+
} catch {
|
|
134801
|
+
return [];
|
|
134802
|
+
}
|
|
134803
|
+
}
|
|
134804
|
+
/**
|
|
134805
|
+
* Upsert a batch of records.
|
|
134806
|
+
* Uses INSERT ... ON CONFLICT(pk) DO UPDATE SET for mapped columns only,
|
|
134807
|
+
* preserving any local columns not present in the cloud record.
|
|
134808
|
+
* Falls back to INSERT OR IGNORE when no primary key is found (append-mode tables).
|
|
134809
|
+
*/
|
|
134810
|
+
upsertBatch(safeTable, records, localColumnSet) {
|
|
134811
|
+
if (!this.db || records.length === 0) return 0;
|
|
134812
|
+
const firstRecord = records[0];
|
|
134813
|
+
const columns = Object.keys(firstRecord).filter((k68) => localColumnSet.has(k68));
|
|
134814
|
+
if (columns.length === 0) return 0;
|
|
134815
|
+
const safeColumns = columns.map(validateIdentifier);
|
|
134816
|
+
const placeholders = columns.map(() => "?").join(", ");
|
|
134817
|
+
const rawTable = safeTable.replace(/"/g, "");
|
|
134818
|
+
const pkColumns = this.getPrimaryKeyColumns(rawTable);
|
|
134819
|
+
let sql;
|
|
134820
|
+
if (pkColumns.length > 0) {
|
|
134821
|
+
const safePkColumns = pkColumns.map(validateIdentifier);
|
|
134822
|
+
const updateColumns = columns.filter((c70) => !pkColumns.includes(c70));
|
|
134823
|
+
if (updateColumns.length > 0) {
|
|
134824
|
+
const updateSet = updateColumns.map((c70) => `${validateIdentifier(c70)} = excluded.${validateIdentifier(c70)}`).join(", ");
|
|
134825
|
+
sql = `INSERT INTO ${safeTable} (${safeColumns.join(", ")}) VALUES (${placeholders}) ON CONFLICT(${safePkColumns.join(", ")}) DO UPDATE SET ${updateSet}`;
|
|
134826
|
+
} else {
|
|
134827
|
+
sql = `INSERT OR IGNORE INTO ${safeTable} (${safeColumns.join(", ")}) VALUES (${placeholders})`;
|
|
134828
|
+
}
|
|
134829
|
+
} else {
|
|
134830
|
+
sql = `INSERT OR IGNORE INTO ${safeTable} (${safeColumns.join(", ")}) VALUES (${placeholders})`;
|
|
134831
|
+
}
|
|
134832
|
+
const stmt = this.db.prepare(sql);
|
|
134833
|
+
const insertMany = this.db.transaction((recs) => {
|
|
134834
|
+
let count = 0;
|
|
134835
|
+
for (const record of recs) {
|
|
134836
|
+
const values = columns.map((col) => this.serializeValue(record[col]));
|
|
134837
|
+
stmt.run(...values);
|
|
134838
|
+
count++;
|
|
134839
|
+
}
|
|
134840
|
+
return count;
|
|
134841
|
+
});
|
|
134842
|
+
return insertMany(records);
|
|
134843
|
+
}
|
|
134844
|
+
/**
|
|
134845
|
+
* Serialize a value for SQLite insertion
|
|
134846
|
+
*/
|
|
134847
|
+
serializeValue(value) {
|
|
134848
|
+
if (value === null || value === void 0) return null;
|
|
134849
|
+
if (typeof value === "object" && !Buffer.isBuffer(value) && !(value instanceof Date)) {
|
|
134850
|
+
return JSON.stringify(value);
|
|
134851
|
+
}
|
|
134852
|
+
if (value instanceof Date) {
|
|
134853
|
+
return value.toISOString();
|
|
134854
|
+
}
|
|
134855
|
+
if (typeof value === "boolean") {
|
|
134856
|
+
return value ? 1 : 0;
|
|
134857
|
+
}
|
|
134858
|
+
if (Buffer.isBuffer(value)) {
|
|
134859
|
+
return value;
|
|
134860
|
+
}
|
|
134861
|
+
return value;
|
|
134862
|
+
}
|
|
134863
|
+
};
|
|
134864
|
+
function createSQLiteWriter(config) {
|
|
134865
|
+
return new SQLiteWriter(config);
|
|
134866
|
+
}
|
|
134867
|
+
|
|
134315
134868
|
// src/sync/sync-agent.ts
|
|
134316
134869
|
init_esm_node();
|
|
134317
134870
|
init_logging();
|
|
134318
134871
|
init_error_utils();
|
|
134319
|
-
var
|
|
134872
|
+
var logger17 = LoggerFactory.create("sync-agent");
|
|
134320
134873
|
var CloudSyncAgent = class {
|
|
134321
134874
|
config;
|
|
134322
134875
|
readers = /* @__PURE__ */ new Map();
|
|
@@ -134538,13 +135091,20 @@ var CloudSyncAgent = class {
|
|
|
134538
135091
|
let cloudCount = 0;
|
|
134539
135092
|
if (this.writer) {
|
|
134540
135093
|
try {
|
|
135094
|
+
await this.writer.beginTransaction();
|
|
135095
|
+
await this.writer.execute("SET LOCAL enable_indexonlyscan = off");
|
|
134541
135096
|
const rows = await this.writer.query(
|
|
134542
135097
|
`SELECT COUNT(*) as count FROM ${source.targetTable} WHERE source_env = $1`,
|
|
134543
135098
|
[this.config.environment]
|
|
134544
135099
|
);
|
|
135100
|
+
await this.writer.commit();
|
|
134545
135101
|
cloudCount = rows[0]?.count || 0;
|
|
134546
135102
|
} catch (e20) {
|
|
134547
|
-
|
|
135103
|
+
try {
|
|
135104
|
+
await this.writer.rollback();
|
|
135105
|
+
} catch {
|
|
135106
|
+
}
|
|
135107
|
+
logger17.debug("Cloud count query failed", { source: source.name, error: e20 instanceof Error ? e20.message : String(e20) });
|
|
134548
135108
|
cloudCount = -1;
|
|
134549
135109
|
}
|
|
134550
135110
|
}
|
|
@@ -134661,6 +135221,308 @@ async function syncIncrementalToCloud(since, config) {
|
|
|
134661
135221
|
}
|
|
134662
135222
|
}
|
|
134663
135223
|
|
|
135224
|
+
// src/sync/pull-agent.ts
|
|
135225
|
+
init_esm_node();
|
|
135226
|
+
import * as fs23 from "fs";
|
|
135227
|
+
import * as path21 from "path";
|
|
135228
|
+
init_error_utils();
|
|
135229
|
+
init_logging();
|
|
135230
|
+
var logger18 = LoggerFactory.create("pull-agent");
|
|
135231
|
+
var PullSyncAgent = class {
|
|
135232
|
+
config;
|
|
135233
|
+
reader = null;
|
|
135234
|
+
writer = null;
|
|
135235
|
+
cloudWriter = null;
|
|
135236
|
+
report = null;
|
|
135237
|
+
constructor(config = {}) {
|
|
135238
|
+
this.config = {
|
|
135239
|
+
...DEFAULT_PULL_CONFIG,
|
|
135240
|
+
...config,
|
|
135241
|
+
cloud: { ...DEFAULT_PULL_CONFIG.cloud, ...config.cloud },
|
|
135242
|
+
sources: config.sources || DEFAULT_PULL_CONFIG.sources
|
|
135243
|
+
};
|
|
135244
|
+
}
|
|
135245
|
+
/**
|
|
135246
|
+
* Initialize connections to both cloud and local databases
|
|
135247
|
+
*/
|
|
135248
|
+
async initialize() {
|
|
135249
|
+
this.log("Initializing pull sync agent...");
|
|
135250
|
+
const tunnelManager = createConnectionManager(this.config.cloud);
|
|
135251
|
+
this.cloudWriter = createPostgresWriter({
|
|
135252
|
+
cloud: this.config.cloud,
|
|
135253
|
+
tunnelManager
|
|
135254
|
+
});
|
|
135255
|
+
await this.cloudWriter.connect();
|
|
135256
|
+
this.log("Connected to cloud database");
|
|
135257
|
+
this.reader = createPostgresReader({
|
|
135258
|
+
writer: this.cloudWriter,
|
|
135259
|
+
environment: this.config.environment
|
|
135260
|
+
});
|
|
135261
|
+
const dbPath = this.resolveTargetDb();
|
|
135262
|
+
this.writer = createSQLiteWriter({ dbPath });
|
|
135263
|
+
await this.writer.connect();
|
|
135264
|
+
this.log(`Connected to local database: ${dbPath}`);
|
|
135265
|
+
}
|
|
135266
|
+
/**
|
|
135267
|
+
* Full pull: download all cloud data into local DB
|
|
135268
|
+
*/
|
|
135269
|
+
async pullAll() {
|
|
135270
|
+
this.report = this.createReport("full");
|
|
135271
|
+
try {
|
|
135272
|
+
this.ensureInitialized();
|
|
135273
|
+
this.backupLocalDb();
|
|
135274
|
+
const sources = this.getEnabledSources();
|
|
135275
|
+
let completed = 0;
|
|
135276
|
+
for (const source of sources) {
|
|
135277
|
+
this.progress(`Pulling ${source.name}...`, completed / sources.length);
|
|
135278
|
+
const result = await this.pullTable(source);
|
|
135279
|
+
this.report.results.push(result);
|
|
135280
|
+
completed++;
|
|
135281
|
+
}
|
|
135282
|
+
this.report.status = this.report.results.every((r54) => r54.success) ? "completed" : "partial";
|
|
135283
|
+
} catch (error) {
|
|
135284
|
+
this.report.status = "failed";
|
|
135285
|
+
this.report.errors.push(toErrorMessage(error));
|
|
135286
|
+
} finally {
|
|
135287
|
+
this.finalizeReport();
|
|
135288
|
+
}
|
|
135289
|
+
return this.report;
|
|
135290
|
+
}
|
|
135291
|
+
/**
|
|
135292
|
+
* Incremental pull: only records changed since a timestamp
|
|
135293
|
+
*/
|
|
135294
|
+
async pullIncremental(since) {
|
|
135295
|
+
this.report = this.createReport("incremental");
|
|
135296
|
+
const sinceDate = since || new Date(Date.now() - 24 * 60 * 60 * 1e3);
|
|
135297
|
+
try {
|
|
135298
|
+
this.ensureInitialized();
|
|
135299
|
+
this.backupLocalDb();
|
|
135300
|
+
const sources = this.getEnabledSources().filter((s70) => s70.mode !== "full");
|
|
135301
|
+
for (const source of sources) {
|
|
135302
|
+
this.progress(`Incremental pull ${source.name}...`, 0);
|
|
135303
|
+
const result = await this.pullTableIncremental(source, sinceDate);
|
|
135304
|
+
this.report.results.push(result);
|
|
135305
|
+
}
|
|
135306
|
+
this.report.status = this.report.results.every((r54) => r54.success) ? "completed" : "partial";
|
|
135307
|
+
} catch (error) {
|
|
135308
|
+
this.report.status = "failed";
|
|
135309
|
+
this.report.errors.push(toErrorMessage(error));
|
|
135310
|
+
} finally {
|
|
135311
|
+
this.finalizeReport();
|
|
135312
|
+
}
|
|
135313
|
+
return this.report;
|
|
135314
|
+
}
|
|
135315
|
+
/**
|
|
135316
|
+
* Pull a single table from cloud to local
|
|
135317
|
+
*/
|
|
135318
|
+
async pullTable(source) {
|
|
135319
|
+
const startTime = Date.now();
|
|
135320
|
+
const result = {
|
|
135321
|
+
success: false,
|
|
135322
|
+
table: source.localTable,
|
|
135323
|
+
source: source.name,
|
|
135324
|
+
recordsSynced: 0,
|
|
135325
|
+
conflictsResolved: 0,
|
|
135326
|
+
recordsSkipped: 0,
|
|
135327
|
+
durationMs: 0,
|
|
135328
|
+
warnings: []
|
|
135329
|
+
};
|
|
135330
|
+
try {
|
|
135331
|
+
this.ensureInitialized();
|
|
135332
|
+
const records = await this.reader.readAll(source);
|
|
135333
|
+
this.log(`Read ${records.length} records from cloud ${source.cloudTable}`);
|
|
135334
|
+
if (records.length === 0) {
|
|
135335
|
+
result.success = true;
|
|
135336
|
+
result.durationMs = Date.now() - startTime;
|
|
135337
|
+
return result;
|
|
135338
|
+
}
|
|
135339
|
+
if (!this.config.dryRun) {
|
|
135340
|
+
const written = await this.writer.upsert(source.localTable, records);
|
|
135341
|
+
result.recordsSynced = written;
|
|
135342
|
+
result.recordsSkipped = records.length - written;
|
|
135343
|
+
} else {
|
|
135344
|
+
result.recordsSynced = records.length;
|
|
135345
|
+
this.log(`[DRY RUN] Would write ${records.length} records to local ${source.localTable}`);
|
|
135346
|
+
}
|
|
135347
|
+
result.success = true;
|
|
135348
|
+
} catch (error) {
|
|
135349
|
+
result.error = toErrorMessage(error);
|
|
135350
|
+
this.config.onError?.(toError(error), source.name);
|
|
135351
|
+
}
|
|
135352
|
+
result.durationMs = Date.now() - startTime;
|
|
135353
|
+
return result;
|
|
135354
|
+
}
|
|
135355
|
+
/**
|
|
135356
|
+
* Pull incremental changes for a single table
|
|
135357
|
+
*/
|
|
135358
|
+
async pullTableIncremental(source, since) {
|
|
135359
|
+
const startTime = Date.now();
|
|
135360
|
+
const result = {
|
|
135361
|
+
success: false,
|
|
135362
|
+
table: source.localTable,
|
|
135363
|
+
source: source.name,
|
|
135364
|
+
recordsSynced: 0,
|
|
135365
|
+
conflictsResolved: 0,
|
|
135366
|
+
recordsSkipped: 0,
|
|
135367
|
+
durationMs: 0
|
|
135368
|
+
};
|
|
135369
|
+
try {
|
|
135370
|
+
this.ensureInitialized();
|
|
135371
|
+
const records = await this.reader.readChanged(source, since);
|
|
135372
|
+
this.log(`Read ${records.length} changed records from cloud ${source.cloudTable} (since ${since.toISOString()})`);
|
|
135373
|
+
if (records.length === 0) {
|
|
135374
|
+
result.success = true;
|
|
135375
|
+
result.durationMs = Date.now() - startTime;
|
|
135376
|
+
return result;
|
|
135377
|
+
}
|
|
135378
|
+
if (!this.config.dryRun) {
|
|
135379
|
+
const written = await this.writer.upsert(source.localTable, records);
|
|
135380
|
+
result.recordsSynced = written;
|
|
135381
|
+
} else {
|
|
135382
|
+
result.recordsSynced = records.length;
|
|
135383
|
+
}
|
|
135384
|
+
result.success = true;
|
|
135385
|
+
} catch (error) {
|
|
135386
|
+
result.error = toErrorMessage(error);
|
|
135387
|
+
}
|
|
135388
|
+
result.durationMs = Date.now() - startTime;
|
|
135389
|
+
return result;
|
|
135390
|
+
}
|
|
135391
|
+
/**
|
|
135392
|
+
* Verify pull by comparing cloud and local counts
|
|
135393
|
+
*/
|
|
135394
|
+
async verify() {
|
|
135395
|
+
this.ensureInitialized();
|
|
135396
|
+
const results = [];
|
|
135397
|
+
for (const source of this.getEnabledSources()) {
|
|
135398
|
+
const cloudCount = await this.reader.count(source);
|
|
135399
|
+
const localCount = await this.writer.count(source.localTable);
|
|
135400
|
+
results.push({
|
|
135401
|
+
source: source.name,
|
|
135402
|
+
cloudTable: source.cloudTable,
|
|
135403
|
+
localTable: source.localTable,
|
|
135404
|
+
cloudCount,
|
|
135405
|
+
localCount,
|
|
135406
|
+
match: cloudCount === localCount || cloudCount === -1,
|
|
135407
|
+
diff: localCount - cloudCount
|
|
135408
|
+
});
|
|
135409
|
+
}
|
|
135410
|
+
return {
|
|
135411
|
+
verified: results.every((r54) => r54.match),
|
|
135412
|
+
results
|
|
135413
|
+
};
|
|
135414
|
+
}
|
|
135415
|
+
/**
|
|
135416
|
+
* Close all connections
|
|
135417
|
+
*/
|
|
135418
|
+
async close() {
|
|
135419
|
+
if (this.writer) {
|
|
135420
|
+
await this.writer.close();
|
|
135421
|
+
this.writer = null;
|
|
135422
|
+
}
|
|
135423
|
+
if (this.cloudWriter) {
|
|
135424
|
+
await this.cloudWriter.close();
|
|
135425
|
+
this.cloudWriter = null;
|
|
135426
|
+
}
|
|
135427
|
+
this.reader = null;
|
|
135428
|
+
this.log("Pull sync agent closed");
|
|
135429
|
+
}
|
|
135430
|
+
// Private helpers
|
|
135431
|
+
ensureInitialized() {
|
|
135432
|
+
if (!this.reader || !this.writer) {
|
|
135433
|
+
throw new Error("PullSyncAgent not initialized. Call initialize() first.");
|
|
135434
|
+
}
|
|
135435
|
+
}
|
|
135436
|
+
getEnabledSources() {
|
|
135437
|
+
let sources = this.config.sources.filter((s70) => s70.enabled);
|
|
135438
|
+
if (this.config.tables && this.config.tables.length > 0) {
|
|
135439
|
+
const tableSet = new Set(this.config.tables);
|
|
135440
|
+
sources = sources.filter((s70) => tableSet.has(s70.localTable) || tableSet.has(s70.name));
|
|
135441
|
+
}
|
|
135442
|
+
const priorityOrder = { high: 0, medium: 1, low: 2 };
|
|
135443
|
+
return sources.sort((a37, b68) => priorityOrder[a37.priority] - priorityOrder[b68.priority]);
|
|
135444
|
+
}
|
|
135445
|
+
resolveTargetDb() {
|
|
135446
|
+
if (this.config.targetDb) {
|
|
135447
|
+
return path21.resolve(this.config.targetDb);
|
|
135448
|
+
}
|
|
135449
|
+
return path21.resolve(process.cwd(), ".agentic-qe/memory.db");
|
|
135450
|
+
}
|
|
135451
|
+
backupLocalDb() {
|
|
135452
|
+
if (this.config.dryRun) return;
|
|
135453
|
+
const dbPath = this.resolveTargetDb();
|
|
135454
|
+
if (!fs23.existsSync(dbPath)) return;
|
|
135455
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
135456
|
+
const backupPath = `${dbPath}.bak-${timestamp}`;
|
|
135457
|
+
try {
|
|
135458
|
+
fs23.copyFileSync(dbPath, backupPath);
|
|
135459
|
+
this.log(`Backed up local DB to ${backupPath}`);
|
|
135460
|
+
} catch (error) {
|
|
135461
|
+
this.log(`Warning: Failed to backup local DB: ${toErrorMessage(error)}`, "warn");
|
|
135462
|
+
}
|
|
135463
|
+
}
|
|
135464
|
+
createReport(mode) {
|
|
135465
|
+
return {
|
|
135466
|
+
syncId: v4_default(),
|
|
135467
|
+
startedAt: /* @__PURE__ */ new Date(),
|
|
135468
|
+
status: "running",
|
|
135469
|
+
environment: this.config.environment,
|
|
135470
|
+
mode,
|
|
135471
|
+
results: [],
|
|
135472
|
+
totalRecordsSynced: 0,
|
|
135473
|
+
totalConflictsResolved: 0,
|
|
135474
|
+
totalDurationMs: 0,
|
|
135475
|
+
errors: []
|
|
135476
|
+
};
|
|
135477
|
+
}
|
|
135478
|
+
finalizeReport() {
|
|
135479
|
+
if (!this.report) return;
|
|
135480
|
+
this.report.completedAt = /* @__PURE__ */ new Date();
|
|
135481
|
+
this.report.totalDurationMs = this.report.completedAt.getTime() - this.report.startedAt.getTime();
|
|
135482
|
+
this.report.totalRecordsSynced = this.report.results.reduce((sum, r54) => sum + r54.recordsSynced, 0);
|
|
135483
|
+
this.report.totalConflictsResolved = this.report.results.reduce((sum, r54) => sum + r54.conflictsResolved, 0);
|
|
135484
|
+
}
|
|
135485
|
+
log(message, level = "info") {
|
|
135486
|
+
if (!this.config.verbose && level === "info") return;
|
|
135487
|
+
const prefix = `[PullSync:${this.config.environment}]`;
|
|
135488
|
+
switch (level) {
|
|
135489
|
+
case "warn":
|
|
135490
|
+
console.warn(`${prefix} ${message}`);
|
|
135491
|
+
break;
|
|
135492
|
+
case "error":
|
|
135493
|
+
console.error(`${prefix} ${message}`);
|
|
135494
|
+
break;
|
|
135495
|
+
default:
|
|
135496
|
+
console.log(`${prefix} ${message}`);
|
|
135497
|
+
}
|
|
135498
|
+
}
|
|
135499
|
+
progress(message, progress) {
|
|
135500
|
+
this.config.onProgress?.(message, progress);
|
|
135501
|
+
this.log(message);
|
|
135502
|
+
}
|
|
135503
|
+
};
|
|
135504
|
+
function createPullSyncAgent(config) {
|
|
135505
|
+
return new PullSyncAgent(config);
|
|
135506
|
+
}
|
|
135507
|
+
async function pullFromCloud(config) {
|
|
135508
|
+
const agent = createPullSyncAgent({ ...config, verbose: true });
|
|
135509
|
+
await agent.initialize();
|
|
135510
|
+
try {
|
|
135511
|
+
return await agent.pullAll();
|
|
135512
|
+
} finally {
|
|
135513
|
+
await agent.close();
|
|
135514
|
+
}
|
|
135515
|
+
}
|
|
135516
|
+
async function pullIncrementalFromCloud(since, config) {
|
|
135517
|
+
const agent = createPullSyncAgent({ ...config, verbose: true });
|
|
135518
|
+
await agent.initialize();
|
|
135519
|
+
try {
|
|
135520
|
+
return await agent.pullIncremental(since);
|
|
135521
|
+
} finally {
|
|
135522
|
+
await agent.close();
|
|
135523
|
+
}
|
|
135524
|
+
}
|
|
135525
|
+
|
|
134664
135526
|
// src/integrations/embeddings/cache/EmbeddingCache.ts
|
|
134665
135527
|
init_safe_db();
|
|
134666
135528
|
init_unified_memory();
|
|
@@ -134676,16 +135538,16 @@ init_sql_safety();
|
|
|
134676
135538
|
init_error_utils();
|
|
134677
135539
|
init_safe_json();
|
|
134678
135540
|
init_logging();
|
|
134679
|
-
import { resolve as
|
|
135541
|
+
import { resolve as resolve14, dirname as dirname12 } from "path";
|
|
134680
135542
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
134681
|
-
var
|
|
135543
|
+
var logger19 = LoggerFactory.create("sync-embedding-generator");
|
|
134682
135544
|
var __filename4 = fileURLToPath5(import.meta.url);
|
|
134683
135545
|
var __dirname4 = dirname12(__filename4);
|
|
134684
135546
|
|
|
134685
135547
|
// src/cli/commands/sync.ts
|
|
134686
135548
|
init_error_utils();
|
|
134687
|
-
import * as
|
|
134688
|
-
import * as
|
|
135549
|
+
import * as fs24 from "fs";
|
|
135550
|
+
import * as path22 from "path";
|
|
134689
135551
|
function createSyncCommands() {
|
|
134690
135552
|
const syncCmd = new Command14("sync").description("Sync local learning data to cloud PostgreSQL");
|
|
134691
135553
|
syncCmd.option("-f, --full", "Run full sync instead of incremental").option("-e, --env <environment>", "Environment identifier", process.env.AQE_ENV || "devpod").option("--dry-run", "Preview sync without making changes").option("-v, --verbose", "Enable verbose output").option("--since <date>", "Sync changes since date (ISO 8601)").option("--sources <sources>", "Comma-separated list of sources to sync").action(async (options) => {
|
|
@@ -134721,6 +135583,34 @@ function createSyncCommands() {
|
|
|
134721
135583
|
process.exit(1);
|
|
134722
135584
|
}
|
|
134723
135585
|
});
|
|
135586
|
+
syncCmd.command("pull").description("Pull cloud learning data into local SQLite database").option("-f, --full", "Full pull (all cloud data)").option("-e, --env <environment>", "Pull only data from specific environment", "all").option("--tables <tables>", "Comma-separated list of tables to pull").option("--dry-run", "Preview pull without writing to local DB").option("--target <path>", "Custom target SQLite database path").option("--since <date>", "Pull changes since date (ISO 8601)").option("-v, --verbose", "Enable verbose output").action(async (options) => {
|
|
135587
|
+
const pullConfig = {
|
|
135588
|
+
environment: options.env,
|
|
135589
|
+
verbose: options.verbose,
|
|
135590
|
+
dryRun: options.dryRun,
|
|
135591
|
+
targetDb: options.target
|
|
135592
|
+
};
|
|
135593
|
+
if (options.tables) {
|
|
135594
|
+
pullConfig.tables = options.tables.split(",").map((t50) => t50.trim());
|
|
135595
|
+
}
|
|
135596
|
+
const spinner = ora2("Initializing pull sync agent...").start();
|
|
135597
|
+
try {
|
|
135598
|
+
let report;
|
|
135599
|
+
if (options.full) {
|
|
135600
|
+
spinner.text = "Pulling all data from cloud...";
|
|
135601
|
+
report = await pullFromCloud(pullConfig);
|
|
135602
|
+
} else {
|
|
135603
|
+
const since = options.since ? new Date(options.since) : void 0;
|
|
135604
|
+
spinner.text = `Pulling ${since ? "changes since " + since.toISOString() : "incremental changes (last 24h)"}...`;
|
|
135605
|
+
report = await pullIncrementalFromCloud(since, pullConfig);
|
|
135606
|
+
}
|
|
135607
|
+
spinner.stop();
|
|
135608
|
+
printPullReport(report);
|
|
135609
|
+
} catch (error) {
|
|
135610
|
+
spinner.fail(`Pull failed: ${toErrorMessage(error)}`);
|
|
135611
|
+
process.exit(1);
|
|
135612
|
+
}
|
|
135613
|
+
});
|
|
134724
135614
|
syncCmd.command("status").description("Show sync status and data source information").option("-e, --env <environment>", "Environment identifier", process.env.AQE_ENV || "devpod").action(async (options) => {
|
|
134725
135615
|
const spinner = ora2("Checking sync status...").start();
|
|
134726
135616
|
try {
|
|
@@ -134751,16 +135641,16 @@ function createSyncCommands() {
|
|
|
134751
135641
|
}
|
|
134752
135642
|
});
|
|
134753
135643
|
syncCmd.command("init").description("Initialize cloud schema (requires GCP credentials)").option("--dry-run", "Print schema without executing").option("-o, --output <file>", "Save schema to file").action(async (options) => {
|
|
134754
|
-
const schemaPath =
|
|
135644
|
+
const schemaPath = path22.join(__dirname, "../../sync/schema/cloud-schema.sql");
|
|
134755
135645
|
let schema;
|
|
134756
135646
|
try {
|
|
134757
|
-
schema =
|
|
135647
|
+
schema = fs24.readFileSync(schemaPath, "utf-8");
|
|
134758
135648
|
} catch {
|
|
134759
|
-
const altPath =
|
|
134760
|
-
schema =
|
|
135649
|
+
const altPath = path22.join(process.cwd(), "v3/src/sync/schema/cloud-schema.sql");
|
|
135650
|
+
schema = fs24.readFileSync(altPath, "utf-8");
|
|
134761
135651
|
}
|
|
134762
135652
|
if (options.output) {
|
|
134763
|
-
|
|
135653
|
+
fs24.writeFileSync(options.output, schema);
|
|
134764
135654
|
console.log(chalk26.green(`Schema saved to ${options.output}`));
|
|
134765
135655
|
return;
|
|
134766
135656
|
}
|
|
@@ -134890,13 +135780,48 @@ function printVerifyResult(result) {
|
|
|
134890
135780
|
console.log();
|
|
134891
135781
|
}
|
|
134892
135782
|
}
|
|
135783
|
+
function printPullReport(report) {
|
|
135784
|
+
const statusColor = report.status === "completed" ? chalk26.green : report.status === "partial" ? chalk26.yellow : chalk26.red;
|
|
135785
|
+
console.log(chalk26.cyan("\n=== Pull Sync Report (Cloud \u2192 Local) ===\n"));
|
|
135786
|
+
console.log(chalk26.bold("Sync ID:"), report.syncId);
|
|
135787
|
+
console.log(chalk26.bold("Status:"), statusColor(report.status.toUpperCase()));
|
|
135788
|
+
console.log(chalk26.bold("Environment:"), report.environment);
|
|
135789
|
+
console.log(chalk26.bold("Mode:"), report.mode);
|
|
135790
|
+
console.log(chalk26.bold("Duration:"), `${report.totalDurationMs}ms`);
|
|
135791
|
+
console.log();
|
|
135792
|
+
console.log(chalk26.bold("Summary:"));
|
|
135793
|
+
console.log(` Records Pulled: ${chalk26.green(report.totalRecordsSynced)}`);
|
|
135794
|
+
console.log();
|
|
135795
|
+
if (report.results.length > 0) {
|
|
135796
|
+
console.log(chalk26.bold("Results by Table:"));
|
|
135797
|
+
for (const result of report.results) {
|
|
135798
|
+
const icon = result.success ? chalk26.green("\u2713") : chalk26.red("\u2717");
|
|
135799
|
+
console.log(` ${icon} ${result.source} \u2192 ${result.table}`);
|
|
135800
|
+
console.log(` Records: ${result.recordsSynced}`);
|
|
135801
|
+
console.log(` Duration: ${result.durationMs}ms`);
|
|
135802
|
+
if (result.recordsSkipped > 0) {
|
|
135803
|
+
console.log(` Skipped: ${chalk26.yellow(result.recordsSkipped)}`);
|
|
135804
|
+
}
|
|
135805
|
+
if (result.error) {
|
|
135806
|
+
console.log(` Error: ${chalk26.red(result.error)}`);
|
|
135807
|
+
}
|
|
135808
|
+
}
|
|
135809
|
+
console.log();
|
|
135810
|
+
}
|
|
135811
|
+
if (report.errors.length > 0) {
|
|
135812
|
+
console.log(chalk26.red("Errors:"));
|
|
135813
|
+
for (const error of report.errors) {
|
|
135814
|
+
console.log(` - ${error}`);
|
|
135815
|
+
}
|
|
135816
|
+
}
|
|
135817
|
+
}
|
|
134893
135818
|
|
|
134894
135819
|
// src/cli/commands/hooks.ts
|
|
134895
135820
|
init_qe_reasoning_bank();
|
|
134896
135821
|
init_safe_json();
|
|
134897
135822
|
import { Command as Command15 } from "commander";
|
|
134898
135823
|
import chalk27 from "chalk";
|
|
134899
|
-
import
|
|
135824
|
+
import path23 from "node:path";
|
|
134900
135825
|
init_unified_memory();
|
|
134901
135826
|
|
|
134902
135827
|
// src/integrations/coherence/types.ts
|
|
@@ -135049,9 +135974,9 @@ var CohomologyAdapter = class {
|
|
|
135049
135974
|
* @param wasmLoader - WASM module loader
|
|
135050
135975
|
* @param logger - Optional logger for diagnostics
|
|
135051
135976
|
*/
|
|
135052
|
-
constructor(wasmLoader2,
|
|
135977
|
+
constructor(wasmLoader2, logger22 = DEFAULT_COHERENCE_LOGGER) {
|
|
135053
135978
|
this.wasmLoader = wasmLoader2;
|
|
135054
|
-
this.logger =
|
|
135979
|
+
this.logger = logger22;
|
|
135055
135980
|
}
|
|
135056
135981
|
engine = null;
|
|
135057
135982
|
initialized = false;
|
|
@@ -135395,9 +136320,9 @@ var SpectralAdapter = class {
|
|
|
135395
136320
|
* @param wasmLoader - WASM module loader
|
|
135396
136321
|
* @param logger - Optional logger for diagnostics
|
|
135397
136322
|
*/
|
|
135398
|
-
constructor(wasmLoader2,
|
|
136323
|
+
constructor(wasmLoader2, logger22 = DEFAULT_COHERENCE_LOGGER) {
|
|
135399
136324
|
this.wasmLoader = wasmLoader2;
|
|
135400
|
-
this.logger =
|
|
136325
|
+
this.logger = logger22;
|
|
135401
136326
|
}
|
|
135402
136327
|
engine = null;
|
|
135403
136328
|
initialized = false;
|
|
@@ -135806,9 +136731,9 @@ var CausalAdapter = class {
|
|
|
135806
136731
|
* @param wasmLoader - WASM module loader
|
|
135807
136732
|
* @param logger - Optional logger for diagnostics
|
|
135808
136733
|
*/
|
|
135809
|
-
constructor(wasmLoader2,
|
|
136734
|
+
constructor(wasmLoader2, logger22 = DEFAULT_COHERENCE_LOGGER) {
|
|
135810
136735
|
this.wasmLoader = wasmLoader2;
|
|
135811
|
-
this.logger =
|
|
136736
|
+
this.logger = logger22;
|
|
135812
136737
|
}
|
|
135813
136738
|
engine = null;
|
|
135814
136739
|
initialized = false;
|
|
@@ -136057,11 +136982,11 @@ function createCategoryEngineWrapper(rawEngine) {
|
|
|
136057
136982
|
add_morphism(source, target, name) {
|
|
136058
136983
|
morphisms.push({ source, target, name });
|
|
136059
136984
|
},
|
|
136060
|
-
verify_composition(
|
|
136061
|
-
if (
|
|
136062
|
-
for (let i58 = 0; i58 <
|
|
136063
|
-
const source =
|
|
136064
|
-
const target =
|
|
136985
|
+
verify_composition(path27) {
|
|
136986
|
+
if (path27.length < 2) return true;
|
|
136987
|
+
for (let i58 = 0; i58 < path27.length - 1; i58++) {
|
|
136988
|
+
const source = path27[i58];
|
|
136989
|
+
const target = path27[i58 + 1];
|
|
136065
136990
|
const hasMorphism = morphisms.some((m74) => m74.source === source && m74.target === target);
|
|
136066
136991
|
if (!hasMorphism) return false;
|
|
136067
136992
|
}
|
|
@@ -136101,9 +137026,9 @@ var CategoryAdapter = class {
|
|
|
136101
137026
|
* @param wasmLoader - WASM module loader
|
|
136102
137027
|
* @param logger - Optional logger for diagnostics
|
|
136103
137028
|
*/
|
|
136104
|
-
constructor(wasmLoader2,
|
|
137029
|
+
constructor(wasmLoader2, logger22 = DEFAULT_COHERENCE_LOGGER) {
|
|
136105
137030
|
this.wasmLoader = wasmLoader2;
|
|
136106
|
-
this.logger =
|
|
137031
|
+
this.logger = logger22;
|
|
136107
137032
|
}
|
|
136108
137033
|
engine = null;
|
|
136109
137034
|
initialized = false;
|
|
@@ -136176,14 +137101,14 @@ var CategoryAdapter = class {
|
|
|
136176
137101
|
* @param path - Array of type names representing a composition path
|
|
136177
137102
|
* @returns True if the composition is valid
|
|
136178
137103
|
*/
|
|
136179
|
-
verifyComposition(
|
|
137104
|
+
verifyComposition(path27) {
|
|
136180
137105
|
this.ensureInitialized();
|
|
136181
|
-
if (
|
|
137106
|
+
if (path27.length < 2) {
|
|
136182
137107
|
return true;
|
|
136183
137108
|
}
|
|
136184
|
-
const isValid = this.engine.verify_composition(
|
|
137109
|
+
const isValid = this.engine.verify_composition(path27);
|
|
136185
137110
|
this.logger.debug("Verified composition", {
|
|
136186
|
-
path:
|
|
137111
|
+
path: path27,
|
|
136187
137112
|
isValid
|
|
136188
137113
|
});
|
|
136189
137114
|
return isValid;
|
|
@@ -136222,8 +137147,8 @@ var CategoryAdapter = class {
|
|
|
136222
137147
|
for (const element of pipeline10.elements) {
|
|
136223
137148
|
this.addMorphism(element.inputType, element.outputType, element.name);
|
|
136224
137149
|
}
|
|
136225
|
-
const
|
|
136226
|
-
const compositionValid = this.verifyComposition(
|
|
137150
|
+
const path27 = this.buildCompositionPath(pipeline10);
|
|
137151
|
+
const compositionValid = this.verifyComposition(path27);
|
|
136227
137152
|
const mismatches = this.checkTypeConsistency();
|
|
136228
137153
|
const warnings = this.generateWarnings(pipeline10, compositionValid, mismatches);
|
|
136229
137154
|
const durationMs = Date.now() - startTime;
|
|
@@ -136247,17 +137172,17 @@ var CategoryAdapter = class {
|
|
|
136247
137172
|
* Build a composition path from a pipeline
|
|
136248
137173
|
*/
|
|
136249
137174
|
buildCompositionPath(pipeline10) {
|
|
136250
|
-
const
|
|
137175
|
+
const path27 = [pipeline10.inputType];
|
|
136251
137176
|
for (const element of pipeline10.elements) {
|
|
136252
|
-
if (element.inputType !==
|
|
136253
|
-
|
|
137177
|
+
if (element.inputType !== path27[path27.length - 1]) {
|
|
137178
|
+
path27.push(element.inputType);
|
|
136254
137179
|
}
|
|
136255
|
-
|
|
137180
|
+
path27.push(element.outputType);
|
|
136256
137181
|
}
|
|
136257
|
-
if (
|
|
136258
|
-
|
|
137182
|
+
if (path27[path27.length - 1] !== pipeline10.outputType) {
|
|
137183
|
+
path27.push(pipeline10.outputType);
|
|
136259
137184
|
}
|
|
136260
|
-
return
|
|
137185
|
+
return path27;
|
|
136261
137186
|
}
|
|
136262
137187
|
/**
|
|
136263
137188
|
* Infer a schema from a type name
|
|
@@ -136388,9 +137313,9 @@ function createHomotopyEngineWrapper(rawEngine) {
|
|
|
136388
137313
|
}
|
|
136389
137314
|
return false;
|
|
136390
137315
|
},
|
|
136391
|
-
verify_path_equivalence(path1,
|
|
137316
|
+
verify_path_equivalence(path1, path27) {
|
|
136392
137317
|
const pathObj1 = { steps: path1 };
|
|
136393
|
-
const pathObj2 = { steps:
|
|
137318
|
+
const pathObj2 = { steps: path27 };
|
|
136394
137319
|
return rawEngine.checkTypeEquivalence(pathObj1, pathObj2);
|
|
136395
137320
|
},
|
|
136396
137321
|
get_unproven_propositions() {
|
|
@@ -136415,9 +137340,9 @@ var HomotopyAdapter = class {
|
|
|
136415
137340
|
* @param wasmLoader - WASM module loader
|
|
136416
137341
|
* @param logger - Optional logger for diagnostics
|
|
136417
137342
|
*/
|
|
136418
|
-
constructor(wasmLoader2,
|
|
137343
|
+
constructor(wasmLoader2, logger22 = DEFAULT_COHERENCE_LOGGER) {
|
|
136419
137344
|
this.wasmLoader = wasmLoader2;
|
|
136420
|
-
this.logger =
|
|
137345
|
+
this.logger = logger22;
|
|
136421
137346
|
}
|
|
136422
137347
|
engine = null;
|
|
136423
137348
|
initialized = false;
|
|
@@ -136506,19 +137431,19 @@ var HomotopyAdapter = class {
|
|
|
136506
137431
|
* @param path2 - Second execution path
|
|
136507
137432
|
* @returns Path equivalence result
|
|
136508
137433
|
*/
|
|
136509
|
-
verifyPathEquivalence(path1,
|
|
137434
|
+
verifyPathEquivalence(path1, path27) {
|
|
136510
137435
|
this.ensureInitialized();
|
|
136511
|
-
const equivalent = this.engine.verify_path_equivalence(path1,
|
|
136512
|
-
const explanation = this.generateEquivalenceExplanation(path1,
|
|
137436
|
+
const equivalent = this.engine.verify_path_equivalence(path1, path27);
|
|
137437
|
+
const explanation = this.generateEquivalenceExplanation(path1, path27, equivalent);
|
|
136513
137438
|
const result = {
|
|
136514
137439
|
equivalent,
|
|
136515
137440
|
path1,
|
|
136516
|
-
path2:
|
|
137441
|
+
path2: path27,
|
|
136517
137442
|
explanation
|
|
136518
137443
|
};
|
|
136519
137444
|
this.logger.debug("Verified path equivalence", {
|
|
136520
137445
|
path1Length: path1.length,
|
|
136521
|
-
path2Length:
|
|
137446
|
+
path2Length: path27.length,
|
|
136522
137447
|
equivalent
|
|
136523
137448
|
});
|
|
136524
137449
|
return result;
|
|
@@ -136526,24 +137451,24 @@ var HomotopyAdapter = class {
|
|
|
136526
137451
|
/**
|
|
136527
137452
|
* Generate an explanation for path equivalence result
|
|
136528
137453
|
*/
|
|
136529
|
-
generateEquivalenceExplanation(path1,
|
|
137454
|
+
generateEquivalenceExplanation(path1, path27, equivalent) {
|
|
136530
137455
|
if (equivalent) {
|
|
136531
|
-
if (path1.length ===
|
|
137456
|
+
if (path1.length === path27.length) {
|
|
136532
137457
|
return `The execution paths are homotopically equivalent. Both paths traverse the same abstract structure and will produce equivalent results.`;
|
|
136533
137458
|
} else {
|
|
136534
|
-
const longer = path1.length >
|
|
137459
|
+
const longer = path1.length > path27.length ? "first" : "second";
|
|
136535
137460
|
return `The execution paths are equivalent despite different lengths. The ${longer} path contains redundant steps that can be contracted without changing the result (homotopy contraction).`;
|
|
136536
137461
|
}
|
|
136537
137462
|
} else {
|
|
136538
137463
|
let divergeIndex = 0;
|
|
136539
|
-
const minLen = Math.min(path1.length,
|
|
136540
|
-
while (divergeIndex < minLen && path1[divergeIndex] ===
|
|
137464
|
+
const minLen = Math.min(path1.length, path27.length);
|
|
137465
|
+
while (divergeIndex < minLen && path1[divergeIndex] === path27[divergeIndex]) {
|
|
136541
137466
|
divergeIndex++;
|
|
136542
137467
|
}
|
|
136543
137468
|
if (divergeIndex === 0) {
|
|
136544
|
-
return `The execution paths diverge immediately. Path 1 starts with '${path1[0]}' while Path 2 starts with '${
|
|
137469
|
+
return `The execution paths diverge immediately. Path 1 starts with '${path1[0]}' while Path 2 starts with '${path27[0]}'. These lead to fundamentally different computation spaces.`;
|
|
136545
137470
|
}
|
|
136546
|
-
return `The execution paths diverge at step ${divergeIndex + 1}. After '${path1[divergeIndex - 1]}', Path 1 proceeds to '${path1[divergeIndex]}' while Path 2 proceeds to '${
|
|
137471
|
+
return `The execution paths diverge at step ${divergeIndex + 1}. After '${path1[divergeIndex - 1]}', Path 1 proceeds to '${path1[divergeIndex]}' while Path 2 proceeds to '${path27[divergeIndex]}'. No homotopy exists between these paths.`;
|
|
136547
137472
|
}
|
|
136548
137473
|
}
|
|
136549
137474
|
/**
|
|
@@ -136617,9 +137542,9 @@ var WitnessAdapter = class {
|
|
|
136617
137542
|
* @param wasmLoader - WASM module loader
|
|
136618
137543
|
* @param logger - Optional logger for diagnostics
|
|
136619
137544
|
*/
|
|
136620
|
-
constructor(wasmLoader2,
|
|
137545
|
+
constructor(wasmLoader2, logger22 = DEFAULT_COHERENCE_LOGGER) {
|
|
136621
137546
|
this.wasmLoader = wasmLoader2;
|
|
136622
|
-
this.logger =
|
|
137547
|
+
this.logger = logger22;
|
|
136623
137548
|
}
|
|
136624
137549
|
engine = null;
|
|
136625
137550
|
initialized = false;
|
|
@@ -136914,10 +137839,10 @@ var CoherenceService = class {
|
|
|
136914
137839
|
* @param config - Optional service configuration
|
|
136915
137840
|
* @param logger - Optional logger for diagnostics
|
|
136916
137841
|
*/
|
|
136917
|
-
constructor(wasmLoader2, config = {},
|
|
137842
|
+
constructor(wasmLoader2, config = {}, logger22) {
|
|
136918
137843
|
this.wasmLoader = wasmLoader2;
|
|
136919
137844
|
this.config = { ...DEFAULT_COHERENCE_CONFIG, ...config };
|
|
136920
|
-
this.logger =
|
|
137845
|
+
this.logger = logger22 || DEFAULT_COHERENCE_LOGGER;
|
|
136921
137846
|
}
|
|
136922
137847
|
config;
|
|
136923
137848
|
logger;
|
|
@@ -137618,8 +138543,8 @@ var CoherenceService = class {
|
|
|
137618
138543
|
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
137619
138544
|
}
|
|
137620
138545
|
};
|
|
137621
|
-
async function createCoherenceService(wasmLoader2, config,
|
|
137622
|
-
const service = new CoherenceService(wasmLoader2, config,
|
|
138546
|
+
async function createCoherenceService(wasmLoader2, config, logger22) {
|
|
138547
|
+
const service = new CoherenceService(wasmLoader2, config, logger22);
|
|
137623
138548
|
await service.initialize();
|
|
137624
138549
|
return service;
|
|
137625
138550
|
}
|
|
@@ -137629,7 +138554,7 @@ init_error_utils();
|
|
|
137629
138554
|
import { createRequire as createRequire9 } from "node:module";
|
|
137630
138555
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
137631
138556
|
import { dirname as dirname13, join as join44 } from "node:path";
|
|
137632
|
-
import { readFileSync as readFileSync32, existsSync as
|
|
138557
|
+
import { readFileSync as readFileSync32, existsSync as existsSync46 } from "node:fs";
|
|
137633
138558
|
var FALLBACK_RETRY_DELAYS_MS = [1e3, 2e3, 4e3];
|
|
137634
138559
|
var WasmLoader = class {
|
|
137635
138560
|
state = "unloaded";
|
|
@@ -137894,8 +138819,8 @@ var WasmLoader = class {
|
|
|
137894
138819
|
})(),
|
|
137895
138820
|
join44(process.cwd(), "node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm")
|
|
137896
138821
|
].filter((p74) => p74 !== null);
|
|
137897
|
-
for (const
|
|
137898
|
-
if (
|
|
138822
|
+
for (const path27 of wasmPaths) {
|
|
138823
|
+
if (existsSync46(path27)) {
|
|
137899
138824
|
return true;
|
|
137900
138825
|
}
|
|
137901
138826
|
}
|
|
@@ -138157,9 +139082,9 @@ var WasmLoader = class {
|
|
|
138157
139082
|
join44(process.cwd(), "node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm")
|
|
138158
139083
|
].filter((p74) => p74 !== null);
|
|
138159
139084
|
let wasmPath = null;
|
|
138160
|
-
for (const
|
|
138161
|
-
if (
|
|
138162
|
-
wasmPath =
|
|
139085
|
+
for (const path27 of wasmPaths) {
|
|
139086
|
+
if (existsSync46(path27)) {
|
|
139087
|
+
wasmPath = path27;
|
|
138163
139088
|
break;
|
|
138164
139089
|
}
|
|
138165
139090
|
}
|
|
@@ -138196,7 +139121,7 @@ Ensure prime-radiant-advanced-wasm is installed.`
|
|
|
138196
139121
|
* Sleep for a specified duration.
|
|
138197
139122
|
*/
|
|
138198
139123
|
sleep(ms) {
|
|
138199
|
-
return new Promise((
|
|
139124
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
138200
139125
|
}
|
|
138201
139126
|
// ===========================================================================
|
|
138202
139127
|
// ADR-052 A4.3: Fallback Mode Management
|
|
@@ -138326,7 +139251,7 @@ async function initializeHooksSystem() {
|
|
|
138326
139251
|
if (state.initialized) return;
|
|
138327
139252
|
try {
|
|
138328
139253
|
const projectRoot = findProjectRoot();
|
|
138329
|
-
const dataDir =
|
|
139254
|
+
const dataDir = path23.join(projectRoot, ".agentic-qe");
|
|
138330
139255
|
const memoryBackend2 = await createHybridBackendWithTimeout(dataDir);
|
|
138331
139256
|
try {
|
|
138332
139257
|
state.coherenceService = await createCoherenceService(wasmLoader);
|
|
@@ -138372,7 +139297,7 @@ async function createHybridBackendWithTimeout(dataDir) {
|
|
|
138372
139297
|
const timeoutMs = 5e3;
|
|
138373
139298
|
const backend = new HybridMemoryBackend({
|
|
138374
139299
|
sqlite: {
|
|
138375
|
-
path:
|
|
139300
|
+
path: path23.join(dataDir, "memory.db"),
|
|
138376
139301
|
// ADR-046: Unified storage
|
|
138377
139302
|
walMode: true,
|
|
138378
139303
|
poolSize: 3,
|
|
@@ -138678,7 +139603,7 @@ Examples:
|
|
|
138678
139603
|
let dreamTriggered = false;
|
|
138679
139604
|
try {
|
|
138680
139605
|
const projectRoot = findProjectRoot();
|
|
138681
|
-
const dataDir =
|
|
139606
|
+
const dataDir = path23.join(projectRoot, ".agentic-qe");
|
|
138682
139607
|
const memoryBackend2 = await createHybridBackendWithTimeout(dataDir);
|
|
138683
139608
|
await incrementDreamExperience(memoryBackend2);
|
|
138684
139609
|
} catch {
|
|
@@ -138777,7 +139702,7 @@ Examples:
|
|
|
138777
139702
|
null
|
|
138778
139703
|
);
|
|
138779
139704
|
const projectRoot = findProjectRoot();
|
|
138780
|
-
const dataDir =
|
|
139705
|
+
const dataDir = path23.join(projectRoot, ".agentic-qe");
|
|
138781
139706
|
const memoryBackend2 = await createHybridBackendWithTimeout(dataDir);
|
|
138782
139707
|
await incrementDreamExperience(memoryBackend2);
|
|
138783
139708
|
} catch (persistError) {
|
|
@@ -138982,7 +139907,7 @@ Registered: ${events.length}/${Object.keys(QE_HOOK_EVENTS).length}`)
|
|
|
138982
139907
|
const { reasoningBank } = await getHooksSystem();
|
|
138983
139908
|
const stats = await reasoningBank.getStats();
|
|
138984
139909
|
const projectRoot = findProjectRoot();
|
|
138985
|
-
const dataDir =
|
|
139910
|
+
const dataDir = path23.join(projectRoot, ".agentic-qe");
|
|
138986
139911
|
const memoryBackend2 = await createHybridBackendWithTimeout(dataDir);
|
|
138987
139912
|
let dreamState = await memoryBackend2.get(DREAM_STATE_KEY);
|
|
138988
139913
|
const isNewSession = !dreamState || !dreamState.sessionStartTime;
|
|
@@ -139141,7 +140066,7 @@ Registered: ${events.length}/${Object.keys(QE_HOOK_EVENTS).length}`)
|
|
|
139141
140066
|
});
|
|
139142
140067
|
}
|
|
139143
140068
|
const projectRoot = findProjectRoot();
|
|
139144
|
-
const dataDir =
|
|
140069
|
+
const dataDir = path23.join(projectRoot, ".agentic-qe");
|
|
139145
140070
|
const memoryBackend2 = await createHybridBackendWithTimeout(dataDir);
|
|
139146
140071
|
const expCount = await incrementDreamExperience(memoryBackend2);
|
|
139147
140072
|
dreamResult = await checkAndTriggerDream(memoryBackend2);
|
|
@@ -139334,7 +140259,7 @@ Registered: ${events.length}/${Object.keys(QE_HOOK_EVENTS).length}`)
|
|
|
139334
140259
|
});
|
|
139335
140260
|
experienceRecorded = true;
|
|
139336
140261
|
const projectRoot = findProjectRoot();
|
|
139337
|
-
const dataDir =
|
|
140262
|
+
const dataDir = path23.join(projectRoot, ".agentic-qe");
|
|
139338
140263
|
const memoryBackend2 = await createHybridBackendWithTimeout(dataDir);
|
|
139339
140264
|
await incrementDreamExperience(memoryBackend2);
|
|
139340
140265
|
} catch (initError) {
|
|
@@ -139367,8 +140292,8 @@ init_safe_json();
|
|
|
139367
140292
|
init_qe_patterns();
|
|
139368
140293
|
import { Command as Command16 } from "commander";
|
|
139369
140294
|
import chalk29 from "chalk";
|
|
139370
|
-
import
|
|
139371
|
-
import { existsSync as
|
|
140295
|
+
import path26 from "node:path";
|
|
140296
|
+
import { existsSync as existsSync48, writeFileSync as writeFileSync22, readFileSync as readFileSync33, mkdirSync as mkdirSync19, copyFileSync as copyFileSync9 } from "node:fs";
|
|
139372
140297
|
import { stat as stat3, unlink } from "node:fs/promises";
|
|
139373
140298
|
|
|
139374
140299
|
// src/learning/metrics-tracker.ts
|
|
@@ -139376,22 +140301,22 @@ init_safe_db();
|
|
|
139376
140301
|
init_qe_patterns();
|
|
139377
140302
|
init_safe_json();
|
|
139378
140303
|
init_logging();
|
|
139379
|
-
import
|
|
139380
|
-
import { existsSync as
|
|
139381
|
-
var
|
|
140304
|
+
import path24 from "node:path";
|
|
140305
|
+
import { existsSync as existsSync47 } from "node:fs";
|
|
140306
|
+
var logger21 = LoggerFactory.create("metrics-tracker");
|
|
139382
140307
|
var LearningMetricsTracker = class {
|
|
139383
140308
|
db = null;
|
|
139384
140309
|
dbPath;
|
|
139385
140310
|
initialized = false;
|
|
139386
140311
|
constructor(projectRoot = process.cwd()) {
|
|
139387
|
-
this.dbPath =
|
|
140312
|
+
this.dbPath = path24.join(projectRoot, ".agentic-qe", "memory.db");
|
|
139388
140313
|
}
|
|
139389
140314
|
/**
|
|
139390
140315
|
* Initialize the tracker (open database, ensure tables exist)
|
|
139391
140316
|
*/
|
|
139392
140317
|
async initialize() {
|
|
139393
140318
|
if (this.initialized) return;
|
|
139394
|
-
if (!
|
|
140319
|
+
if (!existsSync47(this.dbPath)) {
|
|
139395
140320
|
throw new Error(`Database not found: ${this.dbPath}. Run "aqe init --auto" first.`);
|
|
139396
140321
|
}
|
|
139397
140322
|
this.db = openDatabase(this.dbPath);
|
|
@@ -139659,7 +140584,7 @@ var LearningMetricsTracker = class {
|
|
|
139659
140584
|
try {
|
|
139660
140585
|
domainCoverage = safeJsonParse(row.domain_coverage_json || "{}");
|
|
139661
140586
|
} catch (e20) {
|
|
139662
|
-
|
|
140587
|
+
logger21.debug("Domain coverage JSON parse failed", { error: e20 instanceof Error ? e20.message : String(e20) });
|
|
139663
140588
|
for (const domain of QE_DOMAIN_LIST) {
|
|
139664
140589
|
domainCoverage[domain] = 0;
|
|
139665
140590
|
}
|
|
@@ -139750,7 +140675,7 @@ init_unified_memory();
|
|
|
139750
140675
|
init_qe_reasoning_bank();
|
|
139751
140676
|
init_safe_db();
|
|
139752
140677
|
import chalk28 from "chalk";
|
|
139753
|
-
import
|
|
140678
|
+
import path25 from "node:path";
|
|
139754
140679
|
import { createReadStream, createWriteStream } from "node:fs";
|
|
139755
140680
|
import { createGzip, createGunzip } from "node:zlib";
|
|
139756
140681
|
import { pipeline as pipeline9 } from "node:stream/promises";
|
|
@@ -139764,10 +140689,10 @@ async function initializeLearningSystem2() {
|
|
|
139764
140689
|
return state2.reasoningBank;
|
|
139765
140690
|
}
|
|
139766
140691
|
const projectRoot = findProjectRoot();
|
|
139767
|
-
const dataDir =
|
|
140692
|
+
const dataDir = path25.join(projectRoot, ".agentic-qe");
|
|
139768
140693
|
const backend = new HybridMemoryBackend({
|
|
139769
140694
|
sqlite: {
|
|
139770
|
-
path:
|
|
140695
|
+
path: path25.join(dataDir, "memory.db"),
|
|
139771
140696
|
walMode: true,
|
|
139772
140697
|
poolSize: 3,
|
|
139773
140698
|
busyTimeout: 5e3
|
|
@@ -139877,7 +140802,7 @@ function stripAnsi(text) {
|
|
|
139877
140802
|
}
|
|
139878
140803
|
function getDbPath() {
|
|
139879
140804
|
const projectRoot = findProjectRoot();
|
|
139880
|
-
return
|
|
140805
|
+
return path25.join(projectRoot, ".agentic-qe", "memory.db");
|
|
139881
140806
|
}
|
|
139882
140807
|
async function compressFile(inputPath, outputPath) {
|
|
139883
140808
|
const gzPath = outputPath || `${inputPath}.gz`;
|
|
@@ -140167,7 +141092,7 @@ function registerExportCommand(learning) {
|
|
|
140167
141092
|
if (options.json) {
|
|
140168
141093
|
printJson2(exportData);
|
|
140169
141094
|
} else {
|
|
140170
|
-
const outputPath =
|
|
141095
|
+
const outputPath = path26.resolve(options.output);
|
|
140171
141096
|
writeFileSync22(outputPath, JSON.stringify(exportData, null, 2), "utf-8");
|
|
140172
141097
|
printSuccess2(`Exported ${patterns.length} patterns to ${outputPath}`);
|
|
140173
141098
|
}
|
|
@@ -140181,8 +141106,8 @@ function registerExportCommand(learning) {
|
|
|
140181
141106
|
function registerImportCommand(learning) {
|
|
140182
141107
|
learning.command("import").description("Import patterns from file").requiredOption("-i, --input <file>", "Input file path").option("--dry-run", "Show what would be imported without making changes").option("--json", "Output as JSON").action(async (options) => {
|
|
140183
141108
|
try {
|
|
140184
|
-
const inputPath =
|
|
140185
|
-
if (!
|
|
141109
|
+
const inputPath = path26.resolve(options.input);
|
|
141110
|
+
if (!existsSync48(inputPath)) throw new Error(`File not found: ${inputPath}`);
|
|
140186
141111
|
const content = readFileSync33(inputPath, "utf-8");
|
|
140187
141112
|
const importData = safeJsonParse(content);
|
|
140188
141113
|
if (!importData.patterns || !Array.isArray(importData.patterns)) throw new Error("Invalid pattern file format");
|
|
@@ -140243,15 +141168,15 @@ function registerResetCommand(learning) {
|
|
|
140243
141168
|
process.exit(0);
|
|
140244
141169
|
}
|
|
140245
141170
|
const projectRoot = findProjectRoot();
|
|
140246
|
-
const dataDir =
|
|
141171
|
+
const dataDir = path26.join(projectRoot, ".agentic-qe");
|
|
140247
141172
|
const filesToReset = [
|
|
140248
|
-
|
|
140249
|
-
|
|
141173
|
+
path26.join(dataDir, "data", "patterns"),
|
|
141174
|
+
path26.join(dataDir, "data", "hnsw")
|
|
140250
141175
|
];
|
|
140251
|
-
if (!options.patternsOnly) filesToReset.push(
|
|
141176
|
+
if (!options.patternsOnly) filesToReset.push(path26.join(dataDir, "data", "learning-config.json"));
|
|
140252
141177
|
console.log(chalk29.bold("\n\u{1F5D1}\uFE0F Resetting Learning Data\n"));
|
|
140253
141178
|
for (const file of filesToReset) {
|
|
140254
|
-
if (
|
|
141179
|
+
if (existsSync48(file)) console.log(chalk29.dim(` Removing: ${path26.relative(projectRoot, file)}`));
|
|
140255
141180
|
}
|
|
140256
141181
|
printSuccess2('Learning data reset. Run "aqe init --auto" to reinitialize.\n');
|
|
140257
141182
|
process.exit(0);
|
|
@@ -140265,8 +141190,8 @@ function registerExtractCommand(learning) {
|
|
|
140265
141190
|
learning.command("extract").description("Extract QE patterns from existing learning experiences").option("--min-reward <n>", "Minimum reward threshold for pattern extraction", "0.7").option("--min-count <n>", "Minimum occurrences to form a pattern", "3").option("--dry-run", "Show what would be extracted without saving").option("--json", "Output as JSON").action(async (options) => {
|
|
140266
141191
|
try {
|
|
140267
141192
|
const projectRoot = findProjectRoot();
|
|
140268
|
-
const dbPath =
|
|
140269
|
-
if (!
|
|
141193
|
+
const dbPath = path26.join(projectRoot, ".agentic-qe", "memory.db");
|
|
141194
|
+
if (!existsSync48(dbPath)) throw new Error('No memory database found. Run "aqe init --auto" first.');
|
|
140270
141195
|
const minReward = parseFloat(options.minReward);
|
|
140271
141196
|
const minCount = parseInt(options.minCount, 10);
|
|
140272
141197
|
console.log(chalk29.bold("\n\u{1F52C} Pattern Extraction from Learning Experiences\n"));
|
|
@@ -140391,13 +141316,13 @@ function registerInfoCommand(learning) {
|
|
|
140391
141316
|
learning.command("info").description("Show learning system configuration and paths").action(async () => {
|
|
140392
141317
|
try {
|
|
140393
141318
|
const projectRoot = findProjectRoot();
|
|
140394
|
-
const dataDir =
|
|
141319
|
+
const dataDir = path26.join(projectRoot, ".agentic-qe");
|
|
140395
141320
|
console.log(chalk29.bold("\n\u{1F4CB} AQE Learning System Info\n"));
|
|
140396
141321
|
console.log(chalk29.bold("Paths:"));
|
|
140397
141322
|
console.log(` Data directory: ${dataDir}`);
|
|
140398
|
-
console.log(` Memory database: ${
|
|
140399
|
-
console.log(` HNSW index: ${
|
|
140400
|
-
console.log(` Patterns: ${
|
|
141323
|
+
console.log(` Memory database: ${path26.join(dataDir, "memory.db")}`);
|
|
141324
|
+
console.log(` HNSW index: ${path26.join(dataDir, "data", "hnsw")}`);
|
|
141325
|
+
console.log(` Patterns: ${path26.join(dataDir, "data", "patterns")}`);
|
|
140401
141326
|
console.log(chalk29.bold("\nConfiguration:"));
|
|
140402
141327
|
console.log(` Learning enabled: ${process.env.AQE_LEARNING_ENABLED !== "false" ? chalk29.green("yes") : chalk29.red("no")}`);
|
|
140403
141328
|
console.log(` V3 mode: ${process.env.AQE_V3_MODE === "true" ? chalk29.green("yes") : chalk29.dim("no")}`);
|
|
@@ -140419,22 +141344,22 @@ function registerBackupCommand(learning) {
|
|
|
140419
141344
|
learning.command("backup").description("Backup learning database to a file").option("-o, --output <path>", "Output file path").option("--compress", "Compress backup with gzip").option("--verify", "Verify backup integrity after creation").option("--json", "Output as JSON").action(async (options) => {
|
|
140420
141345
|
try {
|
|
140421
141346
|
const dbPath = getDbPath();
|
|
140422
|
-
if (!
|
|
141347
|
+
if (!existsSync48(dbPath)) throw new Error(`No learning database found at: ${dbPath}`);
|
|
140423
141348
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
140424
|
-
const defaultOutput =
|
|
140425
|
-
let outputPath = options.output ?
|
|
140426
|
-
const backupDir =
|
|
140427
|
-
if (!
|
|
141349
|
+
const defaultOutput = path26.join(process.cwd(), "backups", `learning-${timestamp}.db`);
|
|
141350
|
+
let outputPath = options.output ? path26.resolve(options.output) : defaultOutput;
|
|
141351
|
+
const backupDir = path26.dirname(outputPath);
|
|
141352
|
+
if (!existsSync48(backupDir)) mkdirSync19(backupDir, { recursive: true });
|
|
140428
141353
|
const sourceStats = await stat3(dbPath);
|
|
140429
141354
|
const sourceSizeKB = (sourceStats.size / 1024).toFixed(2);
|
|
140430
|
-
|
|
141355
|
+
copyFileSync9(dbPath, outputPath);
|
|
140431
141356
|
const walPath = `${dbPath}-wal`;
|
|
140432
|
-
if (
|
|
141357
|
+
if (existsSync48(walPath)) copyFileSync9(walPath, `${outputPath}-wal`);
|
|
140433
141358
|
let finalPath = outputPath;
|
|
140434
141359
|
if (options.compress) {
|
|
140435
141360
|
finalPath = await compressFile(outputPath);
|
|
140436
141361
|
await unlink(outputPath);
|
|
140437
|
-
if (
|
|
141362
|
+
if (existsSync48(`${outputPath}-wal`)) await unlink(`${outputPath}-wal`);
|
|
140438
141363
|
}
|
|
140439
141364
|
const finalStats = await stat3(finalPath);
|
|
140440
141365
|
const finalSizeKB = (finalStats.size / 1024).toFixed(2);
|
|
@@ -140470,9 +141395,9 @@ function registerBackupCommand(learning) {
|
|
|
140470
141395
|
function registerRestoreCommand(learning) {
|
|
140471
141396
|
learning.command("restore").description("Restore learning database from backup").requiredOption("-i, --input <path>", "Backup file path to restore from").option("--verify", "Verify backup integrity before restore").option("--force", "Overwrite existing database without confirmation").option("--json", "Output as JSON").action(async (options) => {
|
|
140472
141397
|
try {
|
|
140473
|
-
const inputPath =
|
|
141398
|
+
const inputPath = path26.resolve(options.input);
|
|
140474
141399
|
const dbPath = getDbPath();
|
|
140475
|
-
if (!
|
|
141400
|
+
if (!existsSync48(inputPath)) throw new Error(`Backup file not found: ${inputPath}`);
|
|
140476
141401
|
const isCompressed = inputPath.endsWith(".gz");
|
|
140477
141402
|
let restorePath = inputPath;
|
|
140478
141403
|
if (isCompressed) {
|
|
@@ -140483,23 +141408,23 @@ function registerRestoreCommand(learning) {
|
|
|
140483
141408
|
if (options.verify) {
|
|
140484
141409
|
const verificationResult = await verifyDatabaseIntegrity(restorePath);
|
|
140485
141410
|
if (!verificationResult.valid) {
|
|
140486
|
-
if (isCompressed &&
|
|
141411
|
+
if (isCompressed && existsSync48(restorePath)) await unlink(restorePath);
|
|
140487
141412
|
throw new Error(`Backup verification failed: ${verificationResult.message}`);
|
|
140488
141413
|
}
|
|
140489
141414
|
}
|
|
140490
|
-
if (
|
|
141415
|
+
if (existsSync48(dbPath) && !options.force) {
|
|
140491
141416
|
printError2(`Database already exists at: ${dbPath}`);
|
|
140492
141417
|
console.log(chalk29.yellow(" Use --force to overwrite"));
|
|
140493
|
-
if (isCompressed &&
|
|
141418
|
+
if (isCompressed && existsSync48(restorePath)) await unlink(restorePath);
|
|
140494
141419
|
process.exit(1);
|
|
140495
141420
|
}
|
|
140496
|
-
const targetDir =
|
|
140497
|
-
if (!
|
|
140498
|
-
if (
|
|
140499
|
-
if (
|
|
140500
|
-
if (
|
|
140501
|
-
|
|
140502
|
-
if (isCompressed &&
|
|
141421
|
+
const targetDir = path26.dirname(dbPath);
|
|
141422
|
+
if (!existsSync48(targetDir)) mkdirSync19(targetDir, { recursive: true });
|
|
141423
|
+
if (existsSync48(dbPath)) await unlink(dbPath);
|
|
141424
|
+
if (existsSync48(`${dbPath}-wal`)) await unlink(`${dbPath}-wal`);
|
|
141425
|
+
if (existsSync48(`${dbPath}-shm`)) await unlink(`${dbPath}-shm`);
|
|
141426
|
+
copyFileSync9(restorePath, dbPath);
|
|
141427
|
+
if (isCompressed && existsSync48(restorePath)) await unlink(restorePath);
|
|
140503
141428
|
const restoredStats = await stat3(dbPath);
|
|
140504
141429
|
const schemaVersion = await getSchemaVersion(dbPath);
|
|
140505
141430
|
if (options.json) {
|
|
@@ -140522,8 +141447,8 @@ function registerRestoreCommand(learning) {
|
|
|
140522
141447
|
function registerVerifyCommand(learning) {
|
|
140523
141448
|
learning.command("verify").description("Verify learning database integrity").option("-f, --file <path>", "Database file to verify (defaults to current)").option("--json", "Output as JSON").action(async (options) => {
|
|
140524
141449
|
try {
|
|
140525
|
-
const dbPath = options.file ?
|
|
140526
|
-
if (!
|
|
141450
|
+
const dbPath = options.file ? path26.resolve(options.file) : getDbPath();
|
|
141451
|
+
if (!existsSync48(dbPath)) throw new Error(`Database file not found: ${dbPath}`);
|
|
140527
141452
|
const verificationResult = await verifyDatabaseIntegrity(dbPath);
|
|
140528
141453
|
const schemaVersion = await getSchemaVersion(dbPath);
|
|
140529
141454
|
const fileStats = await stat3(dbPath);
|
|
@@ -140565,7 +141490,7 @@ function registerExportFullCommand(learning) {
|
|
|
140565
141490
|
learning.command("export-full").description("Export all learning data including patterns, trajectories, and experiences").option("-o, --output <file>", "Output file path", "aqe-learning-export.json").option("--compress", "Compress output with gzip").option("--include-trajectories", "Include learning trajectories").option("--include-experiences", "Include learning experiences").option("--json", "Output as JSON (to stdout)").action(async (options) => {
|
|
140566
141491
|
try {
|
|
140567
141492
|
const dbPath = getDbPath();
|
|
140568
|
-
if (!
|
|
141493
|
+
if (!existsSync48(dbPath)) throw new Error('No learning database found. Run "aqe init --auto" first.');
|
|
140569
141494
|
const reasoningBank = await initializeLearningSystem2();
|
|
140570
141495
|
const schemaVersion = await getSchemaVersion(dbPath);
|
|
140571
141496
|
const searchResult = await reasoningBank.searchPatterns("*", { limit: 1e4 });
|
|
@@ -140617,7 +141542,7 @@ function registerExportFullCommand(learning) {
|
|
|
140617
141542
|
if (options.json) {
|
|
140618
141543
|
printJson2(exportData);
|
|
140619
141544
|
} else {
|
|
140620
|
-
let outputPath =
|
|
141545
|
+
let outputPath = path26.resolve(options.output);
|
|
140621
141546
|
writeFileSync22(outputPath, JSON.stringify(exportData, null, 2), "utf-8");
|
|
140622
141547
|
if (options.compress) {
|
|
140623
141548
|
const compressedPath = await compressFile(outputPath);
|
|
@@ -140643,8 +141568,8 @@ function registerExportFullCommand(learning) {
|
|
|
140643
141568
|
function registerImportMergeCommand(learning) {
|
|
140644
141569
|
learning.command("import-merge").description("Import and merge patterns from export file (preserves existing data)").requiredOption("-i, --input <file>", "Input file path").option("--skip-duplicates", "Skip patterns with matching names (default: update)").option("--dry-run", "Show what would be imported without making changes").option("--json", "Output as JSON").action(async (options) => {
|
|
140645
141570
|
try {
|
|
140646
|
-
let inputPath =
|
|
140647
|
-
if (!
|
|
141571
|
+
let inputPath = path26.resolve(options.input);
|
|
141572
|
+
if (!existsSync48(inputPath)) throw new Error(`File not found: ${inputPath}`);
|
|
140648
141573
|
let content;
|
|
140649
141574
|
if (inputPath.endsWith(".gz")) {
|
|
140650
141575
|
const tempPath = inputPath.replace(".gz", ".tmp.json");
|
|
@@ -140927,7 +141852,7 @@ function registerDreamCommand(learning) {
|
|
|
140927
141852
|
import { Command as Command17 } from "commander";
|
|
140928
141853
|
import { spawn as spawn7 } from "child_process";
|
|
140929
141854
|
import { join as join45, dirname as dirname14 } from "path";
|
|
140930
|
-
import { existsSync as
|
|
141855
|
+
import { existsSync as existsSync49 } from "fs";
|
|
140931
141856
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
140932
141857
|
function createMcpCommand() {
|
|
140933
141858
|
const cmd = new Command17("mcp").description("Start the MCP protocol server for Claude Code integration").option("--http <port>", "Also start HTTP server for AG-UI/A2A protocols", "0").option("--verbose", "Enable verbose logging").action(async (options) => {
|
|
@@ -140979,7 +141904,7 @@ function findMcpEntry() {
|
|
|
140979
141904
|
join45(process.cwd(), "node_modules", "agentic-qe", "v3", "dist", "mcp", "entry.js")
|
|
140980
141905
|
];
|
|
140981
141906
|
for (const candidate of candidates) {
|
|
140982
|
-
if (
|
|
141907
|
+
if (existsSync49(candidate)) {
|
|
140983
141908
|
return candidate;
|
|
140984
141909
|
}
|
|
140985
141910
|
}
|
|
@@ -141101,14 +142026,14 @@ async function cleanupAndExit(code = 0) {
|
|
|
141101
142026
|
process.exit(code);
|
|
141102
142027
|
}
|
|
141103
142028
|
var program = new Command18();
|
|
141104
|
-
var VERSION = true ? "3.6.
|
|
142029
|
+
var VERSION = true ? "3.6.17" : "0.0.0-dev";
|
|
141105
142030
|
program.name("aqe").description("Agentic QE - Domain-Driven Quality Engineering").version(VERSION);
|
|
141106
142031
|
var registry = createCommandRegistry(context, cleanupAndExit, ensureInitialized);
|
|
141107
142032
|
registry.registerAll(program);
|
|
141108
142033
|
var workflowCmd = program.command("workflow").description("Manage QE workflows and pipelines (ADR-041)");
|
|
141109
142034
|
workflowCmd.command("run <file>").description("Execute a QE pipeline from YAML file").option("-w, --watch", "Watch execution progress").option("-v, --verbose", "Show detailed output").option("--params <json>", "Additional parameters as JSON", "{}").action(async (file, options) => {
|
|
141110
142035
|
if (!await ensureInitialized()) return;
|
|
141111
|
-
const
|
|
142036
|
+
const fs25 = await import("fs");
|
|
141112
142037
|
const pathModule = await import("path");
|
|
141113
142038
|
const filePath = pathModule.resolve(file);
|
|
141114
142039
|
try {
|
|
@@ -141176,7 +142101,7 @@ workflowCmd.command("run <file>").description("Execute a QE pipeline from YAML f
|
|
|
141176
142101
|
if (status.status === "completed" || status.status === "failed" || status.status === "cancelled") {
|
|
141177
142102
|
break;
|
|
141178
142103
|
}
|
|
141179
|
-
await new Promise((
|
|
142104
|
+
await new Promise((resolve15) => setTimeout(resolve15, 500));
|
|
141180
142105
|
}
|
|
141181
142106
|
const finalStatus = context.workflowOrchestrator.getWorkflowStatus(executionId);
|
|
141182
142107
|
if (finalStatus) {
|
|
@@ -141348,14 +142273,14 @@ workflowCmd.command("list").description("List workflows").option("-s, --schedule
|
|
|
141348
142273
|
}
|
|
141349
142274
|
});
|
|
141350
142275
|
workflowCmd.command("validate <file>").description("Validate a pipeline YAML file").option("-v, --verbose", "Show detailed validation results").action(async (file, options) => {
|
|
141351
|
-
const
|
|
142276
|
+
const fs25 = await import("fs");
|
|
141352
142277
|
const pathModule = await import("path");
|
|
141353
142278
|
const filePath = pathModule.resolve(file);
|
|
141354
142279
|
try {
|
|
141355
142280
|
console.log(chalk30.blue(`
|
|
141356
142281
|
Validating pipeline: ${file}
|
|
141357
142282
|
`));
|
|
141358
|
-
if (!
|
|
142283
|
+
if (!fs25.existsSync(filePath)) {
|
|
141359
142284
|
console.log(chalk30.red(`File not found: ${filePath}`));
|
|
141360
142285
|
await cleanupAndExit(1);
|
|
141361
142286
|
}
|