agentic-qe 3.6.16 → 3.6.18
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 +38 -0
- package/v3/assets/agents/v3/qe-queen-coordinator.md +9 -3
- package/v3/dist/cli/bundle.js +1619 -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/coordination/agent-teams/domain-team-manager.d.ts +6 -0
- package/v3/dist/coordination/agent-teams/domain-team-manager.d.ts.map +1 -1
- package/v3/dist/coordination/agent-teams/domain-team-manager.js +20 -0
- package/v3/dist/coordination/agent-teams/domain-team-manager.js.map +1 -1
- package/v3/dist/coordination/queen-coordinator.d.ts +2 -0
- package/v3/dist/coordination/queen-coordinator.d.ts.map +1 -1
- package/v3/dist/coordination/queen-coordinator.js +21 -0
- package/v3/dist/coordination/queen-coordinator.js.map +1 -1
- package/v3/dist/mcp/bundle.js +685 -21
- package/v3/dist/mcp/handlers/agent-handlers.d.ts +9 -0
- package/v3/dist/mcp/handlers/agent-handlers.d.ts.map +1 -1
- package/v3/dist/mcp/handlers/agent-handlers.js +30 -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 +63 -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/index.d.ts +1 -0
- package/v3/dist/mcp/handlers/index.d.ts.map +1 -1
- package/v3/dist/mcp/handlers/index.js +2 -0
- package/v3/dist/mcp/handlers/index.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/handlers/team-handlers.d.ts +40 -0
- package/v3/dist/mcp/handlers/team-handlers.d.ts.map +1 -0
- package/v3/dist/mcp/handlers/team-handlers.js +251 -0
- package/v3/dist/mcp/handlers/team-handlers.js.map +1 -0
- 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 +131 -3
- 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 +49 -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) {
|
|
@@ -107315,6 +107315,22 @@ var DomainTeamManager = class _DomainTeamManager {
|
|
|
107315
107315
|
const team = this.teams.get(domain);
|
|
107316
107316
|
return team ? this.toSnapshot(team) : void 0;
|
|
107317
107317
|
}
|
|
107318
|
+
/**
|
|
107319
|
+
* Add a specific agent as a teammate to an existing domain team.
|
|
107320
|
+
* Unlike scaleTeam(), this uses the real agent ID rather than generating one.
|
|
107321
|
+
* @returns True if the agent was added, false if team doesn't exist or is full
|
|
107322
|
+
*/
|
|
107323
|
+
addTeammate(domain, agentId) {
|
|
107324
|
+
const team = this.teams.get(domain);
|
|
107325
|
+
if (!team) return false;
|
|
107326
|
+
if (agentId === team.leadAgentId || team.teammateIds.includes(agentId)) return false;
|
|
107327
|
+
const maxSize = this.getMaxTeamSize(domain);
|
|
107328
|
+
if (1 + team.teammateIds.length >= maxSize) return false;
|
|
107329
|
+
team.teammateIds.push(agentId);
|
|
107330
|
+
team.lastActivity.set(agentId, Date.now());
|
|
107331
|
+
this.adapter.registerAgent(agentId, domain);
|
|
107332
|
+
return true;
|
|
107333
|
+
}
|
|
107318
107334
|
/** List all active domain teams. */
|
|
107319
107335
|
listDomainTeams() {
|
|
107320
107336
|
return Array.from(this.teams.values(), (t50) => this.toSnapshot(t50));
|
|
@@ -110861,8 +110877,8 @@ var CrossPhaseHookExecutor = class {
|
|
|
110861
110877
|
try {
|
|
110862
110878
|
const parts = condition.split(/\s*(>|<|>=|<=|==|!=)\s*/);
|
|
110863
110879
|
if (parts.length !== 3) return false;
|
|
110864
|
-
const [
|
|
110865
|
-
const actual = this.getValueFromPath(context2,
|
|
110880
|
+
const [path27, op, value] = parts;
|
|
110881
|
+
const actual = this.getValueFromPath(context2, path27);
|
|
110866
110882
|
const expected = isNaN(Number(value)) ? value : Number(value);
|
|
110867
110883
|
const actualNum = typeof actual === "number" ? actual : Number(actual);
|
|
110868
110884
|
const expectedNum = typeof expected === "number" ? expected : Number(expected);
|
|
@@ -110886,8 +110902,8 @@ var CrossPhaseHookExecutor = class {
|
|
|
110886
110902
|
return false;
|
|
110887
110903
|
}
|
|
110888
110904
|
}
|
|
110889
|
-
getValueFromPath(obj,
|
|
110890
|
-
return
|
|
110905
|
+
getValueFromPath(obj, path27) {
|
|
110906
|
+
return path27.split(".").reduce((curr, key) => {
|
|
110891
110907
|
if (curr && typeof curr === "object" && key in curr) {
|
|
110892
110908
|
return curr[key];
|
|
110893
110909
|
}
|
|
@@ -110896,8 +110912,8 @@ var CrossPhaseHookExecutor = class {
|
|
|
110896
110912
|
}
|
|
110897
110913
|
extractFromContext(extract, context2) {
|
|
110898
110914
|
const result = {};
|
|
110899
|
-
for (const [key,
|
|
110900
|
-
result[key] = this.getValueFromPath(context2,
|
|
110915
|
+
for (const [key, path27] of Object.entries(extract)) {
|
|
110916
|
+
result[key] = this.getValueFromPath(context2, path27);
|
|
110901
110917
|
}
|
|
110902
110918
|
return result;
|
|
110903
110919
|
}
|
|
@@ -111537,7 +111553,7 @@ function startWorkStealingTimer(config, doStealing) {
|
|
|
111537
111553
|
clearInterval(timer);
|
|
111538
111554
|
return;
|
|
111539
111555
|
}
|
|
111540
|
-
await new Promise((
|
|
111556
|
+
await new Promise((resolve15) => setTimeout(resolve15, backoffMs));
|
|
111541
111557
|
}
|
|
111542
111558
|
}, config.workStealing.checkInterval);
|
|
111543
111559
|
return timer;
|
|
@@ -111976,6 +111992,22 @@ var QueenCoordinator = class {
|
|
|
111976
111992
|
});
|
|
111977
111993
|
if (result.success) {
|
|
111978
111994
|
this.domainLastActivity.set(domain, /* @__PURE__ */ new Date());
|
|
111995
|
+
if (this.domainTeamManager) {
|
|
111996
|
+
const existingTeam = this.domainTeamManager.getDomainTeam(domain);
|
|
111997
|
+
if (!existingTeam) {
|
|
111998
|
+
try {
|
|
111999
|
+
this.domainTeamManager.createDomainTeam(domain, result.value);
|
|
112000
|
+
} catch {
|
|
112001
|
+
if (!this.domainTeamManager.addTeammate(domain, result.value)) {
|
|
112002
|
+
console.warn(`[QueenCoordinator] Agent ${result.value} could not join ${domain} team (full or max teams reached)`);
|
|
112003
|
+
}
|
|
112004
|
+
}
|
|
112005
|
+
} else {
|
|
112006
|
+
if (!this.domainTeamManager.addTeammate(domain, result.value)) {
|
|
112007
|
+
console.warn(`[QueenCoordinator] Agent ${result.value} could not join ${domain} team (full)`);
|
|
112008
|
+
}
|
|
112009
|
+
}
|
|
112010
|
+
}
|
|
111979
112011
|
await this.publishEvent("AgentSpawned", { agentId: result.value, domain, type, capabilities });
|
|
111980
112012
|
}
|
|
111981
112013
|
return result;
|
|
@@ -112083,6 +112115,9 @@ var QueenCoordinator = class {
|
|
|
112083
112115
|
getDomainTeamManager() {
|
|
112084
112116
|
return this.domainTeamManager;
|
|
112085
112117
|
}
|
|
112118
|
+
getAgentTeamsAdapter() {
|
|
112119
|
+
return this.agentTeamsAdapter;
|
|
112120
|
+
}
|
|
112086
112121
|
getTierSelector() {
|
|
112087
112122
|
return this.tierSelector;
|
|
112088
112123
|
}
|
|
@@ -113260,7 +113295,7 @@ var DefaultProtocolExecutor = class {
|
|
|
113260
113295
|
* Sleep helper
|
|
113261
113296
|
*/
|
|
113262
113297
|
sleep(ms) {
|
|
113263
|
-
return new Promise((
|
|
113298
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
113264
113299
|
}
|
|
113265
113300
|
};
|
|
113266
113301
|
|
|
@@ -114039,8 +114074,8 @@ var TokenMetricsCollectorImpl = class _TokenMetricsCollectorImpl {
|
|
|
114039
114074
|
* Save metrics to persistent storage
|
|
114040
114075
|
*/
|
|
114041
114076
|
async save() {
|
|
114042
|
-
const
|
|
114043
|
-
const
|
|
114077
|
+
const fs25 = await import("fs");
|
|
114078
|
+
const path27 = await import("path");
|
|
114044
114079
|
const data = {
|
|
114045
114080
|
version: "1.0.0",
|
|
114046
114081
|
sessionId: this.sessionId,
|
|
@@ -114054,26 +114089,26 @@ var TokenMetricsCollectorImpl = class _TokenMetricsCollectorImpl {
|
|
|
114054
114089
|
},
|
|
114055
114090
|
lastSavedAt: Date.now()
|
|
114056
114091
|
};
|
|
114057
|
-
const filePath =
|
|
114058
|
-
const dirPath =
|
|
114059
|
-
if (!
|
|
114060
|
-
|
|
114092
|
+
const filePath = path27.resolve(this.persistenceConfig.filePath);
|
|
114093
|
+
const dirPath = path27.dirname(filePath);
|
|
114094
|
+
if (!fs25.existsSync(dirPath)) {
|
|
114095
|
+
fs25.mkdirSync(dirPath, { recursive: true });
|
|
114061
114096
|
}
|
|
114062
|
-
|
|
114097
|
+
fs25.writeFileSync(filePath, JSON.stringify(data, null, 2));
|
|
114063
114098
|
this.isDirty = false;
|
|
114064
114099
|
}
|
|
114065
114100
|
/**
|
|
114066
114101
|
* Load metrics from persistent storage
|
|
114067
114102
|
*/
|
|
114068
114103
|
async load() {
|
|
114069
|
-
const
|
|
114070
|
-
const
|
|
114071
|
-
const filePath =
|
|
114072
|
-
if (!
|
|
114104
|
+
const fs25 = await import("fs");
|
|
114105
|
+
const path27 = await import("path");
|
|
114106
|
+
const filePath = path27.resolve(this.persistenceConfig.filePath);
|
|
114107
|
+
if (!fs25.existsSync(filePath)) {
|
|
114073
114108
|
return false;
|
|
114074
114109
|
}
|
|
114075
114110
|
try {
|
|
114076
|
-
const content =
|
|
114111
|
+
const content = fs25.readFileSync(filePath, "utf-8");
|
|
114077
114112
|
const data = safeJsonParse(content);
|
|
114078
114113
|
if (!data.version || !data.version.startsWith("1.")) {
|
|
114079
114114
|
console.warn("[TokenMetricsCollector] Incompatible data version, skipping load");
|
|
@@ -115240,9 +115275,9 @@ function validatePipeline(pipeline10) {
|
|
|
115240
115275
|
function detectCircularDependencies(stages) {
|
|
115241
115276
|
const visited = /* @__PURE__ */ new Set();
|
|
115242
115277
|
const recursionStack = /* @__PURE__ */ new Set();
|
|
115243
|
-
const visit = (stageName,
|
|
115278
|
+
const visit = (stageName, path27) => {
|
|
115244
115279
|
if (recursionStack.has(stageName)) {
|
|
115245
|
-
return [...
|
|
115280
|
+
return [...path27, stageName].join(" -> ");
|
|
115246
115281
|
}
|
|
115247
115282
|
if (visited.has(stageName)) {
|
|
115248
115283
|
return null;
|
|
@@ -115252,7 +115287,7 @@ function detectCircularDependencies(stages) {
|
|
|
115252
115287
|
const stage = stages.find((s70) => s70.name === stageName);
|
|
115253
115288
|
if (stage?.depends_on) {
|
|
115254
115289
|
for (const dep of stage.depends_on) {
|
|
115255
|
-
const result = visit(dep, [...
|
|
115290
|
+
const result = visit(dep, [...path27, stageName]);
|
|
115256
115291
|
if (result) return result;
|
|
115257
115292
|
}
|
|
115258
115293
|
}
|
|
@@ -115722,7 +115757,7 @@ var PersistentScheduler = class {
|
|
|
115722
115757
|
* Sleep for specified milliseconds
|
|
115723
115758
|
*/
|
|
115724
115759
|
sleep(ms) {
|
|
115725
|
-
return new Promise((
|
|
115760
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
115726
115761
|
}
|
|
115727
115762
|
/**
|
|
115728
115763
|
* Log debug message if debug mode is enabled
|
|
@@ -115872,7 +115907,7 @@ var ALL_DOMAINS2 = [
|
|
|
115872
115907
|
"enterprise-integration"
|
|
115873
115908
|
];
|
|
115874
115909
|
function getAQEVersion() {
|
|
115875
|
-
return true ? "3.6.
|
|
115910
|
+
return true ? "3.6.18" : "3.0.0";
|
|
115876
115911
|
}
|
|
115877
115912
|
function createDefaultConfig(projectName, projectRoot) {
|
|
115878
115913
|
return {
|
|
@@ -118664,9 +118699,9 @@ var N8nInstaller = class {
|
|
|
118664
118699
|
// Monorepo location
|
|
118665
118700
|
join21(process.cwd(), "../.claude/agents/n8n")
|
|
118666
118701
|
];
|
|
118667
|
-
for (const
|
|
118668
|
-
if (existsSync19(
|
|
118669
|
-
return
|
|
118702
|
+
for (const path27 of possiblePaths) {
|
|
118703
|
+
if (existsSync19(path27)) {
|
|
118704
|
+
return path27;
|
|
118670
118705
|
}
|
|
118671
118706
|
}
|
|
118672
118707
|
return join21(process.cwd(), ".claude/agents/n8n");
|
|
@@ -118681,9 +118716,9 @@ var N8nInstaller = class {
|
|
|
118681
118716
|
join21(process.cwd(), ".claude/skills"),
|
|
118682
118717
|
join21(__dirname2, "../../assets/skills")
|
|
118683
118718
|
];
|
|
118684
|
-
for (const
|
|
118685
|
-
if (existsSync19(
|
|
118686
|
-
return
|
|
118719
|
+
for (const path27 of possiblePaths) {
|
|
118720
|
+
if (existsSync19(path27)) {
|
|
118721
|
+
return path27;
|
|
118687
118722
|
}
|
|
118688
118723
|
}
|
|
118689
118724
|
return join21(process.cwd(), ".claude/skills");
|
|
@@ -120442,8 +120477,8 @@ var HooksPhase = class extends BasePhase {
|
|
|
120442
120477
|
let installed = false;
|
|
120443
120478
|
for (const src of assetPaths) {
|
|
120444
120479
|
if (existsSync25(src)) {
|
|
120445
|
-
const { copyFileSync:
|
|
120446
|
-
|
|
120480
|
+
const { copyFileSync: copyFileSync10 } = __require("fs");
|
|
120481
|
+
copyFileSync10(src, crossPhasePath);
|
|
120447
120482
|
context2.services.log(" Installed cross-phase memory config");
|
|
120448
120483
|
installed = true;
|
|
120449
120484
|
break;
|
|
@@ -121022,7 +121057,7 @@ try {
|
|
|
121022
121057
|
error: "aqe-mcp not found. Install globally with: npm install -g agentic-qe"
|
|
121023
121058
|
};
|
|
121024
121059
|
}
|
|
121025
|
-
return new Promise((
|
|
121060
|
+
return new Promise((resolve15) => {
|
|
121026
121061
|
try {
|
|
121027
121062
|
const env = {
|
|
121028
121063
|
...process.env,
|
|
@@ -121043,7 +121078,7 @@ try {
|
|
|
121043
121078
|
errorOutput += data.toString();
|
|
121044
121079
|
});
|
|
121045
121080
|
child.on("error", (error) => {
|
|
121046
|
-
|
|
121081
|
+
resolve15({
|
|
121047
121082
|
started: false,
|
|
121048
121083
|
pid: null,
|
|
121049
121084
|
error: error.message
|
|
@@ -121058,12 +121093,12 @@ try {
|
|
|
121058
121093
|
`;
|
|
121059
121094
|
writeFileSync11(logFile, logEntry, { flag: "a" });
|
|
121060
121095
|
child.unref();
|
|
121061
|
-
|
|
121096
|
+
resolve15({
|
|
121062
121097
|
started: true,
|
|
121063
121098
|
pid: child.pid
|
|
121064
121099
|
});
|
|
121065
121100
|
} else {
|
|
121066
|
-
|
|
121101
|
+
resolve15({
|
|
121067
121102
|
started: false,
|
|
121068
121103
|
pid: null,
|
|
121069
121104
|
error: errorOutput || "No PID assigned"
|
|
@@ -121071,7 +121106,7 @@ try {
|
|
|
121071
121106
|
}
|
|
121072
121107
|
} catch {
|
|
121073
121108
|
const errMsg = errorOutput.includes("ERR_MODULE_NOT_FOUND") ? "Missing dependencies. Run: npm install agentic-qe" : errorOutput || "Process exited immediately";
|
|
121074
|
-
|
|
121109
|
+
resolve15({
|
|
121075
121110
|
started: false,
|
|
121076
121111
|
pid: null,
|
|
121077
121112
|
error: errMsg
|
|
@@ -121079,7 +121114,7 @@ try {
|
|
|
121079
121114
|
}
|
|
121080
121115
|
}, 1500);
|
|
121081
121116
|
} catch (error) {
|
|
121082
|
-
|
|
121117
|
+
resolve15({
|
|
121083
121118
|
started: false,
|
|
121084
121119
|
pid: null,
|
|
121085
121120
|
error: error instanceof Error ? error.message : "Spawn failed"
|
|
@@ -123310,7 +123345,7 @@ var TaskHandler14 = class {
|
|
|
123310
123345
|
}
|
|
123311
123346
|
}
|
|
123312
123347
|
if (!completed) {
|
|
123313
|
-
await new Promise((
|
|
123348
|
+
await new Promise((resolve15) => setTimeout(resolve15, 500));
|
|
123314
123349
|
}
|
|
123315
123350
|
}
|
|
123316
123351
|
if (!completed) {
|
|
@@ -123946,8 +123981,8 @@ function createTestCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
123946
123981
|
console.log(chalk9.red("Test generation domain not available"));
|
|
123947
123982
|
return;
|
|
123948
123983
|
}
|
|
123949
|
-
const
|
|
123950
|
-
const targetPath =
|
|
123984
|
+
const path27 = await import("path");
|
|
123985
|
+
const targetPath = path27.resolve(target || ".");
|
|
123951
123986
|
const sourceFiles = walkSourceFiles(targetPath, { includeTests: false });
|
|
123952
123987
|
if (sourceFiles.length === 0) {
|
|
123953
123988
|
console.log(chalk9.yellow("No source files found"));
|
|
@@ -123968,14 +124003,14 @@ function createTestCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
123968
124003
|
console.log(chalk9.cyan(" Tests:"));
|
|
123969
124004
|
for (const test of generated.tests.slice(0, 10)) {
|
|
123970
124005
|
console.log(` ${chalk9.white(test.name)}`);
|
|
123971
|
-
console.log(chalk9.gray(` Source: ${
|
|
124006
|
+
console.log(chalk9.gray(` Source: ${path27.basename(test.sourceFile)}`));
|
|
123972
124007
|
console.log(chalk9.gray(` Assertions: ${test.assertions}`));
|
|
123973
124008
|
if (test.testCode) {
|
|
123974
124009
|
console.log(chalk9.gray(` Test File: ${test.testFile}`));
|
|
123975
|
-
const
|
|
123976
|
-
const testDir =
|
|
123977
|
-
|
|
123978
|
-
|
|
124010
|
+
const fs25 = await import("fs");
|
|
124011
|
+
const testDir = path27.dirname(test.testFile);
|
|
124012
|
+
fs25.mkdirSync(testDir, { recursive: true });
|
|
124013
|
+
fs25.writeFileSync(test.testFile, test.testCode, "utf-8");
|
|
123979
124014
|
console.log(chalk9.green(` Written to: ${test.testFile}`));
|
|
123980
124015
|
}
|
|
123981
124016
|
}
|
|
@@ -123999,8 +124034,8 @@ function createTestCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
123999
124034
|
console.log(chalk9.red("Test execution domain not available"));
|
|
124000
124035
|
return;
|
|
124001
124036
|
}
|
|
124002
|
-
const
|
|
124003
|
-
const targetPath =
|
|
124037
|
+
const path27 = await import("path");
|
|
124038
|
+
const targetPath = path27.resolve(target || ".");
|
|
124004
124039
|
const testFiles = walkSourceFiles(targetPath, { testsOnly: true });
|
|
124005
124040
|
if (testFiles.length === 0) {
|
|
124006
124041
|
console.log(chalk9.yellow("No test files found"));
|
|
@@ -124090,9 +124125,9 @@ var WizardPrompt = class {
|
|
|
124090
124125
|
* Generic prompt helper - wraps readline.question in a Promise
|
|
124091
124126
|
*/
|
|
124092
124127
|
static prompt(rl, question) {
|
|
124093
|
-
return new Promise((
|
|
124128
|
+
return new Promise((resolve15) => {
|
|
124094
124129
|
rl.question(question, (answer) => {
|
|
124095
|
-
|
|
124130
|
+
resolve15(answer);
|
|
124096
124131
|
});
|
|
124097
124132
|
});
|
|
124098
124133
|
}
|
|
@@ -124261,8 +124296,8 @@ var WizardFormat = class {
|
|
|
124261
124296
|
/**
|
|
124262
124297
|
* Format a path relative to cwd
|
|
124263
124298
|
*/
|
|
124264
|
-
static relativePath(
|
|
124265
|
-
return relative6(cwd,
|
|
124299
|
+
static relativePath(path27, cwd) {
|
|
124300
|
+
return relative6(cwd, path27) || ".";
|
|
124266
124301
|
}
|
|
124267
124302
|
/**
|
|
124268
124303
|
* Format a boolean as Yes/No
|
|
@@ -124903,9 +124938,9 @@ function createCoverageCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
124903
124938
|
console.log(chalk13.red("Coverage analysis domain not available"));
|
|
124904
124939
|
return;
|
|
124905
124940
|
}
|
|
124906
|
-
const
|
|
124907
|
-
const
|
|
124908
|
-
const targetPath =
|
|
124941
|
+
const fs25 = await import("fs");
|
|
124942
|
+
const path27 = await import("path");
|
|
124943
|
+
const targetPath = path27.resolve(analyzeTarget);
|
|
124909
124944
|
const sourceFiles = walkSourceFiles(targetPath, { includeTests: false });
|
|
124910
124945
|
if (sourceFiles.length === 0) {
|
|
124911
124946
|
console.log(chalk13.yellow("No source files found"));
|
|
@@ -124914,11 +124949,11 @@ function createCoverageCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
124914
124949
|
console.log(chalk13.gray(` Analyzing ${sourceFiles.length} files...
|
|
124915
124950
|
`));
|
|
124916
124951
|
const files = sourceFiles.map((filePath) => {
|
|
124917
|
-
const content =
|
|
124952
|
+
const content = fs25.readFileSync(filePath, "utf-8");
|
|
124918
124953
|
const lines = content.split("\n");
|
|
124919
124954
|
const totalLines2 = lines.length;
|
|
124920
124955
|
const testFile = filePath.replace(".ts", ".test.ts").replace("/src/", "/tests/");
|
|
124921
|
-
const hasTest =
|
|
124956
|
+
const hasTest = fs25.existsSync(testFile);
|
|
124922
124957
|
const coverageRate = hasTest ? 0.75 + Math.random() * 0.2 : 0.2 + Math.random() * 0.3;
|
|
124923
124958
|
const coveredLines2 = Math.floor(totalLines2 * coverageRate);
|
|
124924
124959
|
const uncoveredLines = Array.from({ length: totalLines2 - coveredLines2 }, (_56, i58) => i58 + coveredLines2 + 1);
|
|
@@ -125092,8 +125127,8 @@ function createSecurityCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125092
125127
|
console.log(chalk15.red("Security domain not available"));
|
|
125093
125128
|
return;
|
|
125094
125129
|
}
|
|
125095
|
-
const
|
|
125096
|
-
const targetPath =
|
|
125130
|
+
const path27 = await import("path");
|
|
125131
|
+
const targetPath = path27.resolve(options.target);
|
|
125097
125132
|
const files = walkSourceFiles(targetPath, { includeTests: true });
|
|
125098
125133
|
if (files.length === 0) {
|
|
125099
125134
|
console.log(chalk15.yellow("No files found to scan"));
|
|
@@ -125169,12 +125204,12 @@ function createCodeCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125169
125204
|
console.log(chalk16.red("Code intelligence domain not available"));
|
|
125170
125205
|
return;
|
|
125171
125206
|
}
|
|
125172
|
-
const
|
|
125207
|
+
const path27 = await import("path");
|
|
125173
125208
|
if (action === "index") {
|
|
125174
125209
|
console.log(chalk16.blue(`
|
|
125175
125210
|
Indexing codebase at ${target || "."}...
|
|
125176
125211
|
`));
|
|
125177
|
-
const targetPath =
|
|
125212
|
+
const targetPath = path27.resolve(target || ".");
|
|
125178
125213
|
const paths = walkSourceFiles(targetPath, {
|
|
125179
125214
|
includeTests: options.includeTests || false
|
|
125180
125215
|
});
|
|
@@ -125235,7 +125270,7 @@ function createCodeCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125235
125270
|
console.log(chalk16.blue(`
|
|
125236
125271
|
Analyzing impact for ${target || "recent changes"}...
|
|
125237
125272
|
`));
|
|
125238
|
-
const targetPath =
|
|
125273
|
+
const targetPath = path27.resolve(target || ".");
|
|
125239
125274
|
const changedFiles = walkSourceFiles(targetPath, { maxDepth: 2 }).slice(0, 10);
|
|
125240
125275
|
const result = await codeAPI.analyzeImpact({
|
|
125241
125276
|
changedFiles,
|
|
@@ -125281,7 +125316,7 @@ function createCodeCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125281
125316
|
console.log(chalk16.blue(`
|
|
125282
125317
|
Mapping dependencies for ${target || "."}...
|
|
125283
125318
|
`));
|
|
125284
|
-
const targetPath =
|
|
125319
|
+
const targetPath = path27.resolve(target || ".");
|
|
125285
125320
|
const files = walkSourceFiles(targetPath, { maxDepth: 2 }).slice(0, 50);
|
|
125286
125321
|
const result = await codeAPI.mapDependencies({
|
|
125287
125322
|
files,
|
|
@@ -125433,32 +125468,32 @@ var v3Agents = [
|
|
|
125433
125468
|
function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
125434
125469
|
const migrateCmd = new Command6("migrate").description("V2-to-V3 migration tools with agent compatibility (ADR-048)");
|
|
125435
125470
|
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
|
|
125471
|
+
const fs25 = await import("fs");
|
|
125472
|
+
const path27 = await import("path");
|
|
125438
125473
|
console.log(chalk17.blue("\n V2 to V3 Migration (ADR-048)\n"));
|
|
125439
125474
|
const cwd = process.cwd();
|
|
125440
|
-
const v2Dir =
|
|
125441
|
-
const v3Dir =
|
|
125442
|
-
const claudeAgentDir =
|
|
125475
|
+
const v2Dir = path27.join(cwd, ".agentic-qe");
|
|
125476
|
+
const v3Dir = path27.join(cwd, ".aqe");
|
|
125477
|
+
const claudeAgentDir = path27.join(cwd, ".claude", "agents");
|
|
125443
125478
|
console.log(chalk17.white("1. Detecting v2 installation..."));
|
|
125444
|
-
const hasV2Dir =
|
|
125445
|
-
const hasClaudeAgents =
|
|
125479
|
+
const hasV2Dir = fs25.existsSync(v2Dir);
|
|
125480
|
+
const hasClaudeAgents = fs25.existsSync(claudeAgentDir);
|
|
125446
125481
|
if (!hasV2Dir && !hasClaudeAgents) {
|
|
125447
125482
|
console.log(chalk17.yellow(" ! No v2 installation found"));
|
|
125448
125483
|
console.log(chalk17.gray(" This might be a fresh project. Use `aqe init` instead."));
|
|
125449
125484
|
await cleanupAndExit2(0);
|
|
125450
125485
|
}
|
|
125451
125486
|
const v2Files = {
|
|
125452
|
-
memoryDb:
|
|
125453
|
-
config:
|
|
125454
|
-
patterns:
|
|
125487
|
+
memoryDb: path27.join(v2Dir, "memory.db"),
|
|
125488
|
+
config: path27.join(v2Dir, "config.json"),
|
|
125489
|
+
patterns: path27.join(v2Dir, "patterns")
|
|
125455
125490
|
};
|
|
125456
|
-
const hasMemory = hasV2Dir &&
|
|
125457
|
-
const hasConfig = hasV2Dir &&
|
|
125458
|
-
const hasPatterns = hasV2Dir &&
|
|
125491
|
+
const hasMemory = hasV2Dir && fs25.existsSync(v2Files.memoryDb);
|
|
125492
|
+
const hasConfig = hasV2Dir && fs25.existsSync(v2Files.config);
|
|
125493
|
+
const hasPatterns = hasV2Dir && fs25.existsSync(v2Files.patterns);
|
|
125459
125494
|
const agentsToMigrate = [];
|
|
125460
125495
|
if (hasClaudeAgents) {
|
|
125461
|
-
const files =
|
|
125496
|
+
const files = fs25.readdirSync(claudeAgentDir);
|
|
125462
125497
|
for (const file of files) {
|
|
125463
125498
|
if (file.endsWith(".md") && file.startsWith("qe-")) {
|
|
125464
125499
|
const agentName = file.replace(".md", "");
|
|
@@ -125475,7 +125510,7 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125475
125510
|
console.log(chalk17.gray(` Agents to migrate: ${agentsToMigrate.length}
|
|
125476
125511
|
`));
|
|
125477
125512
|
console.log(chalk17.white("2. Checking v3 status..."));
|
|
125478
|
-
if (
|
|
125513
|
+
if (fs25.existsSync(v3Dir) && !options.force) {
|
|
125479
125514
|
console.log(chalk17.yellow(" ! v3 directory already exists at .aqe/"));
|
|
125480
125515
|
console.log(chalk17.gray(" Use --force to overwrite existing v3 installation."));
|
|
125481
125516
|
await cleanupAndExit2(1);
|
|
@@ -125484,14 +125519,14 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125484
125519
|
if (options.dryRun) {
|
|
125485
125520
|
console.log(chalk17.blue(" Dry Run - Migration Plan:\n"));
|
|
125486
125521
|
if (!options.skipMemory && hasMemory) {
|
|
125487
|
-
const stats =
|
|
125522
|
+
const stats = fs25.statSync(v2Files.memoryDb);
|
|
125488
125523
|
console.log(chalk17.gray(` - Migrate memory.db (${(stats.size / 1024).toFixed(1)} KB)`));
|
|
125489
125524
|
}
|
|
125490
125525
|
if (!options.skipConfig && hasConfig) {
|
|
125491
125526
|
console.log(chalk17.gray(" - Convert config.json to v3 format"));
|
|
125492
125527
|
}
|
|
125493
125528
|
if (!options.skipPatterns && hasPatterns) {
|
|
125494
|
-
const patternFiles =
|
|
125529
|
+
const patternFiles = fs25.readdirSync(v2Files.patterns);
|
|
125495
125530
|
console.log(chalk17.gray(` - Migrate ${patternFiles.length} pattern files`));
|
|
125496
125531
|
}
|
|
125497
125532
|
if (!options.skipAgents && agentsToMigrate.length > 0) {
|
|
@@ -125506,22 +125541,22 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125506
125541
|
}
|
|
125507
125542
|
if (options.backup) {
|
|
125508
125543
|
console.log(chalk17.white("3. Creating backup..."));
|
|
125509
|
-
const backupDir =
|
|
125544
|
+
const backupDir = path27.join(cwd, ".aqe-backup", `backup-${Date.now()}`);
|
|
125510
125545
|
try {
|
|
125511
|
-
|
|
125546
|
+
fs25.mkdirSync(backupDir, { recursive: true });
|
|
125512
125547
|
const copyDir = (src, dest) => {
|
|
125513
|
-
if (!
|
|
125514
|
-
if (
|
|
125515
|
-
|
|
125516
|
-
for (const file of
|
|
125517
|
-
copyDir(
|
|
125548
|
+
if (!fs25.existsSync(src)) return;
|
|
125549
|
+
if (fs25.statSync(src).isDirectory()) {
|
|
125550
|
+
fs25.mkdirSync(dest, { recursive: true });
|
|
125551
|
+
for (const file of fs25.readdirSync(src)) {
|
|
125552
|
+
copyDir(path27.join(src, file), path27.join(dest, file));
|
|
125518
125553
|
}
|
|
125519
125554
|
} else {
|
|
125520
|
-
|
|
125555
|
+
fs25.copyFileSync(src, dest);
|
|
125521
125556
|
}
|
|
125522
125557
|
};
|
|
125523
|
-
if (hasV2Dir) copyDir(v2Dir,
|
|
125524
|
-
if (hasClaudeAgents) copyDir(claudeAgentDir,
|
|
125558
|
+
if (hasV2Dir) copyDir(v2Dir, path27.join(backupDir, ".agentic-qe"));
|
|
125559
|
+
if (hasClaudeAgents) copyDir(claudeAgentDir, path27.join(backupDir, ".claude", "agents"));
|
|
125525
125560
|
console.log(chalk17.green(` * Backup created at .aqe-backup/
|
|
125526
125561
|
`));
|
|
125527
125562
|
} catch (err3) {
|
|
@@ -125534,11 +125569,11 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125534
125569
|
if (!options.target || options.target === "config" || options.target === "memory") {
|
|
125535
125570
|
console.log(chalk17.white("4. Creating v3 directory structure..."));
|
|
125536
125571
|
try {
|
|
125537
|
-
|
|
125538
|
-
|
|
125539
|
-
|
|
125540
|
-
|
|
125541
|
-
|
|
125572
|
+
fs25.mkdirSync(v3Dir, { recursive: true });
|
|
125573
|
+
fs25.mkdirSync(path27.join(v3Dir, "agentdb"), { recursive: true });
|
|
125574
|
+
fs25.mkdirSync(path27.join(v3Dir, "reasoning-bank"), { recursive: true });
|
|
125575
|
+
fs25.mkdirSync(path27.join(v3Dir, "cache"), { recursive: true });
|
|
125576
|
+
fs25.mkdirSync(path27.join(v3Dir, "logs"), { recursive: true });
|
|
125542
125577
|
console.log(chalk17.green(" * Directory structure created\n"));
|
|
125543
125578
|
} catch (err3) {
|
|
125544
125579
|
console.log(chalk17.red(` x Failed: ${err3}
|
|
@@ -125549,17 +125584,17 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125549
125584
|
if ((!options.target || options.target === "memory") && !options.skipMemory && hasMemory) {
|
|
125550
125585
|
console.log(chalk17.white("5. Migrating memory database..."));
|
|
125551
125586
|
try {
|
|
125552
|
-
const destDb =
|
|
125553
|
-
|
|
125554
|
-
const indexFile =
|
|
125555
|
-
|
|
125587
|
+
const destDb = path27.join(v3Dir, "agentdb", "memory.db");
|
|
125588
|
+
fs25.copyFileSync(v2Files.memoryDb, destDb);
|
|
125589
|
+
const indexFile = path27.join(v3Dir, "agentdb", "index.json");
|
|
125590
|
+
fs25.writeFileSync(indexFile, JSON.stringify({
|
|
125556
125591
|
version: "3.0.0",
|
|
125557
125592
|
migratedFrom: "v2",
|
|
125558
125593
|
migratedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
125559
125594
|
hnswEnabled: true,
|
|
125560
125595
|
vectorDimensions: 768
|
|
125561
125596
|
}, null, 2));
|
|
125562
|
-
const stats =
|
|
125597
|
+
const stats = fs25.statSync(v2Files.memoryDb);
|
|
125563
125598
|
console.log(chalk17.green(` * Memory database migrated (${(stats.size / 1024).toFixed(1)} KB)
|
|
125564
125599
|
`));
|
|
125565
125600
|
} catch (err3) {
|
|
@@ -125576,7 +125611,7 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125576
125611
|
if ((!options.target || options.target === "config") && !options.skipConfig && hasConfig) {
|
|
125577
125612
|
console.log(chalk17.white("6. Migrating configuration..."));
|
|
125578
125613
|
try {
|
|
125579
|
-
const v2ConfigRaw =
|
|
125614
|
+
const v2ConfigRaw = fs25.readFileSync(v2Files.config, "utf-8");
|
|
125580
125615
|
const v2Config = parseJsonFile(v2ConfigRaw, v2Files.config);
|
|
125581
125616
|
const v3Config = {
|
|
125582
125617
|
version: "3.0.0",
|
|
@@ -125612,8 +125647,8 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125612
125647
|
migrationDate: (/* @__PURE__ */ new Date()).toISOString()
|
|
125613
125648
|
}
|
|
125614
125649
|
};
|
|
125615
|
-
const destConfig =
|
|
125616
|
-
|
|
125650
|
+
const destConfig = path27.join(v3Dir, "config.json");
|
|
125651
|
+
fs25.writeFileSync(destConfig, JSON.stringify(v3Config, null, 2));
|
|
125617
125652
|
console.log(chalk17.green(" * Configuration migrated\n"));
|
|
125618
125653
|
} catch (err3) {
|
|
125619
125654
|
console.log(chalk17.red(` x Config migration failed: ${err3}
|
|
@@ -125629,18 +125664,18 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125629
125664
|
if ((!options.target || options.target === "memory") && !options.skipPatterns && hasPatterns) {
|
|
125630
125665
|
console.log(chalk17.white("7. Migrating patterns to ReasoningBank..."));
|
|
125631
125666
|
try {
|
|
125632
|
-
const patternFiles =
|
|
125667
|
+
const patternFiles = fs25.readdirSync(v2Files.patterns);
|
|
125633
125668
|
let migratedCount = 0;
|
|
125634
125669
|
for (const file of patternFiles) {
|
|
125635
|
-
const srcPath =
|
|
125636
|
-
const destPath =
|
|
125637
|
-
if (
|
|
125638
|
-
|
|
125670
|
+
const srcPath = path27.join(v2Files.patterns, file);
|
|
125671
|
+
const destPath = path27.join(v3Dir, "reasoning-bank", file);
|
|
125672
|
+
if (fs25.statSync(srcPath).isFile()) {
|
|
125673
|
+
fs25.copyFileSync(srcPath, destPath);
|
|
125639
125674
|
migratedCount++;
|
|
125640
125675
|
}
|
|
125641
125676
|
}
|
|
125642
|
-
const indexPath =
|
|
125643
|
-
|
|
125677
|
+
const indexPath = path27.join(v3Dir, "reasoning-bank", "index.json");
|
|
125678
|
+
fs25.writeFileSync(indexPath, JSON.stringify({
|
|
125644
125679
|
version: "3.0.0",
|
|
125645
125680
|
migratedFrom: "v2",
|
|
125646
125681
|
migratedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -125661,17 +125696,17 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
125661
125696
|
if ((!options.target || options.target === "agents") && !options.skipAgents && agentsToMigrate.length > 0) {
|
|
125662
125697
|
console.log(chalk17.white("8. Migrating agent names (ADR-048)..."));
|
|
125663
125698
|
let migratedAgents = 0;
|
|
125664
|
-
const deprecatedDir =
|
|
125665
|
-
if (!
|
|
125666
|
-
|
|
125699
|
+
const deprecatedDir = path27.join(claudeAgentDir, "deprecated");
|
|
125700
|
+
if (!fs25.existsSync(deprecatedDir)) {
|
|
125701
|
+
fs25.mkdirSync(deprecatedDir, { recursive: true });
|
|
125667
125702
|
}
|
|
125668
125703
|
for (const v2Name of agentsToMigrate) {
|
|
125669
125704
|
const v3Name = resolveAgentName(v2Name);
|
|
125670
|
-
const v2FilePath =
|
|
125671
|
-
const v3FilePath =
|
|
125672
|
-
const deprecatedPath =
|
|
125705
|
+
const v2FilePath = path27.join(claudeAgentDir, `${v2Name}.md`);
|
|
125706
|
+
const v3FilePath = path27.join(claudeAgentDir, `${v3Name}.md`);
|
|
125707
|
+
const deprecatedPath = path27.join(deprecatedDir, `${v2Name}.md.v2`);
|
|
125673
125708
|
try {
|
|
125674
|
-
const content =
|
|
125709
|
+
const content = fs25.readFileSync(v2FilePath, "utf-8");
|
|
125675
125710
|
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
125676
125711
|
if (!frontmatterMatch) {
|
|
125677
125712
|
console.log(chalk17.yellow(` ! ${v2Name}: No frontmatter found, skipping`));
|
|
@@ -125699,8 +125734,8 @@ v2_compat:
|
|
|
125699
125734
|
const newContent = `---
|
|
125700
125735
|
${newFrontmatter}
|
|
125701
125736
|
---${body}`;
|
|
125702
|
-
|
|
125703
|
-
|
|
125737
|
+
fs25.writeFileSync(v3FilePath, newContent, "utf-8");
|
|
125738
|
+
fs25.renameSync(v2FilePath, deprecatedPath);
|
|
125704
125739
|
console.log(chalk17.gray(` ${v2Name} -> ${v3Name}`));
|
|
125705
125740
|
migratedAgents++;
|
|
125706
125741
|
} catch (err3) {
|
|
@@ -125721,10 +125756,10 @@ ${newFrontmatter}
|
|
|
125721
125756
|
}
|
|
125722
125757
|
console.log(chalk17.white("9. Validating migration..."));
|
|
125723
125758
|
const validationResults = {
|
|
125724
|
-
v3DirExists:
|
|
125725
|
-
configExists:
|
|
125726
|
-
agentdbExists:
|
|
125727
|
-
reasoningBankExists:
|
|
125759
|
+
v3DirExists: fs25.existsSync(v3Dir),
|
|
125760
|
+
configExists: fs25.existsSync(path27.join(v3Dir, "config.json")),
|
|
125761
|
+
agentdbExists: fs25.existsSync(path27.join(v3Dir, "agentdb")),
|
|
125762
|
+
reasoningBankExists: fs25.existsSync(path27.join(v3Dir, "reasoning-bank"))
|
|
125728
125763
|
};
|
|
125729
125764
|
const allValid = Object.values(validationResults).every((v62) => v62);
|
|
125730
125765
|
if (allValid) {
|
|
@@ -125744,18 +125779,18 @@ ${newFrontmatter}
|
|
|
125744
125779
|
await cleanupAndExit2(0);
|
|
125745
125780
|
});
|
|
125746
125781
|
migrateCmd.command("status").description("Check migration status of current project").option("--json", "Output as JSON").action(async (options) => {
|
|
125747
|
-
const
|
|
125748
|
-
const
|
|
125782
|
+
const fs25 = await import("fs");
|
|
125783
|
+
const path27 = await import("path");
|
|
125749
125784
|
const cwd = process.cwd();
|
|
125750
|
-
const v2Dir =
|
|
125751
|
-
const v3Dir =
|
|
125752
|
-
const claudeAgentDir =
|
|
125753
|
-
const isV2Project =
|
|
125754
|
-
const isV3Project =
|
|
125785
|
+
const v2Dir = path27.join(cwd, ".agentic-qe");
|
|
125786
|
+
const v3Dir = path27.join(cwd, ".aqe");
|
|
125787
|
+
const claudeAgentDir = path27.join(cwd, ".claude", "agents");
|
|
125788
|
+
const isV2Project = fs25.existsSync(v2Dir);
|
|
125789
|
+
const isV3Project = fs25.existsSync(v3Dir);
|
|
125755
125790
|
const agentsToMigrate = [];
|
|
125756
125791
|
const agentsMigrated = [];
|
|
125757
|
-
if (
|
|
125758
|
-
const files =
|
|
125792
|
+
if (fs25.existsSync(claudeAgentDir)) {
|
|
125793
|
+
const files = fs25.readdirSync(claudeAgentDir);
|
|
125759
125794
|
for (const file of files) {
|
|
125760
125795
|
if (file.endsWith(".md") && file.startsWith("qe-")) {
|
|
125761
125796
|
const agentName = file.replace(".md", "");
|
|
@@ -125804,15 +125839,15 @@ ${newFrontmatter}
|
|
|
125804
125839
|
await cleanupAndExit2(0);
|
|
125805
125840
|
});
|
|
125806
125841
|
migrateCmd.command("verify").description("Verify migration integrity").option("--fix", "Attempt to fix issues automatically").action(async (options) => {
|
|
125807
|
-
const
|
|
125808
|
-
const
|
|
125842
|
+
const fs25 = await import("fs");
|
|
125843
|
+
const path27 = await import("path");
|
|
125809
125844
|
console.log(chalk17.bold("\n Verifying Migration...\n"));
|
|
125810
125845
|
const cwd = process.cwd();
|
|
125811
|
-
const v3Dir =
|
|
125812
|
-
const claudeAgentDir =
|
|
125846
|
+
const v3Dir = path27.join(cwd, ".aqe");
|
|
125847
|
+
const claudeAgentDir = path27.join(cwd, ".claude", "agents");
|
|
125813
125848
|
const deprecatedInUse = [];
|
|
125814
|
-
if (
|
|
125815
|
-
const files =
|
|
125849
|
+
if (fs25.existsSync(claudeAgentDir)) {
|
|
125850
|
+
const files = fs25.readdirSync(claudeAgentDir);
|
|
125816
125851
|
for (const file of files) {
|
|
125817
125852
|
if (file.endsWith(".md") && file.startsWith("qe-")) {
|
|
125818
125853
|
const agentName = file.replace(".md", "");
|
|
@@ -125825,8 +125860,8 @@ ${newFrontmatter}
|
|
|
125825
125860
|
const checks = [
|
|
125826
125861
|
{
|
|
125827
125862
|
name: "V3 Directory",
|
|
125828
|
-
passed:
|
|
125829
|
-
message:
|
|
125863
|
+
passed: fs25.existsSync(v3Dir),
|
|
125864
|
+
message: fs25.existsSync(v3Dir) ? "Exists" : "Missing .aqe/"
|
|
125830
125865
|
},
|
|
125831
125866
|
{
|
|
125832
125867
|
name: "Agent Compatibility",
|
|
@@ -125835,7 +125870,7 @@ ${newFrontmatter}
|
|
|
125835
125870
|
},
|
|
125836
125871
|
{
|
|
125837
125872
|
name: "Config Format",
|
|
125838
|
-
passed:
|
|
125873
|
+
passed: fs25.existsSync(path27.join(v3Dir, "config.json")),
|
|
125839
125874
|
message: "Valid v3 config"
|
|
125840
125875
|
}
|
|
125841
125876
|
];
|
|
@@ -125860,15 +125895,15 @@ ${newFrontmatter}
|
|
|
125860
125895
|
await cleanupAndExit2(0);
|
|
125861
125896
|
});
|
|
125862
125897
|
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
|
|
125898
|
+
const fs25 = await import("fs");
|
|
125899
|
+
const path27 = await import("path");
|
|
125865
125900
|
const cwd = process.cwd();
|
|
125866
|
-
const backupRoot =
|
|
125867
|
-
if (!
|
|
125901
|
+
const backupRoot = path27.join(cwd, ".aqe-backup");
|
|
125902
|
+
if (!fs25.existsSync(backupRoot)) {
|
|
125868
125903
|
console.log(chalk17.yellow("\n! No backups found.\n"));
|
|
125869
125904
|
return;
|
|
125870
125905
|
}
|
|
125871
|
-
const backups =
|
|
125906
|
+
const backups = fs25.readdirSync(backupRoot).filter((f74) => f74.startsWith("backup-")).sort().reverse();
|
|
125872
125907
|
if (backups.length === 0) {
|
|
125873
125908
|
console.log(chalk17.yellow("\n! No backups found.\n"));
|
|
125874
125909
|
return;
|
|
@@ -125880,8 +125915,8 @@ ${newFrontmatter}
|
|
|
125880
125915
|
console.log(` ${chalk17.cyan(backup)} - ${date.toLocaleString()}`);
|
|
125881
125916
|
}
|
|
125882
125917
|
const targetBackup = options.backupId || backups[0];
|
|
125883
|
-
const backupPath =
|
|
125884
|
-
if (!
|
|
125918
|
+
const backupPath = path27.join(backupRoot, targetBackup);
|
|
125919
|
+
if (!fs25.existsSync(backupPath)) {
|
|
125885
125920
|
console.log(chalk17.red(`
|
|
125886
125921
|
Backup not found: ${targetBackup}
|
|
125887
125922
|
`));
|
|
@@ -125896,21 +125931,21 @@ ${newFrontmatter}
|
|
|
125896
125931
|
console.log(chalk17.bold(`
|
|
125897
125932
|
Rolling back to ${targetBackup}...
|
|
125898
125933
|
`));
|
|
125899
|
-
const v2Backup =
|
|
125900
|
-
const agentsBackup =
|
|
125901
|
-
if (
|
|
125902
|
-
const v2Dir =
|
|
125903
|
-
|
|
125934
|
+
const v2Backup = path27.join(backupPath, ".agentic-qe");
|
|
125935
|
+
const agentsBackup = path27.join(backupPath, ".claude", "agents");
|
|
125936
|
+
if (fs25.existsSync(v2Backup)) {
|
|
125937
|
+
const v2Dir = path27.join(cwd, ".agentic-qe");
|
|
125938
|
+
fs25.cpSync(v2Backup, v2Dir, { recursive: true });
|
|
125904
125939
|
console.log(chalk17.dim(" Restored .agentic-qe/"));
|
|
125905
125940
|
}
|
|
125906
|
-
if (
|
|
125907
|
-
const agentsDir =
|
|
125908
|
-
|
|
125941
|
+
if (fs25.existsSync(agentsBackup)) {
|
|
125942
|
+
const agentsDir = path27.join(cwd, ".claude", "agents");
|
|
125943
|
+
fs25.cpSync(agentsBackup, agentsDir, { recursive: true });
|
|
125909
125944
|
console.log(chalk17.dim(" Restored .claude/agents/"));
|
|
125910
125945
|
}
|
|
125911
|
-
const v3Dir =
|
|
125912
|
-
if (
|
|
125913
|
-
|
|
125946
|
+
const v3Dir = path27.join(cwd, ".aqe");
|
|
125947
|
+
if (fs25.existsSync(v3Dir)) {
|
|
125948
|
+
fs25.rmSync(v3Dir, { recursive: true, force: true });
|
|
125914
125949
|
console.log(chalk17.dim(" Removed .aqe/"));
|
|
125915
125950
|
}
|
|
125916
125951
|
console.log(chalk17.green("\n Rollback complete!\n"));
|
|
@@ -127468,8 +127503,8 @@ function createCompletionsCommand(cleanupAndExit2) {
|
|
|
127468
127503
|
console.log(generateCompletion("powershell"));
|
|
127469
127504
|
});
|
|
127470
127505
|
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
|
|
127506
|
+
const fs25 = await import("fs");
|
|
127507
|
+
const path27 = await import("path");
|
|
127473
127508
|
const shellInfo = options.shell ? { name: options.shell, configFile: null, detected: false } : detectShell();
|
|
127474
127509
|
if (shellInfo.name === "unknown") {
|
|
127475
127510
|
console.log(chalk18.red("Could not detect shell. Please specify with --shell option.\n"));
|
|
@@ -127483,11 +127518,11 @@ Installing completions for ${shellInfo.name}...
|
|
|
127483
127518
|
const script = generateCompletion(shellInfo.name);
|
|
127484
127519
|
if (shellInfo.name === "fish") {
|
|
127485
127520
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
127486
|
-
const fishCompletionsDir =
|
|
127521
|
+
const fishCompletionsDir = path27.join(homeDir, ".config", "fish", "completions");
|
|
127487
127522
|
try {
|
|
127488
|
-
|
|
127489
|
-
const completionFile =
|
|
127490
|
-
|
|
127523
|
+
fs25.mkdirSync(fishCompletionsDir, { recursive: true });
|
|
127524
|
+
const completionFile = path27.join(fishCompletionsDir, "aqe.fish");
|
|
127525
|
+
fs25.writeFileSync(completionFile, script);
|
|
127491
127526
|
console.log(chalk18.green(`Completions installed to: ${completionFile}`));
|
|
127492
127527
|
console.log(chalk18.gray("\nRestart your shell or run: source ~/.config/fish/completions/aqe.fish\n"));
|
|
127493
127528
|
} catch (err3) {
|
|
@@ -127719,13 +127754,13 @@ var FleetInitEnhancer = class {
|
|
|
127719
127754
|
input: process.stdin,
|
|
127720
127755
|
output: process.stdout
|
|
127721
127756
|
});
|
|
127722
|
-
return new Promise((
|
|
127757
|
+
return new Promise((resolve15) => {
|
|
127723
127758
|
rl.question(
|
|
127724
127759
|
chalk19.white(" Run code intelligence scan now? [Y/n]: "),
|
|
127725
127760
|
(answer) => {
|
|
127726
127761
|
rl.close();
|
|
127727
127762
|
const normalized = answer.trim().toLowerCase();
|
|
127728
|
-
|
|
127763
|
+
resolve15(normalized === "" || normalized === "y" || normalized === "yes");
|
|
127729
127764
|
}
|
|
127730
127765
|
);
|
|
127731
127766
|
});
|
|
@@ -128227,11 +128262,11 @@ function createFleetCommand(context2, cleanupAndExit2, ensureInitialized2, regis
|
|
|
128227
128262
|
}
|
|
128228
128263
|
const results = await Promise.all(
|
|
128229
128264
|
agentOperations.map(async (op, index) => {
|
|
128230
|
-
await new Promise((
|
|
128265
|
+
await new Promise((resolve15) => setTimeout(resolve15, index * 200));
|
|
128231
128266
|
progress.updateAgent(op.id, 0, { status: "running" });
|
|
128232
128267
|
try {
|
|
128233
128268
|
for (let p74 = 10; p74 <= 90; p74 += 20) {
|
|
128234
|
-
await new Promise((
|
|
128269
|
+
await new Promise((resolve15) => setTimeout(resolve15, 300 + Math.random() * 200));
|
|
128235
128270
|
progress.updateAgent(op.id, p74, {
|
|
128236
128271
|
eta: Math.round((100 - p74) * 50)
|
|
128237
128272
|
});
|
|
@@ -128654,7 +128689,7 @@ var SwarmSkillValidator = class {
|
|
|
128654
128689
|
* Helper to delay execution
|
|
128655
128690
|
*/
|
|
128656
128691
|
delay(ms) {
|
|
128657
|
-
return new Promise((
|
|
128692
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
128658
128693
|
}
|
|
128659
128694
|
/**
|
|
128660
128695
|
* Get current configuration
|
|
@@ -128740,7 +128775,7 @@ var DEFAULT_PARALLEL_EVAL_CONFIG = {
|
|
|
128740
128775
|
var MockLLMExecutor = class {
|
|
128741
128776
|
async execute(prompt, model, options) {
|
|
128742
128777
|
const delay = Math.random() * MOCK_LLM_MAX_DELAY_MS + MOCK_LLM_MIN_DELAY_MS;
|
|
128743
|
-
await new Promise((
|
|
128778
|
+
await new Promise((resolve15) => setTimeout(resolve15, delay));
|
|
128744
128779
|
const output = this.generateMockResponse(prompt);
|
|
128745
128780
|
return {
|
|
128746
128781
|
output,
|
|
@@ -133008,6 +133043,160 @@ import chalk26 from "chalk";
|
|
|
133008
133043
|
import ora2 from "ora";
|
|
133009
133044
|
|
|
133010
133045
|
// src/sync/interfaces.ts
|
|
133046
|
+
var DEFAULT_PULL_CONFIG = {
|
|
133047
|
+
cloud: {
|
|
133048
|
+
project: process.env.GCP_PROJECT || "",
|
|
133049
|
+
zone: process.env.GCP_ZONE || "",
|
|
133050
|
+
instance: process.env.GCP_INSTANCE || "",
|
|
133051
|
+
database: process.env.GCP_DATABASE || "",
|
|
133052
|
+
user: process.env.GCP_USER || "",
|
|
133053
|
+
tunnelPort: parseInt(process.env.GCP_TUNNEL_PORT || "15432", 10)
|
|
133054
|
+
},
|
|
133055
|
+
environment: process.env.AQE_ENV || "all",
|
|
133056
|
+
batchSize: 1e3,
|
|
133057
|
+
sources: [
|
|
133058
|
+
// QE Patterns (cloud 0 records, but may grow)
|
|
133059
|
+
{
|
|
133060
|
+
name: "qe-patterns",
|
|
133061
|
+
cloudTable: "aqe.qe_patterns",
|
|
133062
|
+
localTable: "qe_patterns",
|
|
133063
|
+
enabled: true,
|
|
133064
|
+
priority: "high",
|
|
133065
|
+
mode: "incremental",
|
|
133066
|
+
dropColumns: ["source_env", "embedding", "sync_version"],
|
|
133067
|
+
transforms: { reusable: "boolean-to-int" }
|
|
133068
|
+
},
|
|
133069
|
+
// SONA patterns (873 records)
|
|
133070
|
+
{
|
|
133071
|
+
name: "sona-patterns",
|
|
133072
|
+
cloudTable: "aqe.sona_patterns",
|
|
133073
|
+
localTable: "sona_patterns",
|
|
133074
|
+
enabled: true,
|
|
133075
|
+
priority: "high",
|
|
133076
|
+
mode: "incremental",
|
|
133077
|
+
dropColumns: ["source_env", "sync_version"],
|
|
133078
|
+
transforms: {
|
|
133079
|
+
is_active: "boolean-to-int",
|
|
133080
|
+
requires_fine_tuning: "boolean-to-int"
|
|
133081
|
+
}
|
|
133082
|
+
},
|
|
133083
|
+
// GOAP actions (2,335 records)
|
|
133084
|
+
{
|
|
133085
|
+
name: "goap-actions",
|
|
133086
|
+
cloudTable: "aqe.goap_actions",
|
|
133087
|
+
localTable: "goap_actions",
|
|
133088
|
+
enabled: true,
|
|
133089
|
+
priority: "high",
|
|
133090
|
+
mode: "incremental",
|
|
133091
|
+
dropColumns: ["source_env", "sync_version"],
|
|
133092
|
+
columnMap: { duration_estimate: "estimated_duration_ms" }
|
|
133093
|
+
},
|
|
133094
|
+
// GOAP plans (91 records)
|
|
133095
|
+
{
|
|
133096
|
+
name: "goap-plans",
|
|
133097
|
+
cloudTable: "aqe.goap_plans",
|
|
133098
|
+
localTable: "goap_plans",
|
|
133099
|
+
enabled: true,
|
|
133100
|
+
priority: "medium",
|
|
133101
|
+
mode: "incremental",
|
|
133102
|
+
dropColumns: ["source_env", "sync_version"],
|
|
133103
|
+
columnMap: { estimated_duration: "estimated_duration_ms" }
|
|
133104
|
+
},
|
|
133105
|
+
// Memory entries → kv_store (0 records in cloud currently)
|
|
133106
|
+
{
|
|
133107
|
+
name: "memory-entries",
|
|
133108
|
+
cloudTable: "aqe.memory_entries",
|
|
133109
|
+
localTable: "kv_store",
|
|
133110
|
+
enabled: true,
|
|
133111
|
+
priority: "high",
|
|
133112
|
+
mode: "incremental",
|
|
133113
|
+
dropColumns: ["source_env", "sync_version"],
|
|
133114
|
+
columnMap: { partition: "namespace" }
|
|
133115
|
+
},
|
|
133116
|
+
// Learning experiences → captured_experiences (7,702 records)
|
|
133117
|
+
// Drop 'id' because cloud uses SERIAL auto-increment, local uses UUID
|
|
133118
|
+
// Map 'created_at' → 'started_at' since push mapped started_at → created_at
|
|
133119
|
+
{
|
|
133120
|
+
name: "learning-experiences",
|
|
133121
|
+
cloudTable: "aqe.learning_experiences",
|
|
133122
|
+
localTable: "captured_experiences",
|
|
133123
|
+
enabled: true,
|
|
133124
|
+
priority: "high",
|
|
133125
|
+
mode: "append",
|
|
133126
|
+
dropColumns: ["id", "source_env", "sync_version"],
|
|
133127
|
+
columnMap: {
|
|
133128
|
+
agent_id: "agent",
|
|
133129
|
+
task_id: "task",
|
|
133130
|
+
task_type: "domain",
|
|
133131
|
+
state: "result_json",
|
|
133132
|
+
action: "steps_json",
|
|
133133
|
+
reward: "quality",
|
|
133134
|
+
next_state: "routing_json",
|
|
133135
|
+
episode_id: "tags",
|
|
133136
|
+
created_at: "started_at"
|
|
133137
|
+
}
|
|
133138
|
+
},
|
|
133139
|
+
// Q-learning patterns → rl_q_values (3 records)
|
|
133140
|
+
{
|
|
133141
|
+
name: "qlearning-patterns",
|
|
133142
|
+
cloudTable: "aqe.qlearning_patterns",
|
|
133143
|
+
localTable: "rl_q_values",
|
|
133144
|
+
enabled: true,
|
|
133145
|
+
priority: "medium",
|
|
133146
|
+
mode: "incremental",
|
|
133147
|
+
dropColumns: ["source_env", "sync_version"],
|
|
133148
|
+
columnMap: {
|
|
133149
|
+
state: "state_key",
|
|
133150
|
+
action: "action_key",
|
|
133151
|
+
last_update: "updated_at"
|
|
133152
|
+
}
|
|
133153
|
+
},
|
|
133154
|
+
// Routing outcomes (186 records)
|
|
133155
|
+
{
|
|
133156
|
+
name: "routing-outcomes",
|
|
133157
|
+
cloudTable: "aqe.routing_outcomes",
|
|
133158
|
+
localTable: "routing_outcomes",
|
|
133159
|
+
enabled: true,
|
|
133160
|
+
priority: "medium",
|
|
133161
|
+
mode: "append",
|
|
133162
|
+
dropColumns: ["source_env", "sync_version"]
|
|
133163
|
+
},
|
|
133164
|
+
// QE trajectories (0 records in cloud currently)
|
|
133165
|
+
{
|
|
133166
|
+
name: "qe-trajectories",
|
|
133167
|
+
cloudTable: "aqe.qe_trajectories",
|
|
133168
|
+
localTable: "qe_trajectories",
|
|
133169
|
+
enabled: true,
|
|
133170
|
+
priority: "medium",
|
|
133171
|
+
mode: "append",
|
|
133172
|
+
dropColumns: ["source_env", "sync_version", "embedding"]
|
|
133173
|
+
},
|
|
133174
|
+
// Dream insights (680 records)
|
|
133175
|
+
{
|
|
133176
|
+
name: "dream-insights",
|
|
133177
|
+
cloudTable: "aqe.dream_insights",
|
|
133178
|
+
localTable: "dream_insights",
|
|
133179
|
+
enabled: true,
|
|
133180
|
+
priority: "low",
|
|
133181
|
+
mode: "append",
|
|
133182
|
+
dropColumns: ["source_env", "sync_version"]
|
|
133183
|
+
},
|
|
133184
|
+
// Claude-Flow memory (2 records in cloud)
|
|
133185
|
+
// Push syncs from JSON file; pull writes to kv_store since local has no dedicated table
|
|
133186
|
+
{
|
|
133187
|
+
name: "claude-flow-memory",
|
|
133188
|
+
cloudTable: "aqe.claude_flow_memory",
|
|
133189
|
+
localTable: "kv_store",
|
|
133190
|
+
enabled: true,
|
|
133191
|
+
priority: "low",
|
|
133192
|
+
mode: "incremental",
|
|
133193
|
+
dropColumns: ["source_env", "sync_version"],
|
|
133194
|
+
columnMap: { partition: "namespace" }
|
|
133195
|
+
}
|
|
133196
|
+
// NOTE: intelligence-qlearning (JSON push source) is NOT pulled back —
|
|
133197
|
+
// the cloud qlearning_patterns table is already pulled via the qlearning-patterns source above.
|
|
133198
|
+
]
|
|
133199
|
+
};
|
|
133011
133200
|
var DEFAULT_SYNC_CONFIG = {
|
|
133012
133201
|
local: {
|
|
133013
133202
|
// PRIMARY: Root database (consolidated, MCP-active)
|
|
@@ -133730,21 +133919,21 @@ var IAPTunnelManager = class {
|
|
|
133730
133919
|
* Check if a port is accepting connections
|
|
133731
133920
|
*/
|
|
133732
133921
|
checkPort(host, port, timeout = 2e3) {
|
|
133733
|
-
return new Promise((
|
|
133922
|
+
return new Promise((resolve15) => {
|
|
133734
133923
|
const socket = createConnection({ host, port });
|
|
133735
133924
|
const timer = setTimeout(() => {
|
|
133736
133925
|
socket.destroy();
|
|
133737
|
-
|
|
133926
|
+
resolve15(false);
|
|
133738
133927
|
}, timeout);
|
|
133739
133928
|
socket.on("connect", () => {
|
|
133740
133929
|
clearTimeout(timer);
|
|
133741
133930
|
socket.destroy();
|
|
133742
|
-
|
|
133931
|
+
resolve15(true);
|
|
133743
133932
|
});
|
|
133744
133933
|
socket.on("error", () => {
|
|
133745
133934
|
clearTimeout(timer);
|
|
133746
133935
|
socket.destroy();
|
|
133747
|
-
|
|
133936
|
+
resolve15(false);
|
|
133748
133937
|
});
|
|
133749
133938
|
});
|
|
133750
133939
|
}
|
|
@@ -133766,7 +133955,7 @@ var IAPTunnelManager = class {
|
|
|
133766
133955
|
};
|
|
133767
133956
|
return this.connection;
|
|
133768
133957
|
}
|
|
133769
|
-
return new Promise((
|
|
133958
|
+
return new Promise((resolve15, reject) => {
|
|
133770
133959
|
const args = [
|
|
133771
133960
|
"compute",
|
|
133772
133961
|
"start-iap-tunnel",
|
|
@@ -133810,7 +133999,7 @@ var IAPTunnelManager = class {
|
|
|
133810
133999
|
startedAt: /* @__PURE__ */ new Date()
|
|
133811
134000
|
};
|
|
133812
134001
|
console.log(`[TunnelManager] Tunnel ready on port ${this.config.tunnelPort}`);
|
|
133813
|
-
|
|
134002
|
+
resolve15(this.connection);
|
|
133814
134003
|
return;
|
|
133815
134004
|
}
|
|
133816
134005
|
await new Promise((r54) => setTimeout(r54, 1e3));
|
|
@@ -133853,7 +134042,7 @@ var IAPTunnelManager = class {
|
|
|
133853
134042
|
if (this.process) {
|
|
133854
134043
|
console.log("[TunnelManager] Stopping tunnel");
|
|
133855
134044
|
this.process.kill("SIGTERM");
|
|
133856
|
-
await new Promise((
|
|
134045
|
+
await new Promise((resolve15) => setTimeout(resolve15, 1e3));
|
|
133857
134046
|
if (this.process) {
|
|
133858
134047
|
this.process.kill("SIGKILL");
|
|
133859
134048
|
}
|
|
@@ -134312,11 +134501,410 @@ function createPostgresWriter(config) {
|
|
|
134312
134501
|
return new PostgresWriter(config);
|
|
134313
134502
|
}
|
|
134314
134503
|
|
|
134504
|
+
// src/sync/cloud/postgres-reader.ts
|
|
134505
|
+
init_sql_safety();
|
|
134506
|
+
init_error_utils();
|
|
134507
|
+
init_logging();
|
|
134508
|
+
var logger15 = LoggerFactory.create("postgres-reader");
|
|
134509
|
+
var PostgresReader = class {
|
|
134510
|
+
writer;
|
|
134511
|
+
environment;
|
|
134512
|
+
constructor(config) {
|
|
134513
|
+
this.writer = config.writer;
|
|
134514
|
+
this.environment = config.environment;
|
|
134515
|
+
}
|
|
134516
|
+
/**
|
|
134517
|
+
* Validate and sanitize a 'schema.table' cloud table reference.
|
|
134518
|
+
* Throws if the format is invalid (must contain exactly one dot).
|
|
134519
|
+
*/
|
|
134520
|
+
sanitizeCloudTable(cloudTable) {
|
|
134521
|
+
const dotIndex = cloudTable.indexOf(".");
|
|
134522
|
+
if (dotIndex === -1 || dotIndex === 0 || dotIndex === cloudTable.length - 1) {
|
|
134523
|
+
throw new Error(
|
|
134524
|
+
`Invalid cloud table format '${cloudTable}': expected 'schema.table' (e.g., 'aqe.qe_patterns')`
|
|
134525
|
+
);
|
|
134526
|
+
}
|
|
134527
|
+
const schema = cloudTable.substring(0, dotIndex);
|
|
134528
|
+
const table = cloudTable.substring(dotIndex + 1);
|
|
134529
|
+
return `${validateIdentifier(schema)}.${validateIdentifier(table)}`;
|
|
134530
|
+
}
|
|
134531
|
+
/**
|
|
134532
|
+
* Read all records from a cloud table
|
|
134533
|
+
*/
|
|
134534
|
+
async readAll(source) {
|
|
134535
|
+
const safeTable = this.sanitizeCloudTable(source.cloudTable);
|
|
134536
|
+
let sql;
|
|
134537
|
+
let params;
|
|
134538
|
+
if (this.environment !== "all") {
|
|
134539
|
+
sql = `SELECT * FROM ${safeTable} WHERE source_env = $1`;
|
|
134540
|
+
params = [this.environment];
|
|
134541
|
+
} else {
|
|
134542
|
+
sql = `SELECT * FROM ${safeTable}`;
|
|
134543
|
+
params = [];
|
|
134544
|
+
}
|
|
134545
|
+
try {
|
|
134546
|
+
const rows = await this.writer.query(sql, params);
|
|
134547
|
+
logger15.debug(`Read ${rows.length} records from ${source.cloudTable}`, {
|
|
134548
|
+
env: this.environment
|
|
134549
|
+
});
|
|
134550
|
+
return rows.map((row) => this.transformRecord(row, source));
|
|
134551
|
+
} catch (error) {
|
|
134552
|
+
throw new Error(
|
|
134553
|
+
`Failed to read from ${source.cloudTable}: ${toErrorMessage(error)}`
|
|
134554
|
+
);
|
|
134555
|
+
}
|
|
134556
|
+
}
|
|
134557
|
+
/**
|
|
134558
|
+
* Read records changed since a timestamp
|
|
134559
|
+
*/
|
|
134560
|
+
async readChanged(source, since) {
|
|
134561
|
+
const safeTable = this.sanitizeCloudTable(source.cloudTable);
|
|
134562
|
+
const timestampCol = await this.findTimestampColumn(safeTable);
|
|
134563
|
+
if (!timestampCol) {
|
|
134564
|
+
logger15.debug(`No timestamp column found for ${source.cloudTable}, falling back to readAll`);
|
|
134565
|
+
return this.readAll(source);
|
|
134566
|
+
}
|
|
134567
|
+
let sql;
|
|
134568
|
+
let params;
|
|
134569
|
+
if (this.environment !== "all") {
|
|
134570
|
+
sql = `SELECT * FROM ${safeTable} WHERE ${validateIdentifier(timestampCol)} > $1 AND source_env = $2`;
|
|
134571
|
+
params = [since.toISOString(), this.environment];
|
|
134572
|
+
} else {
|
|
134573
|
+
sql = `SELECT * FROM ${safeTable} WHERE ${validateIdentifier(timestampCol)} > $1`;
|
|
134574
|
+
params = [since.toISOString()];
|
|
134575
|
+
}
|
|
134576
|
+
try {
|
|
134577
|
+
const rows = await this.writer.query(sql, params);
|
|
134578
|
+
return rows.map((row) => this.transformRecord(row, source));
|
|
134579
|
+
} catch (error) {
|
|
134580
|
+
logger15.debug(`Changed query failed for ${source.cloudTable}, falling back to readAll`, {
|
|
134581
|
+
error: toErrorMessage(error)
|
|
134582
|
+
});
|
|
134583
|
+
return this.readAll(source);
|
|
134584
|
+
}
|
|
134585
|
+
}
|
|
134586
|
+
/**
|
|
134587
|
+
* Get record count from a cloud table
|
|
134588
|
+
*/
|
|
134589
|
+
async count(source) {
|
|
134590
|
+
const safeTable = this.sanitizeCloudTable(source.cloudTable);
|
|
134591
|
+
let sql;
|
|
134592
|
+
let params;
|
|
134593
|
+
if (this.environment !== "all") {
|
|
134594
|
+
sql = `SELECT COUNT(*) as count FROM ${safeTable} WHERE source_env = $1`;
|
|
134595
|
+
params = [this.environment];
|
|
134596
|
+
} else {
|
|
134597
|
+
sql = `SELECT COUNT(*) as count FROM ${safeTable}`;
|
|
134598
|
+
params = [];
|
|
134599
|
+
}
|
|
134600
|
+
try {
|
|
134601
|
+
await this.writer.beginTransaction();
|
|
134602
|
+
await this.writer.execute("SET LOCAL enable_indexonlyscan = off");
|
|
134603
|
+
const rows = await this.writer.query(sql, params);
|
|
134604
|
+
await this.writer.commit();
|
|
134605
|
+
return typeof rows[0]?.count === "string" ? parseInt(rows[0].count, 10) : rows[0]?.count || 0;
|
|
134606
|
+
} catch (error) {
|
|
134607
|
+
try {
|
|
134608
|
+
await this.writer.rollback();
|
|
134609
|
+
} catch {
|
|
134610
|
+
}
|
|
134611
|
+
logger15.debug(`Count query failed for ${source.cloudTable}`, {
|
|
134612
|
+
error: toErrorMessage(error)
|
|
134613
|
+
});
|
|
134614
|
+
return -1;
|
|
134615
|
+
}
|
|
134616
|
+
}
|
|
134617
|
+
/**
|
|
134618
|
+
* Transform a cloud record for local insertion.
|
|
134619
|
+
* - Drops specified columns (source_env, embedding, sync_version)
|
|
134620
|
+
* - Renames columns per columnMap
|
|
134621
|
+
* - Applies type transforms (boolean→int, jsonb→text, etc.)
|
|
134622
|
+
*/
|
|
134623
|
+
transformRecord(row, source) {
|
|
134624
|
+
const result = {};
|
|
134625
|
+
for (const [key, value] of Object.entries(row)) {
|
|
134626
|
+
if (source.dropColumns?.includes(key)) {
|
|
134627
|
+
continue;
|
|
134628
|
+
}
|
|
134629
|
+
const localKey = source.columnMap?.[key] || key;
|
|
134630
|
+
result[localKey] = this.transformValue(value, key, source.transforms);
|
|
134631
|
+
}
|
|
134632
|
+
return result;
|
|
134633
|
+
}
|
|
134634
|
+
/**
|
|
134635
|
+
* Transform a single value based on configured transforms
|
|
134636
|
+
*/
|
|
134637
|
+
transformValue(value, columnName, transforms) {
|
|
134638
|
+
if (value === null || value === void 0) {
|
|
134639
|
+
return null;
|
|
134640
|
+
}
|
|
134641
|
+
const transform = transforms?.[columnName];
|
|
134642
|
+
if (transform === "boolean-to-int") {
|
|
134643
|
+
if (typeof value === "boolean") return value ? 1 : 0;
|
|
134644
|
+
if (value === "true" || value === "t") return 1;
|
|
134645
|
+
if (value === "false" || value === "f") return 0;
|
|
134646
|
+
return value;
|
|
134647
|
+
}
|
|
134648
|
+
if (transform === "jsonb-to-text") {
|
|
134649
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
134650
|
+
return value;
|
|
134651
|
+
}
|
|
134652
|
+
if (transform === "timestamptz-to-text") {
|
|
134653
|
+
if (value instanceof Date) return value.toISOString();
|
|
134654
|
+
return value;
|
|
134655
|
+
}
|
|
134656
|
+
if (typeof value === "object" && !Buffer.isBuffer(value)) {
|
|
134657
|
+
return JSON.stringify(value);
|
|
134658
|
+
}
|
|
134659
|
+
if (value instanceof Date) {
|
|
134660
|
+
return value.toISOString();
|
|
134661
|
+
}
|
|
134662
|
+
if (typeof value === "boolean") {
|
|
134663
|
+
return value ? 1 : 0;
|
|
134664
|
+
}
|
|
134665
|
+
return value;
|
|
134666
|
+
}
|
|
134667
|
+
/**
|
|
134668
|
+
* Find a timestamp column in a cloud table
|
|
134669
|
+
*/
|
|
134670
|
+
async findTimestampColumn(safeTable) {
|
|
134671
|
+
const candidates = ["updated_at", "created_at", "last_update", "last_used_at"];
|
|
134672
|
+
try {
|
|
134673
|
+
const schema = safeTable.split(".")[0];
|
|
134674
|
+
const table = safeTable.split(".")[1];
|
|
134675
|
+
const rows = await this.writer.query(
|
|
134676
|
+
`SELECT column_name FROM information_schema.columns
|
|
134677
|
+
WHERE table_schema = $1 AND table_name = $2
|
|
134678
|
+
AND data_type IN ('timestamp with time zone', 'timestamp without time zone')`,
|
|
134679
|
+
[schema, table]
|
|
134680
|
+
);
|
|
134681
|
+
const columnNames = rows.map((r54) => r54.column_name);
|
|
134682
|
+
for (const candidate of candidates) {
|
|
134683
|
+
if (columnNames.includes(candidate)) {
|
|
134684
|
+
return candidate;
|
|
134685
|
+
}
|
|
134686
|
+
}
|
|
134687
|
+
return columnNames[0] || null;
|
|
134688
|
+
} catch {
|
|
134689
|
+
return null;
|
|
134690
|
+
}
|
|
134691
|
+
}
|
|
134692
|
+
};
|
|
134693
|
+
function createPostgresReader(config) {
|
|
134694
|
+
return new PostgresReader(config);
|
|
134695
|
+
}
|
|
134696
|
+
|
|
134697
|
+
// src/sync/writers/sqlite-writer.ts
|
|
134698
|
+
init_safe_db();
|
|
134699
|
+
init_sql_safety();
|
|
134700
|
+
init_error_utils();
|
|
134701
|
+
init_logging();
|
|
134702
|
+
import * as fs22 from "fs";
|
|
134703
|
+
var logger16 = LoggerFactory.create("sqlite-writer");
|
|
134704
|
+
var SQLiteWriter = class {
|
|
134705
|
+
db = null;
|
|
134706
|
+
dbPath;
|
|
134707
|
+
batchSize;
|
|
134708
|
+
constructor(config) {
|
|
134709
|
+
this.dbPath = config.dbPath;
|
|
134710
|
+
this.batchSize = config.batchSize || 500;
|
|
134711
|
+
}
|
|
134712
|
+
/**
|
|
134713
|
+
* Connect to (open) the local SQLite database
|
|
134714
|
+
*/
|
|
134715
|
+
async connect() {
|
|
134716
|
+
if (this.db) return;
|
|
134717
|
+
if (!fs22.existsSync(this.dbPath)) {
|
|
134718
|
+
throw new Error(`SQLite database not found: ${this.dbPath}. Run 'aqe init' to create it.`);
|
|
134719
|
+
}
|
|
134720
|
+
try {
|
|
134721
|
+
this.db = openDatabase(this.dbPath);
|
|
134722
|
+
this.db.pragma("journal_mode = WAL");
|
|
134723
|
+
this.db.pragma("synchronous = NORMAL");
|
|
134724
|
+
logger16.debug(`Opened SQLite database: ${this.dbPath}`);
|
|
134725
|
+
} catch (error) {
|
|
134726
|
+
throw new Error(`Failed to open SQLite database ${this.dbPath}: ${toErrorMessage(error)}`);
|
|
134727
|
+
}
|
|
134728
|
+
}
|
|
134729
|
+
/**
|
|
134730
|
+
* Upsert records into a local table using INSERT OR REPLACE.
|
|
134731
|
+
* Returns the number of records written.
|
|
134732
|
+
*/
|
|
134733
|
+
async upsert(table, records) {
|
|
134734
|
+
if (!this.db) throw new Error("Not connected");
|
|
134735
|
+
if (records.length === 0) return 0;
|
|
134736
|
+
const safeTable = validateTableName(table);
|
|
134737
|
+
if (!this.tableExists(table)) {
|
|
134738
|
+
console.warn(`[SQLiteWriter] Table '${table}' does not exist in local database \u2014 ${records.length} records skipped. Run 'aqe init' to create schema.`);
|
|
134739
|
+
return 0;
|
|
134740
|
+
}
|
|
134741
|
+
const localColumns = this.getTableColumns(table);
|
|
134742
|
+
if (localColumns.length === 0) {
|
|
134743
|
+
logger16.debug(`No columns found for table ${table}`);
|
|
134744
|
+
return 0;
|
|
134745
|
+
}
|
|
134746
|
+
const localColumnSet = new Set(localColumns);
|
|
134747
|
+
let totalWritten = 0;
|
|
134748
|
+
for (let i58 = 0; i58 < records.length; i58 += this.batchSize) {
|
|
134749
|
+
const batch = records.slice(i58, i58 + this.batchSize);
|
|
134750
|
+
try {
|
|
134751
|
+
const written = this.upsertBatch(safeTable, batch, localColumnSet);
|
|
134752
|
+
totalWritten += written;
|
|
134753
|
+
} catch (error) {
|
|
134754
|
+
const batchNum = Math.floor(i58 / this.batchSize) + 1;
|
|
134755
|
+
logger16.debug(`Batch ${batchNum} failed for ${table}, retrying individually`, {
|
|
134756
|
+
error: toErrorMessage(error)
|
|
134757
|
+
});
|
|
134758
|
+
let recovered = 0;
|
|
134759
|
+
for (const record of batch) {
|
|
134760
|
+
try {
|
|
134761
|
+
recovered += this.upsertBatch(safeTable, [record], localColumnSet);
|
|
134762
|
+
} catch (retryError) {
|
|
134763
|
+
const recordId = record["id"] || record["key"] || "?";
|
|
134764
|
+
logger16.debug(`Skipped record ${String(recordId).slice(0, 50)} in ${table}`, {
|
|
134765
|
+
error: toErrorMessage(retryError)
|
|
134766
|
+
});
|
|
134767
|
+
}
|
|
134768
|
+
}
|
|
134769
|
+
totalWritten += recovered;
|
|
134770
|
+
}
|
|
134771
|
+
}
|
|
134772
|
+
return totalWritten;
|
|
134773
|
+
}
|
|
134774
|
+
/**
|
|
134775
|
+
* Get the record count for a table
|
|
134776
|
+
*/
|
|
134777
|
+
async count(table) {
|
|
134778
|
+
if (!this.db) throw new Error("Not connected");
|
|
134779
|
+
if (!this.tableExists(table)) return 0;
|
|
134780
|
+
try {
|
|
134781
|
+
const safeTable = validateTableName(table);
|
|
134782
|
+
const row = this.db.prepare(`SELECT COUNT(*) as count FROM ${safeTable}`).get();
|
|
134783
|
+
return row.count;
|
|
134784
|
+
} catch {
|
|
134785
|
+
return 0;
|
|
134786
|
+
}
|
|
134787
|
+
}
|
|
134788
|
+
/**
|
|
134789
|
+
* Close the database connection
|
|
134790
|
+
*/
|
|
134791
|
+
async close() {
|
|
134792
|
+
if (this.db) {
|
|
134793
|
+
this.db.close();
|
|
134794
|
+
this.db = null;
|
|
134795
|
+
logger16.debug("SQLite writer closed");
|
|
134796
|
+
}
|
|
134797
|
+
}
|
|
134798
|
+
/**
|
|
134799
|
+
* Check if a table exists
|
|
134800
|
+
*/
|
|
134801
|
+
tableExists(table) {
|
|
134802
|
+
if (!this.db) return false;
|
|
134803
|
+
try {
|
|
134804
|
+
const result = this.db.prepare(
|
|
134805
|
+
`SELECT name FROM sqlite_master WHERE type='table' AND name=?`
|
|
134806
|
+
).get(table);
|
|
134807
|
+
return !!result;
|
|
134808
|
+
} catch {
|
|
134809
|
+
return false;
|
|
134810
|
+
}
|
|
134811
|
+
}
|
|
134812
|
+
/**
|
|
134813
|
+
* Get column names for a table
|
|
134814
|
+
*/
|
|
134815
|
+
getTableColumns(table) {
|
|
134816
|
+
if (!this.db) return [];
|
|
134817
|
+
try {
|
|
134818
|
+
const safeTable = validateTableName(table);
|
|
134819
|
+
const columns = this.db.prepare(`PRAGMA table_info(${safeTable})`).all();
|
|
134820
|
+
return columns.map((c70) => c70.name);
|
|
134821
|
+
} catch {
|
|
134822
|
+
return [];
|
|
134823
|
+
}
|
|
134824
|
+
}
|
|
134825
|
+
/**
|
|
134826
|
+
* Get the primary key column(s) for a table
|
|
134827
|
+
*/
|
|
134828
|
+
getPrimaryKeyColumns(table) {
|
|
134829
|
+
if (!this.db) return [];
|
|
134830
|
+
try {
|
|
134831
|
+
const safeTable = validateTableName(table);
|
|
134832
|
+
const columns = this.db.prepare(`PRAGMA table_info(${safeTable})`).all();
|
|
134833
|
+
const pkCols = columns.filter((c70) => c70.pk > 0).sort((a37, b68) => a37.pk - b68.pk).map((c70) => c70.name);
|
|
134834
|
+
return pkCols;
|
|
134835
|
+
} catch {
|
|
134836
|
+
return [];
|
|
134837
|
+
}
|
|
134838
|
+
}
|
|
134839
|
+
/**
|
|
134840
|
+
* Upsert a batch of records.
|
|
134841
|
+
* Uses INSERT ... ON CONFLICT(pk) DO UPDATE SET for mapped columns only,
|
|
134842
|
+
* preserving any local columns not present in the cloud record.
|
|
134843
|
+
* Falls back to INSERT OR IGNORE when no primary key is found (append-mode tables).
|
|
134844
|
+
*/
|
|
134845
|
+
upsertBatch(safeTable, records, localColumnSet) {
|
|
134846
|
+
if (!this.db || records.length === 0) return 0;
|
|
134847
|
+
const firstRecord = records[0];
|
|
134848
|
+
const columns = Object.keys(firstRecord).filter((k68) => localColumnSet.has(k68));
|
|
134849
|
+
if (columns.length === 0) return 0;
|
|
134850
|
+
const safeColumns = columns.map(validateIdentifier);
|
|
134851
|
+
const placeholders = columns.map(() => "?").join(", ");
|
|
134852
|
+
const rawTable = safeTable.replace(/"/g, "");
|
|
134853
|
+
const pkColumns = this.getPrimaryKeyColumns(rawTable);
|
|
134854
|
+
let sql;
|
|
134855
|
+
if (pkColumns.length > 0) {
|
|
134856
|
+
const safePkColumns = pkColumns.map(validateIdentifier);
|
|
134857
|
+
const updateColumns = columns.filter((c70) => !pkColumns.includes(c70));
|
|
134858
|
+
if (updateColumns.length > 0) {
|
|
134859
|
+
const updateSet = updateColumns.map((c70) => `${validateIdentifier(c70)} = excluded.${validateIdentifier(c70)}`).join(", ");
|
|
134860
|
+
sql = `INSERT INTO ${safeTable} (${safeColumns.join(", ")}) VALUES (${placeholders}) ON CONFLICT(${safePkColumns.join(", ")}) DO UPDATE SET ${updateSet}`;
|
|
134861
|
+
} else {
|
|
134862
|
+
sql = `INSERT OR IGNORE INTO ${safeTable} (${safeColumns.join(", ")}) VALUES (${placeholders})`;
|
|
134863
|
+
}
|
|
134864
|
+
} else {
|
|
134865
|
+
sql = `INSERT OR IGNORE INTO ${safeTable} (${safeColumns.join(", ")}) VALUES (${placeholders})`;
|
|
134866
|
+
}
|
|
134867
|
+
const stmt = this.db.prepare(sql);
|
|
134868
|
+
const insertMany = this.db.transaction((recs) => {
|
|
134869
|
+
let count = 0;
|
|
134870
|
+
for (const record of recs) {
|
|
134871
|
+
const values = columns.map((col) => this.serializeValue(record[col]));
|
|
134872
|
+
stmt.run(...values);
|
|
134873
|
+
count++;
|
|
134874
|
+
}
|
|
134875
|
+
return count;
|
|
134876
|
+
});
|
|
134877
|
+
return insertMany(records);
|
|
134878
|
+
}
|
|
134879
|
+
/**
|
|
134880
|
+
* Serialize a value for SQLite insertion
|
|
134881
|
+
*/
|
|
134882
|
+
serializeValue(value) {
|
|
134883
|
+
if (value === null || value === void 0) return null;
|
|
134884
|
+
if (typeof value === "object" && !Buffer.isBuffer(value) && !(value instanceof Date)) {
|
|
134885
|
+
return JSON.stringify(value);
|
|
134886
|
+
}
|
|
134887
|
+
if (value instanceof Date) {
|
|
134888
|
+
return value.toISOString();
|
|
134889
|
+
}
|
|
134890
|
+
if (typeof value === "boolean") {
|
|
134891
|
+
return value ? 1 : 0;
|
|
134892
|
+
}
|
|
134893
|
+
if (Buffer.isBuffer(value)) {
|
|
134894
|
+
return value;
|
|
134895
|
+
}
|
|
134896
|
+
return value;
|
|
134897
|
+
}
|
|
134898
|
+
};
|
|
134899
|
+
function createSQLiteWriter(config) {
|
|
134900
|
+
return new SQLiteWriter(config);
|
|
134901
|
+
}
|
|
134902
|
+
|
|
134315
134903
|
// src/sync/sync-agent.ts
|
|
134316
134904
|
init_esm_node();
|
|
134317
134905
|
init_logging();
|
|
134318
134906
|
init_error_utils();
|
|
134319
|
-
var
|
|
134907
|
+
var logger17 = LoggerFactory.create("sync-agent");
|
|
134320
134908
|
var CloudSyncAgent = class {
|
|
134321
134909
|
config;
|
|
134322
134910
|
readers = /* @__PURE__ */ new Map();
|
|
@@ -134538,13 +135126,20 @@ var CloudSyncAgent = class {
|
|
|
134538
135126
|
let cloudCount = 0;
|
|
134539
135127
|
if (this.writer) {
|
|
134540
135128
|
try {
|
|
135129
|
+
await this.writer.beginTransaction();
|
|
135130
|
+
await this.writer.execute("SET LOCAL enable_indexonlyscan = off");
|
|
134541
135131
|
const rows = await this.writer.query(
|
|
134542
135132
|
`SELECT COUNT(*) as count FROM ${source.targetTable} WHERE source_env = $1`,
|
|
134543
135133
|
[this.config.environment]
|
|
134544
135134
|
);
|
|
135135
|
+
await this.writer.commit();
|
|
134545
135136
|
cloudCount = rows[0]?.count || 0;
|
|
134546
135137
|
} catch (e20) {
|
|
134547
|
-
|
|
135138
|
+
try {
|
|
135139
|
+
await this.writer.rollback();
|
|
135140
|
+
} catch {
|
|
135141
|
+
}
|
|
135142
|
+
logger17.debug("Cloud count query failed", { source: source.name, error: e20 instanceof Error ? e20.message : String(e20) });
|
|
134548
135143
|
cloudCount = -1;
|
|
134549
135144
|
}
|
|
134550
135145
|
}
|
|
@@ -134661,6 +135256,308 @@ async function syncIncrementalToCloud(since, config) {
|
|
|
134661
135256
|
}
|
|
134662
135257
|
}
|
|
134663
135258
|
|
|
135259
|
+
// src/sync/pull-agent.ts
|
|
135260
|
+
init_esm_node();
|
|
135261
|
+
import * as fs23 from "fs";
|
|
135262
|
+
import * as path21 from "path";
|
|
135263
|
+
init_error_utils();
|
|
135264
|
+
init_logging();
|
|
135265
|
+
var logger18 = LoggerFactory.create("pull-agent");
|
|
135266
|
+
var PullSyncAgent = class {
|
|
135267
|
+
config;
|
|
135268
|
+
reader = null;
|
|
135269
|
+
writer = null;
|
|
135270
|
+
cloudWriter = null;
|
|
135271
|
+
report = null;
|
|
135272
|
+
constructor(config = {}) {
|
|
135273
|
+
this.config = {
|
|
135274
|
+
...DEFAULT_PULL_CONFIG,
|
|
135275
|
+
...config,
|
|
135276
|
+
cloud: { ...DEFAULT_PULL_CONFIG.cloud, ...config.cloud },
|
|
135277
|
+
sources: config.sources || DEFAULT_PULL_CONFIG.sources
|
|
135278
|
+
};
|
|
135279
|
+
}
|
|
135280
|
+
/**
|
|
135281
|
+
* Initialize connections to both cloud and local databases
|
|
135282
|
+
*/
|
|
135283
|
+
async initialize() {
|
|
135284
|
+
this.log("Initializing pull sync agent...");
|
|
135285
|
+
const tunnelManager = createConnectionManager(this.config.cloud);
|
|
135286
|
+
this.cloudWriter = createPostgresWriter({
|
|
135287
|
+
cloud: this.config.cloud,
|
|
135288
|
+
tunnelManager
|
|
135289
|
+
});
|
|
135290
|
+
await this.cloudWriter.connect();
|
|
135291
|
+
this.log("Connected to cloud database");
|
|
135292
|
+
this.reader = createPostgresReader({
|
|
135293
|
+
writer: this.cloudWriter,
|
|
135294
|
+
environment: this.config.environment
|
|
135295
|
+
});
|
|
135296
|
+
const dbPath = this.resolveTargetDb();
|
|
135297
|
+
this.writer = createSQLiteWriter({ dbPath });
|
|
135298
|
+
await this.writer.connect();
|
|
135299
|
+
this.log(`Connected to local database: ${dbPath}`);
|
|
135300
|
+
}
|
|
135301
|
+
/**
|
|
135302
|
+
* Full pull: download all cloud data into local DB
|
|
135303
|
+
*/
|
|
135304
|
+
async pullAll() {
|
|
135305
|
+
this.report = this.createReport("full");
|
|
135306
|
+
try {
|
|
135307
|
+
this.ensureInitialized();
|
|
135308
|
+
this.backupLocalDb();
|
|
135309
|
+
const sources = this.getEnabledSources();
|
|
135310
|
+
let completed = 0;
|
|
135311
|
+
for (const source of sources) {
|
|
135312
|
+
this.progress(`Pulling ${source.name}...`, completed / sources.length);
|
|
135313
|
+
const result = await this.pullTable(source);
|
|
135314
|
+
this.report.results.push(result);
|
|
135315
|
+
completed++;
|
|
135316
|
+
}
|
|
135317
|
+
this.report.status = this.report.results.every((r54) => r54.success) ? "completed" : "partial";
|
|
135318
|
+
} catch (error) {
|
|
135319
|
+
this.report.status = "failed";
|
|
135320
|
+
this.report.errors.push(toErrorMessage(error));
|
|
135321
|
+
} finally {
|
|
135322
|
+
this.finalizeReport();
|
|
135323
|
+
}
|
|
135324
|
+
return this.report;
|
|
135325
|
+
}
|
|
135326
|
+
/**
|
|
135327
|
+
* Incremental pull: only records changed since a timestamp
|
|
135328
|
+
*/
|
|
135329
|
+
async pullIncremental(since) {
|
|
135330
|
+
this.report = this.createReport("incremental");
|
|
135331
|
+
const sinceDate = since || new Date(Date.now() - 24 * 60 * 60 * 1e3);
|
|
135332
|
+
try {
|
|
135333
|
+
this.ensureInitialized();
|
|
135334
|
+
this.backupLocalDb();
|
|
135335
|
+
const sources = this.getEnabledSources().filter((s70) => s70.mode !== "full");
|
|
135336
|
+
for (const source of sources) {
|
|
135337
|
+
this.progress(`Incremental pull ${source.name}...`, 0);
|
|
135338
|
+
const result = await this.pullTableIncremental(source, sinceDate);
|
|
135339
|
+
this.report.results.push(result);
|
|
135340
|
+
}
|
|
135341
|
+
this.report.status = this.report.results.every((r54) => r54.success) ? "completed" : "partial";
|
|
135342
|
+
} catch (error) {
|
|
135343
|
+
this.report.status = "failed";
|
|
135344
|
+
this.report.errors.push(toErrorMessage(error));
|
|
135345
|
+
} finally {
|
|
135346
|
+
this.finalizeReport();
|
|
135347
|
+
}
|
|
135348
|
+
return this.report;
|
|
135349
|
+
}
|
|
135350
|
+
/**
|
|
135351
|
+
* Pull a single table from cloud to local
|
|
135352
|
+
*/
|
|
135353
|
+
async pullTable(source) {
|
|
135354
|
+
const startTime = Date.now();
|
|
135355
|
+
const result = {
|
|
135356
|
+
success: false,
|
|
135357
|
+
table: source.localTable,
|
|
135358
|
+
source: source.name,
|
|
135359
|
+
recordsSynced: 0,
|
|
135360
|
+
conflictsResolved: 0,
|
|
135361
|
+
recordsSkipped: 0,
|
|
135362
|
+
durationMs: 0,
|
|
135363
|
+
warnings: []
|
|
135364
|
+
};
|
|
135365
|
+
try {
|
|
135366
|
+
this.ensureInitialized();
|
|
135367
|
+
const records = await this.reader.readAll(source);
|
|
135368
|
+
this.log(`Read ${records.length} records from cloud ${source.cloudTable}`);
|
|
135369
|
+
if (records.length === 0) {
|
|
135370
|
+
result.success = true;
|
|
135371
|
+
result.durationMs = Date.now() - startTime;
|
|
135372
|
+
return result;
|
|
135373
|
+
}
|
|
135374
|
+
if (!this.config.dryRun) {
|
|
135375
|
+
const written = await this.writer.upsert(source.localTable, records);
|
|
135376
|
+
result.recordsSynced = written;
|
|
135377
|
+
result.recordsSkipped = records.length - written;
|
|
135378
|
+
} else {
|
|
135379
|
+
result.recordsSynced = records.length;
|
|
135380
|
+
this.log(`[DRY RUN] Would write ${records.length} records to local ${source.localTable}`);
|
|
135381
|
+
}
|
|
135382
|
+
result.success = true;
|
|
135383
|
+
} catch (error) {
|
|
135384
|
+
result.error = toErrorMessage(error);
|
|
135385
|
+
this.config.onError?.(toError(error), source.name);
|
|
135386
|
+
}
|
|
135387
|
+
result.durationMs = Date.now() - startTime;
|
|
135388
|
+
return result;
|
|
135389
|
+
}
|
|
135390
|
+
/**
|
|
135391
|
+
* Pull incremental changes for a single table
|
|
135392
|
+
*/
|
|
135393
|
+
async pullTableIncremental(source, since) {
|
|
135394
|
+
const startTime = Date.now();
|
|
135395
|
+
const result = {
|
|
135396
|
+
success: false,
|
|
135397
|
+
table: source.localTable,
|
|
135398
|
+
source: source.name,
|
|
135399
|
+
recordsSynced: 0,
|
|
135400
|
+
conflictsResolved: 0,
|
|
135401
|
+
recordsSkipped: 0,
|
|
135402
|
+
durationMs: 0
|
|
135403
|
+
};
|
|
135404
|
+
try {
|
|
135405
|
+
this.ensureInitialized();
|
|
135406
|
+
const records = await this.reader.readChanged(source, since);
|
|
135407
|
+
this.log(`Read ${records.length} changed records from cloud ${source.cloudTable} (since ${since.toISOString()})`);
|
|
135408
|
+
if (records.length === 0) {
|
|
135409
|
+
result.success = true;
|
|
135410
|
+
result.durationMs = Date.now() - startTime;
|
|
135411
|
+
return result;
|
|
135412
|
+
}
|
|
135413
|
+
if (!this.config.dryRun) {
|
|
135414
|
+
const written = await this.writer.upsert(source.localTable, records);
|
|
135415
|
+
result.recordsSynced = written;
|
|
135416
|
+
} else {
|
|
135417
|
+
result.recordsSynced = records.length;
|
|
135418
|
+
}
|
|
135419
|
+
result.success = true;
|
|
135420
|
+
} catch (error) {
|
|
135421
|
+
result.error = toErrorMessage(error);
|
|
135422
|
+
}
|
|
135423
|
+
result.durationMs = Date.now() - startTime;
|
|
135424
|
+
return result;
|
|
135425
|
+
}
|
|
135426
|
+
/**
|
|
135427
|
+
* Verify pull by comparing cloud and local counts
|
|
135428
|
+
*/
|
|
135429
|
+
async verify() {
|
|
135430
|
+
this.ensureInitialized();
|
|
135431
|
+
const results = [];
|
|
135432
|
+
for (const source of this.getEnabledSources()) {
|
|
135433
|
+
const cloudCount = await this.reader.count(source);
|
|
135434
|
+
const localCount = await this.writer.count(source.localTable);
|
|
135435
|
+
results.push({
|
|
135436
|
+
source: source.name,
|
|
135437
|
+
cloudTable: source.cloudTable,
|
|
135438
|
+
localTable: source.localTable,
|
|
135439
|
+
cloudCount,
|
|
135440
|
+
localCount,
|
|
135441
|
+
match: cloudCount === localCount || cloudCount === -1,
|
|
135442
|
+
diff: localCount - cloudCount
|
|
135443
|
+
});
|
|
135444
|
+
}
|
|
135445
|
+
return {
|
|
135446
|
+
verified: results.every((r54) => r54.match),
|
|
135447
|
+
results
|
|
135448
|
+
};
|
|
135449
|
+
}
|
|
135450
|
+
/**
|
|
135451
|
+
* Close all connections
|
|
135452
|
+
*/
|
|
135453
|
+
async close() {
|
|
135454
|
+
if (this.writer) {
|
|
135455
|
+
await this.writer.close();
|
|
135456
|
+
this.writer = null;
|
|
135457
|
+
}
|
|
135458
|
+
if (this.cloudWriter) {
|
|
135459
|
+
await this.cloudWriter.close();
|
|
135460
|
+
this.cloudWriter = null;
|
|
135461
|
+
}
|
|
135462
|
+
this.reader = null;
|
|
135463
|
+
this.log("Pull sync agent closed");
|
|
135464
|
+
}
|
|
135465
|
+
// Private helpers
|
|
135466
|
+
ensureInitialized() {
|
|
135467
|
+
if (!this.reader || !this.writer) {
|
|
135468
|
+
throw new Error("PullSyncAgent not initialized. Call initialize() first.");
|
|
135469
|
+
}
|
|
135470
|
+
}
|
|
135471
|
+
getEnabledSources() {
|
|
135472
|
+
let sources = this.config.sources.filter((s70) => s70.enabled);
|
|
135473
|
+
if (this.config.tables && this.config.tables.length > 0) {
|
|
135474
|
+
const tableSet = new Set(this.config.tables);
|
|
135475
|
+
sources = sources.filter((s70) => tableSet.has(s70.localTable) || tableSet.has(s70.name));
|
|
135476
|
+
}
|
|
135477
|
+
const priorityOrder = { high: 0, medium: 1, low: 2 };
|
|
135478
|
+
return sources.sort((a37, b68) => priorityOrder[a37.priority] - priorityOrder[b68.priority]);
|
|
135479
|
+
}
|
|
135480
|
+
resolveTargetDb() {
|
|
135481
|
+
if (this.config.targetDb) {
|
|
135482
|
+
return path21.resolve(this.config.targetDb);
|
|
135483
|
+
}
|
|
135484
|
+
return path21.resolve(process.cwd(), ".agentic-qe/memory.db");
|
|
135485
|
+
}
|
|
135486
|
+
backupLocalDb() {
|
|
135487
|
+
if (this.config.dryRun) return;
|
|
135488
|
+
const dbPath = this.resolveTargetDb();
|
|
135489
|
+
if (!fs23.existsSync(dbPath)) return;
|
|
135490
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
135491
|
+
const backupPath = `${dbPath}.bak-${timestamp}`;
|
|
135492
|
+
try {
|
|
135493
|
+
fs23.copyFileSync(dbPath, backupPath);
|
|
135494
|
+
this.log(`Backed up local DB to ${backupPath}`);
|
|
135495
|
+
} catch (error) {
|
|
135496
|
+
this.log(`Warning: Failed to backup local DB: ${toErrorMessage(error)}`, "warn");
|
|
135497
|
+
}
|
|
135498
|
+
}
|
|
135499
|
+
createReport(mode) {
|
|
135500
|
+
return {
|
|
135501
|
+
syncId: v4_default(),
|
|
135502
|
+
startedAt: /* @__PURE__ */ new Date(),
|
|
135503
|
+
status: "running",
|
|
135504
|
+
environment: this.config.environment,
|
|
135505
|
+
mode,
|
|
135506
|
+
results: [],
|
|
135507
|
+
totalRecordsSynced: 0,
|
|
135508
|
+
totalConflictsResolved: 0,
|
|
135509
|
+
totalDurationMs: 0,
|
|
135510
|
+
errors: []
|
|
135511
|
+
};
|
|
135512
|
+
}
|
|
135513
|
+
finalizeReport() {
|
|
135514
|
+
if (!this.report) return;
|
|
135515
|
+
this.report.completedAt = /* @__PURE__ */ new Date();
|
|
135516
|
+
this.report.totalDurationMs = this.report.completedAt.getTime() - this.report.startedAt.getTime();
|
|
135517
|
+
this.report.totalRecordsSynced = this.report.results.reduce((sum, r54) => sum + r54.recordsSynced, 0);
|
|
135518
|
+
this.report.totalConflictsResolved = this.report.results.reduce((sum, r54) => sum + r54.conflictsResolved, 0);
|
|
135519
|
+
}
|
|
135520
|
+
log(message, level = "info") {
|
|
135521
|
+
if (!this.config.verbose && level === "info") return;
|
|
135522
|
+
const prefix = `[PullSync:${this.config.environment}]`;
|
|
135523
|
+
switch (level) {
|
|
135524
|
+
case "warn":
|
|
135525
|
+
console.warn(`${prefix} ${message}`);
|
|
135526
|
+
break;
|
|
135527
|
+
case "error":
|
|
135528
|
+
console.error(`${prefix} ${message}`);
|
|
135529
|
+
break;
|
|
135530
|
+
default:
|
|
135531
|
+
console.log(`${prefix} ${message}`);
|
|
135532
|
+
}
|
|
135533
|
+
}
|
|
135534
|
+
progress(message, progress) {
|
|
135535
|
+
this.config.onProgress?.(message, progress);
|
|
135536
|
+
this.log(message);
|
|
135537
|
+
}
|
|
135538
|
+
};
|
|
135539
|
+
function createPullSyncAgent(config) {
|
|
135540
|
+
return new PullSyncAgent(config);
|
|
135541
|
+
}
|
|
135542
|
+
async function pullFromCloud(config) {
|
|
135543
|
+
const agent = createPullSyncAgent({ ...config, verbose: true });
|
|
135544
|
+
await agent.initialize();
|
|
135545
|
+
try {
|
|
135546
|
+
return await agent.pullAll();
|
|
135547
|
+
} finally {
|
|
135548
|
+
await agent.close();
|
|
135549
|
+
}
|
|
135550
|
+
}
|
|
135551
|
+
async function pullIncrementalFromCloud(since, config) {
|
|
135552
|
+
const agent = createPullSyncAgent({ ...config, verbose: true });
|
|
135553
|
+
await agent.initialize();
|
|
135554
|
+
try {
|
|
135555
|
+
return await agent.pullIncremental(since);
|
|
135556
|
+
} finally {
|
|
135557
|
+
await agent.close();
|
|
135558
|
+
}
|
|
135559
|
+
}
|
|
135560
|
+
|
|
134664
135561
|
// src/integrations/embeddings/cache/EmbeddingCache.ts
|
|
134665
135562
|
init_safe_db();
|
|
134666
135563
|
init_unified_memory();
|
|
@@ -134676,16 +135573,16 @@ init_sql_safety();
|
|
|
134676
135573
|
init_error_utils();
|
|
134677
135574
|
init_safe_json();
|
|
134678
135575
|
init_logging();
|
|
134679
|
-
import { resolve as
|
|
135576
|
+
import { resolve as resolve14, dirname as dirname12 } from "path";
|
|
134680
135577
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
134681
|
-
var
|
|
135578
|
+
var logger19 = LoggerFactory.create("sync-embedding-generator");
|
|
134682
135579
|
var __filename4 = fileURLToPath5(import.meta.url);
|
|
134683
135580
|
var __dirname4 = dirname12(__filename4);
|
|
134684
135581
|
|
|
134685
135582
|
// src/cli/commands/sync.ts
|
|
134686
135583
|
init_error_utils();
|
|
134687
|
-
import * as
|
|
134688
|
-
import * as
|
|
135584
|
+
import * as fs24 from "fs";
|
|
135585
|
+
import * as path22 from "path";
|
|
134689
135586
|
function createSyncCommands() {
|
|
134690
135587
|
const syncCmd = new Command14("sync").description("Sync local learning data to cloud PostgreSQL");
|
|
134691
135588
|
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 +135618,34 @@ function createSyncCommands() {
|
|
|
134721
135618
|
process.exit(1);
|
|
134722
135619
|
}
|
|
134723
135620
|
});
|
|
135621
|
+
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) => {
|
|
135622
|
+
const pullConfig = {
|
|
135623
|
+
environment: options.env,
|
|
135624
|
+
verbose: options.verbose,
|
|
135625
|
+
dryRun: options.dryRun,
|
|
135626
|
+
targetDb: options.target
|
|
135627
|
+
};
|
|
135628
|
+
if (options.tables) {
|
|
135629
|
+
pullConfig.tables = options.tables.split(",").map((t50) => t50.trim());
|
|
135630
|
+
}
|
|
135631
|
+
const spinner = ora2("Initializing pull sync agent...").start();
|
|
135632
|
+
try {
|
|
135633
|
+
let report;
|
|
135634
|
+
if (options.full) {
|
|
135635
|
+
spinner.text = "Pulling all data from cloud...";
|
|
135636
|
+
report = await pullFromCloud(pullConfig);
|
|
135637
|
+
} else {
|
|
135638
|
+
const since = options.since ? new Date(options.since) : void 0;
|
|
135639
|
+
spinner.text = `Pulling ${since ? "changes since " + since.toISOString() : "incremental changes (last 24h)"}...`;
|
|
135640
|
+
report = await pullIncrementalFromCloud(since, pullConfig);
|
|
135641
|
+
}
|
|
135642
|
+
spinner.stop();
|
|
135643
|
+
printPullReport(report);
|
|
135644
|
+
} catch (error) {
|
|
135645
|
+
spinner.fail(`Pull failed: ${toErrorMessage(error)}`);
|
|
135646
|
+
process.exit(1);
|
|
135647
|
+
}
|
|
135648
|
+
});
|
|
134724
135649
|
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
135650
|
const spinner = ora2("Checking sync status...").start();
|
|
134726
135651
|
try {
|
|
@@ -134751,16 +135676,16 @@ function createSyncCommands() {
|
|
|
134751
135676
|
}
|
|
134752
135677
|
});
|
|
134753
135678
|
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 =
|
|
135679
|
+
const schemaPath = path22.join(__dirname, "../../sync/schema/cloud-schema.sql");
|
|
134755
135680
|
let schema;
|
|
134756
135681
|
try {
|
|
134757
|
-
schema =
|
|
135682
|
+
schema = fs24.readFileSync(schemaPath, "utf-8");
|
|
134758
135683
|
} catch {
|
|
134759
|
-
const altPath =
|
|
134760
|
-
schema =
|
|
135684
|
+
const altPath = path22.join(process.cwd(), "v3/src/sync/schema/cloud-schema.sql");
|
|
135685
|
+
schema = fs24.readFileSync(altPath, "utf-8");
|
|
134761
135686
|
}
|
|
134762
135687
|
if (options.output) {
|
|
134763
|
-
|
|
135688
|
+
fs24.writeFileSync(options.output, schema);
|
|
134764
135689
|
console.log(chalk26.green(`Schema saved to ${options.output}`));
|
|
134765
135690
|
return;
|
|
134766
135691
|
}
|
|
@@ -134890,13 +135815,48 @@ function printVerifyResult(result) {
|
|
|
134890
135815
|
console.log();
|
|
134891
135816
|
}
|
|
134892
135817
|
}
|
|
135818
|
+
function printPullReport(report) {
|
|
135819
|
+
const statusColor = report.status === "completed" ? chalk26.green : report.status === "partial" ? chalk26.yellow : chalk26.red;
|
|
135820
|
+
console.log(chalk26.cyan("\n=== Pull Sync Report (Cloud \u2192 Local) ===\n"));
|
|
135821
|
+
console.log(chalk26.bold("Sync ID:"), report.syncId);
|
|
135822
|
+
console.log(chalk26.bold("Status:"), statusColor(report.status.toUpperCase()));
|
|
135823
|
+
console.log(chalk26.bold("Environment:"), report.environment);
|
|
135824
|
+
console.log(chalk26.bold("Mode:"), report.mode);
|
|
135825
|
+
console.log(chalk26.bold("Duration:"), `${report.totalDurationMs}ms`);
|
|
135826
|
+
console.log();
|
|
135827
|
+
console.log(chalk26.bold("Summary:"));
|
|
135828
|
+
console.log(` Records Pulled: ${chalk26.green(report.totalRecordsSynced)}`);
|
|
135829
|
+
console.log();
|
|
135830
|
+
if (report.results.length > 0) {
|
|
135831
|
+
console.log(chalk26.bold("Results by Table:"));
|
|
135832
|
+
for (const result of report.results) {
|
|
135833
|
+
const icon = result.success ? chalk26.green("\u2713") : chalk26.red("\u2717");
|
|
135834
|
+
console.log(` ${icon} ${result.source} \u2192 ${result.table}`);
|
|
135835
|
+
console.log(` Records: ${result.recordsSynced}`);
|
|
135836
|
+
console.log(` Duration: ${result.durationMs}ms`);
|
|
135837
|
+
if (result.recordsSkipped > 0) {
|
|
135838
|
+
console.log(` Skipped: ${chalk26.yellow(result.recordsSkipped)}`);
|
|
135839
|
+
}
|
|
135840
|
+
if (result.error) {
|
|
135841
|
+
console.log(` Error: ${chalk26.red(result.error)}`);
|
|
135842
|
+
}
|
|
135843
|
+
}
|
|
135844
|
+
console.log();
|
|
135845
|
+
}
|
|
135846
|
+
if (report.errors.length > 0) {
|
|
135847
|
+
console.log(chalk26.red("Errors:"));
|
|
135848
|
+
for (const error of report.errors) {
|
|
135849
|
+
console.log(` - ${error}`);
|
|
135850
|
+
}
|
|
135851
|
+
}
|
|
135852
|
+
}
|
|
134893
135853
|
|
|
134894
135854
|
// src/cli/commands/hooks.ts
|
|
134895
135855
|
init_qe_reasoning_bank();
|
|
134896
135856
|
init_safe_json();
|
|
134897
135857
|
import { Command as Command15 } from "commander";
|
|
134898
135858
|
import chalk27 from "chalk";
|
|
134899
|
-
import
|
|
135859
|
+
import path23 from "node:path";
|
|
134900
135860
|
init_unified_memory();
|
|
134901
135861
|
|
|
134902
135862
|
// src/integrations/coherence/types.ts
|
|
@@ -135049,9 +136009,9 @@ var CohomologyAdapter = class {
|
|
|
135049
136009
|
* @param wasmLoader - WASM module loader
|
|
135050
136010
|
* @param logger - Optional logger for diagnostics
|
|
135051
136011
|
*/
|
|
135052
|
-
constructor(wasmLoader2,
|
|
136012
|
+
constructor(wasmLoader2, logger22 = DEFAULT_COHERENCE_LOGGER) {
|
|
135053
136013
|
this.wasmLoader = wasmLoader2;
|
|
135054
|
-
this.logger =
|
|
136014
|
+
this.logger = logger22;
|
|
135055
136015
|
}
|
|
135056
136016
|
engine = null;
|
|
135057
136017
|
initialized = false;
|
|
@@ -135395,9 +136355,9 @@ var SpectralAdapter = class {
|
|
|
135395
136355
|
* @param wasmLoader - WASM module loader
|
|
135396
136356
|
* @param logger - Optional logger for diagnostics
|
|
135397
136357
|
*/
|
|
135398
|
-
constructor(wasmLoader2,
|
|
136358
|
+
constructor(wasmLoader2, logger22 = DEFAULT_COHERENCE_LOGGER) {
|
|
135399
136359
|
this.wasmLoader = wasmLoader2;
|
|
135400
|
-
this.logger =
|
|
136360
|
+
this.logger = logger22;
|
|
135401
136361
|
}
|
|
135402
136362
|
engine = null;
|
|
135403
136363
|
initialized = false;
|
|
@@ -135806,9 +136766,9 @@ var CausalAdapter = class {
|
|
|
135806
136766
|
* @param wasmLoader - WASM module loader
|
|
135807
136767
|
* @param logger - Optional logger for diagnostics
|
|
135808
136768
|
*/
|
|
135809
|
-
constructor(wasmLoader2,
|
|
136769
|
+
constructor(wasmLoader2, logger22 = DEFAULT_COHERENCE_LOGGER) {
|
|
135810
136770
|
this.wasmLoader = wasmLoader2;
|
|
135811
|
-
this.logger =
|
|
136771
|
+
this.logger = logger22;
|
|
135812
136772
|
}
|
|
135813
136773
|
engine = null;
|
|
135814
136774
|
initialized = false;
|
|
@@ -136057,11 +137017,11 @@ function createCategoryEngineWrapper(rawEngine) {
|
|
|
136057
137017
|
add_morphism(source, target, name) {
|
|
136058
137018
|
morphisms.push({ source, target, name });
|
|
136059
137019
|
},
|
|
136060
|
-
verify_composition(
|
|
136061
|
-
if (
|
|
136062
|
-
for (let i58 = 0; i58 <
|
|
136063
|
-
const source =
|
|
136064
|
-
const target =
|
|
137020
|
+
verify_composition(path27) {
|
|
137021
|
+
if (path27.length < 2) return true;
|
|
137022
|
+
for (let i58 = 0; i58 < path27.length - 1; i58++) {
|
|
137023
|
+
const source = path27[i58];
|
|
137024
|
+
const target = path27[i58 + 1];
|
|
136065
137025
|
const hasMorphism = morphisms.some((m74) => m74.source === source && m74.target === target);
|
|
136066
137026
|
if (!hasMorphism) return false;
|
|
136067
137027
|
}
|
|
@@ -136101,9 +137061,9 @@ var CategoryAdapter = class {
|
|
|
136101
137061
|
* @param wasmLoader - WASM module loader
|
|
136102
137062
|
* @param logger - Optional logger for diagnostics
|
|
136103
137063
|
*/
|
|
136104
|
-
constructor(wasmLoader2,
|
|
137064
|
+
constructor(wasmLoader2, logger22 = DEFAULT_COHERENCE_LOGGER) {
|
|
136105
137065
|
this.wasmLoader = wasmLoader2;
|
|
136106
|
-
this.logger =
|
|
137066
|
+
this.logger = logger22;
|
|
136107
137067
|
}
|
|
136108
137068
|
engine = null;
|
|
136109
137069
|
initialized = false;
|
|
@@ -136176,14 +137136,14 @@ var CategoryAdapter = class {
|
|
|
136176
137136
|
* @param path - Array of type names representing a composition path
|
|
136177
137137
|
* @returns True if the composition is valid
|
|
136178
137138
|
*/
|
|
136179
|
-
verifyComposition(
|
|
137139
|
+
verifyComposition(path27) {
|
|
136180
137140
|
this.ensureInitialized();
|
|
136181
|
-
if (
|
|
137141
|
+
if (path27.length < 2) {
|
|
136182
137142
|
return true;
|
|
136183
137143
|
}
|
|
136184
|
-
const isValid = this.engine.verify_composition(
|
|
137144
|
+
const isValid = this.engine.verify_composition(path27);
|
|
136185
137145
|
this.logger.debug("Verified composition", {
|
|
136186
|
-
path:
|
|
137146
|
+
path: path27,
|
|
136187
137147
|
isValid
|
|
136188
137148
|
});
|
|
136189
137149
|
return isValid;
|
|
@@ -136222,8 +137182,8 @@ var CategoryAdapter = class {
|
|
|
136222
137182
|
for (const element of pipeline10.elements) {
|
|
136223
137183
|
this.addMorphism(element.inputType, element.outputType, element.name);
|
|
136224
137184
|
}
|
|
136225
|
-
const
|
|
136226
|
-
const compositionValid = this.verifyComposition(
|
|
137185
|
+
const path27 = this.buildCompositionPath(pipeline10);
|
|
137186
|
+
const compositionValid = this.verifyComposition(path27);
|
|
136227
137187
|
const mismatches = this.checkTypeConsistency();
|
|
136228
137188
|
const warnings = this.generateWarnings(pipeline10, compositionValid, mismatches);
|
|
136229
137189
|
const durationMs = Date.now() - startTime;
|
|
@@ -136247,17 +137207,17 @@ var CategoryAdapter = class {
|
|
|
136247
137207
|
* Build a composition path from a pipeline
|
|
136248
137208
|
*/
|
|
136249
137209
|
buildCompositionPath(pipeline10) {
|
|
136250
|
-
const
|
|
137210
|
+
const path27 = [pipeline10.inputType];
|
|
136251
137211
|
for (const element of pipeline10.elements) {
|
|
136252
|
-
if (element.inputType !==
|
|
136253
|
-
|
|
137212
|
+
if (element.inputType !== path27[path27.length - 1]) {
|
|
137213
|
+
path27.push(element.inputType);
|
|
136254
137214
|
}
|
|
136255
|
-
|
|
137215
|
+
path27.push(element.outputType);
|
|
136256
137216
|
}
|
|
136257
|
-
if (
|
|
136258
|
-
|
|
137217
|
+
if (path27[path27.length - 1] !== pipeline10.outputType) {
|
|
137218
|
+
path27.push(pipeline10.outputType);
|
|
136259
137219
|
}
|
|
136260
|
-
return
|
|
137220
|
+
return path27;
|
|
136261
137221
|
}
|
|
136262
137222
|
/**
|
|
136263
137223
|
* Infer a schema from a type name
|
|
@@ -136388,9 +137348,9 @@ function createHomotopyEngineWrapper(rawEngine) {
|
|
|
136388
137348
|
}
|
|
136389
137349
|
return false;
|
|
136390
137350
|
},
|
|
136391
|
-
verify_path_equivalence(path1,
|
|
137351
|
+
verify_path_equivalence(path1, path27) {
|
|
136392
137352
|
const pathObj1 = { steps: path1 };
|
|
136393
|
-
const pathObj2 = { steps:
|
|
137353
|
+
const pathObj2 = { steps: path27 };
|
|
136394
137354
|
return rawEngine.checkTypeEquivalence(pathObj1, pathObj2);
|
|
136395
137355
|
},
|
|
136396
137356
|
get_unproven_propositions() {
|
|
@@ -136415,9 +137375,9 @@ var HomotopyAdapter = class {
|
|
|
136415
137375
|
* @param wasmLoader - WASM module loader
|
|
136416
137376
|
* @param logger - Optional logger for diagnostics
|
|
136417
137377
|
*/
|
|
136418
|
-
constructor(wasmLoader2,
|
|
137378
|
+
constructor(wasmLoader2, logger22 = DEFAULT_COHERENCE_LOGGER) {
|
|
136419
137379
|
this.wasmLoader = wasmLoader2;
|
|
136420
|
-
this.logger =
|
|
137380
|
+
this.logger = logger22;
|
|
136421
137381
|
}
|
|
136422
137382
|
engine = null;
|
|
136423
137383
|
initialized = false;
|
|
@@ -136506,19 +137466,19 @@ var HomotopyAdapter = class {
|
|
|
136506
137466
|
* @param path2 - Second execution path
|
|
136507
137467
|
* @returns Path equivalence result
|
|
136508
137468
|
*/
|
|
136509
|
-
verifyPathEquivalence(path1,
|
|
137469
|
+
verifyPathEquivalence(path1, path27) {
|
|
136510
137470
|
this.ensureInitialized();
|
|
136511
|
-
const equivalent = this.engine.verify_path_equivalence(path1,
|
|
136512
|
-
const explanation = this.generateEquivalenceExplanation(path1,
|
|
137471
|
+
const equivalent = this.engine.verify_path_equivalence(path1, path27);
|
|
137472
|
+
const explanation = this.generateEquivalenceExplanation(path1, path27, equivalent);
|
|
136513
137473
|
const result = {
|
|
136514
137474
|
equivalent,
|
|
136515
137475
|
path1,
|
|
136516
|
-
path2:
|
|
137476
|
+
path2: path27,
|
|
136517
137477
|
explanation
|
|
136518
137478
|
};
|
|
136519
137479
|
this.logger.debug("Verified path equivalence", {
|
|
136520
137480
|
path1Length: path1.length,
|
|
136521
|
-
path2Length:
|
|
137481
|
+
path2Length: path27.length,
|
|
136522
137482
|
equivalent
|
|
136523
137483
|
});
|
|
136524
137484
|
return result;
|
|
@@ -136526,24 +137486,24 @@ var HomotopyAdapter = class {
|
|
|
136526
137486
|
/**
|
|
136527
137487
|
* Generate an explanation for path equivalence result
|
|
136528
137488
|
*/
|
|
136529
|
-
generateEquivalenceExplanation(path1,
|
|
137489
|
+
generateEquivalenceExplanation(path1, path27, equivalent) {
|
|
136530
137490
|
if (equivalent) {
|
|
136531
|
-
if (path1.length ===
|
|
137491
|
+
if (path1.length === path27.length) {
|
|
136532
137492
|
return `The execution paths are homotopically equivalent. Both paths traverse the same abstract structure and will produce equivalent results.`;
|
|
136533
137493
|
} else {
|
|
136534
|
-
const longer = path1.length >
|
|
137494
|
+
const longer = path1.length > path27.length ? "first" : "second";
|
|
136535
137495
|
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
137496
|
}
|
|
136537
137497
|
} else {
|
|
136538
137498
|
let divergeIndex = 0;
|
|
136539
|
-
const minLen = Math.min(path1.length,
|
|
136540
|
-
while (divergeIndex < minLen && path1[divergeIndex] ===
|
|
137499
|
+
const minLen = Math.min(path1.length, path27.length);
|
|
137500
|
+
while (divergeIndex < minLen && path1[divergeIndex] === path27[divergeIndex]) {
|
|
136541
137501
|
divergeIndex++;
|
|
136542
137502
|
}
|
|
136543
137503
|
if (divergeIndex === 0) {
|
|
136544
|
-
return `The execution paths diverge immediately. Path 1 starts with '${path1[0]}' while Path 2 starts with '${
|
|
137504
|
+
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
137505
|
}
|
|
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 '${
|
|
137506
|
+
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
137507
|
}
|
|
136548
137508
|
}
|
|
136549
137509
|
/**
|
|
@@ -136617,9 +137577,9 @@ var WitnessAdapter = class {
|
|
|
136617
137577
|
* @param wasmLoader - WASM module loader
|
|
136618
137578
|
* @param logger - Optional logger for diagnostics
|
|
136619
137579
|
*/
|
|
136620
|
-
constructor(wasmLoader2,
|
|
137580
|
+
constructor(wasmLoader2, logger22 = DEFAULT_COHERENCE_LOGGER) {
|
|
136621
137581
|
this.wasmLoader = wasmLoader2;
|
|
136622
|
-
this.logger =
|
|
137582
|
+
this.logger = logger22;
|
|
136623
137583
|
}
|
|
136624
137584
|
engine = null;
|
|
136625
137585
|
initialized = false;
|
|
@@ -136914,10 +137874,10 @@ var CoherenceService = class {
|
|
|
136914
137874
|
* @param config - Optional service configuration
|
|
136915
137875
|
* @param logger - Optional logger for diagnostics
|
|
136916
137876
|
*/
|
|
136917
|
-
constructor(wasmLoader2, config = {},
|
|
137877
|
+
constructor(wasmLoader2, config = {}, logger22) {
|
|
136918
137878
|
this.wasmLoader = wasmLoader2;
|
|
136919
137879
|
this.config = { ...DEFAULT_COHERENCE_CONFIG, ...config };
|
|
136920
|
-
this.logger =
|
|
137880
|
+
this.logger = logger22 || DEFAULT_COHERENCE_LOGGER;
|
|
136921
137881
|
}
|
|
136922
137882
|
config;
|
|
136923
137883
|
logger;
|
|
@@ -137618,8 +138578,8 @@ var CoherenceService = class {
|
|
|
137618
138578
|
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
137619
138579
|
}
|
|
137620
138580
|
};
|
|
137621
|
-
async function createCoherenceService(wasmLoader2, config,
|
|
137622
|
-
const service = new CoherenceService(wasmLoader2, config,
|
|
138581
|
+
async function createCoherenceService(wasmLoader2, config, logger22) {
|
|
138582
|
+
const service = new CoherenceService(wasmLoader2, config, logger22);
|
|
137623
138583
|
await service.initialize();
|
|
137624
138584
|
return service;
|
|
137625
138585
|
}
|
|
@@ -137629,7 +138589,7 @@ init_error_utils();
|
|
|
137629
138589
|
import { createRequire as createRequire9 } from "node:module";
|
|
137630
138590
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
137631
138591
|
import { dirname as dirname13, join as join44 } from "node:path";
|
|
137632
|
-
import { readFileSync as readFileSync32, existsSync as
|
|
138592
|
+
import { readFileSync as readFileSync32, existsSync as existsSync46 } from "node:fs";
|
|
137633
138593
|
var FALLBACK_RETRY_DELAYS_MS = [1e3, 2e3, 4e3];
|
|
137634
138594
|
var WasmLoader = class {
|
|
137635
138595
|
state = "unloaded";
|
|
@@ -137894,8 +138854,8 @@ var WasmLoader = class {
|
|
|
137894
138854
|
})(),
|
|
137895
138855
|
join44(process.cwd(), "node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm")
|
|
137896
138856
|
].filter((p74) => p74 !== null);
|
|
137897
|
-
for (const
|
|
137898
|
-
if (
|
|
138857
|
+
for (const path27 of wasmPaths) {
|
|
138858
|
+
if (existsSync46(path27)) {
|
|
137899
138859
|
return true;
|
|
137900
138860
|
}
|
|
137901
138861
|
}
|
|
@@ -138157,9 +139117,9 @@ var WasmLoader = class {
|
|
|
138157
139117
|
join44(process.cwd(), "node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm")
|
|
138158
139118
|
].filter((p74) => p74 !== null);
|
|
138159
139119
|
let wasmPath = null;
|
|
138160
|
-
for (const
|
|
138161
|
-
if (
|
|
138162
|
-
wasmPath =
|
|
139120
|
+
for (const path27 of wasmPaths) {
|
|
139121
|
+
if (existsSync46(path27)) {
|
|
139122
|
+
wasmPath = path27;
|
|
138163
139123
|
break;
|
|
138164
139124
|
}
|
|
138165
139125
|
}
|
|
@@ -138196,7 +139156,7 @@ Ensure prime-radiant-advanced-wasm is installed.`
|
|
|
138196
139156
|
* Sleep for a specified duration.
|
|
138197
139157
|
*/
|
|
138198
139158
|
sleep(ms) {
|
|
138199
|
-
return new Promise((
|
|
139159
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
138200
139160
|
}
|
|
138201
139161
|
// ===========================================================================
|
|
138202
139162
|
// ADR-052 A4.3: Fallback Mode Management
|
|
@@ -138326,7 +139286,7 @@ async function initializeHooksSystem() {
|
|
|
138326
139286
|
if (state.initialized) return;
|
|
138327
139287
|
try {
|
|
138328
139288
|
const projectRoot = findProjectRoot();
|
|
138329
|
-
const dataDir =
|
|
139289
|
+
const dataDir = path23.join(projectRoot, ".agentic-qe");
|
|
138330
139290
|
const memoryBackend2 = await createHybridBackendWithTimeout(dataDir);
|
|
138331
139291
|
try {
|
|
138332
139292
|
state.coherenceService = await createCoherenceService(wasmLoader);
|
|
@@ -138372,7 +139332,7 @@ async function createHybridBackendWithTimeout(dataDir) {
|
|
|
138372
139332
|
const timeoutMs = 5e3;
|
|
138373
139333
|
const backend = new HybridMemoryBackend({
|
|
138374
139334
|
sqlite: {
|
|
138375
|
-
path:
|
|
139335
|
+
path: path23.join(dataDir, "memory.db"),
|
|
138376
139336
|
// ADR-046: Unified storage
|
|
138377
139337
|
walMode: true,
|
|
138378
139338
|
poolSize: 3,
|
|
@@ -138678,7 +139638,7 @@ Examples:
|
|
|
138678
139638
|
let dreamTriggered = false;
|
|
138679
139639
|
try {
|
|
138680
139640
|
const projectRoot = findProjectRoot();
|
|
138681
|
-
const dataDir =
|
|
139641
|
+
const dataDir = path23.join(projectRoot, ".agentic-qe");
|
|
138682
139642
|
const memoryBackend2 = await createHybridBackendWithTimeout(dataDir);
|
|
138683
139643
|
await incrementDreamExperience(memoryBackend2);
|
|
138684
139644
|
} catch {
|
|
@@ -138777,7 +139737,7 @@ Examples:
|
|
|
138777
139737
|
null
|
|
138778
139738
|
);
|
|
138779
139739
|
const projectRoot = findProjectRoot();
|
|
138780
|
-
const dataDir =
|
|
139740
|
+
const dataDir = path23.join(projectRoot, ".agentic-qe");
|
|
138781
139741
|
const memoryBackend2 = await createHybridBackendWithTimeout(dataDir);
|
|
138782
139742
|
await incrementDreamExperience(memoryBackend2);
|
|
138783
139743
|
} catch (persistError) {
|
|
@@ -138982,7 +139942,7 @@ Registered: ${events.length}/${Object.keys(QE_HOOK_EVENTS).length}`)
|
|
|
138982
139942
|
const { reasoningBank } = await getHooksSystem();
|
|
138983
139943
|
const stats = await reasoningBank.getStats();
|
|
138984
139944
|
const projectRoot = findProjectRoot();
|
|
138985
|
-
const dataDir =
|
|
139945
|
+
const dataDir = path23.join(projectRoot, ".agentic-qe");
|
|
138986
139946
|
const memoryBackend2 = await createHybridBackendWithTimeout(dataDir);
|
|
138987
139947
|
let dreamState = await memoryBackend2.get(DREAM_STATE_KEY);
|
|
138988
139948
|
const isNewSession = !dreamState || !dreamState.sessionStartTime;
|
|
@@ -139141,7 +140101,7 @@ Registered: ${events.length}/${Object.keys(QE_HOOK_EVENTS).length}`)
|
|
|
139141
140101
|
});
|
|
139142
140102
|
}
|
|
139143
140103
|
const projectRoot = findProjectRoot();
|
|
139144
|
-
const dataDir =
|
|
140104
|
+
const dataDir = path23.join(projectRoot, ".agentic-qe");
|
|
139145
140105
|
const memoryBackend2 = await createHybridBackendWithTimeout(dataDir);
|
|
139146
140106
|
const expCount = await incrementDreamExperience(memoryBackend2);
|
|
139147
140107
|
dreamResult = await checkAndTriggerDream(memoryBackend2);
|
|
@@ -139334,7 +140294,7 @@ Registered: ${events.length}/${Object.keys(QE_HOOK_EVENTS).length}`)
|
|
|
139334
140294
|
});
|
|
139335
140295
|
experienceRecorded = true;
|
|
139336
140296
|
const projectRoot = findProjectRoot();
|
|
139337
|
-
const dataDir =
|
|
140297
|
+
const dataDir = path23.join(projectRoot, ".agentic-qe");
|
|
139338
140298
|
const memoryBackend2 = await createHybridBackendWithTimeout(dataDir);
|
|
139339
140299
|
await incrementDreamExperience(memoryBackend2);
|
|
139340
140300
|
} catch (initError) {
|
|
@@ -139367,8 +140327,8 @@ init_safe_json();
|
|
|
139367
140327
|
init_qe_patterns();
|
|
139368
140328
|
import { Command as Command16 } from "commander";
|
|
139369
140329
|
import chalk29 from "chalk";
|
|
139370
|
-
import
|
|
139371
|
-
import { existsSync as
|
|
140330
|
+
import path26 from "node:path";
|
|
140331
|
+
import { existsSync as existsSync48, writeFileSync as writeFileSync22, readFileSync as readFileSync33, mkdirSync as mkdirSync19, copyFileSync as copyFileSync9 } from "node:fs";
|
|
139372
140332
|
import { stat as stat3, unlink } from "node:fs/promises";
|
|
139373
140333
|
|
|
139374
140334
|
// src/learning/metrics-tracker.ts
|
|
@@ -139376,22 +140336,22 @@ init_safe_db();
|
|
|
139376
140336
|
init_qe_patterns();
|
|
139377
140337
|
init_safe_json();
|
|
139378
140338
|
init_logging();
|
|
139379
|
-
import
|
|
139380
|
-
import { existsSync as
|
|
139381
|
-
var
|
|
140339
|
+
import path24 from "node:path";
|
|
140340
|
+
import { existsSync as existsSync47 } from "node:fs";
|
|
140341
|
+
var logger21 = LoggerFactory.create("metrics-tracker");
|
|
139382
140342
|
var LearningMetricsTracker = class {
|
|
139383
140343
|
db = null;
|
|
139384
140344
|
dbPath;
|
|
139385
140345
|
initialized = false;
|
|
139386
140346
|
constructor(projectRoot = process.cwd()) {
|
|
139387
|
-
this.dbPath =
|
|
140347
|
+
this.dbPath = path24.join(projectRoot, ".agentic-qe", "memory.db");
|
|
139388
140348
|
}
|
|
139389
140349
|
/**
|
|
139390
140350
|
* Initialize the tracker (open database, ensure tables exist)
|
|
139391
140351
|
*/
|
|
139392
140352
|
async initialize() {
|
|
139393
140353
|
if (this.initialized) return;
|
|
139394
|
-
if (!
|
|
140354
|
+
if (!existsSync47(this.dbPath)) {
|
|
139395
140355
|
throw new Error(`Database not found: ${this.dbPath}. Run "aqe init --auto" first.`);
|
|
139396
140356
|
}
|
|
139397
140357
|
this.db = openDatabase(this.dbPath);
|
|
@@ -139659,7 +140619,7 @@ var LearningMetricsTracker = class {
|
|
|
139659
140619
|
try {
|
|
139660
140620
|
domainCoverage = safeJsonParse(row.domain_coverage_json || "{}");
|
|
139661
140621
|
} catch (e20) {
|
|
139662
|
-
|
|
140622
|
+
logger21.debug("Domain coverage JSON parse failed", { error: e20 instanceof Error ? e20.message : String(e20) });
|
|
139663
140623
|
for (const domain of QE_DOMAIN_LIST) {
|
|
139664
140624
|
domainCoverage[domain] = 0;
|
|
139665
140625
|
}
|
|
@@ -139750,7 +140710,7 @@ init_unified_memory();
|
|
|
139750
140710
|
init_qe_reasoning_bank();
|
|
139751
140711
|
init_safe_db();
|
|
139752
140712
|
import chalk28 from "chalk";
|
|
139753
|
-
import
|
|
140713
|
+
import path25 from "node:path";
|
|
139754
140714
|
import { createReadStream, createWriteStream } from "node:fs";
|
|
139755
140715
|
import { createGzip, createGunzip } from "node:zlib";
|
|
139756
140716
|
import { pipeline as pipeline9 } from "node:stream/promises";
|
|
@@ -139764,10 +140724,10 @@ async function initializeLearningSystem2() {
|
|
|
139764
140724
|
return state2.reasoningBank;
|
|
139765
140725
|
}
|
|
139766
140726
|
const projectRoot = findProjectRoot();
|
|
139767
|
-
const dataDir =
|
|
140727
|
+
const dataDir = path25.join(projectRoot, ".agentic-qe");
|
|
139768
140728
|
const backend = new HybridMemoryBackend({
|
|
139769
140729
|
sqlite: {
|
|
139770
|
-
path:
|
|
140730
|
+
path: path25.join(dataDir, "memory.db"),
|
|
139771
140731
|
walMode: true,
|
|
139772
140732
|
poolSize: 3,
|
|
139773
140733
|
busyTimeout: 5e3
|
|
@@ -139877,7 +140837,7 @@ function stripAnsi(text) {
|
|
|
139877
140837
|
}
|
|
139878
140838
|
function getDbPath() {
|
|
139879
140839
|
const projectRoot = findProjectRoot();
|
|
139880
|
-
return
|
|
140840
|
+
return path25.join(projectRoot, ".agentic-qe", "memory.db");
|
|
139881
140841
|
}
|
|
139882
140842
|
async function compressFile(inputPath, outputPath) {
|
|
139883
140843
|
const gzPath = outputPath || `${inputPath}.gz`;
|
|
@@ -140167,7 +141127,7 @@ function registerExportCommand(learning) {
|
|
|
140167
141127
|
if (options.json) {
|
|
140168
141128
|
printJson2(exportData);
|
|
140169
141129
|
} else {
|
|
140170
|
-
const outputPath =
|
|
141130
|
+
const outputPath = path26.resolve(options.output);
|
|
140171
141131
|
writeFileSync22(outputPath, JSON.stringify(exportData, null, 2), "utf-8");
|
|
140172
141132
|
printSuccess2(`Exported ${patterns.length} patterns to ${outputPath}`);
|
|
140173
141133
|
}
|
|
@@ -140181,8 +141141,8 @@ function registerExportCommand(learning) {
|
|
|
140181
141141
|
function registerImportCommand(learning) {
|
|
140182
141142
|
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
141143
|
try {
|
|
140184
|
-
const inputPath =
|
|
140185
|
-
if (!
|
|
141144
|
+
const inputPath = path26.resolve(options.input);
|
|
141145
|
+
if (!existsSync48(inputPath)) throw new Error(`File not found: ${inputPath}`);
|
|
140186
141146
|
const content = readFileSync33(inputPath, "utf-8");
|
|
140187
141147
|
const importData = safeJsonParse(content);
|
|
140188
141148
|
if (!importData.patterns || !Array.isArray(importData.patterns)) throw new Error("Invalid pattern file format");
|
|
@@ -140243,15 +141203,15 @@ function registerResetCommand(learning) {
|
|
|
140243
141203
|
process.exit(0);
|
|
140244
141204
|
}
|
|
140245
141205
|
const projectRoot = findProjectRoot();
|
|
140246
|
-
const dataDir =
|
|
141206
|
+
const dataDir = path26.join(projectRoot, ".agentic-qe");
|
|
140247
141207
|
const filesToReset = [
|
|
140248
|
-
|
|
140249
|
-
|
|
141208
|
+
path26.join(dataDir, "data", "patterns"),
|
|
141209
|
+
path26.join(dataDir, "data", "hnsw")
|
|
140250
141210
|
];
|
|
140251
|
-
if (!options.patternsOnly) filesToReset.push(
|
|
141211
|
+
if (!options.patternsOnly) filesToReset.push(path26.join(dataDir, "data", "learning-config.json"));
|
|
140252
141212
|
console.log(chalk29.bold("\n\u{1F5D1}\uFE0F Resetting Learning Data\n"));
|
|
140253
141213
|
for (const file of filesToReset) {
|
|
140254
|
-
if (
|
|
141214
|
+
if (existsSync48(file)) console.log(chalk29.dim(` Removing: ${path26.relative(projectRoot, file)}`));
|
|
140255
141215
|
}
|
|
140256
141216
|
printSuccess2('Learning data reset. Run "aqe init --auto" to reinitialize.\n');
|
|
140257
141217
|
process.exit(0);
|
|
@@ -140265,8 +141225,8 @@ function registerExtractCommand(learning) {
|
|
|
140265
141225
|
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
141226
|
try {
|
|
140267
141227
|
const projectRoot = findProjectRoot();
|
|
140268
|
-
const dbPath =
|
|
140269
|
-
if (!
|
|
141228
|
+
const dbPath = path26.join(projectRoot, ".agentic-qe", "memory.db");
|
|
141229
|
+
if (!existsSync48(dbPath)) throw new Error('No memory database found. Run "aqe init --auto" first.');
|
|
140270
141230
|
const minReward = parseFloat(options.minReward);
|
|
140271
141231
|
const minCount = parseInt(options.minCount, 10);
|
|
140272
141232
|
console.log(chalk29.bold("\n\u{1F52C} Pattern Extraction from Learning Experiences\n"));
|
|
@@ -140391,13 +141351,13 @@ function registerInfoCommand(learning) {
|
|
|
140391
141351
|
learning.command("info").description("Show learning system configuration and paths").action(async () => {
|
|
140392
141352
|
try {
|
|
140393
141353
|
const projectRoot = findProjectRoot();
|
|
140394
|
-
const dataDir =
|
|
141354
|
+
const dataDir = path26.join(projectRoot, ".agentic-qe");
|
|
140395
141355
|
console.log(chalk29.bold("\n\u{1F4CB} AQE Learning System Info\n"));
|
|
140396
141356
|
console.log(chalk29.bold("Paths:"));
|
|
140397
141357
|
console.log(` Data directory: ${dataDir}`);
|
|
140398
|
-
console.log(` Memory database: ${
|
|
140399
|
-
console.log(` HNSW index: ${
|
|
140400
|
-
console.log(` Patterns: ${
|
|
141358
|
+
console.log(` Memory database: ${path26.join(dataDir, "memory.db")}`);
|
|
141359
|
+
console.log(` HNSW index: ${path26.join(dataDir, "data", "hnsw")}`);
|
|
141360
|
+
console.log(` Patterns: ${path26.join(dataDir, "data", "patterns")}`);
|
|
140401
141361
|
console.log(chalk29.bold("\nConfiguration:"));
|
|
140402
141362
|
console.log(` Learning enabled: ${process.env.AQE_LEARNING_ENABLED !== "false" ? chalk29.green("yes") : chalk29.red("no")}`);
|
|
140403
141363
|
console.log(` V3 mode: ${process.env.AQE_V3_MODE === "true" ? chalk29.green("yes") : chalk29.dim("no")}`);
|
|
@@ -140419,22 +141379,22 @@ function registerBackupCommand(learning) {
|
|
|
140419
141379
|
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
141380
|
try {
|
|
140421
141381
|
const dbPath = getDbPath();
|
|
140422
|
-
if (!
|
|
141382
|
+
if (!existsSync48(dbPath)) throw new Error(`No learning database found at: ${dbPath}`);
|
|
140423
141383
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
140424
|
-
const defaultOutput =
|
|
140425
|
-
let outputPath = options.output ?
|
|
140426
|
-
const backupDir =
|
|
140427
|
-
if (!
|
|
141384
|
+
const defaultOutput = path26.join(process.cwd(), "backups", `learning-${timestamp}.db`);
|
|
141385
|
+
let outputPath = options.output ? path26.resolve(options.output) : defaultOutput;
|
|
141386
|
+
const backupDir = path26.dirname(outputPath);
|
|
141387
|
+
if (!existsSync48(backupDir)) mkdirSync19(backupDir, { recursive: true });
|
|
140428
141388
|
const sourceStats = await stat3(dbPath);
|
|
140429
141389
|
const sourceSizeKB = (sourceStats.size / 1024).toFixed(2);
|
|
140430
|
-
|
|
141390
|
+
copyFileSync9(dbPath, outputPath);
|
|
140431
141391
|
const walPath = `${dbPath}-wal`;
|
|
140432
|
-
if (
|
|
141392
|
+
if (existsSync48(walPath)) copyFileSync9(walPath, `${outputPath}-wal`);
|
|
140433
141393
|
let finalPath = outputPath;
|
|
140434
141394
|
if (options.compress) {
|
|
140435
141395
|
finalPath = await compressFile(outputPath);
|
|
140436
141396
|
await unlink(outputPath);
|
|
140437
|
-
if (
|
|
141397
|
+
if (existsSync48(`${outputPath}-wal`)) await unlink(`${outputPath}-wal`);
|
|
140438
141398
|
}
|
|
140439
141399
|
const finalStats = await stat3(finalPath);
|
|
140440
141400
|
const finalSizeKB = (finalStats.size / 1024).toFixed(2);
|
|
@@ -140470,9 +141430,9 @@ function registerBackupCommand(learning) {
|
|
|
140470
141430
|
function registerRestoreCommand(learning) {
|
|
140471
141431
|
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
141432
|
try {
|
|
140473
|
-
const inputPath =
|
|
141433
|
+
const inputPath = path26.resolve(options.input);
|
|
140474
141434
|
const dbPath = getDbPath();
|
|
140475
|
-
if (!
|
|
141435
|
+
if (!existsSync48(inputPath)) throw new Error(`Backup file not found: ${inputPath}`);
|
|
140476
141436
|
const isCompressed = inputPath.endsWith(".gz");
|
|
140477
141437
|
let restorePath = inputPath;
|
|
140478
141438
|
if (isCompressed) {
|
|
@@ -140483,23 +141443,23 @@ function registerRestoreCommand(learning) {
|
|
|
140483
141443
|
if (options.verify) {
|
|
140484
141444
|
const verificationResult = await verifyDatabaseIntegrity(restorePath);
|
|
140485
141445
|
if (!verificationResult.valid) {
|
|
140486
|
-
if (isCompressed &&
|
|
141446
|
+
if (isCompressed && existsSync48(restorePath)) await unlink(restorePath);
|
|
140487
141447
|
throw new Error(`Backup verification failed: ${verificationResult.message}`);
|
|
140488
141448
|
}
|
|
140489
141449
|
}
|
|
140490
|
-
if (
|
|
141450
|
+
if (existsSync48(dbPath) && !options.force) {
|
|
140491
141451
|
printError2(`Database already exists at: ${dbPath}`);
|
|
140492
141452
|
console.log(chalk29.yellow(" Use --force to overwrite"));
|
|
140493
|
-
if (isCompressed &&
|
|
141453
|
+
if (isCompressed && existsSync48(restorePath)) await unlink(restorePath);
|
|
140494
141454
|
process.exit(1);
|
|
140495
141455
|
}
|
|
140496
|
-
const targetDir =
|
|
140497
|
-
if (!
|
|
140498
|
-
if (
|
|
140499
|
-
if (
|
|
140500
|
-
if (
|
|
140501
|
-
|
|
140502
|
-
if (isCompressed &&
|
|
141456
|
+
const targetDir = path26.dirname(dbPath);
|
|
141457
|
+
if (!existsSync48(targetDir)) mkdirSync19(targetDir, { recursive: true });
|
|
141458
|
+
if (existsSync48(dbPath)) await unlink(dbPath);
|
|
141459
|
+
if (existsSync48(`${dbPath}-wal`)) await unlink(`${dbPath}-wal`);
|
|
141460
|
+
if (existsSync48(`${dbPath}-shm`)) await unlink(`${dbPath}-shm`);
|
|
141461
|
+
copyFileSync9(restorePath, dbPath);
|
|
141462
|
+
if (isCompressed && existsSync48(restorePath)) await unlink(restorePath);
|
|
140503
141463
|
const restoredStats = await stat3(dbPath);
|
|
140504
141464
|
const schemaVersion = await getSchemaVersion(dbPath);
|
|
140505
141465
|
if (options.json) {
|
|
@@ -140522,8 +141482,8 @@ function registerRestoreCommand(learning) {
|
|
|
140522
141482
|
function registerVerifyCommand(learning) {
|
|
140523
141483
|
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
141484
|
try {
|
|
140525
|
-
const dbPath = options.file ?
|
|
140526
|
-
if (!
|
|
141485
|
+
const dbPath = options.file ? path26.resolve(options.file) : getDbPath();
|
|
141486
|
+
if (!existsSync48(dbPath)) throw new Error(`Database file not found: ${dbPath}`);
|
|
140527
141487
|
const verificationResult = await verifyDatabaseIntegrity(dbPath);
|
|
140528
141488
|
const schemaVersion = await getSchemaVersion(dbPath);
|
|
140529
141489
|
const fileStats = await stat3(dbPath);
|
|
@@ -140565,7 +141525,7 @@ function registerExportFullCommand(learning) {
|
|
|
140565
141525
|
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
141526
|
try {
|
|
140567
141527
|
const dbPath = getDbPath();
|
|
140568
|
-
if (!
|
|
141528
|
+
if (!existsSync48(dbPath)) throw new Error('No learning database found. Run "aqe init --auto" first.');
|
|
140569
141529
|
const reasoningBank = await initializeLearningSystem2();
|
|
140570
141530
|
const schemaVersion = await getSchemaVersion(dbPath);
|
|
140571
141531
|
const searchResult = await reasoningBank.searchPatterns("*", { limit: 1e4 });
|
|
@@ -140617,7 +141577,7 @@ function registerExportFullCommand(learning) {
|
|
|
140617
141577
|
if (options.json) {
|
|
140618
141578
|
printJson2(exportData);
|
|
140619
141579
|
} else {
|
|
140620
|
-
let outputPath =
|
|
141580
|
+
let outputPath = path26.resolve(options.output);
|
|
140621
141581
|
writeFileSync22(outputPath, JSON.stringify(exportData, null, 2), "utf-8");
|
|
140622
141582
|
if (options.compress) {
|
|
140623
141583
|
const compressedPath = await compressFile(outputPath);
|
|
@@ -140643,8 +141603,8 @@ function registerExportFullCommand(learning) {
|
|
|
140643
141603
|
function registerImportMergeCommand(learning) {
|
|
140644
141604
|
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
141605
|
try {
|
|
140646
|
-
let inputPath =
|
|
140647
|
-
if (!
|
|
141606
|
+
let inputPath = path26.resolve(options.input);
|
|
141607
|
+
if (!existsSync48(inputPath)) throw new Error(`File not found: ${inputPath}`);
|
|
140648
141608
|
let content;
|
|
140649
141609
|
if (inputPath.endsWith(".gz")) {
|
|
140650
141610
|
const tempPath = inputPath.replace(".gz", ".tmp.json");
|
|
@@ -140927,7 +141887,7 @@ function registerDreamCommand(learning) {
|
|
|
140927
141887
|
import { Command as Command17 } from "commander";
|
|
140928
141888
|
import { spawn as spawn7 } from "child_process";
|
|
140929
141889
|
import { join as join45, dirname as dirname14 } from "path";
|
|
140930
|
-
import { existsSync as
|
|
141890
|
+
import { existsSync as existsSync49 } from "fs";
|
|
140931
141891
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
140932
141892
|
function createMcpCommand() {
|
|
140933
141893
|
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 +141939,7 @@ function findMcpEntry() {
|
|
|
140979
141939
|
join45(process.cwd(), "node_modules", "agentic-qe", "v3", "dist", "mcp", "entry.js")
|
|
140980
141940
|
];
|
|
140981
141941
|
for (const candidate of candidates) {
|
|
140982
|
-
if (
|
|
141942
|
+
if (existsSync49(candidate)) {
|
|
140983
141943
|
return candidate;
|
|
140984
141944
|
}
|
|
140985
141945
|
}
|
|
@@ -141101,14 +142061,14 @@ async function cleanupAndExit(code = 0) {
|
|
|
141101
142061
|
process.exit(code);
|
|
141102
142062
|
}
|
|
141103
142063
|
var program = new Command18();
|
|
141104
|
-
var VERSION = true ? "3.6.
|
|
142064
|
+
var VERSION = true ? "3.6.18" : "0.0.0-dev";
|
|
141105
142065
|
program.name("aqe").description("Agentic QE - Domain-Driven Quality Engineering").version(VERSION);
|
|
141106
142066
|
var registry = createCommandRegistry(context, cleanupAndExit, ensureInitialized);
|
|
141107
142067
|
registry.registerAll(program);
|
|
141108
142068
|
var workflowCmd = program.command("workflow").description("Manage QE workflows and pipelines (ADR-041)");
|
|
141109
142069
|
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
142070
|
if (!await ensureInitialized()) return;
|
|
141111
|
-
const
|
|
142071
|
+
const fs25 = await import("fs");
|
|
141112
142072
|
const pathModule = await import("path");
|
|
141113
142073
|
const filePath = pathModule.resolve(file);
|
|
141114
142074
|
try {
|
|
@@ -141176,7 +142136,7 @@ workflowCmd.command("run <file>").description("Execute a QE pipeline from YAML f
|
|
|
141176
142136
|
if (status.status === "completed" || status.status === "failed" || status.status === "cancelled") {
|
|
141177
142137
|
break;
|
|
141178
142138
|
}
|
|
141179
|
-
await new Promise((
|
|
142139
|
+
await new Promise((resolve15) => setTimeout(resolve15, 500));
|
|
141180
142140
|
}
|
|
141181
142141
|
const finalStatus = context.workflowOrchestrator.getWorkflowStatus(executionId);
|
|
141182
142142
|
if (finalStatus) {
|
|
@@ -141348,14 +142308,14 @@ workflowCmd.command("list").description("List workflows").option("-s, --schedule
|
|
|
141348
142308
|
}
|
|
141349
142309
|
});
|
|
141350
142310
|
workflowCmd.command("validate <file>").description("Validate a pipeline YAML file").option("-v, --verbose", "Show detailed validation results").action(async (file, options) => {
|
|
141351
|
-
const
|
|
142311
|
+
const fs25 = await import("fs");
|
|
141352
142312
|
const pathModule = await import("path");
|
|
141353
142313
|
const filePath = pathModule.resolve(file);
|
|
141354
142314
|
try {
|
|
141355
142315
|
console.log(chalk30.blue(`
|
|
141356
142316
|
Validating pipeline: ${file}
|
|
141357
142317
|
`));
|
|
141358
|
-
if (!
|
|
142318
|
+
if (!fs25.existsSync(filePath)) {
|
|
141359
142319
|
console.log(chalk30.red(`File not found: ${filePath}`));
|
|
141360
142320
|
await cleanupAndExit(1);
|
|
141361
142321
|
}
|