agentic-qe 3.7.14 → 3.7.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/helpers/brain-checkpoint.cjs +11 -0
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +49 -0
- package/dist/cli/bundle.js +1260 -528
- package/dist/cli/commands/prove.d.ts +60 -0
- package/dist/cli/commands/prove.js +167 -0
- package/dist/cli/handlers/brain-handler.js +2 -1
- package/dist/cli/index.js +2 -0
- package/dist/domains/test-generation/coordinator.js +6 -4
- package/dist/domains/test-generation/pattern-injection/edge-case-injector.d.ts +6 -0
- package/dist/domains/test-generation/pattern-injection/edge-case-injector.js +30 -0
- package/dist/feedback/feedback-loop.d.ts +5 -0
- package/dist/feedback/feedback-loop.js +12 -0
- package/dist/feedback/index.d.ts +1 -1
- package/dist/feedback/index.js +1 -1
- package/dist/kernel/hnsw-adapter.d.ts +3 -0
- package/dist/kernel/hnsw-adapter.js +11 -1
- package/dist/kernel/unified-memory-schemas.d.ts +3 -3
- package/dist/kernel/unified-memory-schemas.js +28 -1
- package/dist/kernel/unified-memory.js +57 -0
- package/dist/learning/aqe-learning-engine.js +2 -1
- package/dist/learning/daily-log.d.ts +43 -0
- package/dist/learning/daily-log.js +91 -0
- package/dist/learning/experience-capture-middleware.js +24 -0
- package/dist/learning/experience-capture.d.ts +42 -0
- package/dist/learning/experience-capture.js +94 -4
- package/dist/learning/index.d.ts +4 -0
- package/dist/learning/index.js +8 -0
- package/dist/learning/opd-remediation.d.ts +55 -0
- package/dist/learning/opd-remediation.js +130 -0
- package/dist/learning/pattern-lifecycle.d.ts +12 -1
- package/dist/learning/pattern-lifecycle.js +18 -2
- package/dist/learning/pattern-store.d.ts +12 -4
- package/dist/learning/pattern-store.js +178 -19
- package/dist/learning/qe-hooks.d.ts +1 -0
- package/dist/learning/qe-hooks.js +30 -0
- package/dist/learning/qe-patterns.d.ts +6 -0
- package/dist/learning/qe-patterns.js +10 -1
- package/dist/learning/sqlite-persistence.d.ts +43 -0
- package/dist/learning/sqlite-persistence.js +237 -1
- package/dist/learning/token-tracker.js +4 -0
- package/dist/mcp/bundle.js +836 -48
- package/dist/mcp/handlers/core-handlers.d.ts +5 -0
- package/dist/mcp/handlers/core-handlers.js +11 -0
- package/dist/mcp/handlers/handler-factory.js +92 -11
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.js +2 -0
- package/dist/mcp/tool-scoping.d.ts +36 -0
- package/dist/mcp/tool-scoping.js +129 -0
- package/dist/routing/routing-feedback.d.ts +5 -0
- package/dist/routing/routing-feedback.js +29 -3
- package/dist/sync/pull-agent.js +2 -1
- package/dist/test-scheduling/pipeline.d.ts +7 -0
- package/dist/test-scheduling/pipeline.js +9 -0
- package/package.json +1 -1
package/dist/cli/bundle.js
CHANGED
|
@@ -11,10 +11,10 @@ var __require = /* @__PURE__ */ ((x67) => typeof require !== "undefined" ? requi
|
|
|
11
11
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
12
12
|
throw Error('Dynamic require of "' + x67 + '" is not supported');
|
|
13
13
|
});
|
|
14
|
-
var __glob = (map) => (
|
|
15
|
-
var fn = map[
|
|
14
|
+
var __glob = (map) => (path37) => {
|
|
15
|
+
var fn = map[path37];
|
|
16
16
|
if (fn) return fn();
|
|
17
|
-
throw new Error("Module not found in bundle: " +
|
|
17
|
+
throw new Error("Module not found in bundle: " + path37);
|
|
18
18
|
};
|
|
19
19
|
var __esm = (fn, res) => function __init() {
|
|
20
20
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
@@ -1876,7 +1876,19 @@ var init_hnsw_adapter = __esm({
|
|
|
1876
1876
|
this.backend.add(id, vector, metadata);
|
|
1877
1877
|
}
|
|
1878
1878
|
search(query, k68) {
|
|
1879
|
-
|
|
1879
|
+
const start = performance.now();
|
|
1880
|
+
const results = this.backend.search(query, k68);
|
|
1881
|
+
const elapsed = performance.now() - start;
|
|
1882
|
+
if (elapsed > 50) {
|
|
1883
|
+
console.warn(`[HNSW] search took ${elapsed.toFixed(1)}ms (k=${k68}, results=${results.length})`);
|
|
1884
|
+
}
|
|
1885
|
+
this._lastSearchLatencyMs = elapsed;
|
|
1886
|
+
return results;
|
|
1887
|
+
}
|
|
1888
|
+
/** Last search latency in ms, for instrumentation */
|
|
1889
|
+
_lastSearchLatencyMs = 0;
|
|
1890
|
+
get lastSearchLatencyMs() {
|
|
1891
|
+
return this._lastSearchLatencyMs;
|
|
1880
1892
|
}
|
|
1881
1893
|
remove(id) {
|
|
1882
1894
|
return this.backend.remove(id);
|
|
@@ -2549,7 +2561,7 @@ var init_unified_memory_schemas = __esm({
|
|
|
2549
2561
|
"src/kernel/unified-memory-schemas.ts"() {
|
|
2550
2562
|
"use strict";
|
|
2551
2563
|
init_add_hypergraph_tables();
|
|
2552
|
-
SCHEMA_VERSION =
|
|
2564
|
+
SCHEMA_VERSION = 9;
|
|
2553
2565
|
SCHEMA_VERSION_TABLE = `
|
|
2554
2566
|
CREATE TABLE IF NOT EXISTS schema_version (
|
|
2555
2567
|
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
@@ -2855,6 +2867,31 @@ var init_unified_memory_schemas = __esm({
|
|
|
2855
2867
|
FOREIGN KEY (execution_id) REFERENCES execution_results(id)
|
|
2856
2868
|
);
|
|
2857
2869
|
|
|
2870
|
+
-- FTS5 full-text search index for hybrid vector/text search
|
|
2871
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS qe_patterns_fts USING fts5(
|
|
2872
|
+
name, description, pattern_type, qe_domain,
|
|
2873
|
+
content='qe_patterns',
|
|
2874
|
+
content_rowid='rowid'
|
|
2875
|
+
);
|
|
2876
|
+
|
|
2877
|
+
-- FTS5 triggers to keep index in sync
|
|
2878
|
+
CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_insert AFTER INSERT ON qe_patterns BEGIN
|
|
2879
|
+
INSERT INTO qe_patterns_fts(rowid, name, description, pattern_type, qe_domain)
|
|
2880
|
+
VALUES (new.rowid, new.name, new.description, new.pattern_type, new.qe_domain);
|
|
2881
|
+
END;
|
|
2882
|
+
|
|
2883
|
+
CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_delete AFTER DELETE ON qe_patterns BEGIN
|
|
2884
|
+
INSERT INTO qe_patterns_fts(qe_patterns_fts, rowid, name, description, pattern_type, qe_domain)
|
|
2885
|
+
VALUES ('delete', old.rowid, old.name, old.description, old.pattern_type, old.qe_domain);
|
|
2886
|
+
END;
|
|
2887
|
+
|
|
2888
|
+
CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_update AFTER UPDATE ON qe_patterns BEGIN
|
|
2889
|
+
INSERT INTO qe_patterns_fts(qe_patterns_fts, rowid, name, description, pattern_type, qe_domain)
|
|
2890
|
+
VALUES ('delete', old.rowid, old.name, old.description, old.pattern_type, old.qe_domain);
|
|
2891
|
+
INSERT INTO qe_patterns_fts(rowid, name, description, pattern_type, qe_domain)
|
|
2892
|
+
VALUES (new.rowid, new.name, new.description, new.pattern_type, new.qe_domain);
|
|
2893
|
+
END;
|
|
2894
|
+
|
|
2858
2895
|
-- QE Patterns indexes
|
|
2859
2896
|
CREATE INDEX IF NOT EXISTS idx_qe_patterns_domain ON qe_patterns(qe_domain);
|
|
2860
2897
|
CREATE INDEX IF NOT EXISTS idx_qe_patterns_type ON qe_patterns(pattern_type);
|
|
@@ -3048,10 +3085,12 @@ var init_unified_memory_schemas = __esm({
|
|
|
3048
3085
|
quality_score REAL NOT NULL,
|
|
3049
3086
|
duration_ms REAL NOT NULL,
|
|
3050
3087
|
error TEXT,
|
|
3088
|
+
model_tier TEXT,
|
|
3051
3089
|
created_at TEXT DEFAULT (datetime('now'))
|
|
3052
3090
|
);
|
|
3053
3091
|
CREATE INDEX IF NOT EXISTS idx_routing_outcomes_agent ON routing_outcomes(used_agent);
|
|
3054
3092
|
CREATE INDEX IF NOT EXISTS idx_routing_outcomes_created ON routing_outcomes(created_at);
|
|
3093
|
+
CREATE INDEX IF NOT EXISTS idx_routing_outcomes_tier ON routing_outcomes(model_tier);
|
|
3055
3094
|
|
|
3056
3095
|
-- Coverage sessions (ADR-023: Coverage Learning)
|
|
3057
3096
|
CREATE TABLE IF NOT EXISTS coverage_sessions (
|
|
@@ -4045,6 +4084,7 @@ __export(unified_memory_exports, {
|
|
|
4045
4084
|
validateTableName: () => validateTableName
|
|
4046
4085
|
});
|
|
4047
4086
|
import * as fs from "fs";
|
|
4087
|
+
import * as os from "os";
|
|
4048
4088
|
import * as path from "path";
|
|
4049
4089
|
function clearProjectRootCache() {
|
|
4050
4090
|
_cachedProjectRoot = null;
|
|
@@ -4201,6 +4241,7 @@ var init_unified_memory = __esm({
|
|
|
4201
4241
|
_UnifiedMemoryManager.instance = null;
|
|
4202
4242
|
}
|
|
4203
4243
|
_UnifiedMemoryManager.instancePromise = null;
|
|
4244
|
+
clearProjectRootCache();
|
|
4204
4245
|
}
|
|
4205
4246
|
async initialize() {
|
|
4206
4247
|
if (this.initialized) return;
|
|
@@ -4212,6 +4253,17 @@ var init_unified_memory = __esm({
|
|
|
4212
4253
|
async _doInitialize() {
|
|
4213
4254
|
if (this.initialized) return;
|
|
4214
4255
|
try {
|
|
4256
|
+
const envRoot = process.env.AQE_PROJECT_ROOT;
|
|
4257
|
+
if (envRoot) {
|
|
4258
|
+
const resolvedPath = path.resolve(this.config.dbPath);
|
|
4259
|
+
const resolvedRoot = path.resolve(envRoot);
|
|
4260
|
+
if (!resolvedPath.startsWith(resolvedRoot) && !resolvedPath.startsWith(os.tmpdir()) && resolvedPath.includes(".agentic-qe")) {
|
|
4261
|
+
console.error(
|
|
4262
|
+
`[UnifiedMemory] WARNING: DB path "${this.config.dbPath}" points to a production .agentic-qe/ while AQE_PROJECT_ROOT="${envRoot}". Redirecting to test-safe path.`
|
|
4263
|
+
);
|
|
4264
|
+
this.config.dbPath = path.join(envRoot, ".agentic-qe", "memory.db");
|
|
4265
|
+
}
|
|
4266
|
+
}
|
|
4215
4267
|
const dir = path.dirname(this.config.dbPath);
|
|
4216
4268
|
if (!fs.existsSync(dir)) {
|
|
4217
4269
|
fs.mkdirSync(dir, { recursive: true });
|
|
@@ -4385,6 +4437,36 @@ var init_unified_memory = __esm({
|
|
|
4385
4437
|
if (currentVersion < 6) this.db.exec(HYPERGRAPH_SCHEMA);
|
|
4386
4438
|
if (currentVersion < 7) this.db.exec(SONA_PATTERNS_SCHEMA);
|
|
4387
4439
|
if (currentVersion < 8) this.db.exec(FEEDBACK_SCHEMA);
|
|
4440
|
+
if (currentVersion < 9) {
|
|
4441
|
+
this.db.exec(`
|
|
4442
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS qe_patterns_fts USING fts5(
|
|
4443
|
+
name, description, pattern_type, qe_domain,
|
|
4444
|
+
content='qe_patterns',
|
|
4445
|
+
content_rowid='rowid'
|
|
4446
|
+
);
|
|
4447
|
+
|
|
4448
|
+
CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_insert AFTER INSERT ON qe_patterns BEGIN
|
|
4449
|
+
INSERT INTO qe_patterns_fts(rowid, name, description, pattern_type, qe_domain)
|
|
4450
|
+
VALUES (new.rowid, new.name, new.description, new.pattern_type, new.qe_domain);
|
|
4451
|
+
END;
|
|
4452
|
+
|
|
4453
|
+
CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_delete AFTER DELETE ON qe_patterns BEGIN
|
|
4454
|
+
INSERT INTO qe_patterns_fts(qe_patterns_fts, rowid, name, description, pattern_type, qe_domain)
|
|
4455
|
+
VALUES ('delete', old.rowid, old.name, old.description, old.pattern_type, old.qe_domain);
|
|
4456
|
+
END;
|
|
4457
|
+
|
|
4458
|
+
CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_update AFTER UPDATE ON qe_patterns BEGIN
|
|
4459
|
+
INSERT INTO qe_patterns_fts(qe_patterns_fts, rowid, name, description, pattern_type, qe_domain)
|
|
4460
|
+
VALUES ('delete', old.rowid, old.name, old.description, old.pattern_type, old.qe_domain);
|
|
4461
|
+
INSERT INTO qe_patterns_fts(rowid, name, description, pattern_type, qe_domain)
|
|
4462
|
+
VALUES (new.rowid, new.name, new.description, new.pattern_type, new.qe_domain);
|
|
4463
|
+
END;
|
|
4464
|
+
`);
|
|
4465
|
+
this.db.exec(`
|
|
4466
|
+
INSERT INTO qe_patterns_fts(rowid, name, description, pattern_type, qe_domain)
|
|
4467
|
+
SELECT rowid, name, description, pattern_type, qe_domain FROM qe_patterns;
|
|
4468
|
+
`);
|
|
4469
|
+
}
|
|
4388
4470
|
this.db.prepare(`
|
|
4389
4471
|
INSERT OR REPLACE INTO schema_version (id, version, migrated_at)
|
|
4390
4472
|
VALUES (1, ?, datetime('now'))
|
|
@@ -7327,7 +7409,7 @@ function calculateQualityScore(pattern) {
|
|
|
7327
7409
|
return pattern.confidence * 0.3 + usageScore * 0.2 + pattern.successRate * 0.5;
|
|
7328
7410
|
}
|
|
7329
7411
|
function shouldPromotePattern(pattern, coherenceEnergy, coherenceThreshold = 0.4) {
|
|
7330
|
-
const meetsUsageCriteria = pattern.tier === "short-term" && pattern.successfulUses >=
|
|
7412
|
+
const meetsUsageCriteria = pattern.tier === "short-term" && pattern.successfulUses >= PROMOTION_THRESHOLD;
|
|
7331
7413
|
const meetsQualityCriteria = pattern.successRate >= 0.7 && pattern.confidence >= 0.6;
|
|
7332
7414
|
const meetsCoherenceCriteria = coherenceEnergy === void 0 || coherenceEnergy < coherenceThreshold;
|
|
7333
7415
|
let blockReason;
|
|
@@ -7389,7 +7471,7 @@ function applyPatternTemplate(template, variables) {
|
|
|
7389
7471
|
}
|
|
7390
7472
|
return content;
|
|
7391
7473
|
}
|
|
7392
|
-
var QE_DOMAINS, QE_DOMAIN_LIST;
|
|
7474
|
+
var QE_DOMAINS, PROMOTION_THRESHOLD, QE_DOMAIN_LIST;
|
|
7393
7475
|
var init_qe_patterns = __esm({
|
|
7394
7476
|
"src/learning/qe-patterns.ts"() {
|
|
7395
7477
|
"use strict";
|
|
@@ -7411,6 +7493,7 @@ var init_qe_patterns = __esm({
|
|
|
7411
7493
|
"chaos-resilience": /chaos|resilience|fault|inject|blast|recover|latency|failure|stress|load/i,
|
|
7412
7494
|
"learning-optimization": /learn|pattern|optim|neural|embedding|vector|memory|adapt|train/i
|
|
7413
7495
|
};
|
|
7496
|
+
PROMOTION_THRESHOLD = 3;
|
|
7414
7497
|
QE_DOMAIN_LIST = Object.keys(QE_DOMAINS);
|
|
7415
7498
|
}
|
|
7416
7499
|
});
|
|
@@ -11024,7 +11107,7 @@ var init_gnn_wrapper = __esm({
|
|
|
11024
11107
|
* Save index to file
|
|
11025
11108
|
* Note: @ruvector/gnn uses JSON serialization for layers
|
|
11026
11109
|
*/
|
|
11027
|
-
async saveIndex(namespace,
|
|
11110
|
+
async saveIndex(namespace, path37) {
|
|
11028
11111
|
const index = this.indexes.get(namespace);
|
|
11029
11112
|
if (!index) {
|
|
11030
11113
|
throw new Error(`Namespace ${namespace} not initialized`);
|
|
@@ -11034,15 +11117,15 @@ var init_gnn_wrapper = __esm({
|
|
|
11034
11117
|
vector: Array.from(emb.vector),
|
|
11035
11118
|
metadata: emb.metadata
|
|
11036
11119
|
}));
|
|
11037
|
-
const
|
|
11038
|
-
await
|
|
11120
|
+
const fs32 = await import("fs/promises");
|
|
11121
|
+
await fs32.writeFile(path37, JSON.stringify(data, null, 2));
|
|
11039
11122
|
}
|
|
11040
11123
|
/**
|
|
11041
11124
|
* Load index from file
|
|
11042
11125
|
*/
|
|
11043
|
-
async loadIndex(namespace,
|
|
11044
|
-
const
|
|
11045
|
-
const content = await
|
|
11126
|
+
async loadIndex(namespace, path37) {
|
|
11127
|
+
const fs32 = await import("fs/promises");
|
|
11128
|
+
const content = await fs32.readFile(path37, "utf-8");
|
|
11046
11129
|
const data = safeJsonParse(content);
|
|
11047
11130
|
this.initializeIndex(namespace);
|
|
11048
11131
|
for (const item of data) {
|
|
@@ -12544,7 +12627,7 @@ var init_path_traversal_validator = __esm({
|
|
|
12544
12627
|
/**
|
|
12545
12628
|
* Validate a file path against traversal attacks
|
|
12546
12629
|
*/
|
|
12547
|
-
validate(
|
|
12630
|
+
validate(path37, options = {}) {
|
|
12548
12631
|
const {
|
|
12549
12632
|
basePath = "",
|
|
12550
12633
|
allowAbsolute = false,
|
|
@@ -12553,7 +12636,7 @@ var init_path_traversal_validator = __esm({
|
|
|
12553
12636
|
maxDepth = 10,
|
|
12554
12637
|
maxLength = 4096
|
|
12555
12638
|
} = options;
|
|
12556
|
-
if (
|
|
12639
|
+
if (path37.length > maxLength) {
|
|
12557
12640
|
return {
|
|
12558
12641
|
valid: false,
|
|
12559
12642
|
error: `Path exceeds maximum length of ${maxLength}`,
|
|
@@ -12561,7 +12644,7 @@ var init_path_traversal_validator = __esm({
|
|
|
12561
12644
|
};
|
|
12562
12645
|
}
|
|
12563
12646
|
for (const pattern of PATH_TRAVERSAL_PATTERNS) {
|
|
12564
|
-
if (pattern.test(
|
|
12647
|
+
if (pattern.test(path37)) {
|
|
12565
12648
|
return {
|
|
12566
12649
|
valid: false,
|
|
12567
12650
|
error: "Path traversal attempt detected",
|
|
@@ -12569,7 +12652,7 @@ var init_path_traversal_validator = __esm({
|
|
|
12569
12652
|
};
|
|
12570
12653
|
}
|
|
12571
12654
|
}
|
|
12572
|
-
if (!allowAbsolute && (
|
|
12655
|
+
if (!allowAbsolute && (path37.startsWith("/") || /^[A-Z]:/i.test(path37))) {
|
|
12573
12656
|
return {
|
|
12574
12657
|
valid: false,
|
|
12575
12658
|
error: "Absolute paths are not allowed",
|
|
@@ -12577,7 +12660,7 @@ var init_path_traversal_validator = __esm({
|
|
|
12577
12660
|
};
|
|
12578
12661
|
}
|
|
12579
12662
|
for (const pattern of DANGEROUS_PATH_COMPONENTS) {
|
|
12580
|
-
if (pattern.test(
|
|
12663
|
+
if (pattern.test(path37)) {
|
|
12581
12664
|
return {
|
|
12582
12665
|
valid: false,
|
|
12583
12666
|
error: "Access to system paths is not allowed",
|
|
@@ -12585,7 +12668,7 @@ var init_path_traversal_validator = __esm({
|
|
|
12585
12668
|
};
|
|
12586
12669
|
}
|
|
12587
12670
|
}
|
|
12588
|
-
const normalizedPath = this.normalizePath(
|
|
12671
|
+
const normalizedPath = this.normalizePath(path37);
|
|
12589
12672
|
if (normalizedPath.includes("..")) {
|
|
12590
12673
|
return {
|
|
12591
12674
|
valid: false,
|
|
@@ -12648,8 +12731,8 @@ var init_path_traversal_validator = __esm({
|
|
|
12648
12731
|
/**
|
|
12649
12732
|
* Normalize a path by resolving . and .. components
|
|
12650
12733
|
*/
|
|
12651
|
-
normalizePath(
|
|
12652
|
-
let normalized =
|
|
12734
|
+
normalizePath(path37) {
|
|
12735
|
+
let normalized = path37.replace(/\\/g, "/");
|
|
12653
12736
|
normalized = normalized.replace(/\/+/g, "/");
|
|
12654
12737
|
const parts = normalized.split("/");
|
|
12655
12738
|
const result = [];
|
|
@@ -12690,13 +12773,13 @@ var init_path_traversal_validator = __esm({
|
|
|
12690
12773
|
/**
|
|
12691
12774
|
* Get file extension from path
|
|
12692
12775
|
*/
|
|
12693
|
-
getExtension(
|
|
12694
|
-
const match =
|
|
12776
|
+
getExtension(path37) {
|
|
12777
|
+
const match = path37.match(/\.([^./\\]+)$/);
|
|
12695
12778
|
return match ? match[1] : null;
|
|
12696
12779
|
}
|
|
12697
12780
|
};
|
|
12698
12781
|
defaultValidator2 = new PathTraversalValidator();
|
|
12699
|
-
validatePath = (
|
|
12782
|
+
validatePath = (path37, options) => defaultValidator2.validate(path37, options);
|
|
12700
12783
|
}
|
|
12701
12784
|
});
|
|
12702
12785
|
|
|
@@ -13797,23 +13880,23 @@ var init_knowledge_graph = __esm({
|
|
|
13797
13880
|
if (!incremental) {
|
|
13798
13881
|
await this.clear();
|
|
13799
13882
|
}
|
|
13800
|
-
for (const
|
|
13883
|
+
for (const path37 of paths) {
|
|
13801
13884
|
try {
|
|
13802
13885
|
if (languages && languages.length > 0) {
|
|
13803
|
-
const ext = this.getFileExtension(
|
|
13886
|
+
const ext = this.getFileExtension(path37);
|
|
13804
13887
|
if (!this.matchesLanguage(ext, languages)) {
|
|
13805
13888
|
continue;
|
|
13806
13889
|
}
|
|
13807
13890
|
}
|
|
13808
|
-
if (!includeTests && this.isTestFile(
|
|
13891
|
+
if (!includeTests && this.isTestFile(path37)) {
|
|
13809
13892
|
continue;
|
|
13810
13893
|
}
|
|
13811
|
-
const result = await this.indexFile(
|
|
13894
|
+
const result = await this.indexFile(path37);
|
|
13812
13895
|
nodesCreated += result.nodes;
|
|
13813
13896
|
edgesCreated += result.edges;
|
|
13814
13897
|
} catch (fileError) {
|
|
13815
13898
|
errors.push({
|
|
13816
|
-
file:
|
|
13899
|
+
file: path37,
|
|
13817
13900
|
error: toErrorMessage(fileError)
|
|
13818
13901
|
});
|
|
13819
13902
|
}
|
|
@@ -14527,16 +14610,16 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
|
|
|
14527
14610
|
}
|
|
14528
14611
|
});
|
|
14529
14612
|
}
|
|
14530
|
-
async traverseDependencies(file, direction, depth, visited, nodes, edges,
|
|
14613
|
+
async traverseDependencies(file, direction, depth, visited, nodes, edges, path37, cycles) {
|
|
14531
14614
|
if (depth <= 0 || visited.has(file)) {
|
|
14532
|
-
const cycleStart =
|
|
14615
|
+
const cycleStart = path37.indexOf(file);
|
|
14533
14616
|
if (cycleStart >= 0) {
|
|
14534
|
-
cycles.push([...
|
|
14617
|
+
cycles.push([...path37.slice(cycleStart), file]);
|
|
14535
14618
|
}
|
|
14536
14619
|
return;
|
|
14537
14620
|
}
|
|
14538
14621
|
visited.add(file);
|
|
14539
|
-
|
|
14622
|
+
path37.push(file);
|
|
14540
14623
|
const nodeId = this.pathToNodeId(file);
|
|
14541
14624
|
const fileEdges = await this.getEdges(nodeId, direction);
|
|
14542
14625
|
const inDegree = fileEdges.filter((e20) => e20.target === nodeId).length;
|
|
@@ -14566,12 +14649,12 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
|
|
|
14566
14649
|
visited,
|
|
14567
14650
|
nodes,
|
|
14568
14651
|
edges,
|
|
14569
|
-
|
|
14652
|
+
path37,
|
|
14570
14653
|
cycles
|
|
14571
14654
|
);
|
|
14572
14655
|
}
|
|
14573
14656
|
}
|
|
14574
|
-
|
|
14657
|
+
path37.pop();
|
|
14575
14658
|
}
|
|
14576
14659
|
calculateDependencyMetrics(nodes, edges) {
|
|
14577
14660
|
const totalNodes = nodes.length;
|
|
@@ -14656,23 +14739,23 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
|
|
|
14656
14739
|
const magnitude2 = Math.sqrt(embedding.reduce((sum, v65) => sum + v65 * v65, 0)) || 1;
|
|
14657
14740
|
return embedding.map((v65) => v65 / magnitude2);
|
|
14658
14741
|
}
|
|
14659
|
-
pathToNodeId(
|
|
14660
|
-
return
|
|
14742
|
+
pathToNodeId(path37) {
|
|
14743
|
+
return path37.replace(/[/\\]/g, ":").replace(/\./g, "_");
|
|
14661
14744
|
}
|
|
14662
14745
|
nodeIdToPath(nodeId) {
|
|
14663
|
-
const
|
|
14664
|
-
return
|
|
14746
|
+
const path37 = nodeId.replace(/:/g, "/").replace(/_(?=[^_]*$)/, ".");
|
|
14747
|
+
return path37.includes("/") ? path37 : null;
|
|
14665
14748
|
}
|
|
14666
|
-
getFileName(
|
|
14667
|
-
return
|
|
14749
|
+
getFileName(path37) {
|
|
14750
|
+
return path37.split(/[/\\]/).pop() || path37;
|
|
14668
14751
|
}
|
|
14669
|
-
getFileExtension(
|
|
14670
|
-
const name = this.getFileName(
|
|
14752
|
+
getFileExtension(path37) {
|
|
14753
|
+
const name = this.getFileName(path37);
|
|
14671
14754
|
const parts = name.split(".");
|
|
14672
14755
|
return parts.length > 1 ? parts.pop() : "";
|
|
14673
14756
|
}
|
|
14674
|
-
getFileType(
|
|
14675
|
-
const ext = this.getFileExtension(
|
|
14757
|
+
getFileType(path37) {
|
|
14758
|
+
const ext = this.getFileExtension(path37);
|
|
14676
14759
|
const typeMap = {
|
|
14677
14760
|
ts: "typescript",
|
|
14678
14761
|
tsx: "typescript-react",
|
|
@@ -14701,7 +14784,7 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
|
|
|
14701
14784
|
return exts.includes(ext);
|
|
14702
14785
|
});
|
|
14703
14786
|
}
|
|
14704
|
-
isTestFile(
|
|
14787
|
+
isTestFile(path37) {
|
|
14705
14788
|
const testPatterns = [
|
|
14706
14789
|
/\.test\.[tj]sx?$/,
|
|
14707
14790
|
/\.spec\.[tj]sx?$/,
|
|
@@ -14710,7 +14793,7 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
|
|
|
14710
14793
|
/.*_test\.py$/,
|
|
14711
14794
|
/.*_test\.go$/
|
|
14712
14795
|
];
|
|
14713
|
-
return testPatterns.some((pattern) => pattern.test(
|
|
14796
|
+
return testPatterns.some((pattern) => pattern.test(path37));
|
|
14714
14797
|
}
|
|
14715
14798
|
/**
|
|
14716
14799
|
* Dispose of all resources and clear caches.
|
|
@@ -15049,7 +15132,7 @@ var init_impact_analyzer = __esm({
|
|
|
15049
15132
|
// ============================================================================
|
|
15050
15133
|
// Private Helper Methods
|
|
15051
15134
|
// ============================================================================
|
|
15052
|
-
isTestFile(
|
|
15135
|
+
isTestFile(path37) {
|
|
15053
15136
|
const testPatterns = [
|
|
15054
15137
|
/\.test\.[tj]sx?$/,
|
|
15055
15138
|
/\.spec\.[tj]sx?$/,
|
|
@@ -15058,15 +15141,15 @@ var init_impact_analyzer = __esm({
|
|
|
15058
15141
|
/.*_test\.py$/,
|
|
15059
15142
|
/.*_test\.go$/
|
|
15060
15143
|
];
|
|
15061
|
-
return testPatterns.some((pattern) => pattern.test(
|
|
15144
|
+
return testPatterns.some((pattern) => pattern.test(path37));
|
|
15062
15145
|
}
|
|
15063
|
-
isCriticalPath(
|
|
15146
|
+
isCriticalPath(path37) {
|
|
15064
15147
|
const criticalPatterns = this.config.criticalPaths.map(
|
|
15065
15148
|
(p74) => p74.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*")
|
|
15066
15149
|
);
|
|
15067
|
-
return criticalPatterns.some((pattern) => new RegExp(pattern).test(
|
|
15150
|
+
return criticalPatterns.some((pattern) => new RegExp(pattern).test(path37));
|
|
15068
15151
|
}
|
|
15069
|
-
isEntryPoint(
|
|
15152
|
+
isEntryPoint(path37) {
|
|
15070
15153
|
const entryPatterns = [
|
|
15071
15154
|
/\/index\.[tj]sx?$/,
|
|
15072
15155
|
/\/main\.[tj]sx?$/,
|
|
@@ -15076,14 +15159,14 @@ var init_impact_analyzer = __esm({
|
|
|
15076
15159
|
/\/__init__\.py$/,
|
|
15077
15160
|
/\/main\.go$/
|
|
15078
15161
|
];
|
|
15079
|
-
return entryPatterns.some((pattern) => pattern.test(
|
|
15162
|
+
return entryPatterns.some((pattern) => pattern.test(path37));
|
|
15080
15163
|
}
|
|
15081
|
-
getBaseName(
|
|
15082
|
-
const fileName = this.getFileName(
|
|
15164
|
+
getBaseName(path37) {
|
|
15165
|
+
const fileName = this.getFileName(path37);
|
|
15083
15166
|
return fileName.replace(/\.[^.]+$/, "");
|
|
15084
15167
|
}
|
|
15085
|
-
getFileName(
|
|
15086
|
-
return
|
|
15168
|
+
getFileName(path37) {
|
|
15169
|
+
return path37.split(/[/\\]/).pop() || path37;
|
|
15087
15170
|
}
|
|
15088
15171
|
deduplicateImpact(impact) {
|
|
15089
15172
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -18591,7 +18674,7 @@ var init_pattern_store = __esm({
|
|
|
18591
18674
|
efSearch: 100,
|
|
18592
18675
|
maxElements: 5e4
|
|
18593
18676
|
},
|
|
18594
|
-
promotionThreshold:
|
|
18677
|
+
promotionThreshold: PROMOTION_THRESHOLD,
|
|
18595
18678
|
minConfidence: 0.3,
|
|
18596
18679
|
maxPatternsPerDomain: 5e3,
|
|
18597
18680
|
autoCleanup: true,
|
|
@@ -18624,6 +18707,7 @@ var init_pattern_store = __esm({
|
|
|
18624
18707
|
cleanupTimer;
|
|
18625
18708
|
// Optional SQLite persistence delegate for delete/promote
|
|
18626
18709
|
sqliteStore = null;
|
|
18710
|
+
loadingPromise = null;
|
|
18627
18711
|
// In-memory caches for fast access
|
|
18628
18712
|
patternCache = /* @__PURE__ */ new Map();
|
|
18629
18713
|
domainIndex = /* @__PURE__ */ new Map();
|
|
@@ -18640,12 +18724,22 @@ var init_pattern_store = __esm({
|
|
|
18640
18724
|
searchLatencies: []
|
|
18641
18725
|
};
|
|
18642
18726
|
/**
|
|
18643
|
-
* Set SQLite persistence delegate
|
|
18644
|
-
*
|
|
18645
|
-
*
|
|
18727
|
+
* Set SQLite persistence delegate and load patterns into memory.
|
|
18728
|
+
*
|
|
18729
|
+
* When set, PatternStore will:
|
|
18730
|
+
* 1. Load existing patterns from SQLite into the in-memory cache
|
|
18731
|
+
* 2. Forward create/delete/promote operations to SQLite for persistence
|
|
18732
|
+
* 3. Persist embeddings alongside patterns on store()
|
|
18646
18733
|
*/
|
|
18647
18734
|
setSqliteStore(store) {
|
|
18648
18735
|
this.sqliteStore = store;
|
|
18736
|
+
if (this.initialized) {
|
|
18737
|
+
this.loadingPromise = this.loadPatterns().catch(
|
|
18738
|
+
(e20) => console.warn("[PatternStore] Failed to load patterns after setSqliteStore:", e20)
|
|
18739
|
+
).finally(() => {
|
|
18740
|
+
this.loadingPromise = null;
|
|
18741
|
+
});
|
|
18742
|
+
}
|
|
18649
18743
|
}
|
|
18650
18744
|
/**
|
|
18651
18745
|
* Initialize the pattern store
|
|
@@ -18716,6 +18810,40 @@ var init_pattern_store = __esm({
|
|
|
18716
18810
|
);
|
|
18717
18811
|
await Promise.race([initPromise3, timeoutPromise]);
|
|
18718
18812
|
this.hnswAvailable = this.hnswIndex.isNativeAvailable();
|
|
18813
|
+
if (this.sqliteStore) {
|
|
18814
|
+
try {
|
|
18815
|
+
const embeddings = this.sqliteStore.getAllEmbeddings();
|
|
18816
|
+
const maxBootstrap = this.config.hnsw.maxElements;
|
|
18817
|
+
let loaded = 0;
|
|
18818
|
+
for (const { patternId, embedding } of embeddings) {
|
|
18819
|
+
if (loaded >= maxBootstrap) break;
|
|
18820
|
+
if (!embedding || embedding.length !== this.config.embeddingDimension) continue;
|
|
18821
|
+
const pattern = this.patternCache.get(patternId);
|
|
18822
|
+
if (!pattern) continue;
|
|
18823
|
+
try {
|
|
18824
|
+
await this.hnswIndex.insert(patternId, embedding, {
|
|
18825
|
+
filePath: pattern.patternType,
|
|
18826
|
+
lineCoverage: pattern.confidence * 100,
|
|
18827
|
+
branchCoverage: pattern.qualityScore * 100,
|
|
18828
|
+
functionCoverage: 0,
|
|
18829
|
+
statementCoverage: 0,
|
|
18830
|
+
uncoveredLineCount: 0,
|
|
18831
|
+
uncoveredBranchCount: 0,
|
|
18832
|
+
riskScore: 1 - pattern.confidence,
|
|
18833
|
+
lastUpdated: Date.now(),
|
|
18834
|
+
totalLines: 0
|
|
18835
|
+
});
|
|
18836
|
+
loaded++;
|
|
18837
|
+
} catch {
|
|
18838
|
+
}
|
|
18839
|
+
}
|
|
18840
|
+
if (loaded > 0) {
|
|
18841
|
+
console.log(`[PatternStore] Loaded ${loaded} embeddings from SQLite into HNSW`);
|
|
18842
|
+
}
|
|
18843
|
+
} catch (error) {
|
|
18844
|
+
console.warn("[PatternStore] Failed to load SQLite embeddings into HNSW:", toErrorMessage(error));
|
|
18845
|
+
}
|
|
18846
|
+
}
|
|
18719
18847
|
console.log(
|
|
18720
18848
|
`[PatternStore] HNSW lazy-initialized (native: ${this.hnswAvailable})`
|
|
18721
18849
|
);
|
|
@@ -18729,9 +18857,32 @@ var init_pattern_store = __esm({
|
|
|
18729
18857
|
}
|
|
18730
18858
|
}
|
|
18731
18859
|
/**
|
|
18732
|
-
* Load existing patterns from
|
|
18860
|
+
* Load existing patterns from SQLite into in-memory cache.
|
|
18861
|
+
*
|
|
18862
|
+
* Previously this was a no-op after Issue #258 removed kv_store duplication,
|
|
18863
|
+
* but that left 15,634 SQLite patterns invisible to search on every restart.
|
|
18864
|
+
* Now properly loads from SQLitePatternStore when wired.
|
|
18733
18865
|
*/
|
|
18734
18866
|
async loadPatterns() {
|
|
18867
|
+
if (!this.sqliteStore) {
|
|
18868
|
+
return;
|
|
18869
|
+
}
|
|
18870
|
+
try {
|
|
18871
|
+
const patterns = this.sqliteStore.getPatterns({ limit: 5e4 });
|
|
18872
|
+
for (const pattern of patterns) {
|
|
18873
|
+
this.indexPattern(pattern);
|
|
18874
|
+
}
|
|
18875
|
+
if (patterns.length > 0) {
|
|
18876
|
+
console.log(
|
|
18877
|
+
`[PatternStore] Loaded ${patterns.length} patterns from SQLite into memory cache`
|
|
18878
|
+
);
|
|
18879
|
+
}
|
|
18880
|
+
} catch (error) {
|
|
18881
|
+
console.warn(
|
|
18882
|
+
"[PatternStore] Failed to load patterns from SQLite:",
|
|
18883
|
+
toErrorMessage(error)
|
|
18884
|
+
);
|
|
18885
|
+
}
|
|
18735
18886
|
}
|
|
18736
18887
|
/**
|
|
18737
18888
|
* Index a pattern in local caches
|
|
@@ -18746,7 +18897,11 @@ var init_pattern_store = __esm({
|
|
|
18746
18897
|
this.typeIndex.set(pattern.patternType, /* @__PURE__ */ new Set());
|
|
18747
18898
|
}
|
|
18748
18899
|
this.typeIndex.get(pattern.patternType).add(pattern.id);
|
|
18749
|
-
|
|
18900
|
+
const tier = pattern.tier === "long-term" ? "long-term" : "short-term";
|
|
18901
|
+
if (pattern.tier !== tier) {
|
|
18902
|
+
pattern.tier = tier;
|
|
18903
|
+
}
|
|
18904
|
+
this.tierIndex.get(tier).add(pattern.id);
|
|
18750
18905
|
}
|
|
18751
18906
|
/**
|
|
18752
18907
|
* Remove pattern from local indices
|
|
@@ -18764,6 +18919,9 @@ var init_pattern_store = __esm({
|
|
|
18764
18919
|
if (!this.initialized) {
|
|
18765
18920
|
await this.initialize();
|
|
18766
18921
|
}
|
|
18922
|
+
if (this.loadingPromise) {
|
|
18923
|
+
await this.loadingPromise;
|
|
18924
|
+
}
|
|
18767
18925
|
const validation = validateQEPattern(pattern);
|
|
18768
18926
|
if (!validation.valid) {
|
|
18769
18927
|
return err(new Error(`Invalid pattern: ${validation.errors.join(", ")}`));
|
|
@@ -18780,6 +18938,13 @@ var init_pattern_store = __esm({
|
|
|
18780
18938
|
await this.cleanupDomain(pattern.qeDomain);
|
|
18781
18939
|
}
|
|
18782
18940
|
this.indexPattern(pattern);
|
|
18941
|
+
if (this.sqliteStore) {
|
|
18942
|
+
try {
|
|
18943
|
+
this.sqliteStore.storePattern(pattern, pattern.embedding);
|
|
18944
|
+
} catch (error) {
|
|
18945
|
+
console.warn(`[PatternStore] SQLite persist failed for ${pattern.id}:`, toErrorMessage(error));
|
|
18946
|
+
}
|
|
18947
|
+
}
|
|
18783
18948
|
if (pattern.embedding) {
|
|
18784
18949
|
const hnsw = await this.ensureHNSW();
|
|
18785
18950
|
if (hnsw) {
|
|
@@ -18875,6 +19040,9 @@ var init_pattern_store = __esm({
|
|
|
18875
19040
|
if (!this.initialized) {
|
|
18876
19041
|
await this.initialize();
|
|
18877
19042
|
}
|
|
19043
|
+
if (this.loadingPromise) {
|
|
19044
|
+
await this.loadingPromise;
|
|
19045
|
+
}
|
|
18878
19046
|
return this.patternCache.get(id) ?? null;
|
|
18879
19047
|
}
|
|
18880
19048
|
/**
|
|
@@ -18884,6 +19052,9 @@ var init_pattern_store = __esm({
|
|
|
18884
19052
|
if (!this.initialized) {
|
|
18885
19053
|
await this.initialize();
|
|
18886
19054
|
}
|
|
19055
|
+
if (this.loadingPromise) {
|
|
19056
|
+
await this.loadingPromise;
|
|
19057
|
+
}
|
|
18887
19058
|
const startTime = performance.now();
|
|
18888
19059
|
const limit = options.limit || 10;
|
|
18889
19060
|
const results = [];
|
|
@@ -18909,13 +19080,60 @@ var init_pattern_store = __esm({
|
|
|
18909
19080
|
}
|
|
18910
19081
|
}
|
|
18911
19082
|
}
|
|
19083
|
+
if (typeof query === "string" && query.trim() && this.sqliteStore) {
|
|
19084
|
+
try {
|
|
19085
|
+
const ftsResults = this.sqliteStore.searchFTS(query, limit * 2);
|
|
19086
|
+
if (ftsResults.length > 0) {
|
|
19087
|
+
const ftsScoreMap = new Map(ftsResults.map((r54) => [r54.id, r54.ftsScore]));
|
|
19088
|
+
const existingIds = new Set(results.map((r54) => r54.pattern.id));
|
|
19089
|
+
for (const result of results) {
|
|
19090
|
+
const ftsScore = ftsScoreMap.get(result.pattern.id);
|
|
19091
|
+
if (ftsScore !== void 0) {
|
|
19092
|
+
result.score = 0.75 * result.score + 0.25 * ftsScore;
|
|
19093
|
+
}
|
|
19094
|
+
}
|
|
19095
|
+
for (const ftsResult of ftsResults) {
|
|
19096
|
+
if (existingIds.has(ftsResult.id)) continue;
|
|
19097
|
+
const pattern = await this.get(ftsResult.id);
|
|
19098
|
+
if (pattern && this.matchesFilters(pattern, options)) {
|
|
19099
|
+
const reuseInfo = this.calculateReuseInfo(pattern, ftsResult.ftsScore);
|
|
19100
|
+
results.push({
|
|
19101
|
+
pattern,
|
|
19102
|
+
score: 0.5 * ftsResult.ftsScore,
|
|
19103
|
+
// FTS-only: exact keyword match is valuable
|
|
19104
|
+
matchType: "exact",
|
|
19105
|
+
similarity: ftsResult.ftsScore,
|
|
19106
|
+
canReuse: reuseInfo.canReuse,
|
|
19107
|
+
estimatedTokenSavings: reuseInfo.estimatedTokenSavings,
|
|
19108
|
+
reuseConfidence: reuseInfo.reuseConfidence
|
|
19109
|
+
});
|
|
19110
|
+
}
|
|
19111
|
+
}
|
|
19112
|
+
}
|
|
19113
|
+
} catch {
|
|
19114
|
+
}
|
|
19115
|
+
}
|
|
18912
19116
|
if (typeof query === "string" || results.length < limit) {
|
|
18913
19117
|
const textResults = await this.searchByText(
|
|
18914
19118
|
typeof query === "string" ? query : "",
|
|
18915
19119
|
options,
|
|
18916
19120
|
limit - results.length
|
|
18917
19121
|
);
|
|
18918
|
-
results.
|
|
19122
|
+
const existingIds = new Set(results.map((r54) => r54.pattern.id));
|
|
19123
|
+
for (const tr3 of textResults) {
|
|
19124
|
+
if (!existingIds.has(tr3.pattern.id)) {
|
|
19125
|
+
results.push(tr3);
|
|
19126
|
+
}
|
|
19127
|
+
}
|
|
19128
|
+
}
|
|
19129
|
+
const TEMPORAL_HALF_LIFE_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
19130
|
+
const now = Date.now();
|
|
19131
|
+
for (const result of results) {
|
|
19132
|
+
const lastUsed = result.pattern.lastUsedAt?.getTime() ?? result.pattern.createdAt.getTime();
|
|
19133
|
+
const ageMs = now - lastUsed;
|
|
19134
|
+
const decayFactor = Math.pow(0.5, ageMs / TEMPORAL_HALF_LIFE_MS);
|
|
19135
|
+
const effectiveDecay = result.pattern.usageCount > 0 ? decayFactor : 0.5;
|
|
19136
|
+
result.score = result.score * (0.7 + 0.3 * effectiveDecay);
|
|
18919
19137
|
}
|
|
18920
19138
|
results.sort((a37, b68) => b68.score - a37.score);
|
|
18921
19139
|
const finalResults = results.slice(0, limit);
|
|
@@ -19067,6 +19285,13 @@ var init_pattern_store = __esm({
|
|
|
19067
19285
|
qualityScore,
|
|
19068
19286
|
lastUsedAt: now
|
|
19069
19287
|
};
|
|
19288
|
+
if (this.sqliteStore) {
|
|
19289
|
+
try {
|
|
19290
|
+
this.sqliteStore.recordUsage(id, success);
|
|
19291
|
+
} catch (error) {
|
|
19292
|
+
console.warn(`[PatternStore] SQLite recordUsage failed for ${id}:`, toErrorMessage(error));
|
|
19293
|
+
}
|
|
19294
|
+
}
|
|
19070
19295
|
const promotionCheck = shouldPromotePattern(updated);
|
|
19071
19296
|
const shouldPromote = promotionCheck.meetsUsageCriteria && promotionCheck.meetsQualityCriteria && promotionCheck.meetsCoherenceCriteria;
|
|
19072
19297
|
if (shouldPromote && updated.tier === "short-term") {
|
|
@@ -19192,7 +19417,8 @@ var init_pattern_store = __esm({
|
|
|
19192
19417
|
continue;
|
|
19193
19418
|
}
|
|
19194
19419
|
if (pattern.tier === "short-term") {
|
|
19195
|
-
const
|
|
19420
|
+
const createdTime = pattern.createdAt instanceof Date ? pattern.createdAt.getTime() : new Date(pattern.createdAt).getTime();
|
|
19421
|
+
const ageMs = Date.now() - createdTime;
|
|
19196
19422
|
const isOld = ageMs > 7 * 24 * 60 * 60 * 1e3;
|
|
19197
19423
|
const isLowQuality = pattern.qualityScore < 0.2;
|
|
19198
19424
|
const isUnused = pattern.usageCount === 0 && ageMs > 24 * 60 * 60 * 1e3;
|
|
@@ -19830,9 +20056,9 @@ var init_opencode_installer = __esm({
|
|
|
19830
20056
|
// NPM package location
|
|
19831
20057
|
join32(__dirname3, "../../assets/opencode")
|
|
19832
20058
|
];
|
|
19833
|
-
for (const
|
|
19834
|
-
if (existsSync28(
|
|
19835
|
-
return
|
|
20059
|
+
for (const path37 of possiblePaths) {
|
|
20060
|
+
if (existsSync28(path37)) {
|
|
20061
|
+
return path37;
|
|
19836
20062
|
}
|
|
19837
20063
|
}
|
|
19838
20064
|
return join32(process.cwd(), ".opencode");
|
|
@@ -22312,47 +22538,47 @@ function saveIdMap(rvfPath, strToNum, nextLabel) {
|
|
|
22312
22538
|
};
|
|
22313
22539
|
writeFileSync31(idMapPath(rvfPath), JSON.stringify(data), "utf-8");
|
|
22314
22540
|
}
|
|
22315
|
-
function createRvfStore(
|
|
22541
|
+
function createRvfStore(path37, dimensions) {
|
|
22316
22542
|
const native = getNative();
|
|
22317
22543
|
if (!native) {
|
|
22318
22544
|
throw new Error(
|
|
22319
22545
|
"@ruvector/rvf-node is not available \u2014 install the package or check platform compatibility"
|
|
22320
22546
|
);
|
|
22321
22547
|
}
|
|
22322
|
-
const db = native.RvfDatabase.create(
|
|
22548
|
+
const db = native.RvfDatabase.create(path37, { dimension: dimensions });
|
|
22323
22549
|
const dim = db.dimension();
|
|
22324
22550
|
return new RvfNativeAdapterImpl(
|
|
22325
22551
|
db,
|
|
22326
|
-
|
|
22552
|
+
path37,
|
|
22327
22553
|
dim,
|
|
22328
22554
|
/* @__PURE__ */ new Map(),
|
|
22329
22555
|
/* @__PURE__ */ new Map(),
|
|
22330
22556
|
1
|
|
22331
22557
|
);
|
|
22332
22558
|
}
|
|
22333
|
-
function openRvfStore(
|
|
22559
|
+
function openRvfStore(path37) {
|
|
22334
22560
|
const native = getNative();
|
|
22335
22561
|
if (!native) {
|
|
22336
22562
|
throw new Error(
|
|
22337
22563
|
"@ruvector/rvf-node is not available \u2014 install the package or check platform compatibility"
|
|
22338
22564
|
);
|
|
22339
22565
|
}
|
|
22340
|
-
const db = native.RvfDatabase.open(
|
|
22566
|
+
const db = native.RvfDatabase.open(path37);
|
|
22341
22567
|
const dim = db.dimension();
|
|
22342
|
-
const { strToNum, numToStr, nextLabel } = loadIdMap(
|
|
22343
|
-
return new RvfNativeAdapterImpl(db,
|
|
22568
|
+
const { strToNum, numToStr, nextLabel } = loadIdMap(path37);
|
|
22569
|
+
return new RvfNativeAdapterImpl(db, path37, dim, strToNum, numToStr, nextLabel);
|
|
22344
22570
|
}
|
|
22345
|
-
function openRvfStoreReadonly(
|
|
22571
|
+
function openRvfStoreReadonly(path37) {
|
|
22346
22572
|
const native = getNative();
|
|
22347
22573
|
if (!native) {
|
|
22348
22574
|
throw new Error(
|
|
22349
22575
|
"@ruvector/rvf-node is not available \u2014 install the package or check platform compatibility"
|
|
22350
22576
|
);
|
|
22351
22577
|
}
|
|
22352
|
-
const db = native.RvfDatabase.openReadonly(
|
|
22578
|
+
const db = native.RvfDatabase.openReadonly(path37);
|
|
22353
22579
|
const dim = db.dimension();
|
|
22354
|
-
const { strToNum, numToStr, nextLabel } = loadIdMap(
|
|
22355
|
-
return new RvfNativeAdapterImpl(db,
|
|
22580
|
+
const { strToNum, numToStr, nextLabel } = loadIdMap(path37);
|
|
22581
|
+
return new RvfNativeAdapterImpl(db, path37, dim, strToNum, numToStr, nextLabel);
|
|
22356
22582
|
}
|
|
22357
22583
|
function isRvfNativeAvailable() {
|
|
22358
22584
|
return getNative() !== null;
|
|
@@ -23473,15 +23699,15 @@ var init_vitest_executor = __esm({
|
|
|
23473
23699
|
}
|
|
23474
23700
|
async getCoverageFromReport() {
|
|
23475
23701
|
try {
|
|
23476
|
-
const
|
|
23477
|
-
const
|
|
23702
|
+
const fs32 = await import("fs/promises");
|
|
23703
|
+
const path37 = await import("path");
|
|
23478
23704
|
const coverageDir = this.config.coverageDir || "coverage";
|
|
23479
|
-
const coverageFile =
|
|
23705
|
+
const coverageFile = path37.join(
|
|
23480
23706
|
this.config.cwd || process.cwd(),
|
|
23481
23707
|
coverageDir,
|
|
23482
23708
|
"coverage-summary.json"
|
|
23483
23709
|
);
|
|
23484
|
-
const content = await
|
|
23710
|
+
const content = await fs32.readFile(coverageFile, "utf-8");
|
|
23485
23711
|
const coverage = safeJsonParse(content);
|
|
23486
23712
|
return (coverage.total?.lines?.pct ?? 0) / 100;
|
|
23487
23713
|
} catch {
|
|
@@ -23533,14 +23759,14 @@ var init_test_selector = __esm({
|
|
|
23533
23759
|
{
|
|
23534
23760
|
sourcePattern: /^src\/(.+)\.ts$/,
|
|
23535
23761
|
toTestPaths: (match, _sourceFile) => {
|
|
23536
|
-
const
|
|
23762
|
+
const path37 = match[1];
|
|
23537
23763
|
return [
|
|
23538
|
-
`tests/unit/${
|
|
23539
|
-
`tests/unit/${
|
|
23540
|
-
`tests/${
|
|
23541
|
-
`tests/${
|
|
23542
|
-
`src/${
|
|
23543
|
-
`src/${
|
|
23764
|
+
`tests/unit/${path37}.test.ts`,
|
|
23765
|
+
`tests/unit/${path37}.spec.ts`,
|
|
23766
|
+
`tests/${path37}.test.ts`,
|
|
23767
|
+
`tests/${path37}.spec.ts`,
|
|
23768
|
+
`src/${path37}.test.ts`,
|
|
23769
|
+
`src/${path37}.spec.ts`
|
|
23544
23770
|
];
|
|
23545
23771
|
}
|
|
23546
23772
|
},
|
|
@@ -23548,11 +23774,11 @@ var init_test_selector = __esm({
|
|
|
23548
23774
|
{
|
|
23549
23775
|
sourcePattern: /^src\/(.+)\/index\.ts$/,
|
|
23550
23776
|
toTestPaths: (match, _sourceFile) => {
|
|
23551
|
-
const
|
|
23777
|
+
const path37 = match[1];
|
|
23552
23778
|
return [
|
|
23553
|
-
`tests/unit/${
|
|
23554
|
-
`tests/unit/${
|
|
23555
|
-
`tests/unit/${
|
|
23779
|
+
`tests/unit/${path37}.test.ts`,
|
|
23780
|
+
`tests/unit/${path37}/index.test.ts`,
|
|
23781
|
+
`tests/unit/${path37}.spec.ts`
|
|
23556
23782
|
];
|
|
23557
23783
|
}
|
|
23558
23784
|
},
|
|
@@ -23624,8 +23850,8 @@ var init_test_selector = __esm({
|
|
|
23624
23850
|
* Get tests for a specific list of changed files
|
|
23625
23851
|
*/
|
|
23626
23852
|
async selectTestsForFiles(files) {
|
|
23627
|
-
const changedFiles = files.map((
|
|
23628
|
-
path:
|
|
23853
|
+
const changedFiles = files.map((path37) => ({
|
|
23854
|
+
path: path37,
|
|
23629
23855
|
changeType: "modified"
|
|
23630
23856
|
}));
|
|
23631
23857
|
const { selectedTests, mappings, runAllTests, runAllReason } = await this.mapChangesToTests(changedFiles);
|
|
@@ -23651,7 +23877,7 @@ var init_test_selector = __esm({
|
|
|
23651
23877
|
const changedFiles = [];
|
|
23652
23878
|
for (const line of lines) {
|
|
23653
23879
|
const [status, ...pathParts] = line.split(" ");
|
|
23654
|
-
const
|
|
23880
|
+
const path37 = pathParts.join(" ");
|
|
23655
23881
|
let changeType;
|
|
23656
23882
|
let previousPath;
|
|
23657
23883
|
switch (status[0]) {
|
|
@@ -23666,13 +23892,13 @@ var init_test_selector = __esm({
|
|
|
23666
23892
|
break;
|
|
23667
23893
|
case "R":
|
|
23668
23894
|
changeType = "renamed";
|
|
23669
|
-
previousPath =
|
|
23895
|
+
previousPath = path37;
|
|
23670
23896
|
break;
|
|
23671
23897
|
default:
|
|
23672
23898
|
changeType = "modified";
|
|
23673
23899
|
}
|
|
23674
23900
|
changedFiles.push({
|
|
23675
|
-
path: changeType === "renamed" ? pathParts[1] ||
|
|
23901
|
+
path: changeType === "renamed" ? pathParts[1] || path37 : path37,
|
|
23676
23902
|
changeType,
|
|
23677
23903
|
previousPath
|
|
23678
23904
|
});
|
|
@@ -23749,8 +23975,8 @@ var init_test_selector = __esm({
|
|
|
23749
23975
|
/**
|
|
23750
23976
|
* Check if a file is a config file that should trigger full test run
|
|
23751
23977
|
*/
|
|
23752
|
-
isConfigFile(
|
|
23753
|
-
return /^(vitest\.config|jest\.config|tsconfig|package\.json)/.test(
|
|
23978
|
+
isConfigFile(path37) {
|
|
23979
|
+
return /^(vitest\.config|jest\.config|tsconfig|package\.json)/.test(path37);
|
|
23754
23980
|
}
|
|
23755
23981
|
async findTestsHeuristically(sourcePath) {
|
|
23756
23982
|
const baseName = basename7(sourcePath, ".ts").replace(/\.(tsx?|jsx?)$/, "");
|
|
@@ -23765,12 +23991,12 @@ var init_test_selector = __esm({
|
|
|
23765
23991
|
return this.filterExistingFiles(candidates);
|
|
23766
23992
|
}
|
|
23767
23993
|
async filterExistingFiles(files) {
|
|
23768
|
-
const
|
|
23994
|
+
const fs32 = await import("fs/promises");
|
|
23769
23995
|
const existing = [];
|
|
23770
23996
|
for (const file of files) {
|
|
23771
23997
|
try {
|
|
23772
23998
|
const fullPath = resolve11(this.cwd, file);
|
|
23773
|
-
await
|
|
23999
|
+
await fs32.access(fullPath);
|
|
23774
24000
|
existing.push(file);
|
|
23775
24001
|
} catch (error) {
|
|
23776
24002
|
console.debug("[TestSelector] File access check failed:", error instanceof Error ? error.message : error);
|
|
@@ -23810,8 +24036,8 @@ function createFlakyTracker(config) {
|
|
|
23810
24036
|
async function loadFlakyTracker(historyPath, config) {
|
|
23811
24037
|
const tracker = createFlakyTracker({ ...config, historyPath });
|
|
23812
24038
|
try {
|
|
23813
|
-
const
|
|
23814
|
-
const content = await
|
|
24039
|
+
const fs32 = await import("fs/promises");
|
|
24040
|
+
const content = await fs32.readFile(historyPath, "utf-8");
|
|
23815
24041
|
const records = safeJsonParse(content);
|
|
23816
24042
|
tracker.importHistory(records);
|
|
23817
24043
|
} catch (error) {
|
|
@@ -23820,9 +24046,9 @@ async function loadFlakyTracker(historyPath, config) {
|
|
|
23820
24046
|
return tracker;
|
|
23821
24047
|
}
|
|
23822
24048
|
async function saveFlakyTracker(tracker, historyPath) {
|
|
23823
|
-
const
|
|
24049
|
+
const fs32 = await import("fs/promises");
|
|
23824
24050
|
const history = tracker.exportHistory();
|
|
23825
|
-
await
|
|
24051
|
+
await fs32.writeFile(historyPath, JSON.stringify(history, null, 2));
|
|
23826
24052
|
}
|
|
23827
24053
|
var DEFAULT_CONFIG62, FlakyTestTracker;
|
|
23828
24054
|
var init_flaky_tracker = __esm({
|
|
@@ -24131,16 +24357,16 @@ var init_github_actions = __esm({
|
|
|
24131
24357
|
*/
|
|
24132
24358
|
async writeOutput(results) {
|
|
24133
24359
|
const output = this.generateOutput(results);
|
|
24134
|
-
const
|
|
24360
|
+
const fs32 = await import("fs/promises");
|
|
24135
24361
|
for (const annotation of output.annotations) {
|
|
24136
24362
|
this.writeAnnotation(annotation);
|
|
24137
24363
|
}
|
|
24138
24364
|
if (output.summary && process.env.GITHUB_STEP_SUMMARY) {
|
|
24139
|
-
await
|
|
24365
|
+
await fs32.appendFile(process.env.GITHUB_STEP_SUMMARY, output.summary);
|
|
24140
24366
|
}
|
|
24141
24367
|
if (process.env.GITHUB_OUTPUT) {
|
|
24142
24368
|
const outputLines = Object.entries(output.outputs).map(([key, value]) => `${key}=${value}`).join("\n");
|
|
24143
|
-
await
|
|
24369
|
+
await fs32.appendFile(process.env.GITHUB_OUTPUT, outputLines + "\n");
|
|
24144
24370
|
}
|
|
24145
24371
|
}
|
|
24146
24372
|
// --------------------------------------------------------------------------
|
|
@@ -24372,6 +24598,7 @@ var init_pipeline = __esm({
|
|
|
24372
24598
|
const startTime = Date.now();
|
|
24373
24599
|
let selectedTests = [];
|
|
24374
24600
|
let ranAllTests = this.config.runAllTests ?? false;
|
|
24601
|
+
const selectionStart = performance.now();
|
|
24375
24602
|
if (!ranAllTests) {
|
|
24376
24603
|
const selectionResult = await this.selector.selectAffectedTests();
|
|
24377
24604
|
if (selectionResult.runAllTests) {
|
|
@@ -24385,19 +24612,26 @@ var init_pipeline = __esm({
|
|
|
24385
24612
|
console.log(`[TestSchedulingPipeline] Selected ${selectedTests.length} affected tests`);
|
|
24386
24613
|
}
|
|
24387
24614
|
}
|
|
24615
|
+
const selectionMs = performance.now() - selectionStart;
|
|
24616
|
+
const executionStart = performance.now();
|
|
24388
24617
|
let phaseResults;
|
|
24389
24618
|
if (ranAllTests) {
|
|
24390
24619
|
phaseResults = await this.scheduler.run();
|
|
24391
24620
|
} else {
|
|
24392
24621
|
phaseResults = await this.runWithSelectedTests(selectedTests);
|
|
24393
24622
|
}
|
|
24623
|
+
const executionMs = performance.now() - executionStart;
|
|
24624
|
+
const analysisStart = performance.now();
|
|
24394
24625
|
const flakyAnalysis = this.flakyTracker.analyze();
|
|
24395
24626
|
if (this.config.flakyHistoryPath) {
|
|
24396
24627
|
await saveFlakyTracker(this.flakyTracker, this.config.flakyHistoryPath);
|
|
24397
24628
|
}
|
|
24629
|
+
const analysisMs = performance.now() - analysisStart;
|
|
24630
|
+
const reportingStart = performance.now();
|
|
24398
24631
|
if (this.ciEnvironment.isCI) {
|
|
24399
24632
|
await this.reporter.writeOutput(phaseResults);
|
|
24400
24633
|
}
|
|
24634
|
+
const reportingMs = performance.now() - reportingStart;
|
|
24401
24635
|
const totalDurationMs = Date.now() - startTime;
|
|
24402
24636
|
return {
|
|
24403
24637
|
phaseResults,
|
|
@@ -24405,7 +24639,8 @@ var init_pipeline = __esm({
|
|
|
24405
24639
|
ranAllTests,
|
|
24406
24640
|
flakyAnalysis,
|
|
24407
24641
|
ciEnvironment: this.ciEnvironment,
|
|
24408
|
-
totalDurationMs
|
|
24642
|
+
totalDurationMs,
|
|
24643
|
+
stepLatencies: { selectionMs, executionMs, analysisMs, reportingMs }
|
|
24409
24644
|
};
|
|
24410
24645
|
}
|
|
24411
24646
|
/**
|
|
@@ -26188,6 +26423,24 @@ var init_visual_security = __esm({
|
|
|
26188
26423
|
});
|
|
26189
26424
|
|
|
26190
26425
|
// src/learning/sqlite-persistence.ts
|
|
26426
|
+
function hashEmbedding(text, dimension = 384) {
|
|
26427
|
+
const embedding = new Array(dimension).fill(0);
|
|
26428
|
+
const normalized = text.toLowerCase().trim();
|
|
26429
|
+
for (let pass = 0; pass < 3; pass++) {
|
|
26430
|
+
for (let i58 = 0; i58 < normalized.length; i58++) {
|
|
26431
|
+
const charCode = normalized.charCodeAt(i58);
|
|
26432
|
+
const idx = charCode * (i58 + 1) * (pass + 1) % dimension;
|
|
26433
|
+
embedding[idx] += Math.sin(charCode * (pass + 1)) / (i58 + 1);
|
|
26434
|
+
}
|
|
26435
|
+
}
|
|
26436
|
+
const magnitude2 = Math.sqrt(embedding.reduce((sum, val) => sum + val * val, 0));
|
|
26437
|
+
if (magnitude2 > 0) {
|
|
26438
|
+
for (let i58 = 0; i58 < dimension; i58++) {
|
|
26439
|
+
embedding[i58] /= magnitude2;
|
|
26440
|
+
}
|
|
26441
|
+
}
|
|
26442
|
+
return embedding;
|
|
26443
|
+
}
|
|
26191
26444
|
function createSQLitePatternStore(config = {}) {
|
|
26192
26445
|
return new SQLitePatternStore(config);
|
|
26193
26446
|
}
|
|
@@ -26200,6 +26453,7 @@ var init_sqlite_persistence = __esm({
|
|
|
26200
26453
|
init_safe_json();
|
|
26201
26454
|
init_error_utils();
|
|
26202
26455
|
init_unified_memory();
|
|
26456
|
+
init_real_embeddings();
|
|
26203
26457
|
DEFAULT_SQLITE_CONFIG = {
|
|
26204
26458
|
// LEGACY: Ignored when useUnified=true (the default). All data goes to memory.db
|
|
26205
26459
|
dbPath: ".agentic-qe/memory.db",
|
|
@@ -26233,11 +26487,11 @@ var init_sqlite_persistence = __esm({
|
|
|
26233
26487
|
this.db = this.unifiedMemory.getDatabase();
|
|
26234
26488
|
console.log(`[SQLitePatternStore] Using unified storage: ${this.unifiedMemory.getDbPath()}`);
|
|
26235
26489
|
} else {
|
|
26236
|
-
const
|
|
26237
|
-
const
|
|
26238
|
-
const dir =
|
|
26239
|
-
if (!
|
|
26240
|
-
|
|
26490
|
+
const path37 = await import("path");
|
|
26491
|
+
const fs32 = await import("fs");
|
|
26492
|
+
const dir = path37.dirname(this.config.dbPath);
|
|
26493
|
+
if (!fs32.existsSync(dir)) {
|
|
26494
|
+
fs32.mkdirSync(dir, { recursive: true });
|
|
26241
26495
|
}
|
|
26242
26496
|
this.db = openDatabase(this.config.dbPath);
|
|
26243
26497
|
this.db.pragma(`mmap_size = ${this.config.mmapSize}`);
|
|
@@ -26332,6 +26586,31 @@ var init_sqlite_persistence = __esm({
|
|
|
26332
26586
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_patterns_unique_name_domain_type
|
|
26333
26587
|
ON qe_patterns(name, qe_domain, pattern_type);
|
|
26334
26588
|
|
|
26589
|
+
-- FTS5 full-text search index for hybrid vector/text search
|
|
26590
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS qe_patterns_fts USING fts5(
|
|
26591
|
+
name, description, pattern_type, qe_domain,
|
|
26592
|
+
content='qe_patterns',
|
|
26593
|
+
content_rowid='rowid'
|
|
26594
|
+
);
|
|
26595
|
+
|
|
26596
|
+
-- FTS5 triggers to keep index in sync
|
|
26597
|
+
CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_insert AFTER INSERT ON qe_patterns BEGIN
|
|
26598
|
+
INSERT INTO qe_patterns_fts(rowid, name, description, pattern_type, qe_domain)
|
|
26599
|
+
VALUES (new.rowid, new.name, new.description, new.pattern_type, new.qe_domain);
|
|
26600
|
+
END;
|
|
26601
|
+
|
|
26602
|
+
CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_delete AFTER DELETE ON qe_patterns BEGIN
|
|
26603
|
+
INSERT INTO qe_patterns_fts(qe_patterns_fts, rowid, name, description, pattern_type, qe_domain)
|
|
26604
|
+
VALUES ('delete', old.rowid, old.name, old.description, old.pattern_type, old.qe_domain);
|
|
26605
|
+
END;
|
|
26606
|
+
|
|
26607
|
+
CREATE TRIGGER IF NOT EXISTS qe_patterns_fts_update AFTER UPDATE ON qe_patterns BEGIN
|
|
26608
|
+
INSERT INTO qe_patterns_fts(qe_patterns_fts, rowid, name, description, pattern_type, qe_domain)
|
|
26609
|
+
VALUES ('delete', old.rowid, old.name, old.description, old.pattern_type, old.qe_domain);
|
|
26610
|
+
INSERT INTO qe_patterns_fts(rowid, name, description, pattern_type, qe_domain)
|
|
26611
|
+
VALUES (new.rowid, new.name, new.description, new.pattern_type, new.qe_domain);
|
|
26612
|
+
END;
|
|
26613
|
+
|
|
26335
26614
|
-- Indexes for performance
|
|
26336
26615
|
CREATE INDEX IF NOT EXISTS idx_patterns_domain ON qe_patterns(qe_domain);
|
|
26337
26616
|
CREATE INDEX IF NOT EXISTS idx_patterns_type ON qe_patterns(pattern_type);
|
|
@@ -26394,10 +26673,22 @@ var init_sqlite_persistence = __esm({
|
|
|
26394
26673
|
prepareStatements() {
|
|
26395
26674
|
if (!this.db) throw new Error("Database not initialized");
|
|
26396
26675
|
this.prepared.set("insertPattern", this.db.prepare(`
|
|
26397
|
-
INSERT
|
|
26676
|
+
INSERT INTO qe_patterns (
|
|
26398
26677
|
id, pattern_type, qe_domain, domain, name, description,
|
|
26399
26678
|
confidence, tier, template_json, context_json
|
|
26400
26679
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
26680
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
26681
|
+
confidence = excluded.confidence,
|
|
26682
|
+
tier = excluded.tier,
|
|
26683
|
+
template_json = excluded.template_json,
|
|
26684
|
+
context_json = excluded.context_json,
|
|
26685
|
+
updated_at = datetime('now')
|
|
26686
|
+
ON CONFLICT(name, qe_domain, pattern_type) DO UPDATE SET
|
|
26687
|
+
confidence = excluded.confidence,
|
|
26688
|
+
tier = excluded.tier,
|
|
26689
|
+
template_json = excluded.template_json,
|
|
26690
|
+
context_json = excluded.context_json,
|
|
26691
|
+
updated_at = datetime('now')
|
|
26401
26692
|
`));
|
|
26402
26693
|
this.prepared.set("insertEmbedding", this.db.prepare(`
|
|
26403
26694
|
INSERT OR REPLACE INTO qe_pattern_embeddings (pattern_id, embedding, dimension, model)
|
|
@@ -26506,6 +26797,69 @@ var init_sqlite_persistence = __esm({
|
|
|
26506
26797
|
}
|
|
26507
26798
|
return rows.map((row) => this.rowToPattern(row));
|
|
26508
26799
|
}
|
|
26800
|
+
/**
|
|
26801
|
+
* FTS5 full-text search for patterns.
|
|
26802
|
+
* Returns pattern IDs with BM25 relevance scores.
|
|
26803
|
+
*/
|
|
26804
|
+
searchFTS(query, limit = 20) {
|
|
26805
|
+
if (!this.db) throw new Error("Database not initialized");
|
|
26806
|
+
if (!query.trim()) return [];
|
|
26807
|
+
const sanitized = '"' + query.replace(/"/g, '""') + '"';
|
|
26808
|
+
const start = performance.now();
|
|
26809
|
+
try {
|
|
26810
|
+
const rows = this.db.prepare(`
|
|
26811
|
+
SELECT p.id, rank AS fts_score
|
|
26812
|
+
FROM qe_patterns_fts fts
|
|
26813
|
+
JOIN qe_patterns p ON p.rowid = fts.rowid
|
|
26814
|
+
WHERE qe_patterns_fts MATCH ?
|
|
26815
|
+
ORDER BY rank
|
|
26816
|
+
LIMIT ?
|
|
26817
|
+
`).all(sanitized, limit);
|
|
26818
|
+
const elapsed = performance.now() - start;
|
|
26819
|
+
if (elapsed > 50) {
|
|
26820
|
+
console.warn(`[FTS5] searchFTS took ${elapsed.toFixed(1)}ms (results=${rows.length})`);
|
|
26821
|
+
}
|
|
26822
|
+
this._lastFtsLatencyMs = elapsed;
|
|
26823
|
+
const maxAbsScore = Math.max(...rows.map((r54) => Math.abs(r54.fts_score)), 1);
|
|
26824
|
+
return rows.map((r54) => ({
|
|
26825
|
+
id: r54.id,
|
|
26826
|
+
ftsScore: Math.abs(r54.fts_score) / maxAbsScore
|
|
26827
|
+
}));
|
|
26828
|
+
} catch {
|
|
26829
|
+
return [];
|
|
26830
|
+
}
|
|
26831
|
+
}
|
|
26832
|
+
/** Last FTS5 search latency in ms, for instrumentation */
|
|
26833
|
+
_lastFtsLatencyMs = 0;
|
|
26834
|
+
get lastFtsLatencyMs() {
|
|
26835
|
+
return this._lastFtsLatencyMs;
|
|
26836
|
+
}
|
|
26837
|
+
/**
|
|
26838
|
+
* Ghost pattern check: find patterns in SQLite that have no embeddings.
|
|
26839
|
+
* Used by aqe_health to detect data integrity issues.
|
|
26840
|
+
*/
|
|
26841
|
+
getGhostPatternCount() {
|
|
26842
|
+
if (!this.db) throw new Error("Database not initialized");
|
|
26843
|
+
const total = this.db.prepare(
|
|
26844
|
+
`SELECT COUNT(*) as c FROM qe_patterns WHERE id NOT LIKE 'bench-%'`
|
|
26845
|
+
).get().c;
|
|
26846
|
+
const ghostCount = this.db.prepare(`
|
|
26847
|
+
SELECT COUNT(*) as c FROM qe_patterns p
|
|
26848
|
+
WHERE p.id NOT LIKE 'bench-%'
|
|
26849
|
+
AND p.id NOT IN (SELECT pattern_id FROM qe_pattern_embeddings)
|
|
26850
|
+
`).get().c;
|
|
26851
|
+
const sampleGhosts = this.db.prepare(`
|
|
26852
|
+
SELECT p.id FROM qe_patterns p
|
|
26853
|
+
WHERE p.id NOT LIKE 'bench-%'
|
|
26854
|
+
AND p.id NOT IN (SELECT pattern_id FROM qe_pattern_embeddings)
|
|
26855
|
+
LIMIT 10
|
|
26856
|
+
`).all();
|
|
26857
|
+
return {
|
|
26858
|
+
total,
|
|
26859
|
+
withoutEmbeddings: ghostCount,
|
|
26860
|
+
sampleGhostIds: sampleGhosts.map((g67) => g67.id)
|
|
26861
|
+
};
|
|
26862
|
+
}
|
|
26509
26863
|
/**
|
|
26510
26864
|
* Get all embeddings for HNSW indexing
|
|
26511
26865
|
*/
|
|
@@ -26838,6 +27192,95 @@ var init_sqlite_persistence = __esm({
|
|
|
26838
27192
|
};
|
|
26839
27193
|
}
|
|
26840
27194
|
}
|
|
27195
|
+
/**
|
|
27196
|
+
* Backfill embeddings for patterns that don't have them.
|
|
27197
|
+
* Uses real all-MiniLM-L6-v2 transformer embeddings via @xenova/transformers.
|
|
27198
|
+
* Falls back to hash-based embeddings if ONNX is unavailable.
|
|
27199
|
+
* Skips bench/test patterns (id LIKE 'bench-%').
|
|
27200
|
+
*
|
|
27201
|
+
* @param batchSize - Patterns per inference batch (default: 32, matches model batch size)
|
|
27202
|
+
* @returns Stats about the backfill operation
|
|
27203
|
+
*/
|
|
27204
|
+
async backfillEmbeddings(batchSize = 32) {
|
|
27205
|
+
if (!this.db) throw new Error("Database not initialized");
|
|
27206
|
+
const dimension = getEmbeddingDimension();
|
|
27207
|
+
const patternsWithout = this.db.prepare(`
|
|
27208
|
+
SELECT p.id, p.name, p.description, p.pattern_type, p.qe_domain
|
|
27209
|
+
FROM qe_patterns p
|
|
27210
|
+
WHERE p.id NOT IN (SELECT pattern_id FROM qe_pattern_embeddings)
|
|
27211
|
+
AND p.id NOT LIKE 'bench-%'
|
|
27212
|
+
ORDER BY p.quality_score DESC
|
|
27213
|
+
`).all();
|
|
27214
|
+
const alreadyHad = this.db.prepare(`
|
|
27215
|
+
SELECT COUNT(*) as c FROM qe_pattern_embeddings
|
|
27216
|
+
`).get();
|
|
27217
|
+
if (patternsWithout.length === 0) {
|
|
27218
|
+
console.log(`[SQLitePatternStore] Backfill: all patterns already have embeddings (${alreadyHad.c} total)`);
|
|
27219
|
+
return { processed: 0, skipped: 0, errors: 0, alreadyHad: alreadyHad.c, method: "transformer" };
|
|
27220
|
+
}
|
|
27221
|
+
console.log(`[SQLitePatternStore] Backfill: ${patternsWithout.length} patterns need embeddings (${alreadyHad.c} already have)`);
|
|
27222
|
+
const insertEmbedding = this.prepared.get("insertEmbedding");
|
|
27223
|
+
if (!insertEmbedding) {
|
|
27224
|
+
throw new Error("Prepared statements not ready");
|
|
27225
|
+
}
|
|
27226
|
+
let processed = 0;
|
|
27227
|
+
let skipped = 0;
|
|
27228
|
+
let errors = 0;
|
|
27229
|
+
let method = "transformer";
|
|
27230
|
+
for (let i58 = 0; i58 < patternsWithout.length; i58 += batchSize) {
|
|
27231
|
+
const batch = patternsWithout.slice(i58, i58 + batchSize);
|
|
27232
|
+
const textsWithIds = [];
|
|
27233
|
+
for (const pattern of batch) {
|
|
27234
|
+
const text = [
|
|
27235
|
+
pattern.name,
|
|
27236
|
+
pattern.description,
|
|
27237
|
+
pattern.pattern_type,
|
|
27238
|
+
pattern.qe_domain
|
|
27239
|
+
].filter(Boolean).join(" ");
|
|
27240
|
+
if (!text.trim()) {
|
|
27241
|
+
skipped++;
|
|
27242
|
+
continue;
|
|
27243
|
+
}
|
|
27244
|
+
textsWithIds.push({ id: pattern.id, text });
|
|
27245
|
+
}
|
|
27246
|
+
if (textsWithIds.length === 0) continue;
|
|
27247
|
+
let embeddings;
|
|
27248
|
+
try {
|
|
27249
|
+
embeddings = await computeBatchEmbeddings(textsWithIds.map((t50) => t50.text));
|
|
27250
|
+
} catch (e20) {
|
|
27251
|
+
console.warn(`[SQLitePatternStore] Transformer unavailable, falling back to hash embeddings: ${toErrorMessage(e20)}`);
|
|
27252
|
+
method = "hash-fallback";
|
|
27253
|
+
embeddings = textsWithIds.map((t50) => hashEmbedding(t50.text, dimension));
|
|
27254
|
+
}
|
|
27255
|
+
const embeddingTag = method === "transformer" ? "transformer-backfill" : "hash-backfill";
|
|
27256
|
+
const insertBatch = this.db.transaction(() => {
|
|
27257
|
+
for (let j52 = 0; j52 < textsWithIds.length; j52++) {
|
|
27258
|
+
try {
|
|
27259
|
+
const embedding = embeddings[j52];
|
|
27260
|
+
if (!embedding || embedding.length !== dimension) {
|
|
27261
|
+
errors++;
|
|
27262
|
+
continue;
|
|
27263
|
+
}
|
|
27264
|
+
const buffer = Buffer.from(new Float32Array(embedding).buffer);
|
|
27265
|
+
insertEmbedding.run(textsWithIds[j52].id, buffer, dimension, embeddingTag);
|
|
27266
|
+
processed++;
|
|
27267
|
+
} catch (e20) {
|
|
27268
|
+
errors++;
|
|
27269
|
+
if (errors <= 3) {
|
|
27270
|
+
console.warn(`[SQLitePatternStore] Backfill error for ${textsWithIds[j52].id}:`, toErrorMessage(e20));
|
|
27271
|
+
}
|
|
27272
|
+
}
|
|
27273
|
+
}
|
|
27274
|
+
});
|
|
27275
|
+
insertBatch();
|
|
27276
|
+
const progress = Math.min(i58 + batchSize, patternsWithout.length);
|
|
27277
|
+
if (progress % 100 === 0 || progress >= patternsWithout.length) {
|
|
27278
|
+
console.log(`[SQLitePatternStore] Backfill progress: ${progress}/${patternsWithout.length}`);
|
|
27279
|
+
}
|
|
27280
|
+
}
|
|
27281
|
+
console.log(`[SQLitePatternStore] Backfill complete (${method}): ${processed} processed, ${skipped} skipped, ${errors} errors`);
|
|
27282
|
+
return { processed, skipped, errors, alreadyHad: alreadyHad.c, method };
|
|
27283
|
+
}
|
|
26841
27284
|
/**
|
|
26842
27285
|
* Close the database
|
|
26843
27286
|
*/
|
|
@@ -29398,7 +29841,7 @@ var init_shared_rvf_dual_writer = __esm({
|
|
|
29398
29841
|
|
|
29399
29842
|
// src/workflows/browser/workflow-loader.ts
|
|
29400
29843
|
import { readFile as readFile9, readdir as readdir4 } from "fs/promises";
|
|
29401
|
-
import { join as
|
|
29844
|
+
import { join as join66, basename as basename10 } from "path";
|
|
29402
29845
|
import { parse as parseYaml2 } from "yaml";
|
|
29403
29846
|
function interpolateVariables(template, variables) {
|
|
29404
29847
|
return template.replace(/\{\{([^}]+)\}\}/g, (match, key) => {
|
|
@@ -29432,7 +29875,7 @@ var init_workflow_loader = __esm({
|
|
|
29432
29875
|
templatesDir;
|
|
29433
29876
|
cache = /* @__PURE__ */ new Map();
|
|
29434
29877
|
constructor(templatesDir) {
|
|
29435
|
-
this.templatesDir = templatesDir ||
|
|
29878
|
+
this.templatesDir = templatesDir || join66(__dirname, "templates");
|
|
29436
29879
|
}
|
|
29437
29880
|
/**
|
|
29438
29881
|
* Load a workflow template by name
|
|
@@ -29442,7 +29885,7 @@ var init_workflow_loader = __esm({
|
|
|
29442
29885
|
return this.cache.get(templateName);
|
|
29443
29886
|
}
|
|
29444
29887
|
try {
|
|
29445
|
-
const templatePath =
|
|
29888
|
+
const templatePath = join66(this.templatesDir, `${templateName}.yaml`);
|
|
29446
29889
|
const content = await readFile9(templatePath, "utf-8");
|
|
29447
29890
|
const workflow = parseYaml2(content);
|
|
29448
29891
|
const validation = await this.validate(workflow);
|
|
@@ -29583,7 +30026,7 @@ ${validation.errors.join("\n")}`
|
|
|
29583
30026
|
*/
|
|
29584
30027
|
async getMetadata(templateName) {
|
|
29585
30028
|
try {
|
|
29586
|
-
const templatePath =
|
|
30029
|
+
const templatePath = join66(this.templatesDir, `${templateName}.yaml`);
|
|
29587
30030
|
const content = await readFile9(templatePath, "utf-8");
|
|
29588
30031
|
const workflow = parseYaml2(content);
|
|
29589
30032
|
return {
|
|
@@ -29828,7 +30271,7 @@ var init_browser_workflow = __esm({
|
|
|
29828
30271
|
|
|
29829
30272
|
// src/cli/index.ts
|
|
29830
30273
|
init_error_utils();
|
|
29831
|
-
import { Command as
|
|
30274
|
+
import { Command as Command21 } from "commander";
|
|
29832
30275
|
import chalk33 from "chalk";
|
|
29833
30276
|
|
|
29834
30277
|
// src/kernel/kernel.ts
|
|
@@ -44014,6 +44457,103 @@ var TestQualityGate = class {
|
|
|
44014
44457
|
}
|
|
44015
44458
|
};
|
|
44016
44459
|
|
|
44460
|
+
// src/learning/opd-remediation.ts
|
|
44461
|
+
function generateRemediationHints(pattern, executionHistory, config) {
|
|
44462
|
+
const hints = [];
|
|
44463
|
+
const maxHints = config?.maxHintsPerPattern ?? 3;
|
|
44464
|
+
const totalCount = executionHistory.length;
|
|
44465
|
+
if (totalCount === 0) return hints;
|
|
44466
|
+
const failCount = executionHistory.filter((e20) => !e20.success).length;
|
|
44467
|
+
const failRate = failCount / totalCount;
|
|
44468
|
+
if (failRate > 0.2 && failRate < 0.8 && totalCount >= 3) {
|
|
44469
|
+
hints.push({
|
|
44470
|
+
patternId: pattern.id,
|
|
44471
|
+
observation: `Pattern "${pattern.name}" fails ${(failRate * 100).toFixed(0)}% of the time (${failCount}/${totalCount} executions)`,
|
|
44472
|
+
diagnosis: "Intermittent failures suggest timing dependencies, external service flakiness, or non-deterministic behavior",
|
|
44473
|
+
suggestion: "Add retry logic, mock external dependencies, or add explicit waits for async operations",
|
|
44474
|
+
confidence: Math.min(0.9, 0.5 + totalCount * 0.05),
|
|
44475
|
+
category: "flaky"
|
|
44476
|
+
});
|
|
44477
|
+
}
|
|
44478
|
+
if (failRate >= 0.8 && totalCount >= 2) {
|
|
44479
|
+
hints.push({
|
|
44480
|
+
patternId: pattern.id,
|
|
44481
|
+
observation: `Pattern "${pattern.name}" fails ${(failRate * 100).toFixed(0)}% of executions \u2014 effectively broken`,
|
|
44482
|
+
diagnosis: "Consistent failures indicate the pattern logic is incorrect or the target code changed",
|
|
44483
|
+
suggestion: "Review the pattern against current code. Consider quarantining and creating a replacement pattern.",
|
|
44484
|
+
confidence: 0.85,
|
|
44485
|
+
category: "false-positive"
|
|
44486
|
+
});
|
|
44487
|
+
}
|
|
44488
|
+
if (totalCount >= 5) {
|
|
44489
|
+
const recentFails = executionHistory.slice(-3).filter((e20) => !e20.success).length;
|
|
44490
|
+
const earlySuccesses = executionHistory.slice(0, Math.max(1, totalCount - 3)).filter((e20) => e20.success).length;
|
|
44491
|
+
if (recentFails >= 2 && earlySuccesses >= 2) {
|
|
44492
|
+
hints.push({
|
|
44493
|
+
patternId: pattern.id,
|
|
44494
|
+
observation: `Pattern "${pattern.name}" worked previously but now fails consistently`,
|
|
44495
|
+
diagnosis: "Recent code changes likely broke compatibility with this pattern",
|
|
44496
|
+
suggestion: "Update pattern to match current code structure. Check git log for recent changes to affected files.",
|
|
44497
|
+
confidence: 0.8,
|
|
44498
|
+
category: "outdated"
|
|
44499
|
+
});
|
|
44500
|
+
}
|
|
44501
|
+
}
|
|
44502
|
+
if (pattern.description && pattern.description.length < 20 && failRate > 0.3) {
|
|
44503
|
+
hints.push({
|
|
44504
|
+
patternId: pattern.id,
|
|
44505
|
+
observation: `Pattern "${pattern.name}" has a vague description and high failure rate`,
|
|
44506
|
+
diagnosis: "Pattern may be too broadly scoped \u2014 matching contexts where it does not apply",
|
|
44507
|
+
suggestion: "Narrow the pattern scope by adding specific tags, domain constraints, or more detailed matching criteria",
|
|
44508
|
+
confidence: 0.6,
|
|
44509
|
+
category: "wrong-scope"
|
|
44510
|
+
});
|
|
44511
|
+
}
|
|
44512
|
+
const feedbackMessages = executionHistory.filter((e20) => !e20.success && e20.feedback).map((e20) => e20.feedback).slice(-3);
|
|
44513
|
+
if (feedbackMessages.length > 0) {
|
|
44514
|
+
const commonWords = findCommonKeywords(feedbackMessages);
|
|
44515
|
+
if (commonWords.length > 0) {
|
|
44516
|
+
hints.push({
|
|
44517
|
+
patternId: pattern.id,
|
|
44518
|
+
observation: `Failure feedback contains recurring themes: ${commonWords.join(", ")}`,
|
|
44519
|
+
diagnosis: `Common failure keywords suggest a systematic issue: ${commonWords.slice(0, 3).join(", ")}`,
|
|
44520
|
+
suggestion: `Address the recurring "${commonWords[0]}" issue in the pattern logic or preconditions`,
|
|
44521
|
+
confidence: 0.65,
|
|
44522
|
+
category: "missing-context"
|
|
44523
|
+
});
|
|
44524
|
+
}
|
|
44525
|
+
}
|
|
44526
|
+
return hints.slice(0, maxHints);
|
|
44527
|
+
}
|
|
44528
|
+
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
44529
|
+
"the",
|
|
44530
|
+
"a",
|
|
44531
|
+
"an",
|
|
44532
|
+
"is",
|
|
44533
|
+
"was",
|
|
44534
|
+
"in",
|
|
44535
|
+
"to",
|
|
44536
|
+
"for",
|
|
44537
|
+
"of",
|
|
44538
|
+
"and",
|
|
44539
|
+
"or",
|
|
44540
|
+
"not",
|
|
44541
|
+
"with",
|
|
44542
|
+
"test",
|
|
44543
|
+
"error"
|
|
44544
|
+
]);
|
|
44545
|
+
function findCommonKeywords(feedbacks) {
|
|
44546
|
+
const wordCounts = /* @__PURE__ */ new Map();
|
|
44547
|
+
for (const feedback of feedbacks) {
|
|
44548
|
+
const words = feedback.toLowerCase().split(/\W+/).filter((w54) => w54.length > 2 && !STOP_WORDS.has(w54));
|
|
44549
|
+
const uniqueWords = new Set(words);
|
|
44550
|
+
for (const word of uniqueWords) {
|
|
44551
|
+
wordCounts.set(word, (wordCounts.get(word) ?? 0) + 1);
|
|
44552
|
+
}
|
|
44553
|
+
}
|
|
44554
|
+
return Array.from(wordCounts.entries()).filter(([, count]) => count >= 2).sort((a37, b68) => b68[1] - a37[1]).map(([word]) => word).slice(0, 5);
|
|
44555
|
+
}
|
|
44556
|
+
|
|
44017
44557
|
// src/domains/test-generation/pattern-injection/edge-case-injector.ts
|
|
44018
44558
|
var DEFAULT_INJECTION_CONFIG = {
|
|
44019
44559
|
topN: 3,
|
|
@@ -44179,6 +44719,7 @@ var EdgeCaseInjector = class {
|
|
|
44179
44719
|
}
|
|
44180
44720
|
/**
|
|
44181
44721
|
* Format selected patterns into a prompt context string.
|
|
44722
|
+
* Appends OPD remediation hints for patterns with low success rates.
|
|
44182
44723
|
*/
|
|
44183
44724
|
formatPromptContext(patterns) {
|
|
44184
44725
|
const lines = ["## Historical Edge Cases (from patterns that caught real bugs):"];
|
|
@@ -44188,8 +44729,36 @@ var EdgeCaseInjector = class {
|
|
|
44188
44729
|
const desc = p74.description || p74.name;
|
|
44189
44730
|
lines.push(`${i58 + 1}. [${tag}] ${desc}`);
|
|
44190
44731
|
}
|
|
44732
|
+
const weakPatterns = patterns.filter((p74) => p74.successRate < 0.5);
|
|
44733
|
+
const allHints = [];
|
|
44734
|
+
for (const wp of weakPatterns) {
|
|
44735
|
+
const hints = generateRemediationHints(
|
|
44736
|
+
{ id: wp.key, name: wp.name, description: wp.description, successRate: wp.successRate, usageCount: wp.usageCount, confidence: wp.confidence, tags: wp.tags },
|
|
44737
|
+
this.buildSyntheticHistory(wp)
|
|
44738
|
+
);
|
|
44739
|
+
allHints.push(...hints);
|
|
44740
|
+
}
|
|
44741
|
+
if (allHints.length > 0) {
|
|
44742
|
+
lines.push("");
|
|
44743
|
+
lines.push("## Remediation Notes (patterns with known issues):");
|
|
44744
|
+
for (const hint of allHints.slice(0, 3)) {
|
|
44745
|
+
lines.push(`- [${hint.category}] ${hint.suggestion}`);
|
|
44746
|
+
}
|
|
44747
|
+
}
|
|
44191
44748
|
return lines.join("\n");
|
|
44192
44749
|
}
|
|
44750
|
+
/**
|
|
44751
|
+
* Build a synthetic execution history from pattern metadata.
|
|
44752
|
+
* Used to feed into OPD remediation when full history is unavailable.
|
|
44753
|
+
*/
|
|
44754
|
+
buildSyntheticHistory(pattern) {
|
|
44755
|
+
const total = Math.max(pattern.usageCount, 1);
|
|
44756
|
+
const successes = Math.round(total * pattern.successRate);
|
|
44757
|
+
const history = [];
|
|
44758
|
+
for (let i58 = 0; i58 < successes; i58++) history.push({ success: true });
|
|
44759
|
+
for (let i58 = 0; i58 < total - successes; i58++) history.push({ success: false });
|
|
44760
|
+
return history;
|
|
44761
|
+
}
|
|
44193
44762
|
/**
|
|
44194
44763
|
* Infer a short tag from pattern name when no tags are available.
|
|
44195
44764
|
*/
|
|
@@ -44331,7 +44900,7 @@ function resolveRequest(request) {
|
|
|
44331
44900
|
import { execSync } from "child_process";
|
|
44332
44901
|
import * as fs3 from "fs";
|
|
44333
44902
|
import * as path3 from "path";
|
|
44334
|
-
import * as
|
|
44903
|
+
import * as os2 from "os";
|
|
44335
44904
|
var COMPILE_COMMANDS = {
|
|
44336
44905
|
typescript: { check: "npx tsc --noEmit --strict", fileExt: ".ts" },
|
|
44337
44906
|
java: { check: "javac -d /dev/null", fileExt: ".java" },
|
|
@@ -44352,7 +44921,7 @@ var CompilationValidator = class {
|
|
|
44352
44921
|
suggestions: [`No compilation check available for ${language} -- syntax validation skipped`]
|
|
44353
44922
|
};
|
|
44354
44923
|
}
|
|
44355
|
-
const tmpDir = fs3.mkdtempSync(path3.join(
|
|
44924
|
+
const tmpDir = fs3.mkdtempSync(path3.join(os2.tmpdir(), "aqe-compile-"));
|
|
44356
44925
|
const tmpFile = path3.join(tmpDir, `test_validation${config.fileExt}`);
|
|
44357
44926
|
try {
|
|
44358
44927
|
fs3.writeFileSync(tmpFile, code, "utf-8");
|
|
@@ -46858,7 +47427,9 @@ var QE_HOOK_EVENTS = {
|
|
|
46858
47427
|
// Pattern learning
|
|
46859
47428
|
PatternLearned: "qe:pattern-learned",
|
|
46860
47429
|
PatternApplied: "qe:pattern-applied",
|
|
46861
|
-
PatternPromoted: "qe:pattern-promoted"
|
|
47430
|
+
PatternPromoted: "qe:pattern-promoted",
|
|
47431
|
+
// Session lifecycle
|
|
47432
|
+
PreCompaction: "qe:pre-compaction"
|
|
46862
47433
|
};
|
|
46863
47434
|
function createQEHookHandlers(reasoningBank) {
|
|
46864
47435
|
return {
|
|
@@ -47242,6 +47813,32 @@ Factors: ${riskFactors.join("\n- ")}`,
|
|
|
47242
47813
|
success: true,
|
|
47243
47814
|
data: { patternId, newTier }
|
|
47244
47815
|
};
|
|
47816
|
+
},
|
|
47817
|
+
// ========================================================================
|
|
47818
|
+
// Session Lifecycle Hooks
|
|
47819
|
+
// ========================================================================
|
|
47820
|
+
[QE_HOOK_EVENTS.PreCompaction]: async (ctx) => {
|
|
47821
|
+
const stats = { experiencesFlushed: 0, patternsPromoted: 0 };
|
|
47822
|
+
if (ctx.data?.experienceCaptureService) {
|
|
47823
|
+
const service = ctx.data.experienceCaptureService;
|
|
47824
|
+
const pendingCount = service.getPendingCount?.() ?? 0;
|
|
47825
|
+
if (pendingCount > 0) {
|
|
47826
|
+
const flushed = await service.flushPending?.();
|
|
47827
|
+
stats.experiencesFlushed = flushed ?? pendingCount;
|
|
47828
|
+
}
|
|
47829
|
+
}
|
|
47830
|
+
if (ctx.data?.patternLifecycleManager) {
|
|
47831
|
+
const manager = ctx.data.patternLifecycleManager;
|
|
47832
|
+
const promotionResult = manager.runPromotionSweep?.();
|
|
47833
|
+
if (promotionResult) {
|
|
47834
|
+
stats.patternsPromoted = promotionResult.promoted ?? 0;
|
|
47835
|
+
}
|
|
47836
|
+
}
|
|
47837
|
+
console.log("[QEHooks] Pre-compaction flush:", stats);
|
|
47838
|
+
return {
|
|
47839
|
+
success: true,
|
|
47840
|
+
data: stats
|
|
47841
|
+
};
|
|
47245
47842
|
}
|
|
47246
47843
|
};
|
|
47247
47844
|
}
|
|
@@ -50624,12 +51221,12 @@ var DeterministicGatewayIntegration = class {
|
|
|
50624
51221
|
/**
|
|
50625
51222
|
* Validate a single value against its schema
|
|
50626
51223
|
*/
|
|
50627
|
-
validateValue(value, schema,
|
|
51224
|
+
validateValue(value, schema, path37) {
|
|
50628
51225
|
const errors = [];
|
|
50629
51226
|
if (schema.required && (value === void 0 || value === null)) {
|
|
50630
51227
|
errors.push({
|
|
50631
|
-
path:
|
|
50632
|
-
message: `${
|
|
51228
|
+
path: path37,
|
|
51229
|
+
message: `${path37} is required`,
|
|
50633
51230
|
expected: schema.type,
|
|
50634
51231
|
received: "undefined"
|
|
50635
51232
|
});
|
|
@@ -50641,8 +51238,8 @@ var DeterministicGatewayIntegration = class {
|
|
|
50641
51238
|
const actualType = Array.isArray(value) ? "array" : typeof value;
|
|
50642
51239
|
if (actualType !== schema.type) {
|
|
50643
51240
|
errors.push({
|
|
50644
|
-
path:
|
|
50645
|
-
message: `${
|
|
51241
|
+
path: path37,
|
|
51242
|
+
message: `${path37} must be of type ${schema.type}`,
|
|
50646
51243
|
expected: schema.type,
|
|
50647
51244
|
received: actualType
|
|
50648
51245
|
});
|
|
@@ -50651,16 +51248,16 @@ var DeterministicGatewayIntegration = class {
|
|
|
50651
51248
|
if (schema.type === "string" && typeof value === "string") {
|
|
50652
51249
|
if (schema.minLength !== void 0 && value.length < schema.minLength) {
|
|
50653
51250
|
errors.push({
|
|
50654
|
-
path:
|
|
50655
|
-
message: `${
|
|
51251
|
+
path: path37,
|
|
51252
|
+
message: `${path37} must be at least ${schema.minLength} characters`,
|
|
50656
51253
|
expected: `minLength: ${schema.minLength}`,
|
|
50657
51254
|
received: `length: ${value.length}`
|
|
50658
51255
|
});
|
|
50659
51256
|
}
|
|
50660
51257
|
if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
|
|
50661
51258
|
errors.push({
|
|
50662
|
-
path:
|
|
50663
|
-
message: `${
|
|
51259
|
+
path: path37,
|
|
51260
|
+
message: `${path37} must be at most ${schema.maxLength} characters`,
|
|
50664
51261
|
expected: `maxLength: ${schema.maxLength}`,
|
|
50665
51262
|
received: `length: ${value.length}`
|
|
50666
51263
|
});
|
|
@@ -50668,8 +51265,8 @@ var DeterministicGatewayIntegration = class {
|
|
|
50668
51265
|
const patternRegex = schema.pattern ? createSafeRegex(schema.pattern) : null;
|
|
50669
51266
|
if (patternRegex && !patternRegex.test(value)) {
|
|
50670
51267
|
errors.push({
|
|
50671
|
-
path:
|
|
50672
|
-
message: `${
|
|
51268
|
+
path: path37,
|
|
51269
|
+
message: `${path37} must match pattern ${schema.pattern}`,
|
|
50673
51270
|
expected: `pattern: ${schema.pattern}`,
|
|
50674
51271
|
received: value
|
|
50675
51272
|
});
|
|
@@ -50678,16 +51275,16 @@ var DeterministicGatewayIntegration = class {
|
|
|
50678
51275
|
if (schema.type === "number" && typeof value === "number") {
|
|
50679
51276
|
if (schema.min !== void 0 && value < schema.min) {
|
|
50680
51277
|
errors.push({
|
|
50681
|
-
path:
|
|
50682
|
-
message: `${
|
|
51278
|
+
path: path37,
|
|
51279
|
+
message: `${path37} must be at least ${schema.min}`,
|
|
50683
51280
|
expected: `min: ${schema.min}`,
|
|
50684
51281
|
received: `${value}`
|
|
50685
51282
|
});
|
|
50686
51283
|
}
|
|
50687
51284
|
if (schema.max !== void 0 && value > schema.max) {
|
|
50688
51285
|
errors.push({
|
|
50689
|
-
path:
|
|
50690
|
-
message: `${
|
|
51286
|
+
path: path37,
|
|
51287
|
+
message: `${path37} must be at most ${schema.max}`,
|
|
50691
51288
|
expected: `max: ${schema.max}`,
|
|
50692
51289
|
received: `${value}`
|
|
50693
51290
|
});
|
|
@@ -50695,22 +51292,22 @@ var DeterministicGatewayIntegration = class {
|
|
|
50695
51292
|
}
|
|
50696
51293
|
if (schema.enum && !schema.enum.includes(value)) {
|
|
50697
51294
|
errors.push({
|
|
50698
|
-
path:
|
|
50699
|
-
message: `${
|
|
51295
|
+
path: path37,
|
|
51296
|
+
message: `${path37} must be one of: ${schema.enum.join(", ")}`,
|
|
50700
51297
|
expected: `enum: [${schema.enum.join(", ")}]`,
|
|
50701
51298
|
received: String(value)
|
|
50702
51299
|
});
|
|
50703
51300
|
}
|
|
50704
51301
|
if (schema.type === "array" && Array.isArray(value) && schema.items) {
|
|
50705
51302
|
value.forEach((item, index) => {
|
|
50706
|
-
const itemErrors = this.validateValue(item, schema.items, `${
|
|
51303
|
+
const itemErrors = this.validateValue(item, schema.items, `${path37}[${index}]`);
|
|
50707
51304
|
errors.push(...itemErrors);
|
|
50708
51305
|
});
|
|
50709
51306
|
}
|
|
50710
51307
|
if (schema.type === "object" && typeof value === "object" && schema.properties) {
|
|
50711
51308
|
const objValue = value;
|
|
50712
51309
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
50713
|
-
const propErrors = this.validateValue(objValue[propName], propSchema, `${
|
|
51310
|
+
const propErrors = this.validateValue(objValue[propName], propSchema, `${path37}.${propName}`);
|
|
50714
51311
|
errors.push(...propErrors);
|
|
50715
51312
|
}
|
|
50716
51313
|
}
|
|
@@ -60486,8 +61083,8 @@ var TestGenerationCoordinator = class extends BaseDomainCoordinator {
|
|
|
60486
61083
|
);
|
|
60487
61084
|
console.log("[TestGenerationCoordinator] QEFlashAttention initialized for test-similarity");
|
|
60488
61085
|
} catch (error) {
|
|
60489
|
-
console.
|
|
60490
|
-
|
|
61086
|
+
console.warn("[TestGenerationCoordinator] QEFlashAttention unavailable (optional native module), continuing without it:", toErrorMessage(error));
|
|
61087
|
+
this.flashAttention = null;
|
|
60491
61088
|
}
|
|
60492
61089
|
}
|
|
60493
61090
|
if (this.config.enableDecisionTransformer) {
|
|
@@ -60498,8 +61095,8 @@ var TestGenerationCoordinator = class extends BaseDomainCoordinator {
|
|
|
60498
61095
|
});
|
|
60499
61096
|
console.log("[TestGenerationCoordinator] DecisionTransformer created for test case selection");
|
|
60500
61097
|
} catch (error) {
|
|
60501
|
-
console.
|
|
60502
|
-
|
|
61098
|
+
console.warn("[TestGenerationCoordinator] DecisionTransformer unavailable (optional native module), continuing without it:", toErrorMessage(error));
|
|
61099
|
+
this.decisionTransformer = null;
|
|
60503
61100
|
}
|
|
60504
61101
|
}
|
|
60505
61102
|
this.subscribeToEvents();
|
|
@@ -64961,11 +65558,11 @@ var AgentBrowserCommandExecutor = class {
|
|
|
64961
65558
|
/**
|
|
64962
65559
|
* Take screenshot
|
|
64963
65560
|
*/
|
|
64964
|
-
screenshot(
|
|
65561
|
+
screenshot(path37, fullPage) {
|
|
64965
65562
|
const args = [];
|
|
64966
|
-
if (
|
|
65563
|
+
if (path37) args.push(path37);
|
|
64967
65564
|
if (fullPage) args.push("--full");
|
|
64968
|
-
if (!
|
|
65565
|
+
if (!path37) args.push("--json");
|
|
64969
65566
|
return this.execute("screenshot", args);
|
|
64970
65567
|
}
|
|
64971
65568
|
// ========================================================================
|
|
@@ -65043,14 +65640,14 @@ var AgentBrowserCommandExecutor = class {
|
|
|
65043
65640
|
/**
|
|
65044
65641
|
* Save browser state (cookies, storage)
|
|
65045
65642
|
*/
|
|
65046
|
-
saveState(
|
|
65047
|
-
return this.execute("state", ["save",
|
|
65643
|
+
saveState(path37) {
|
|
65644
|
+
return this.execute("state", ["save", path37]);
|
|
65048
65645
|
}
|
|
65049
65646
|
/**
|
|
65050
65647
|
* Load browser state
|
|
65051
65648
|
*/
|
|
65052
|
-
loadState(
|
|
65053
|
-
return this.execute("state", ["load",
|
|
65649
|
+
loadState(path37) {
|
|
65650
|
+
return this.execute("state", ["load", path37]);
|
|
65054
65651
|
}
|
|
65055
65652
|
// ========================================================================
|
|
65056
65653
|
// Trace recording
|
|
@@ -66327,9 +66924,9 @@ var AgentBrowserClient = class {
|
|
|
66327
66924
|
/**
|
|
66328
66925
|
* Save browser state (cookies, storage, etc.)
|
|
66329
66926
|
*/
|
|
66330
|
-
async saveState(
|
|
66927
|
+
async saveState(path37) {
|
|
66331
66928
|
try {
|
|
66332
|
-
const result = this.executor.saveState(
|
|
66929
|
+
const result = this.executor.saveState(path37);
|
|
66333
66930
|
if (!result.success) {
|
|
66334
66931
|
return err2(new BrowserError(result.error ?? "Save state failed", "SAVE_STATE_FAILED", "agent-browser"));
|
|
66335
66932
|
}
|
|
@@ -66348,9 +66945,9 @@ var AgentBrowserClient = class {
|
|
|
66348
66945
|
/**
|
|
66349
66946
|
* Load previously saved browser state
|
|
66350
66947
|
*/
|
|
66351
|
-
async loadState(
|
|
66948
|
+
async loadState(path37) {
|
|
66352
66949
|
try {
|
|
66353
|
-
const result = this.executor.loadState(
|
|
66950
|
+
const result = this.executor.loadState(path37);
|
|
66354
66951
|
if (!result.success) {
|
|
66355
66952
|
return err2(new BrowserError(result.error ?? "Load state failed", "LOAD_STATE_FAILED", "agent-browser"));
|
|
66356
66953
|
}
|
|
@@ -73290,16 +73887,16 @@ var CoverageEmbedder = class {
|
|
|
73290
73887
|
const idealRegions = Math.ceil(coverage.uncoveredLines.length / 5);
|
|
73291
73888
|
return regions > 0 ? Math.min(1, idealRegions / regions) : 0;
|
|
73292
73889
|
}
|
|
73293
|
-
extractPathFeatures(
|
|
73294
|
-
const parts =
|
|
73295
|
-
const extension =
|
|
73890
|
+
extractPathFeatures(path37) {
|
|
73891
|
+
const parts = path37.split("/").filter(Boolean);
|
|
73892
|
+
const extension = path37.split(".").pop() || "";
|
|
73296
73893
|
const fileName = parts[parts.length - 1] || "";
|
|
73297
73894
|
return {
|
|
73298
73895
|
depth: parts.length,
|
|
73299
73896
|
extension,
|
|
73300
|
-
hashNormalized: this.hashString(
|
|
73301
|
-
isTest: /\.(test|spec)\.(ts|js|tsx|jsx)$/.test(
|
|
73302
|
-
isConfig: /\.(config|rc)\.(ts|js|json|yaml|yml)$/.test(
|
|
73897
|
+
hashNormalized: this.hashString(path37) / 1e6,
|
|
73898
|
+
isTest: /\.(test|spec)\.(ts|js|tsx|jsx)$/.test(path37) || parts.includes("tests") || parts.includes("__tests__"),
|
|
73899
|
+
isConfig: /\.(config|rc)\.(ts|js|json|yaml|yml)$/.test(path37),
|
|
73303
73900
|
isIndex: fileName.startsWith("index."),
|
|
73304
73901
|
inSrc: parts.includes("src"),
|
|
73305
73902
|
inLib: parts.includes("lib"),
|
|
@@ -73646,12 +74243,12 @@ var GhostCoverageAnalyzerService = class _GhostCoverageAnalyzerService {
|
|
|
73646
74243
|
ratio(n61, d74) {
|
|
73647
74244
|
return d74 > 0 ? n61 / d74 : 0;
|
|
73648
74245
|
}
|
|
73649
|
-
gapId(
|
|
73650
|
-
const h66 = `${
|
|
74246
|
+
gapId(path37, cat) {
|
|
74247
|
+
const h66 = `${path37}:${cat}`.split("").reduce((a37, c70) => (a37 << 5) - a37 + c70.charCodeAt(0) | 0, 0);
|
|
73651
74248
|
return `phantom-${Math.abs(h66).toString(16)}`;
|
|
73652
74249
|
}
|
|
73653
|
-
gapDescription(
|
|
73654
|
-
const n61 =
|
|
74250
|
+
gapDescription(path37, cat, dist) {
|
|
74251
|
+
const n61 = path37.split("/").pop() || path37;
|
|
73655
74252
|
const s70 = dist > 0.7 ? "significant" : dist > 0.4 ? "moderate" : "minor";
|
|
73656
74253
|
const m74 = {
|
|
73657
74254
|
"missing-error-handler": `${n61}: ${s70} missing error handler tests. Cover error paths and failure recovery.`,
|
|
@@ -76085,7 +76682,7 @@ function getCodeMetricsAnalyzer() {
|
|
|
76085
76682
|
}
|
|
76086
76683
|
|
|
76087
76684
|
// src/shared/metrics/system-metrics.ts
|
|
76088
|
-
import * as
|
|
76685
|
+
import * as os3 from "os";
|
|
76089
76686
|
var SystemMetricsCollector = class {
|
|
76090
76687
|
lastCpuUsage = null;
|
|
76091
76688
|
lastCpuTime = 0;
|
|
@@ -76117,8 +76714,8 @@ var SystemMetricsCollector = class {
|
|
|
76117
76714
|
* Collect CPU metrics
|
|
76118
76715
|
*/
|
|
76119
76716
|
collectCpuMetrics() {
|
|
76120
|
-
const cpus2 =
|
|
76121
|
-
const loadAverage =
|
|
76717
|
+
const cpus2 = os3.cpus();
|
|
76718
|
+
const loadAverage = os3.loadavg();
|
|
76122
76719
|
let totalIdle = 0;
|
|
76123
76720
|
let totalTick = 0;
|
|
76124
76721
|
for (const cpu of cpus2) {
|
|
@@ -76138,8 +76735,8 @@ var SystemMetricsCollector = class {
|
|
|
76138
76735
|
* Collect memory metrics
|
|
76139
76736
|
*/
|
|
76140
76737
|
collectMemoryMetrics() {
|
|
76141
|
-
const total =
|
|
76142
|
-
const free =
|
|
76738
|
+
const total = os3.totalmem();
|
|
76739
|
+
const free = os3.freemem();
|
|
76143
76740
|
const used = total - free;
|
|
76144
76741
|
const usage = used / total * 100;
|
|
76145
76742
|
return {
|
|
@@ -76162,7 +76759,7 @@ var SystemMetricsCollector = class {
|
|
|
76162
76759
|
const cpuPercent = totalCpuUs / elapsedUs * 100;
|
|
76163
76760
|
this.lastCpuUsage = cpuUsage;
|
|
76164
76761
|
this.lastCpuTime = now;
|
|
76165
|
-
const totalMem =
|
|
76762
|
+
const totalMem = os3.totalmem();
|
|
76166
76763
|
const memPercent = memUsage.rss / totalMem * 100;
|
|
76167
76764
|
return {
|
|
76168
76765
|
cpuUsage: Math.min(100, Math.round(cpuPercent * 100) / 100),
|
|
@@ -76718,10 +77315,10 @@ ${codeContext.slice(0, 2e3)}
|
|
|
76718
77315
|
const coverage = await this.memory.get(key);
|
|
76719
77316
|
return coverage ?? null;
|
|
76720
77317
|
}
|
|
76721
|
-
hashFilePath(
|
|
77318
|
+
hashFilePath(path37) {
|
|
76722
77319
|
let hash = 0;
|
|
76723
|
-
for (let i58 = 0; i58 <
|
|
76724
|
-
hash = (hash << 5) - hash +
|
|
77320
|
+
for (let i58 = 0; i58 < path37.length; i58++) {
|
|
77321
|
+
hash = (hash << 5) - hash + path37.charCodeAt(i58);
|
|
76725
77322
|
hash = hash & hash;
|
|
76726
77323
|
}
|
|
76727
77324
|
return hash.toString(16);
|
|
@@ -90935,10 +91532,10 @@ function countTestsByFilePattern(projectPath, config) {
|
|
|
90935
91532
|
fileTests = countTestsInGoFile(fullPath);
|
|
90936
91533
|
}
|
|
90937
91534
|
total += fileTests;
|
|
90938
|
-
const
|
|
90939
|
-
if (
|
|
91535
|
+
const path37 = fullPath.toLowerCase();
|
|
91536
|
+
if (path37.includes("e2e") || path37.includes("end-to-end")) {
|
|
90940
91537
|
e2e += fileTests;
|
|
90941
|
-
} else if (
|
|
91538
|
+
} else if (path37.includes("integration")) {
|
|
90942
91539
|
integration += fileTests;
|
|
90943
91540
|
} else {
|
|
90944
91541
|
unit += fileTests;
|
|
@@ -91768,7 +92365,7 @@ var HypergraphEngine = class {
|
|
|
91768
92365
|
];
|
|
91769
92366
|
const effectiveMaxDepth = Math.min(maxDepth, this.config.maxTraversalDepth);
|
|
91770
92367
|
while (queue.length > 0) {
|
|
91771
|
-
const { nodeId, depth, path:
|
|
92368
|
+
const { nodeId, depth, path: path37 } = queue.shift();
|
|
91772
92369
|
if (!visitedNodes.has(nodeId)) {
|
|
91773
92370
|
const node = await this.getNode(nodeId);
|
|
91774
92371
|
if (node) {
|
|
@@ -91777,7 +92374,7 @@ var HypergraphEngine = class {
|
|
|
91777
92374
|
}
|
|
91778
92375
|
maxDepthReached = Math.max(maxDepthReached, depth);
|
|
91779
92376
|
if (depth >= effectiveMaxDepth) {
|
|
91780
|
-
paths.push(
|
|
92377
|
+
paths.push(path37);
|
|
91781
92378
|
continue;
|
|
91782
92379
|
}
|
|
91783
92380
|
const edgeCriteria = { sourceId: nodeId };
|
|
@@ -91786,15 +92383,15 @@ var HypergraphEngine = class {
|
|
|
91786
92383
|
}
|
|
91787
92384
|
const edges = await this.findEdges(edgeCriteria);
|
|
91788
92385
|
if (edges.length === 0) {
|
|
91789
|
-
paths.push(
|
|
92386
|
+
paths.push(path37);
|
|
91790
92387
|
continue;
|
|
91791
92388
|
}
|
|
91792
92389
|
for (const edge of edges) {
|
|
91793
92390
|
if (!visitedEdges.has(edge.id)) {
|
|
91794
92391
|
visitedEdges.set(edge.id, edge);
|
|
91795
92392
|
const newPath = {
|
|
91796
|
-
nodes: [...
|
|
91797
|
-
edges: [...
|
|
92393
|
+
nodes: [...path37.nodes, edge.targetId],
|
|
92394
|
+
edges: [...path37.edges, edge.id]
|
|
91798
92395
|
};
|
|
91799
92396
|
queue.push({
|
|
91800
92397
|
nodeId: edge.targetId,
|
|
@@ -92175,11 +92772,11 @@ async function createHypergraphEngine(config) {
|
|
|
92175
92772
|
init_wrappers();
|
|
92176
92773
|
async function indexCodeEmbeddings(gnnIndex, fileReader, paths) {
|
|
92177
92774
|
try {
|
|
92178
|
-
for (const
|
|
92775
|
+
for (const path37 of paths) {
|
|
92179
92776
|
try {
|
|
92180
|
-
const result = await fileReader.readFile(
|
|
92777
|
+
const result = await fileReader.readFile(path37);
|
|
92181
92778
|
if (result.success && result.value) {
|
|
92182
|
-
const embedding = await generateCodeEmbedding(
|
|
92779
|
+
const embedding = await generateCodeEmbedding(path37, result.value);
|
|
92183
92780
|
const embeddingObj = {
|
|
92184
92781
|
vector: embedding,
|
|
92185
92782
|
dimension: 384,
|
|
@@ -92187,12 +92784,12 @@ async function indexCodeEmbeddings(gnnIndex, fileReader, paths) {
|
|
|
92187
92784
|
text: result.value.slice(0, 1e3),
|
|
92188
92785
|
timestamp: Date.now(),
|
|
92189
92786
|
quantization: "none",
|
|
92190
|
-
metadata: { path:
|
|
92787
|
+
metadata: { path: path37 }
|
|
92191
92788
|
};
|
|
92192
92789
|
gnnIndex.addEmbedding(embeddingObj);
|
|
92193
92790
|
}
|
|
92194
92791
|
} catch (error) {
|
|
92195
|
-
console.error(`Failed to index ${
|
|
92792
|
+
console.error(`Failed to index ${path37}:`, error);
|
|
92196
92793
|
}
|
|
92197
92794
|
}
|
|
92198
92795
|
console.log(`[GNN] Indexed ${paths.length} code embeddings`);
|
|
@@ -92200,9 +92797,9 @@ async function indexCodeEmbeddings(gnnIndex, fileReader, paths) {
|
|
|
92200
92797
|
console.error("Failed to index code embeddings:", error);
|
|
92201
92798
|
}
|
|
92202
92799
|
}
|
|
92203
|
-
async function generateCodeEmbedding(
|
|
92800
|
+
async function generateCodeEmbedding(path37, content) {
|
|
92204
92801
|
const features = [];
|
|
92205
|
-
const ext =
|
|
92802
|
+
const ext = path37.split(".").pop();
|
|
92206
92803
|
const typeHash = hashCode(ext || "");
|
|
92207
92804
|
features.push(typeHash % 1e3 / 1e3);
|
|
92208
92805
|
features.push(Math.min(1, content.length / 1e4));
|
|
@@ -92623,14 +93220,14 @@ var CodeIntelligenceCoordinator = class extends BaseDomainCoordinator {
|
|
|
92623
93220
|
async initializeHypergraph() {
|
|
92624
93221
|
try {
|
|
92625
93222
|
const { openDatabase: openDatabase2 } = await Promise.resolve().then(() => (init_safe_db(), safe_db_exports));
|
|
92626
|
-
const
|
|
92627
|
-
const
|
|
93223
|
+
const fs32 = await import("fs");
|
|
93224
|
+
const path37 = await import("path");
|
|
92628
93225
|
const { findProjectRoot: findProjectRoot2 } = await Promise.resolve().then(() => (init_unified_memory(), unified_memory_exports));
|
|
92629
93226
|
const projectRoot = findProjectRoot2();
|
|
92630
|
-
const dbPath = this.config.hypergraphDbPath ||
|
|
92631
|
-
const dir =
|
|
92632
|
-
if (!
|
|
92633
|
-
|
|
93227
|
+
const dbPath = this.config.hypergraphDbPath || path37.join(projectRoot, ".agentic-qe", "hypergraph.db");
|
|
93228
|
+
const dir = path37.dirname(dbPath);
|
|
93229
|
+
if (!fs32.existsSync(dir)) {
|
|
93230
|
+
fs32.mkdirSync(dir, { recursive: true });
|
|
92634
93231
|
}
|
|
92635
93232
|
this.hypergraphDb = openDatabase2(dbPath);
|
|
92636
93233
|
this.hypergraph = await createHypergraphEngine({
|
|
@@ -93158,11 +93755,11 @@ var CodeIntelligenceCoordinator = class extends BaseDomainCoordinator {
|
|
|
93158
93755
|
// ============================================================================
|
|
93159
93756
|
async indexForSemanticSearch(paths) {
|
|
93160
93757
|
const filesToIndex = paths.slice(0, 100);
|
|
93161
|
-
for (const
|
|
93758
|
+
for (const path37 of filesToIndex) {
|
|
93162
93759
|
try {
|
|
93163
|
-
const result = await this.fileReader.readFile(
|
|
93760
|
+
const result = await this.fileReader.readFile(path37);
|
|
93164
93761
|
if (result.success && result.value) {
|
|
93165
|
-
await this.semanticAnalyzer.indexCode(
|
|
93762
|
+
await this.semanticAnalyzer.indexCode(path37, result.value);
|
|
93166
93763
|
}
|
|
93167
93764
|
} catch {
|
|
93168
93765
|
}
|
|
@@ -93370,8 +93967,8 @@ var CodeIntelligenceCoordinator = class extends BaseDomainCoordinator {
|
|
|
93370
93967
|
for (const marker of markers) {
|
|
93371
93968
|
try {
|
|
93372
93969
|
const markerPath = `${currentPath}/${marker}`;
|
|
93373
|
-
const
|
|
93374
|
-
if (
|
|
93970
|
+
const fs32 = __require("fs");
|
|
93971
|
+
if (fs32.existsSync(markerPath)) {
|
|
93375
93972
|
return currentPath;
|
|
93376
93973
|
}
|
|
93377
93974
|
} catch {
|
|
@@ -93877,8 +94474,8 @@ var FilePath = class _FilePath {
|
|
|
93877
94474
|
equals(other) {
|
|
93878
94475
|
return this._value === other._value;
|
|
93879
94476
|
}
|
|
93880
|
-
static create(
|
|
93881
|
-
return new _FilePath(
|
|
94477
|
+
static create(path37) {
|
|
94478
|
+
return new _FilePath(path37);
|
|
93882
94479
|
}
|
|
93883
94480
|
};
|
|
93884
94481
|
var RiskScore = class _RiskScore {
|
|
@@ -94616,8 +95213,8 @@ var SASTScanner = class {
|
|
|
94616
95213
|
let content;
|
|
94617
95214
|
let lines;
|
|
94618
95215
|
try {
|
|
94619
|
-
const
|
|
94620
|
-
content = await
|
|
95216
|
+
const fs32 = await import("fs/promises");
|
|
95217
|
+
content = await fs32.readFile(filePath, "utf-8");
|
|
94621
95218
|
lines = content.split("\n");
|
|
94622
95219
|
} catch {
|
|
94623
95220
|
return { vulnerabilities: [], linesScanned: 0 };
|
|
@@ -95307,10 +95904,10 @@ async function extractAndCrawlLinks(html, baseUrl, currentCrawled, maxDepth, vul
|
|
|
95307
95904
|
}
|
|
95308
95905
|
}
|
|
95309
95906
|
const linksToCrawl = Array.from(discoveredLinks).slice(0, Math.min(10, maxCrawl - crawledUrls));
|
|
95310
|
-
for (const
|
|
95907
|
+
for (const path37 of linksToCrawl) {
|
|
95311
95908
|
if (crawledUrls >= maxCrawl) break;
|
|
95312
95909
|
try {
|
|
95313
|
-
const crawlUrl = new URL(
|
|
95910
|
+
const crawlUrl = new URL(path37, baseUrl.origin).toString();
|
|
95314
95911
|
const crawlResponse = await fetch(crawlUrl, {
|
|
95315
95912
|
method: "GET",
|
|
95316
95913
|
headers: { "User-Agent": "AgenticQE-DAST-Scanner/3.0" },
|
|
@@ -95319,11 +95916,11 @@ async function extractAndCrawlLinks(html, baseUrl, currentCrawled, maxDepth, vul
|
|
|
95319
95916
|
});
|
|
95320
95917
|
crawledUrls++;
|
|
95321
95918
|
if (crawlResponse.ok) {
|
|
95322
|
-
if (
|
|
95919
|
+
if (path37.includes("password") || path37.includes("token") || path37.includes("api_key")) {
|
|
95323
95920
|
vulnerabilities.push({
|
|
95324
95921
|
id: v4_default(),
|
|
95325
95922
|
title: "Sensitive Data in URL Path",
|
|
95326
|
-
description: `URL path may contain sensitive parameter names: ${
|
|
95923
|
+
description: `URL path may contain sensitive parameter names: ${path37}`,
|
|
95327
95924
|
severity: "medium",
|
|
95328
95925
|
category: "sensitive-data",
|
|
95329
95926
|
location: { file: crawlUrl },
|
|
@@ -96832,8 +97429,8 @@ var DependencyScanner = class {
|
|
|
96832
97429
|
*/
|
|
96833
97430
|
async scanPackageJson(packageJsonPath) {
|
|
96834
97431
|
try {
|
|
96835
|
-
const
|
|
96836
|
-
const content = await
|
|
97432
|
+
const fs32 = await import("fs/promises");
|
|
97433
|
+
const content = await fs32.readFile(packageJsonPath, "utf-8");
|
|
96837
97434
|
const packageJson = safeJsonParse(content);
|
|
96838
97435
|
const allDependencies = {
|
|
96839
97436
|
...packageJson.dependencies || {},
|
|
@@ -101149,17 +101746,17 @@ Provide:
|
|
|
101149
101746
|
warnings.push("No consumers defined for contract");
|
|
101150
101747
|
}
|
|
101151
101748
|
}
|
|
101152
|
-
validateServiceInfo(info,
|
|
101749
|
+
validateServiceInfo(info, path37, errors) {
|
|
101153
101750
|
if (!info.name || info.name.trim() === "") {
|
|
101154
101751
|
errors.push({
|
|
101155
|
-
path: `${
|
|
101752
|
+
path: `${path37}.name`,
|
|
101156
101753
|
message: "Service name is required",
|
|
101157
101754
|
code: "REQUIRED_FIELD"
|
|
101158
101755
|
});
|
|
101159
101756
|
}
|
|
101160
101757
|
if (!info.version || info.version.trim() === "") {
|
|
101161
101758
|
errors.push({
|
|
101162
|
-
path: `${
|
|
101759
|
+
path: `${path37}.version`,
|
|
101163
101760
|
message: "Service version is required",
|
|
101164
101761
|
code: "REQUIRED_FIELD"
|
|
101165
101762
|
});
|
|
@@ -101805,13 +102402,13 @@ Provide:
|
|
|
101805
102402
|
/**
|
|
101806
102403
|
* Validate nested field selections
|
|
101807
102404
|
*/
|
|
101808
|
-
validateGraphQLSelections(selections, typeName, schemaInfo,
|
|
102405
|
+
validateGraphQLSelections(selections, typeName, schemaInfo, path37, errors) {
|
|
101809
102406
|
const typeDef = schemaInfo.types[typeName];
|
|
101810
102407
|
if (!typeDef) {
|
|
101811
102408
|
if (["String", "Int", "Float", "Boolean", "ID"].includes(typeName)) {
|
|
101812
102409
|
if (selections.length > 0) {
|
|
101813
102410
|
errors.push({
|
|
101814
|
-
path:
|
|
102411
|
+
path: path37,
|
|
101815
102412
|
keyword: "selection",
|
|
101816
102413
|
message: `Cannot select fields on scalar type '${typeName}'`,
|
|
101817
102414
|
params: { type: typeName }
|
|
@@ -101824,7 +102421,7 @@ Provide:
|
|
|
101824
102421
|
const fieldDef = typeDef.fields[selection.name];
|
|
101825
102422
|
if (!fieldDef) {
|
|
101826
102423
|
errors.push({
|
|
101827
|
-
path: `${
|
|
102424
|
+
path: `${path37}.${selection.name}`,
|
|
101828
102425
|
keyword: "field",
|
|
101829
102426
|
message: `Field '${selection.name}' does not exist on type '${typeName}'`,
|
|
101830
102427
|
params: { field: selection.name, type: typeName }
|
|
@@ -101835,7 +102432,7 @@ Provide:
|
|
|
101835
102432
|
selection.selections,
|
|
101836
102433
|
nestedType,
|
|
101837
102434
|
schemaInfo,
|
|
101838
|
-
`${
|
|
102435
|
+
`${path37}.${selection.name}`,
|
|
101839
102436
|
errors
|
|
101840
102437
|
);
|
|
101841
102438
|
}
|
|
@@ -101844,14 +102441,14 @@ Provide:
|
|
|
101844
102441
|
/**
|
|
101845
102442
|
* Validate variable type matches expected GraphQL type
|
|
101846
102443
|
*/
|
|
101847
|
-
validateGraphQLVariableType(value, expectedType,
|
|
102444
|
+
validateGraphQLVariableType(value, expectedType, path37, errors) {
|
|
101848
102445
|
const baseType = this.unwrapGraphQLType(expectedType);
|
|
101849
102446
|
const isNonNull = expectedType.endsWith("!");
|
|
101850
102447
|
const isList = expectedType.includes("[");
|
|
101851
102448
|
if (value === null || value === void 0) {
|
|
101852
102449
|
if (isNonNull) {
|
|
101853
102450
|
errors.push({
|
|
101854
|
-
path:
|
|
102451
|
+
path: path37,
|
|
101855
102452
|
keyword: "type",
|
|
101856
102453
|
message: `Variable cannot be null (expected ${expectedType})`,
|
|
101857
102454
|
params: { expectedType }
|
|
@@ -101862,7 +102459,7 @@ Provide:
|
|
|
101862
102459
|
if (isList) {
|
|
101863
102460
|
if (!Array.isArray(value)) {
|
|
101864
102461
|
errors.push({
|
|
101865
|
-
path:
|
|
102462
|
+
path: path37,
|
|
101866
102463
|
keyword: "type",
|
|
101867
102464
|
message: `Expected array for type ${expectedType}`,
|
|
101868
102465
|
params: { expectedType, actualType: typeof value }
|
|
@@ -101875,7 +102472,7 @@ Provide:
|
|
|
101875
102472
|
case "ID":
|
|
101876
102473
|
if (typeof value !== "string") {
|
|
101877
102474
|
errors.push({
|
|
101878
|
-
path:
|
|
102475
|
+
path: path37,
|
|
101879
102476
|
keyword: "type",
|
|
101880
102477
|
message: `Expected string for type ${baseType}`,
|
|
101881
102478
|
params: { expectedType: baseType, actualType: typeof value }
|
|
@@ -101885,7 +102482,7 @@ Provide:
|
|
|
101885
102482
|
case "Int":
|
|
101886
102483
|
if (typeof value !== "number" || !Number.isInteger(value)) {
|
|
101887
102484
|
errors.push({
|
|
101888
|
-
path:
|
|
102485
|
+
path: path37,
|
|
101889
102486
|
keyword: "type",
|
|
101890
102487
|
message: `Expected integer for type Int`,
|
|
101891
102488
|
params: { expectedType: "Int", actualType: typeof value }
|
|
@@ -101895,7 +102492,7 @@ Provide:
|
|
|
101895
102492
|
case "Float":
|
|
101896
102493
|
if (typeof value !== "number") {
|
|
101897
102494
|
errors.push({
|
|
101898
|
-
path:
|
|
102495
|
+
path: path37,
|
|
101899
102496
|
keyword: "type",
|
|
101900
102497
|
message: `Expected number for type Float`,
|
|
101901
102498
|
params: { expectedType: "Float", actualType: typeof value }
|
|
@@ -101905,7 +102502,7 @@ Provide:
|
|
|
101905
102502
|
case "Boolean":
|
|
101906
102503
|
if (typeof value !== "boolean") {
|
|
101907
102504
|
errors.push({
|
|
101908
|
-
path:
|
|
102505
|
+
path: path37,
|
|
101909
102506
|
keyword: "type",
|
|
101910
102507
|
message: `Expected boolean for type Boolean`,
|
|
101911
102508
|
params: { expectedType: "Boolean", actualType: typeof value }
|
|
@@ -101916,7 +102513,7 @@ Provide:
|
|
|
101916
102513
|
default:
|
|
101917
102514
|
if (typeof value !== "object") {
|
|
101918
102515
|
errors.push({
|
|
101919
|
-
path:
|
|
102516
|
+
path: path37,
|
|
101920
102517
|
keyword: "type",
|
|
101921
102518
|
message: `Expected object for type ${baseType}`,
|
|
101922
102519
|
params: { expectedType: baseType, actualType: typeof value }
|
|
@@ -101924,10 +102521,10 @@ Provide:
|
|
|
101924
102521
|
}
|
|
101925
102522
|
}
|
|
101926
102523
|
}
|
|
101927
|
-
basicTypeValidation(data, schema,
|
|
102524
|
+
basicTypeValidation(data, schema, path37, errors, depth = 0) {
|
|
101928
102525
|
if (depth > this.config.maxSchemaDepth) {
|
|
101929
102526
|
errors.push({
|
|
101930
|
-
path:
|
|
102527
|
+
path: path37,
|
|
101931
102528
|
keyword: "maxDepth",
|
|
101932
102529
|
message: "Maximum schema depth exceeded",
|
|
101933
102530
|
params: { maxDepth: this.config.maxSchemaDepth }
|
|
@@ -101944,7 +102541,7 @@ Provide:
|
|
|
101944
102541
|
for (const prop of required) {
|
|
101945
102542
|
if (!(prop in dataObj)) {
|
|
101946
102543
|
errors.push({
|
|
101947
|
-
path:
|
|
102544
|
+
path: path37 ? `${path37}.${prop}` : prop,
|
|
101948
102545
|
keyword: "required",
|
|
101949
102546
|
message: `Required property '${prop}' is missing`,
|
|
101950
102547
|
params: { missingProperty: prop }
|
|
@@ -101956,7 +102553,7 @@ Provide:
|
|
|
101956
102553
|
this.basicTypeValidation(
|
|
101957
102554
|
dataObj[prop],
|
|
101958
102555
|
propSchema,
|
|
101959
|
-
|
|
102556
|
+
path37 ? `${path37}.${prop}` : prop,
|
|
101960
102557
|
errors,
|
|
101961
102558
|
depth + 1
|
|
101962
102559
|
);
|
|
@@ -101965,26 +102562,26 @@ Provide:
|
|
|
101965
102562
|
} else if (type === "array" && actualType === "array") {
|
|
101966
102563
|
const items = schema.items;
|
|
101967
102564
|
const dataArr = data;
|
|
101968
|
-
this.validateArrayConstraints(dataArr, schema,
|
|
102565
|
+
this.validateArrayConstraints(dataArr, schema, path37, errors);
|
|
101969
102566
|
if (items) {
|
|
101970
102567
|
for (let i58 = 0; i58 < dataArr.length; i58++) {
|
|
101971
102568
|
this.basicTypeValidation(
|
|
101972
102569
|
dataArr[i58],
|
|
101973
102570
|
items,
|
|
101974
|
-
`${
|
|
102571
|
+
`${path37}[${i58}]`,
|
|
101975
102572
|
errors,
|
|
101976
102573
|
depth + 1
|
|
101977
102574
|
);
|
|
101978
102575
|
}
|
|
101979
102576
|
}
|
|
101980
102577
|
} else if (type === "string" && actualType === "string") {
|
|
101981
|
-
this.validateStringConstraints(data, schema,
|
|
102578
|
+
this.validateStringConstraints(data, schema, path37, errors);
|
|
101982
102579
|
} else if ((type === "number" || type === "integer") && (actualType === "number" || actualType === "integer")) {
|
|
101983
|
-
this.validateNumberConstraints(data, schema,
|
|
102580
|
+
this.validateNumberConstraints(data, schema, path37, errors);
|
|
101984
102581
|
} else if (type !== actualType) {
|
|
101985
102582
|
if (!(type === "number" && actualType === "integer")) {
|
|
101986
102583
|
errors.push({
|
|
101987
|
-
path:
|
|
102584
|
+
path: path37,
|
|
101988
102585
|
keyword: "type",
|
|
101989
102586
|
message: `Expected type '${type}' but got '${actualType}'`,
|
|
101990
102587
|
params: { expectedType: type, actualType }
|
|
@@ -101995,7 +102592,7 @@ Provide:
|
|
|
101995
102592
|
const enumValues = schema.enum;
|
|
101996
102593
|
if (!enumValues.some((v65) => JSON.stringify(v65) === JSON.stringify(data))) {
|
|
101997
102594
|
errors.push({
|
|
101998
|
-
path:
|
|
102595
|
+
path: path37,
|
|
101999
102596
|
keyword: "enum",
|
|
102000
102597
|
message: `Value must be one of: ${enumValues.map((v65) => JSON.stringify(v65)).join(", ")}`,
|
|
102001
102598
|
params: { allowedValues: enumValues }
|
|
@@ -102003,13 +102600,13 @@ Provide:
|
|
|
102003
102600
|
}
|
|
102004
102601
|
}
|
|
102005
102602
|
}
|
|
102006
|
-
validateStringConstraints(data, schema,
|
|
102603
|
+
validateStringConstraints(data, schema, path37, errors) {
|
|
102007
102604
|
const minLength = schema.minLength;
|
|
102008
102605
|
const maxLength = schema.maxLength;
|
|
102009
102606
|
const pattern = schema.pattern;
|
|
102010
102607
|
if (minLength !== void 0 && data.length < minLength) {
|
|
102011
102608
|
errors.push({
|
|
102012
|
-
path:
|
|
102609
|
+
path: path37,
|
|
102013
102610
|
keyword: "minLength",
|
|
102014
102611
|
message: `String must be at least ${minLength} characters`,
|
|
102015
102612
|
params: { limit: minLength, actual: data.length }
|
|
@@ -102017,7 +102614,7 @@ Provide:
|
|
|
102017
102614
|
}
|
|
102018
102615
|
if (maxLength !== void 0 && data.length > maxLength) {
|
|
102019
102616
|
errors.push({
|
|
102020
|
-
path:
|
|
102617
|
+
path: path37,
|
|
102021
102618
|
keyword: "maxLength",
|
|
102022
102619
|
message: `String must be at most ${maxLength} characters`,
|
|
102023
102620
|
params: { limit: maxLength, actual: data.length }
|
|
@@ -102027,7 +102624,7 @@ Provide:
|
|
|
102027
102624
|
const regex = createSafeRegex(pattern);
|
|
102028
102625
|
if (regex && !regex.test(data)) {
|
|
102029
102626
|
errors.push({
|
|
102030
|
-
path:
|
|
102627
|
+
path: path37,
|
|
102031
102628
|
keyword: "pattern",
|
|
102032
102629
|
message: `String must match pattern: ${pattern}`,
|
|
102033
102630
|
params: { pattern }
|
|
@@ -102035,7 +102632,7 @@ Provide:
|
|
|
102035
102632
|
}
|
|
102036
102633
|
}
|
|
102037
102634
|
}
|
|
102038
|
-
validateNumberConstraints(data, schema,
|
|
102635
|
+
validateNumberConstraints(data, schema, path37, errors) {
|
|
102039
102636
|
const minimum = schema.minimum;
|
|
102040
102637
|
const maximum = schema.maximum;
|
|
102041
102638
|
const exclusiveMinimum = schema.exclusiveMinimum;
|
|
@@ -102043,7 +102640,7 @@ Provide:
|
|
|
102043
102640
|
const multipleOf = schema.multipleOf;
|
|
102044
102641
|
if (minimum !== void 0 && data < minimum) {
|
|
102045
102642
|
errors.push({
|
|
102046
|
-
path:
|
|
102643
|
+
path: path37,
|
|
102047
102644
|
keyword: "minimum",
|
|
102048
102645
|
message: `Number must be >= ${minimum}`,
|
|
102049
102646
|
params: { limit: minimum, actual: data }
|
|
@@ -102051,7 +102648,7 @@ Provide:
|
|
|
102051
102648
|
}
|
|
102052
102649
|
if (maximum !== void 0 && data > maximum) {
|
|
102053
102650
|
errors.push({
|
|
102054
|
-
path:
|
|
102651
|
+
path: path37,
|
|
102055
102652
|
keyword: "maximum",
|
|
102056
102653
|
message: `Number must be <= ${maximum}`,
|
|
102057
102654
|
params: { limit: maximum, actual: data }
|
|
@@ -102059,7 +102656,7 @@ Provide:
|
|
|
102059
102656
|
}
|
|
102060
102657
|
if (exclusiveMinimum !== void 0 && data <= exclusiveMinimum) {
|
|
102061
102658
|
errors.push({
|
|
102062
|
-
path:
|
|
102659
|
+
path: path37,
|
|
102063
102660
|
keyword: "exclusiveMinimum",
|
|
102064
102661
|
message: `Number must be > ${exclusiveMinimum}`,
|
|
102065
102662
|
params: { limit: exclusiveMinimum, actual: data }
|
|
@@ -102067,7 +102664,7 @@ Provide:
|
|
|
102067
102664
|
}
|
|
102068
102665
|
if (exclusiveMaximum !== void 0 && data >= exclusiveMaximum) {
|
|
102069
102666
|
errors.push({
|
|
102070
|
-
path:
|
|
102667
|
+
path: path37,
|
|
102071
102668
|
keyword: "exclusiveMaximum",
|
|
102072
102669
|
message: `Number must be < ${exclusiveMaximum}`,
|
|
102073
102670
|
params: { limit: exclusiveMaximum, actual: data }
|
|
@@ -102075,20 +102672,20 @@ Provide:
|
|
|
102075
102672
|
}
|
|
102076
102673
|
if (multipleOf !== void 0 && data % multipleOf !== 0) {
|
|
102077
102674
|
errors.push({
|
|
102078
|
-
path:
|
|
102675
|
+
path: path37,
|
|
102079
102676
|
keyword: "multipleOf",
|
|
102080
102677
|
message: `Number must be a multiple of ${multipleOf}`,
|
|
102081
102678
|
params: { multipleOf, actual: data }
|
|
102082
102679
|
});
|
|
102083
102680
|
}
|
|
102084
102681
|
}
|
|
102085
|
-
validateArrayConstraints(data, schema,
|
|
102682
|
+
validateArrayConstraints(data, schema, path37, errors) {
|
|
102086
102683
|
const minItems = schema.minItems;
|
|
102087
102684
|
const maxItems = schema.maxItems;
|
|
102088
102685
|
const uniqueItems = schema.uniqueItems;
|
|
102089
102686
|
if (minItems !== void 0 && data.length < minItems) {
|
|
102090
102687
|
errors.push({
|
|
102091
|
-
path:
|
|
102688
|
+
path: path37,
|
|
102092
102689
|
keyword: "minItems",
|
|
102093
102690
|
message: `Array must have at least ${minItems} items`,
|
|
102094
102691
|
params: { limit: minItems, actual: data.length }
|
|
@@ -102096,7 +102693,7 @@ Provide:
|
|
|
102096
102693
|
}
|
|
102097
102694
|
if (maxItems !== void 0 && data.length > maxItems) {
|
|
102098
102695
|
errors.push({
|
|
102099
|
-
path:
|
|
102696
|
+
path: path37,
|
|
102100
102697
|
keyword: "maxItems",
|
|
102101
102698
|
message: `Array must have at most ${maxItems} items`,
|
|
102102
102699
|
params: { limit: maxItems, actual: data.length }
|
|
@@ -102108,7 +102705,7 @@ Provide:
|
|
|
102108
102705
|
const serialized = JSON.stringify(data[i58]);
|
|
102109
102706
|
if (seen.has(serialized)) {
|
|
102110
102707
|
errors.push({
|
|
102111
|
-
path: `${
|
|
102708
|
+
path: `${path37}[${i58}]`,
|
|
102112
102709
|
keyword: "uniqueItems",
|
|
102113
102710
|
message: "Array items must be unique",
|
|
102114
102711
|
params: { duplicateIndex: i58 }
|
|
@@ -102604,11 +103201,11 @@ var ApiCompatibilityService = class {
|
|
|
102604
103201
|
} catch {
|
|
102605
103202
|
}
|
|
102606
103203
|
}
|
|
102607
|
-
scanObjectForDeprecations(obj,
|
|
103204
|
+
scanObjectForDeprecations(obj, path37, deprecations, version2, context2) {
|
|
102608
103205
|
if (!obj || typeof obj !== "object") return;
|
|
102609
103206
|
const record = obj;
|
|
102610
103207
|
if (record.deprecated === true) {
|
|
102611
|
-
const location = context2 ? `${context2} -> ${
|
|
103208
|
+
const location = context2 ? `${context2} -> ${path37}` : path37;
|
|
102612
103209
|
deprecations.push({
|
|
102613
103210
|
location,
|
|
102614
103211
|
reason: typeof record.description === "string" ? record.description : "Field marked as deprecated",
|
|
@@ -102617,7 +103214,7 @@ var ApiCompatibilityService = class {
|
|
|
102617
103214
|
});
|
|
102618
103215
|
}
|
|
102619
103216
|
if (record["x-deprecated"] === true) {
|
|
102620
|
-
const location = context2 ? `${context2} -> ${
|
|
103217
|
+
const location = context2 ? `${context2} -> ${path37}` : path37;
|
|
102621
103218
|
deprecations.push({
|
|
102622
103219
|
location,
|
|
102623
103220
|
reason: typeof record["x-deprecated-message"] === "string" ? record["x-deprecated-message"] : "Element marked as deprecated via x-deprecated",
|
|
@@ -102629,7 +103226,7 @@ var ApiCompatibilityService = class {
|
|
|
102629
103226
|
for (const [propName, propValue] of Object.entries(props)) {
|
|
102630
103227
|
this.scanObjectForDeprecations(
|
|
102631
103228
|
propValue,
|
|
102632
|
-
`${
|
|
103229
|
+
`${path37}.${propName}`,
|
|
102633
103230
|
deprecations,
|
|
102634
103231
|
version2,
|
|
102635
103232
|
context2
|
|
@@ -102639,7 +103236,7 @@ var ApiCompatibilityService = class {
|
|
|
102639
103236
|
if (record.items && typeof record.items === "object") {
|
|
102640
103237
|
this.scanObjectForDeprecations(
|
|
102641
103238
|
record.items,
|
|
102642
|
-
`${
|
|
103239
|
+
`${path37}[]`,
|
|
102643
103240
|
deprecations,
|
|
102644
103241
|
version2,
|
|
102645
103242
|
context2
|
|
@@ -103388,13 +103985,13 @@ var ContractTestingCoordinator = class extends BaseDomainCoordinator {
|
|
|
103388
103985
|
}
|
|
103389
103986
|
return contracts;
|
|
103390
103987
|
}
|
|
103391
|
-
async loadContractFromPath(
|
|
103392
|
-
const content = await this.loadFileContent(
|
|
103988
|
+
async loadContractFromPath(path37) {
|
|
103989
|
+
const content = await this.loadFileContent(path37);
|
|
103393
103990
|
if (!content) {
|
|
103394
103991
|
return null;
|
|
103395
103992
|
}
|
|
103396
103993
|
try {
|
|
103397
|
-
const filePath =
|
|
103994
|
+
const filePath = path37.value.toLowerCase();
|
|
103398
103995
|
if (filePath.endsWith(".json")) {
|
|
103399
103996
|
const parsed = safeJsonParse(content);
|
|
103400
103997
|
if (parsed.openapi || parsed.swagger) {
|
|
@@ -103402,22 +103999,22 @@ var ContractTestingCoordinator = class extends BaseDomainCoordinator {
|
|
|
103402
103999
|
}
|
|
103403
104000
|
return parsed;
|
|
103404
104001
|
} else if (filePath.endsWith(".yaml") || filePath.endsWith(".yml")) {
|
|
103405
|
-
console.warn("YAML contract files not yet supported:",
|
|
104002
|
+
console.warn("YAML contract files not yet supported:", path37.value);
|
|
103406
104003
|
return null;
|
|
103407
104004
|
}
|
|
103408
104005
|
return safeJsonParse(content);
|
|
103409
104006
|
} catch (error) {
|
|
103410
104007
|
console.error(
|
|
103411
|
-
`Failed to parse contract from ${
|
|
104008
|
+
`Failed to parse contract from ${path37.value}:`,
|
|
103412
104009
|
toErrorMessage(error)
|
|
103413
104010
|
);
|
|
103414
104011
|
return null;
|
|
103415
104012
|
}
|
|
103416
104013
|
}
|
|
103417
|
-
async loadFileContent(
|
|
103418
|
-
const result = await this.fileReader.readFile(
|
|
104014
|
+
async loadFileContent(path37) {
|
|
104015
|
+
const result = await this.fileReader.readFile(path37.value);
|
|
103419
104016
|
if (!result.success) {
|
|
103420
|
-
console.error(`Failed to read file ${
|
|
104017
|
+
console.error(`Failed to read file ${path37.value}:`, result.error);
|
|
103421
104018
|
return null;
|
|
103422
104019
|
}
|
|
103423
104020
|
return result.value;
|
|
@@ -103428,13 +104025,13 @@ var ContractTestingCoordinator = class extends BaseDomainCoordinator {
|
|
|
103428
104025
|
const paths = spec.paths || {};
|
|
103429
104026
|
const endpoints = [];
|
|
103430
104027
|
const schemas = [];
|
|
103431
|
-
for (const [
|
|
104028
|
+
for (const [path37, methods] of Object.entries(paths)) {
|
|
103432
104029
|
const httpMethods = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
|
|
103433
104030
|
for (const method of httpMethods) {
|
|
103434
104031
|
const operation = methods[method.toLowerCase()];
|
|
103435
104032
|
if (operation) {
|
|
103436
104033
|
endpoints.push({
|
|
103437
|
-
path:
|
|
104034
|
+
path: path37,
|
|
103438
104035
|
method,
|
|
103439
104036
|
requestSchema: this.extractRequestSchema(operation),
|
|
103440
104037
|
responseSchema: this.extractResponseSchema(operation),
|
|
@@ -104163,10 +104760,10 @@ var SchemaValidatorService = class {
|
|
|
104163
104760
|
// ============================================================================
|
|
104164
104761
|
// Private Validation Methods
|
|
104165
104762
|
// ============================================================================
|
|
104166
|
-
validateValue(value, schema,
|
|
104763
|
+
validateValue(value, schema, path37, errors, depth) {
|
|
104167
104764
|
if (depth > this.config.maxRecursionDepth) {
|
|
104168
104765
|
errors.push({
|
|
104169
|
-
path:
|
|
104766
|
+
path: path37,
|
|
104170
104767
|
keyword: "maxDepth",
|
|
104171
104768
|
message: "Maximum recursion depth exceeded",
|
|
104172
104769
|
params: { maxDepth: this.config.maxRecursionDepth }
|
|
@@ -104179,7 +104776,7 @@ var SchemaValidatorService = class {
|
|
|
104179
104776
|
}
|
|
104180
104777
|
if (this.config.strictMode) {
|
|
104181
104778
|
errors.push({
|
|
104182
|
-
path:
|
|
104779
|
+
path: path37,
|
|
104183
104780
|
keyword: "type",
|
|
104184
104781
|
message: "Value cannot be null",
|
|
104185
104782
|
params: {}
|
|
@@ -104189,15 +104786,15 @@ var SchemaValidatorService = class {
|
|
|
104189
104786
|
}
|
|
104190
104787
|
const schemaType = schema.type;
|
|
104191
104788
|
if (schema.oneOf) {
|
|
104192
|
-
this.validateOneOf(value, schema.oneOf,
|
|
104789
|
+
this.validateOneOf(value, schema.oneOf, path37, errors, depth);
|
|
104193
104790
|
return;
|
|
104194
104791
|
}
|
|
104195
104792
|
if (schema.anyOf) {
|
|
104196
|
-
this.validateAnyOf(value, schema.anyOf,
|
|
104793
|
+
this.validateAnyOf(value, schema.anyOf, path37, errors, depth);
|
|
104197
104794
|
return;
|
|
104198
104795
|
}
|
|
104199
104796
|
if (schema.allOf) {
|
|
104200
|
-
this.validateAllOf(value, schema.allOf,
|
|
104797
|
+
this.validateAllOf(value, schema.allOf, path37, errors, depth);
|
|
104201
104798
|
return;
|
|
104202
104799
|
}
|
|
104203
104800
|
if (schemaType) {
|
|
@@ -104205,7 +104802,7 @@ var SchemaValidatorService = class {
|
|
|
104205
104802
|
const actualType = this.getJsonType(value);
|
|
104206
104803
|
if (!types.some((t50) => this.typesMatch(actualType, t50))) {
|
|
104207
104804
|
errors.push({
|
|
104208
|
-
path:
|
|
104805
|
+
path: path37,
|
|
104209
104806
|
keyword: "type",
|
|
104210
104807
|
message: `Expected type '${types.join(" | ")}' but got '${actualType}'`,
|
|
104211
104808
|
params: { expectedType: types, actualType }
|
|
@@ -104214,19 +104811,19 @@ var SchemaValidatorService = class {
|
|
|
104214
104811
|
}
|
|
104215
104812
|
}
|
|
104216
104813
|
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
104217
|
-
this.validateObject(value, schema,
|
|
104814
|
+
this.validateObject(value, schema, path37, errors, depth);
|
|
104218
104815
|
} else if (Array.isArray(value)) {
|
|
104219
|
-
this.validateArray(value, schema,
|
|
104816
|
+
this.validateArray(value, schema, path37, errors, depth);
|
|
104220
104817
|
} else if (typeof value === "string") {
|
|
104221
|
-
this.validateString(value, schema,
|
|
104818
|
+
this.validateString(value, schema, path37, errors);
|
|
104222
104819
|
} else if (typeof value === "number") {
|
|
104223
|
-
this.validateNumber(value, schema,
|
|
104820
|
+
this.validateNumber(value, schema, path37, errors);
|
|
104224
104821
|
}
|
|
104225
104822
|
if (schema.enum) {
|
|
104226
104823
|
const enumValues = schema.enum;
|
|
104227
104824
|
if (!enumValues.includes(value)) {
|
|
104228
104825
|
errors.push({
|
|
104229
|
-
path:
|
|
104826
|
+
path: path37,
|
|
104230
104827
|
keyword: "enum",
|
|
104231
104828
|
message: `Value must be one of: ${enumValues.map((v65) => JSON.stringify(v65)).join(", ")}`,
|
|
104232
104829
|
params: { allowedValues: enumValues }
|
|
@@ -104236,7 +104833,7 @@ var SchemaValidatorService = class {
|
|
|
104236
104833
|
if ("const" in schema) {
|
|
104237
104834
|
if (value !== schema.const) {
|
|
104238
104835
|
errors.push({
|
|
104239
|
-
path:
|
|
104836
|
+
path: path37,
|
|
104240
104837
|
keyword: "const",
|
|
104241
104838
|
message: `Value must be ${JSON.stringify(schema.const)}`,
|
|
104242
104839
|
params: { expected: schema.const }
|
|
@@ -104244,14 +104841,14 @@ var SchemaValidatorService = class {
|
|
|
104244
104841
|
}
|
|
104245
104842
|
}
|
|
104246
104843
|
}
|
|
104247
|
-
validateObject(value, schema,
|
|
104844
|
+
validateObject(value, schema, path37, errors, depth) {
|
|
104248
104845
|
const properties = schema.properties || {};
|
|
104249
104846
|
const required = schema.required || [];
|
|
104250
104847
|
const additionalProperties = schema.additionalProperties;
|
|
104251
104848
|
for (const prop of required) {
|
|
104252
104849
|
if (!(prop in value)) {
|
|
104253
104850
|
errors.push({
|
|
104254
|
-
path:
|
|
104851
|
+
path: path37 ? `${path37}.${prop}` : prop,
|
|
104255
104852
|
keyword: "required",
|
|
104256
104853
|
message: `Required property '${prop}' is missing`,
|
|
104257
104854
|
params: { missingProperty: prop }
|
|
@@ -104259,7 +104856,7 @@ var SchemaValidatorService = class {
|
|
|
104259
104856
|
}
|
|
104260
104857
|
}
|
|
104261
104858
|
for (const [prop, propValue] of Object.entries(value)) {
|
|
104262
|
-
const propPath =
|
|
104859
|
+
const propPath = path37 ? `${path37}.${prop}` : prop;
|
|
104263
104860
|
if (prop in properties) {
|
|
104264
104861
|
this.validateValue(propValue, properties[prop], propPath, errors, depth + 1);
|
|
104265
104862
|
} else if (this.config.strictMode && additionalProperties === false) {
|
|
@@ -104282,7 +104879,7 @@ var SchemaValidatorService = class {
|
|
|
104282
104879
|
const propCount = Object.keys(value).length;
|
|
104283
104880
|
if (typeof schema.minProperties === "number" && propCount < schema.minProperties) {
|
|
104284
104881
|
errors.push({
|
|
104285
|
-
path:
|
|
104882
|
+
path: path37,
|
|
104286
104883
|
keyword: "minProperties",
|
|
104287
104884
|
message: `Object must have at least ${schema.minProperties} properties`,
|
|
104288
104885
|
params: { limit: schema.minProperties, actual: propCount }
|
|
@@ -104290,23 +104887,23 @@ var SchemaValidatorService = class {
|
|
|
104290
104887
|
}
|
|
104291
104888
|
if (typeof schema.maxProperties === "number" && propCount > schema.maxProperties) {
|
|
104292
104889
|
errors.push({
|
|
104293
|
-
path:
|
|
104890
|
+
path: path37,
|
|
104294
104891
|
keyword: "maxProperties",
|
|
104295
104892
|
message: `Object must have at most ${schema.maxProperties} properties`,
|
|
104296
104893
|
params: { limit: schema.maxProperties, actual: propCount }
|
|
104297
104894
|
});
|
|
104298
104895
|
}
|
|
104299
104896
|
}
|
|
104300
|
-
validateArray(value, schema,
|
|
104897
|
+
validateArray(value, schema, path37, errors, depth) {
|
|
104301
104898
|
const items = schema.items;
|
|
104302
104899
|
if (items) {
|
|
104303
104900
|
for (let i58 = 0; i58 < value.length; i58++) {
|
|
104304
|
-
this.validateValue(value[i58], items, `${
|
|
104901
|
+
this.validateValue(value[i58], items, `${path37}[${i58}]`, errors, depth + 1);
|
|
104305
104902
|
}
|
|
104306
104903
|
}
|
|
104307
104904
|
if (typeof schema.minItems === "number" && value.length < schema.minItems) {
|
|
104308
104905
|
errors.push({
|
|
104309
|
-
path:
|
|
104906
|
+
path: path37,
|
|
104310
104907
|
keyword: "minItems",
|
|
104311
104908
|
message: `Array must have at least ${schema.minItems} items`,
|
|
104312
104909
|
params: { limit: schema.minItems, actual: value.length }
|
|
@@ -104314,7 +104911,7 @@ var SchemaValidatorService = class {
|
|
|
104314
104911
|
}
|
|
104315
104912
|
if (typeof schema.maxItems === "number" && value.length > schema.maxItems) {
|
|
104316
104913
|
errors.push({
|
|
104317
|
-
path:
|
|
104914
|
+
path: path37,
|
|
104318
104915
|
keyword: "maxItems",
|
|
104319
104916
|
message: `Array must have at most ${schema.maxItems} items`,
|
|
104320
104917
|
params: { limit: schema.maxItems, actual: value.length }
|
|
@@ -104326,7 +104923,7 @@ var SchemaValidatorService = class {
|
|
|
104326
104923
|
const serialized = JSON.stringify(value[i58]);
|
|
104327
104924
|
if (seen.has(serialized)) {
|
|
104328
104925
|
errors.push({
|
|
104329
|
-
path: `${
|
|
104926
|
+
path: `${path37}[${i58}]`,
|
|
104330
104927
|
keyword: "uniqueItems",
|
|
104331
104928
|
message: "Array items must be unique",
|
|
104332
104929
|
params: { duplicateIndex: i58 }
|
|
@@ -104336,10 +104933,10 @@ var SchemaValidatorService = class {
|
|
|
104336
104933
|
}
|
|
104337
104934
|
}
|
|
104338
104935
|
}
|
|
104339
|
-
validateString(value, schema,
|
|
104936
|
+
validateString(value, schema, path37, errors) {
|
|
104340
104937
|
if (typeof schema.minLength === "number" && value.length < schema.minLength) {
|
|
104341
104938
|
errors.push({
|
|
104342
|
-
path:
|
|
104939
|
+
path: path37,
|
|
104343
104940
|
keyword: "minLength",
|
|
104344
104941
|
message: `String must be at least ${schema.minLength} characters`,
|
|
104345
104942
|
params: { limit: schema.minLength, actual: value.length }
|
|
@@ -104347,7 +104944,7 @@ var SchemaValidatorService = class {
|
|
|
104347
104944
|
}
|
|
104348
104945
|
if (typeof schema.maxLength === "number" && value.length > schema.maxLength) {
|
|
104349
104946
|
errors.push({
|
|
104350
|
-
path:
|
|
104947
|
+
path: path37,
|
|
104351
104948
|
keyword: "maxLength",
|
|
104352
104949
|
message: `String must be at most ${schema.maxLength} characters`,
|
|
104353
104950
|
params: { limit: schema.maxLength, actual: value.length }
|
|
@@ -104357,7 +104954,7 @@ var SchemaValidatorService = class {
|
|
|
104357
104954
|
const regex = createSafeRegex(schema.pattern);
|
|
104358
104955
|
if (regex && !regex.test(value)) {
|
|
104359
104956
|
errors.push({
|
|
104360
|
-
path:
|
|
104957
|
+
path: path37,
|
|
104361
104958
|
keyword: "pattern",
|
|
104362
104959
|
message: `String must match pattern '${schema.pattern}'`,
|
|
104363
104960
|
params: { pattern: schema.pattern }
|
|
@@ -104365,15 +104962,15 @@ var SchemaValidatorService = class {
|
|
|
104365
104962
|
}
|
|
104366
104963
|
}
|
|
104367
104964
|
if (typeof schema.format === "string") {
|
|
104368
|
-
this.validateFormat(value, schema.format,
|
|
104965
|
+
this.validateFormat(value, schema.format, path37, errors);
|
|
104369
104966
|
}
|
|
104370
104967
|
}
|
|
104371
|
-
validateNumber(value, schema,
|
|
104968
|
+
validateNumber(value, schema, path37, errors) {
|
|
104372
104969
|
if (typeof schema.minimum === "number") {
|
|
104373
104970
|
if (schema.exclusiveMinimum === true) {
|
|
104374
104971
|
if (value <= schema.minimum) {
|
|
104375
104972
|
errors.push({
|
|
104376
|
-
path:
|
|
104973
|
+
path: path37,
|
|
104377
104974
|
keyword: "exclusiveMinimum",
|
|
104378
104975
|
message: `Number must be greater than ${schema.minimum}`,
|
|
104379
104976
|
params: { limit: schema.minimum, actual: value }
|
|
@@ -104381,7 +104978,7 @@ var SchemaValidatorService = class {
|
|
|
104381
104978
|
}
|
|
104382
104979
|
} else if (value < schema.minimum) {
|
|
104383
104980
|
errors.push({
|
|
104384
|
-
path:
|
|
104981
|
+
path: path37,
|
|
104385
104982
|
keyword: "minimum",
|
|
104386
104983
|
message: `Number must be at least ${schema.minimum}`,
|
|
104387
104984
|
params: { limit: schema.minimum, actual: value }
|
|
@@ -104392,7 +104989,7 @@ var SchemaValidatorService = class {
|
|
|
104392
104989
|
if (schema.exclusiveMaximum === true) {
|
|
104393
104990
|
if (value >= schema.maximum) {
|
|
104394
104991
|
errors.push({
|
|
104395
|
-
path:
|
|
104992
|
+
path: path37,
|
|
104396
104993
|
keyword: "exclusiveMaximum",
|
|
104397
104994
|
message: `Number must be less than ${schema.maximum}`,
|
|
104398
104995
|
params: { limit: schema.maximum, actual: value }
|
|
@@ -104400,7 +104997,7 @@ var SchemaValidatorService = class {
|
|
|
104400
104997
|
}
|
|
104401
104998
|
} else if (value > schema.maximum) {
|
|
104402
104999
|
errors.push({
|
|
104403
|
-
path:
|
|
105000
|
+
path: path37,
|
|
104404
105001
|
keyword: "maximum",
|
|
104405
105002
|
message: `Number must be at most ${schema.maximum}`,
|
|
104406
105003
|
params: { limit: schema.maximum, actual: value }
|
|
@@ -104411,7 +105008,7 @@ var SchemaValidatorService = class {
|
|
|
104411
105008
|
const remainder = value % schema.multipleOf;
|
|
104412
105009
|
if (Math.abs(remainder) > 1e-10) {
|
|
104413
105010
|
errors.push({
|
|
104414
|
-
path:
|
|
105011
|
+
path: path37,
|
|
104415
105012
|
keyword: "multipleOf",
|
|
104416
105013
|
message: `Number must be a multiple of ${schema.multipleOf}`,
|
|
104417
105014
|
params: { multipleOf: schema.multipleOf, actual: value }
|
|
@@ -104419,7 +105016,7 @@ var SchemaValidatorService = class {
|
|
|
104419
105016
|
}
|
|
104420
105017
|
}
|
|
104421
105018
|
}
|
|
104422
|
-
validateFormat(value, format,
|
|
105019
|
+
validateFormat(value, format, path37, errors) {
|
|
104423
105020
|
let isValid = true;
|
|
104424
105021
|
switch (format) {
|
|
104425
105022
|
case "email":
|
|
@@ -104456,46 +105053,46 @@ var SchemaValidatorService = class {
|
|
|
104456
105053
|
}
|
|
104457
105054
|
if (!isValid) {
|
|
104458
105055
|
errors.push({
|
|
104459
|
-
path:
|
|
105056
|
+
path: path37,
|
|
104460
105057
|
keyword: "format",
|
|
104461
105058
|
message: `String must be a valid ${format}`,
|
|
104462
105059
|
params: { format }
|
|
104463
105060
|
});
|
|
104464
105061
|
}
|
|
104465
105062
|
}
|
|
104466
|
-
validateOneOf(value, schemas,
|
|
105063
|
+
validateOneOf(value, schemas, path37, errors, depth) {
|
|
104467
105064
|
const validCount = schemas.reduce((count, schema) => {
|
|
104468
105065
|
const subErrors = [];
|
|
104469
|
-
this.validateValue(value, schema,
|
|
105066
|
+
this.validateValue(value, schema, path37, subErrors, depth + 1);
|
|
104470
105067
|
return count + (subErrors.length === 0 ? 1 : 0);
|
|
104471
105068
|
}, 0);
|
|
104472
105069
|
if (validCount !== 1) {
|
|
104473
105070
|
errors.push({
|
|
104474
|
-
path:
|
|
105071
|
+
path: path37,
|
|
104475
105072
|
keyword: "oneOf",
|
|
104476
105073
|
message: `Value must match exactly one schema (matched ${validCount})`,
|
|
104477
105074
|
params: { matched: validCount }
|
|
104478
105075
|
});
|
|
104479
105076
|
}
|
|
104480
105077
|
}
|
|
104481
|
-
validateAnyOf(value, schemas,
|
|
105078
|
+
validateAnyOf(value, schemas, path37, errors, depth) {
|
|
104482
105079
|
const hasValid = schemas.some((schema) => {
|
|
104483
105080
|
const subErrors = [];
|
|
104484
|
-
this.validateValue(value, schema,
|
|
105081
|
+
this.validateValue(value, schema, path37, subErrors, depth + 1);
|
|
104485
105082
|
return subErrors.length === 0;
|
|
104486
105083
|
});
|
|
104487
105084
|
if (!hasValid) {
|
|
104488
105085
|
errors.push({
|
|
104489
|
-
path:
|
|
105086
|
+
path: path37,
|
|
104490
105087
|
keyword: "anyOf",
|
|
104491
105088
|
message: "Value must match at least one schema",
|
|
104492
105089
|
params: {}
|
|
104493
105090
|
});
|
|
104494
105091
|
}
|
|
104495
105092
|
}
|
|
104496
|
-
validateAllOf(value, schemas,
|
|
105093
|
+
validateAllOf(value, schemas, path37, errors, depth) {
|
|
104497
105094
|
for (const schema of schemas) {
|
|
104498
|
-
this.validateValue(value, schema,
|
|
105095
|
+
this.validateValue(value, schema, path37, errors, depth + 1);
|
|
104499
105096
|
}
|
|
104500
105097
|
}
|
|
104501
105098
|
getJsonType(value) {
|
|
@@ -104528,20 +105125,20 @@ var SchemaValidatorService = class {
|
|
|
104528
105125
|
});
|
|
104529
105126
|
}
|
|
104530
105127
|
}
|
|
104531
|
-
compareSchemaObjects(oldSchema, newSchema,
|
|
105128
|
+
compareSchemaObjects(oldSchema, newSchema, path37, additions, removals, modifications) {
|
|
104532
105129
|
const oldProps = oldSchema.properties || {};
|
|
104533
105130
|
const newProps = newSchema.properties || {};
|
|
104534
105131
|
const oldRequired = new Set(oldSchema.required || []);
|
|
104535
105132
|
const newRequired = new Set(newSchema.required || []);
|
|
104536
105133
|
for (const prop of Object.keys(oldProps)) {
|
|
104537
105134
|
if (!(prop in newProps)) {
|
|
104538
|
-
const propPath =
|
|
105135
|
+
const propPath = path37 ? `${path37}.${prop}` : prop;
|
|
104539
105136
|
removals.push(propPath);
|
|
104540
105137
|
}
|
|
104541
105138
|
}
|
|
104542
105139
|
for (const prop of Object.keys(newProps)) {
|
|
104543
105140
|
if (!(prop in oldProps)) {
|
|
104544
|
-
const propPath =
|
|
105141
|
+
const propPath = path37 ? `${path37}.${prop}` : prop;
|
|
104545
105142
|
additions.push(propPath);
|
|
104546
105143
|
if (newRequired.has(prop)) {
|
|
104547
105144
|
modifications.push({
|
|
@@ -104555,7 +105152,7 @@ var SchemaValidatorService = class {
|
|
|
104555
105152
|
}
|
|
104556
105153
|
if (oldSchema.type !== newSchema.type) {
|
|
104557
105154
|
modifications.push({
|
|
104558
|
-
path:
|
|
105155
|
+
path: path37 || "root",
|
|
104559
105156
|
oldType: String(oldSchema.type || "any"),
|
|
104560
105157
|
newType: String(newSchema.type || "any"),
|
|
104561
105158
|
isBreaking: true
|
|
@@ -104564,7 +105161,7 @@ var SchemaValidatorService = class {
|
|
|
104564
105161
|
const newRequiredArray = Array.from(newRequired);
|
|
104565
105162
|
for (const prop of newRequiredArray) {
|
|
104566
105163
|
if (!oldRequired.has(prop) && prop in oldProps) {
|
|
104567
|
-
const propPath =
|
|
105164
|
+
const propPath = path37 ? `${path37}.${prop}` : prop;
|
|
104568
105165
|
modifications.push({
|
|
104569
105166
|
path: propPath,
|
|
104570
105167
|
oldType: "optional",
|
|
@@ -105440,7 +106037,7 @@ var VisualTesterService = class {
|
|
|
105440
106037
|
const timestamp = /* @__PURE__ */ new Date();
|
|
105441
106038
|
const urlHash = this.hashUrl(url);
|
|
105442
106039
|
const viewportKey = `${viewport.width}x${viewport.height}`;
|
|
105443
|
-
const
|
|
106040
|
+
const path37 = FilePath.create(
|
|
105444
106041
|
`${this.config.baselineDirectory}/${urlHash}_${viewportKey}_${screenshotId}.png`
|
|
105445
106042
|
);
|
|
105446
106043
|
const loadTime = this.estimateLoadTime(url, viewport);
|
|
@@ -105456,7 +106053,7 @@ var VisualTesterService = class {
|
|
|
105456
106053
|
url,
|
|
105457
106054
|
viewport,
|
|
105458
106055
|
timestamp,
|
|
105459
|
-
path:
|
|
106056
|
+
path: path37,
|
|
105460
106057
|
metadata
|
|
105461
106058
|
};
|
|
105462
106059
|
await this.storeScreenshotMetadata(screenshot);
|
|
@@ -105473,7 +106070,7 @@ var VisualTesterService = class {
|
|
|
105473
106070
|
const viewport = options?.viewport || this.config.defaultViewport;
|
|
105474
106071
|
const screenshotId = v4_default();
|
|
105475
106072
|
const timestamp = /* @__PURE__ */ new Date();
|
|
105476
|
-
const
|
|
106073
|
+
const path37 = FilePath.create(
|
|
105477
106074
|
`${this.config.baselineDirectory}/${screenshotId}.png`
|
|
105478
106075
|
);
|
|
105479
106076
|
const metadata = {
|
|
@@ -105488,7 +106085,7 @@ var VisualTesterService = class {
|
|
|
105488
106085
|
url,
|
|
105489
106086
|
viewport,
|
|
105490
106087
|
timestamp,
|
|
105491
|
-
path:
|
|
106088
|
+
path: path37,
|
|
105492
106089
|
metadata
|
|
105493
106090
|
};
|
|
105494
106091
|
await this.storeScreenshotMetadata(screenshot);
|
|
@@ -109700,12 +110297,12 @@ var VisualAccessibilityCoordinator = class extends BaseDomainCoordinator {
|
|
|
109700
110297
|
*/
|
|
109701
110298
|
extractPathFeatures(url) {
|
|
109702
110299
|
const features = [];
|
|
109703
|
-
const
|
|
110300
|
+
const path37 = new URL(url).pathname;
|
|
109704
110301
|
const commonPaths = ["dashboard", "checkout", "login", "profile", "settings", "api", "admin", "search"];
|
|
109705
110302
|
for (const cp of commonPaths) {
|
|
109706
|
-
features.push(
|
|
110303
|
+
features.push(path37.includes(cp) ? 1 : 0);
|
|
109707
110304
|
}
|
|
109708
|
-
const depth =
|
|
110305
|
+
const depth = path37.split("/").filter(Boolean).length;
|
|
109709
110306
|
features.push(depth / 10);
|
|
109710
110307
|
features.push(url.includes("?") ? 1 : 0);
|
|
109711
110308
|
features.push(url.startsWith("https://") ? 1 : 0);
|
|
@@ -113304,12 +113901,12 @@ var ChaosResilienceCoordinator = class extends BaseDomainCoordinator {
|
|
|
113304
113901
|
}
|
|
113305
113902
|
return experiments;
|
|
113306
113903
|
}
|
|
113307
|
-
generateCriticalPathExperiment(
|
|
113308
|
-
const pathName =
|
|
113904
|
+
generateCriticalPathExperiment(path37, _architecture) {
|
|
113905
|
+
const pathName = path37.join("-");
|
|
113309
113906
|
return {
|
|
113310
113907
|
id: v4_default(),
|
|
113311
113908
|
name: `critical-path-${pathName}`,
|
|
113312
|
-
description: `Test critical path: ${
|
|
113909
|
+
description: `Test critical path: ${path37.join(" -> ")}`,
|
|
113313
113910
|
hypothesis: {
|
|
113314
113911
|
statement: "System should handle partial path failure gracefully",
|
|
113315
113912
|
metrics: [
|
|
@@ -113322,7 +113919,7 @@ var ChaosResilienceCoordinator = class extends BaseDomainCoordinator {
|
|
|
113322
113919
|
},
|
|
113323
113920
|
steadyState: {
|
|
113324
113921
|
description: "All services in path are healthy",
|
|
113325
|
-
probes:
|
|
113922
|
+
probes: path37.map((service) => ({
|
|
113326
113923
|
name: `${service}-health`,
|
|
113327
113924
|
type: "http",
|
|
113328
113925
|
target: `http://${service}/health`,
|
|
@@ -113330,7 +113927,7 @@ var ChaosResilienceCoordinator = class extends BaseDomainCoordinator {
|
|
|
113330
113927
|
timeout: 5e3
|
|
113331
113928
|
}))
|
|
113332
113929
|
},
|
|
113333
|
-
faults:
|
|
113930
|
+
faults: path37.slice(0, -1).map((service) => ({
|
|
113334
113931
|
id: v4_default(),
|
|
113335
113932
|
type: "latency",
|
|
113336
113933
|
target: {
|
|
@@ -120174,8 +120771,8 @@ var WorkflowOrchestrator = class {
|
|
|
120174
120771
|
}
|
|
120175
120772
|
}
|
|
120176
120773
|
}
|
|
120177
|
-
getValueByPath(obj,
|
|
120178
|
-
const parts =
|
|
120774
|
+
getValueByPath(obj, path37) {
|
|
120775
|
+
const parts = path37.split(".");
|
|
120179
120776
|
let current = obj;
|
|
120180
120777
|
for (const part of parts) {
|
|
120181
120778
|
if (current === null || current === void 0) return void 0;
|
|
@@ -120184,8 +120781,8 @@ var WorkflowOrchestrator = class {
|
|
|
120184
120781
|
}
|
|
120185
120782
|
return current;
|
|
120186
120783
|
}
|
|
120187
|
-
setValueByPath(obj,
|
|
120188
|
-
const parts =
|
|
120784
|
+
setValueByPath(obj, path37, value) {
|
|
120785
|
+
const parts = path37.split(".");
|
|
120189
120786
|
const dangerousKeys = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
120190
120787
|
for (const part of parts) {
|
|
120191
120788
|
if (dangerousKeys.has(part)) throw new Error(`Invalid path: contains dangerous prototype key`);
|
|
@@ -120332,15 +120929,15 @@ var WorkflowOrchestrator = class {
|
|
|
120332
120929
|
detectCircularDependencies(steps) {
|
|
120333
120930
|
const visited = /* @__PURE__ */ new Set();
|
|
120334
120931
|
const recursionStack = /* @__PURE__ */ new Set();
|
|
120335
|
-
const visit = (stepId,
|
|
120336
|
-
if (recursionStack.has(stepId)) return [...
|
|
120932
|
+
const visit = (stepId, path37) => {
|
|
120933
|
+
if (recursionStack.has(stepId)) return [...path37, stepId].join(" -> ");
|
|
120337
120934
|
if (visited.has(stepId)) return null;
|
|
120338
120935
|
visited.add(stepId);
|
|
120339
120936
|
recursionStack.add(stepId);
|
|
120340
120937
|
const step = steps.find((s70) => s70.id === stepId);
|
|
120341
120938
|
if (step?.dependsOn) {
|
|
120342
120939
|
for (const dep of step.dependsOn) {
|
|
120343
|
-
const result = visit(dep, [...
|
|
120940
|
+
const result = visit(dep, [...path37, stepId]);
|
|
120344
120941
|
if (result) return result;
|
|
120345
120942
|
}
|
|
120346
120943
|
}
|
|
@@ -129311,8 +129908,8 @@ var CrossPhaseHookExecutor = class {
|
|
|
129311
129908
|
try {
|
|
129312
129909
|
const parts = condition.split(/\s*(>|<|>=|<=|==|!=)\s*/);
|
|
129313
129910
|
if (parts.length !== 3) return false;
|
|
129314
|
-
const [
|
|
129315
|
-
const actual = this.getValueFromPath(context2,
|
|
129911
|
+
const [path37, op, value] = parts;
|
|
129912
|
+
const actual = this.getValueFromPath(context2, path37);
|
|
129316
129913
|
const expected = isNaN(Number(value)) ? value : Number(value);
|
|
129317
129914
|
const actualNum = typeof actual === "number" ? actual : Number(actual);
|
|
129318
129915
|
const expectedNum = typeof expected === "number" ? expected : Number(expected);
|
|
@@ -129336,8 +129933,8 @@ var CrossPhaseHookExecutor = class {
|
|
|
129336
129933
|
return false;
|
|
129337
129934
|
}
|
|
129338
129935
|
}
|
|
129339
|
-
getValueFromPath(obj,
|
|
129340
|
-
return
|
|
129936
|
+
getValueFromPath(obj, path37) {
|
|
129937
|
+
return path37.split(".").reduce((curr, key) => {
|
|
129341
129938
|
if (curr && typeof curr === "object" && key in curr) {
|
|
129342
129939
|
return curr[key];
|
|
129343
129940
|
}
|
|
@@ -129346,8 +129943,8 @@ var CrossPhaseHookExecutor = class {
|
|
|
129346
129943
|
}
|
|
129347
129944
|
extractFromContext(extract, context2) {
|
|
129348
129945
|
const result = {};
|
|
129349
|
-
for (const [key,
|
|
129350
|
-
result[key] = this.getValueFromPath(context2,
|
|
129946
|
+
for (const [key, path37] of Object.entries(extract)) {
|
|
129947
|
+
result[key] = this.getValueFromPath(context2, path37);
|
|
129351
129948
|
}
|
|
129352
129949
|
return result;
|
|
129353
129950
|
}
|
|
@@ -132189,6 +132786,9 @@ var TokenMetricsCollectorImpl = class _TokenMetricsCollectorImpl {
|
|
|
132189
132786
|
if (config) {
|
|
132190
132787
|
this.costConfig = { ...DEFAULT_COST_CONFIG, ...config };
|
|
132191
132788
|
}
|
|
132789
|
+
this.initializeDb().catch(() => {
|
|
132790
|
+
});
|
|
132791
|
+
this.startAutoSave();
|
|
132192
132792
|
}
|
|
132193
132793
|
/**
|
|
132194
132794
|
* Set cost configuration for token pricing.
|
|
@@ -132244,6 +132844,7 @@ var TokenMetricsCollectorImpl = class _TokenMetricsCollectorImpl {
|
|
|
132244
132844
|
this.totalTokensSaved += tokensSaved;
|
|
132245
132845
|
}
|
|
132246
132846
|
this.isDirty = true;
|
|
132847
|
+
this.maybePersistToKv();
|
|
132247
132848
|
}
|
|
132248
132849
|
/**
|
|
132249
132850
|
* Record pattern reuse for a task (tokens saved by skipping LLM call).
|
|
@@ -132516,8 +133117,8 @@ var TokenMetricsCollectorImpl = class _TokenMetricsCollectorImpl {
|
|
|
132516
133117
|
* Save metrics to persistent storage
|
|
132517
133118
|
*/
|
|
132518
133119
|
async save() {
|
|
132519
|
-
const
|
|
132520
|
-
const
|
|
133120
|
+
const fs32 = await import("fs");
|
|
133121
|
+
const path37 = await import("path");
|
|
132521
133122
|
const data = {
|
|
132522
133123
|
version: "1.0.0",
|
|
132523
133124
|
sessionId: this.sessionId,
|
|
@@ -132531,26 +133132,26 @@ var TokenMetricsCollectorImpl = class _TokenMetricsCollectorImpl {
|
|
|
132531
133132
|
},
|
|
132532
133133
|
lastSavedAt: Date.now()
|
|
132533
133134
|
};
|
|
132534
|
-
const filePath =
|
|
132535
|
-
const dirPath =
|
|
132536
|
-
if (!
|
|
132537
|
-
|
|
133135
|
+
const filePath = path37.resolve(this.persistenceConfig.filePath);
|
|
133136
|
+
const dirPath = path37.dirname(filePath);
|
|
133137
|
+
if (!fs32.existsSync(dirPath)) {
|
|
133138
|
+
fs32.mkdirSync(dirPath, { recursive: true });
|
|
132538
133139
|
}
|
|
132539
|
-
|
|
133140
|
+
fs32.writeFileSync(filePath, JSON.stringify(data, null, 2));
|
|
132540
133141
|
this.isDirty = false;
|
|
132541
133142
|
}
|
|
132542
133143
|
/**
|
|
132543
133144
|
* Load metrics from persistent storage
|
|
132544
133145
|
*/
|
|
132545
133146
|
async load() {
|
|
132546
|
-
const
|
|
132547
|
-
const
|
|
132548
|
-
const filePath =
|
|
132549
|
-
if (!
|
|
133147
|
+
const fs32 = await import("fs");
|
|
133148
|
+
const path37 = await import("path");
|
|
133149
|
+
const filePath = path37.resolve(this.persistenceConfig.filePath);
|
|
133150
|
+
if (!fs32.existsSync(filePath)) {
|
|
132550
133151
|
return false;
|
|
132551
133152
|
}
|
|
132552
133153
|
try {
|
|
132553
|
-
const content =
|
|
133154
|
+
const content = fs32.readFileSync(filePath, "utf-8");
|
|
132554
133155
|
const data = safeJsonParse(content);
|
|
132555
133156
|
if (!data.version || !data.version.startsWith("1.")) {
|
|
132556
133157
|
console.warn("[TokenMetricsCollector] Incompatible data version, skipping load");
|
|
@@ -133718,9 +134319,9 @@ function validatePipeline(pipeline11) {
|
|
|
133718
134319
|
function detectCircularDependencies(stages) {
|
|
133719
134320
|
const visited = /* @__PURE__ */ new Set();
|
|
133720
134321
|
const recursionStack = /* @__PURE__ */ new Set();
|
|
133721
|
-
const visit = (stageName,
|
|
134322
|
+
const visit = (stageName, path37) => {
|
|
133722
134323
|
if (recursionStack.has(stageName)) {
|
|
133723
|
-
return [...
|
|
134324
|
+
return [...path37, stageName].join(" -> ");
|
|
133724
134325
|
}
|
|
133725
134326
|
if (visited.has(stageName)) {
|
|
133726
134327
|
return null;
|
|
@@ -133730,7 +134331,7 @@ function detectCircularDependencies(stages) {
|
|
|
133730
134331
|
const stage = stages.find((s70) => s70.name === stageName);
|
|
133731
134332
|
if (stage?.depends_on) {
|
|
133732
134333
|
for (const dep of stage.depends_on) {
|
|
133733
|
-
const result = visit(dep, [...
|
|
134334
|
+
const result = visit(dep, [...path37, stageName]);
|
|
133734
134335
|
if (result) return result;
|
|
133735
134336
|
}
|
|
133736
134337
|
}
|
|
@@ -133850,7 +134451,7 @@ init_safe_json();
|
|
|
133850
134451
|
import { randomUUID as randomUUID17 } from "crypto";
|
|
133851
134452
|
import * as fs18 from "fs";
|
|
133852
134453
|
import * as path19 from "path";
|
|
133853
|
-
import * as
|
|
134454
|
+
import * as os4 from "os";
|
|
133854
134455
|
init_safe_json();
|
|
133855
134456
|
init_error_utils();
|
|
133856
134457
|
var DEFAULT_CONFIG_DIR = ".aqe";
|
|
@@ -133877,7 +134478,7 @@ var PersistentScheduler = class {
|
|
|
133877
134478
|
* Prevents writing to arbitrary filesystem locations
|
|
133878
134479
|
*/
|
|
133879
134480
|
validateSchedulesPath(schedulesPath) {
|
|
133880
|
-
const homeDir =
|
|
134481
|
+
const homeDir = os4.homedir();
|
|
133881
134482
|
const resolvedPath = path19.resolve(schedulesPath);
|
|
133882
134483
|
const resolvedHome = path19.resolve(homeDir);
|
|
133883
134484
|
if (resolvedPath.startsWith(resolvedHome + path19.sep) || resolvedPath === resolvedHome) {
|
|
@@ -133888,7 +134489,7 @@ var PersistentScheduler = class {
|
|
|
133888
134489
|
if (resolvedPath.startsWith(resolvedCwd + path19.sep) || resolvedPath === resolvedCwd) {
|
|
133889
134490
|
return;
|
|
133890
134491
|
}
|
|
133891
|
-
const tmpDir =
|
|
134492
|
+
const tmpDir = os4.tmpdir();
|
|
133892
134493
|
const resolvedTmp = path19.resolve(tmpDir);
|
|
133893
134494
|
if (resolvedPath.startsWith(resolvedTmp + path19.sep) || resolvedPath === resolvedTmp) {
|
|
133894
134495
|
return;
|
|
@@ -133901,7 +134502,7 @@ var PersistentScheduler = class {
|
|
|
133901
134502
|
* Get the default path for schedules.json
|
|
133902
134503
|
*/
|
|
133903
134504
|
getDefaultSchedulesPath() {
|
|
133904
|
-
const homeDir =
|
|
134505
|
+
const homeDir = os4.homedir();
|
|
133905
134506
|
return path19.join(homeDir, DEFAULT_CONFIG_DIR, SCHEDULES_FILE);
|
|
133906
134507
|
}
|
|
133907
134508
|
/**
|
|
@@ -134351,7 +134952,7 @@ var ALL_DOMAINS2 = [
|
|
|
134351
134952
|
"enterprise-integration"
|
|
134352
134953
|
];
|
|
134353
134954
|
function getAQEVersion() {
|
|
134354
|
-
return true ? "3.7.
|
|
134955
|
+
return true ? "3.7.16" : "3.0.0";
|
|
134355
134956
|
}
|
|
134356
134957
|
function createDefaultConfig(projectName, projectRoot) {
|
|
134357
134958
|
return {
|
|
@@ -137135,9 +137736,9 @@ var N8nInstaller = class {
|
|
|
137135
137736
|
// NPM package location
|
|
137136
137737
|
join24(__dirname2, "../../assets/agents/n8n")
|
|
137137
137738
|
];
|
|
137138
|
-
for (const
|
|
137139
|
-
if (existsSync20(
|
|
137140
|
-
return
|
|
137739
|
+
for (const path37 of possiblePaths) {
|
|
137740
|
+
if (existsSync20(path37)) {
|
|
137741
|
+
return path37;
|
|
137141
137742
|
}
|
|
137142
137743
|
}
|
|
137143
137744
|
return join24(process.cwd(), ".claude/agents/n8n");
|
|
@@ -137151,9 +137752,9 @@ var N8nInstaller = class {
|
|
|
137151
137752
|
join24(process.cwd(), ".claude/skills"),
|
|
137152
137753
|
join24(__dirname2, "../../assets/skills")
|
|
137153
137754
|
];
|
|
137154
|
-
for (const
|
|
137155
|
-
if (existsSync20(
|
|
137156
|
-
return
|
|
137755
|
+
for (const path37 of possiblePaths) {
|
|
137756
|
+
if (existsSync20(path37)) {
|
|
137757
|
+
return path37;
|
|
137157
137758
|
}
|
|
137158
137759
|
}
|
|
137159
137760
|
return join24(process.cwd(), ".claude/skills");
|
|
@@ -142556,6 +143157,7 @@ function createProtocolHandler(cleanupAndExit2, ensureInitialized2) {
|
|
|
142556
143157
|
}
|
|
142557
143158
|
|
|
142558
143159
|
// src/cli/handlers/brain-handler.ts
|
|
143160
|
+
init_unified_memory();
|
|
142559
143161
|
import path20 from "path";
|
|
142560
143162
|
import chalk9 from "chalk";
|
|
142561
143163
|
|
|
@@ -143594,10 +144196,10 @@ function resolveFormat(format) {
|
|
|
143594
144196
|
}
|
|
143595
144197
|
return isRvfAvailable() ? "rvf" : "jsonl";
|
|
143596
144198
|
}
|
|
143597
|
-
function detectImportFormat(
|
|
144199
|
+
function detectImportFormat(path37, format) {
|
|
143598
144200
|
if (format === "rvf") return "rvf";
|
|
143599
144201
|
if (format === "jsonl") return "jsonl";
|
|
143600
|
-
if (
|
|
144202
|
+
if (path37.endsWith(".rvf")) return "rvf";
|
|
143601
144203
|
return "jsonl";
|
|
143602
144204
|
}
|
|
143603
144205
|
|
|
@@ -143823,7 +144425,7 @@ Examples:
|
|
|
143823
144425
|
}
|
|
143824
144426
|
};
|
|
143825
144427
|
function defaultDbPath() {
|
|
143826
|
-
return path20.join(
|
|
144428
|
+
return path20.join(findProjectRoot(), ".agentic-qe", "memory.db");
|
|
143827
144429
|
}
|
|
143828
144430
|
function formatBytes(bytes) {
|
|
143829
144431
|
if (bytes < 1024) return `${bytes} B`;
|
|
@@ -143936,8 +144538,8 @@ function createTestCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
143936
144538
|
console.log(chalk10.red("Test generation domain not available"));
|
|
143937
144539
|
return;
|
|
143938
144540
|
}
|
|
143939
|
-
const
|
|
143940
|
-
const targetPath =
|
|
144541
|
+
const path37 = await import("path");
|
|
144542
|
+
const targetPath = path37.resolve(target || ".");
|
|
143941
144543
|
const sourceFiles = walkSourceFiles(targetPath, { includeTests: false });
|
|
143942
144544
|
if (sourceFiles.length === 0) {
|
|
143943
144545
|
console.log(chalk10.yellow("No source files found"));
|
|
@@ -143973,14 +144575,14 @@ function createTestCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
143973
144575
|
console.log(chalk10.cyan(" Tests:"));
|
|
143974
144576
|
for (const test of generated.tests.slice(0, 10)) {
|
|
143975
144577
|
console.log(` ${chalk10.white(test.name)}`);
|
|
143976
|
-
console.log(chalk10.gray(` Source: ${
|
|
144578
|
+
console.log(chalk10.gray(` Source: ${path37.basename(test.sourceFile)}`));
|
|
143977
144579
|
console.log(chalk10.gray(` Assertions: ${test.assertions}`));
|
|
143978
144580
|
if (test.testCode) {
|
|
143979
144581
|
console.log(chalk10.gray(` Test File: ${test.testFile}`));
|
|
143980
|
-
const
|
|
143981
|
-
const testDir =
|
|
143982
|
-
|
|
143983
|
-
|
|
144582
|
+
const fs32 = await import("fs");
|
|
144583
|
+
const testDir = path37.dirname(test.testFile);
|
|
144584
|
+
fs32.mkdirSync(testDir, { recursive: true });
|
|
144585
|
+
fs32.writeFileSync(test.testFile, test.testCode, "utf-8");
|
|
143984
144586
|
console.log(chalk10.green(` Written to: ${test.testFile}`));
|
|
143985
144587
|
}
|
|
143986
144588
|
}
|
|
@@ -144005,8 +144607,8 @@ function createTestCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
144005
144607
|
console.log(chalk10.red("Test execution domain not available"));
|
|
144006
144608
|
return;
|
|
144007
144609
|
}
|
|
144008
|
-
const
|
|
144009
|
-
const targetPath =
|
|
144610
|
+
const path37 = await import("path");
|
|
144611
|
+
const targetPath = path37.resolve(target || ".");
|
|
144010
144612
|
const testFiles = walkSourceFiles(targetPath, { testsOnly: true });
|
|
144011
144613
|
if (testFiles.length === 0) {
|
|
144012
144614
|
console.log(chalk10.yellow("No test files found"));
|
|
@@ -144362,8 +144964,8 @@ var WizardFormat = class {
|
|
|
144362
144964
|
/**
|
|
144363
144965
|
* Format a path relative to cwd
|
|
144364
144966
|
*/
|
|
144365
|
-
static relativePath(
|
|
144366
|
-
return relative7(cwd,
|
|
144967
|
+
static relativePath(path37, cwd) {
|
|
144968
|
+
return relative7(cwd, path37) || ".";
|
|
144367
144969
|
}
|
|
144368
144970
|
/**
|
|
144369
144971
|
* Format a boolean as Yes/No
|
|
@@ -145179,8 +145781,8 @@ function createCoverageCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
145179
145781
|
console.log(chalk14.red("Coverage analysis domain not available"));
|
|
145180
145782
|
return;
|
|
145181
145783
|
}
|
|
145182
|
-
const
|
|
145183
|
-
const targetPath =
|
|
145784
|
+
const path37 = await import("path");
|
|
145785
|
+
const targetPath = path37.resolve(analyzeTarget);
|
|
145184
145786
|
const sourceFiles = walkSourceFiles(targetPath, { includeTests: false });
|
|
145185
145787
|
if (sourceFiles.length === 0) {
|
|
145186
145788
|
console.log(chalk14.yellow("No source files found"));
|
|
@@ -145502,8 +146104,8 @@ function createSecurityCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
145502
146104
|
console.log(chalk16.red("Security domain not available"));
|
|
145503
146105
|
return;
|
|
145504
146106
|
}
|
|
145505
|
-
const
|
|
145506
|
-
const targetPath =
|
|
146107
|
+
const path37 = await import("path");
|
|
146108
|
+
const targetPath = path37.resolve(options.target);
|
|
145507
146109
|
const files = walkSourceFiles(targetPath, { includeTests: true });
|
|
145508
146110
|
if (files.length === 0) {
|
|
145509
146111
|
console.log(chalk16.yellow("No files found to scan"));
|
|
@@ -145616,13 +146218,13 @@ function createCodeCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
145616
146218
|
console.log(chalk17.red("Code intelligence domain not available"));
|
|
145617
146219
|
return;
|
|
145618
146220
|
}
|
|
145619
|
-
const
|
|
146221
|
+
const path37 = await import("path");
|
|
145620
146222
|
const format = options.format || "text";
|
|
145621
146223
|
if (action === "index") {
|
|
145622
146224
|
console.log(chalk17.blue(`
|
|
145623
146225
|
Indexing codebase at ${target || "."}...
|
|
145624
146226
|
`));
|
|
145625
|
-
const targetPath =
|
|
146227
|
+
const targetPath = path37.resolve(target || ".");
|
|
145626
146228
|
const paths = walkSourceFiles(targetPath, {
|
|
145627
146229
|
includeTests: options.includeTests || false
|
|
145628
146230
|
});
|
|
@@ -145691,7 +146293,7 @@ function createCodeCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
145691
146293
|
console.log(chalk17.blue(`
|
|
145692
146294
|
Analyzing impact for ${target || "recent changes"}...
|
|
145693
146295
|
`));
|
|
145694
|
-
const targetPath =
|
|
146296
|
+
const targetPath = path37.resolve(target || ".");
|
|
145695
146297
|
const changedFiles = walkSourceFiles(targetPath, { maxDepth: 2 }).slice(0, 10);
|
|
145696
146298
|
const result = await codeAPI.analyzeImpact({
|
|
145697
146299
|
changedFiles,
|
|
@@ -145741,7 +146343,7 @@ function createCodeCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
145741
146343
|
console.log(chalk17.blue(`
|
|
145742
146344
|
Mapping dependencies for ${target || "."}...
|
|
145743
146345
|
`));
|
|
145744
|
-
const targetPath =
|
|
146346
|
+
const targetPath = path37.resolve(target || ".");
|
|
145745
146347
|
const files = walkSourceFiles(targetPath, { maxDepth: 2 }).slice(0, 50);
|
|
145746
146348
|
const result = await codeAPI.mapDependencies({
|
|
145747
146349
|
files,
|
|
@@ -145897,32 +146499,32 @@ var v3Agents = [
|
|
|
145897
146499
|
function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
145898
146500
|
const migrateCmd = new Command6("migrate").description("V2-to-V3 migration tools with agent compatibility (ADR-048)");
|
|
145899
146501
|
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) => {
|
|
145900
|
-
const
|
|
145901
|
-
const
|
|
146502
|
+
const fs32 = await import("fs");
|
|
146503
|
+
const path37 = await import("path");
|
|
145902
146504
|
console.log(chalk18.blue("\n V2 to V3 Migration (ADR-048)\n"));
|
|
145903
146505
|
const cwd = process.cwd();
|
|
145904
|
-
const v2Dir =
|
|
145905
|
-
const v3Dir =
|
|
145906
|
-
const claudeAgentDir =
|
|
146506
|
+
const v2Dir = path37.join(cwd, ".agentic-qe");
|
|
146507
|
+
const v3Dir = path37.join(cwd, ".aqe");
|
|
146508
|
+
const claudeAgentDir = path37.join(cwd, ".claude", "agents");
|
|
145907
146509
|
console.log(chalk18.white("1. Detecting v2 installation..."));
|
|
145908
|
-
const hasV2Dir =
|
|
145909
|
-
const hasClaudeAgents =
|
|
146510
|
+
const hasV2Dir = fs32.existsSync(v2Dir);
|
|
146511
|
+
const hasClaudeAgents = fs32.existsSync(claudeAgentDir);
|
|
145910
146512
|
if (!hasV2Dir && !hasClaudeAgents) {
|
|
145911
146513
|
console.log(chalk18.yellow(" ! No v2 installation found"));
|
|
145912
146514
|
console.log(chalk18.gray(" This might be a fresh project. Use `aqe init` instead."));
|
|
145913
146515
|
await cleanupAndExit2(0);
|
|
145914
146516
|
}
|
|
145915
146517
|
const v2Files = {
|
|
145916
|
-
memoryDb:
|
|
145917
|
-
config:
|
|
145918
|
-
patterns:
|
|
146518
|
+
memoryDb: path37.join(v2Dir, "memory.db"),
|
|
146519
|
+
config: path37.join(v2Dir, "config.json"),
|
|
146520
|
+
patterns: path37.join(v2Dir, "patterns")
|
|
145919
146521
|
};
|
|
145920
|
-
const hasMemory = hasV2Dir &&
|
|
145921
|
-
const hasConfig = hasV2Dir &&
|
|
145922
|
-
const hasPatterns = hasV2Dir &&
|
|
146522
|
+
const hasMemory = hasV2Dir && fs32.existsSync(v2Files.memoryDb);
|
|
146523
|
+
const hasConfig = hasV2Dir && fs32.existsSync(v2Files.config);
|
|
146524
|
+
const hasPatterns = hasV2Dir && fs32.existsSync(v2Files.patterns);
|
|
145923
146525
|
const agentsToMigrate = [];
|
|
145924
146526
|
if (hasClaudeAgents) {
|
|
145925
|
-
const files =
|
|
146527
|
+
const files = fs32.readdirSync(claudeAgentDir);
|
|
145926
146528
|
for (const file of files) {
|
|
145927
146529
|
if (file.endsWith(".md") && file.startsWith("qe-")) {
|
|
145928
146530
|
const agentName = file.replace(".md", "");
|
|
@@ -145939,7 +146541,7 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
145939
146541
|
console.log(chalk18.gray(` Agents to migrate: ${agentsToMigrate.length}
|
|
145940
146542
|
`));
|
|
145941
146543
|
console.log(chalk18.white("2. Checking v3 status..."));
|
|
145942
|
-
if (
|
|
146544
|
+
if (fs32.existsSync(v3Dir) && !options.force) {
|
|
145943
146545
|
console.log(chalk18.yellow(" ! v3 directory already exists at .aqe/"));
|
|
145944
146546
|
console.log(chalk18.gray(" Use --force to overwrite existing v3 installation."));
|
|
145945
146547
|
await cleanupAndExit2(1);
|
|
@@ -145948,14 +146550,14 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
145948
146550
|
if (options.dryRun) {
|
|
145949
146551
|
console.log(chalk18.blue(" Dry Run - Migration Plan:\n"));
|
|
145950
146552
|
if (!options.skipMemory && hasMemory) {
|
|
145951
|
-
const stats =
|
|
146553
|
+
const stats = fs32.statSync(v2Files.memoryDb);
|
|
145952
146554
|
console.log(chalk18.gray(` - Migrate memory.db (${(stats.size / 1024).toFixed(1)} KB)`));
|
|
145953
146555
|
}
|
|
145954
146556
|
if (!options.skipConfig && hasConfig) {
|
|
145955
146557
|
console.log(chalk18.gray(" - Convert config.json to v3 format"));
|
|
145956
146558
|
}
|
|
145957
146559
|
if (!options.skipPatterns && hasPatterns) {
|
|
145958
|
-
const patternFiles =
|
|
146560
|
+
const patternFiles = fs32.readdirSync(v2Files.patterns);
|
|
145959
146561
|
console.log(chalk18.gray(` - Migrate ${patternFiles.length} pattern files`));
|
|
145960
146562
|
}
|
|
145961
146563
|
if (!options.skipAgents && agentsToMigrate.length > 0) {
|
|
@@ -145970,22 +146572,22 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
145970
146572
|
}
|
|
145971
146573
|
if (options.backup) {
|
|
145972
146574
|
console.log(chalk18.white("3. Creating backup..."));
|
|
145973
|
-
const backupDir =
|
|
146575
|
+
const backupDir = path37.join(cwd, ".aqe-backup", `backup-${Date.now()}`);
|
|
145974
146576
|
try {
|
|
145975
|
-
|
|
146577
|
+
fs32.mkdirSync(backupDir, { recursive: true });
|
|
145976
146578
|
const copyDir = (src, dest) => {
|
|
145977
|
-
if (!
|
|
145978
|
-
if (
|
|
145979
|
-
|
|
145980
|
-
for (const file of
|
|
145981
|
-
copyDir(
|
|
146579
|
+
if (!fs32.existsSync(src)) return;
|
|
146580
|
+
if (fs32.statSync(src).isDirectory()) {
|
|
146581
|
+
fs32.mkdirSync(dest, { recursive: true });
|
|
146582
|
+
for (const file of fs32.readdirSync(src)) {
|
|
146583
|
+
copyDir(path37.join(src, file), path37.join(dest, file));
|
|
145982
146584
|
}
|
|
145983
146585
|
} else {
|
|
145984
|
-
|
|
146586
|
+
fs32.copyFileSync(src, dest);
|
|
145985
146587
|
}
|
|
145986
146588
|
};
|
|
145987
|
-
if (hasV2Dir) copyDir(v2Dir,
|
|
145988
|
-
if (hasClaudeAgents) copyDir(claudeAgentDir,
|
|
146589
|
+
if (hasV2Dir) copyDir(v2Dir, path37.join(backupDir, ".agentic-qe"));
|
|
146590
|
+
if (hasClaudeAgents) copyDir(claudeAgentDir, path37.join(backupDir, ".claude", "agents"));
|
|
145989
146591
|
console.log(chalk18.green(` * Backup created at .aqe-backup/
|
|
145990
146592
|
`));
|
|
145991
146593
|
} catch (err3) {
|
|
@@ -145998,11 +146600,11 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
145998
146600
|
if (!options.target || options.target === "config" || options.target === "memory") {
|
|
145999
146601
|
console.log(chalk18.white("4. Creating v3 directory structure..."));
|
|
146000
146602
|
try {
|
|
146001
|
-
|
|
146002
|
-
|
|
146003
|
-
|
|
146004
|
-
|
|
146005
|
-
|
|
146603
|
+
fs32.mkdirSync(v3Dir, { recursive: true });
|
|
146604
|
+
fs32.mkdirSync(path37.join(v3Dir, "agentdb"), { recursive: true });
|
|
146605
|
+
fs32.mkdirSync(path37.join(v3Dir, "reasoning-bank"), { recursive: true });
|
|
146606
|
+
fs32.mkdirSync(path37.join(v3Dir, "cache"), { recursive: true });
|
|
146607
|
+
fs32.mkdirSync(path37.join(v3Dir, "logs"), { recursive: true });
|
|
146006
146608
|
console.log(chalk18.green(" * Directory structure created\n"));
|
|
146007
146609
|
} catch (err3) {
|
|
146008
146610
|
console.log(chalk18.red(` x Failed: ${err3}
|
|
@@ -146013,17 +146615,17 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
146013
146615
|
if ((!options.target || options.target === "memory") && !options.skipMemory && hasMemory) {
|
|
146014
146616
|
console.log(chalk18.white("5. Migrating memory database..."));
|
|
146015
146617
|
try {
|
|
146016
|
-
const destDb =
|
|
146017
|
-
|
|
146018
|
-
const indexFile =
|
|
146019
|
-
|
|
146618
|
+
const destDb = path37.join(v3Dir, "agentdb", "memory.db");
|
|
146619
|
+
fs32.copyFileSync(v2Files.memoryDb, destDb);
|
|
146620
|
+
const indexFile = path37.join(v3Dir, "agentdb", "index.json");
|
|
146621
|
+
fs32.writeFileSync(indexFile, JSON.stringify({
|
|
146020
146622
|
version: "3.0.0",
|
|
146021
146623
|
migratedFrom: "v2",
|
|
146022
146624
|
migratedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
146023
146625
|
hnswEnabled: true,
|
|
146024
146626
|
vectorDimensions: 384
|
|
146025
146627
|
}, null, 2));
|
|
146026
|
-
const stats =
|
|
146628
|
+
const stats = fs32.statSync(v2Files.memoryDb);
|
|
146027
146629
|
console.log(chalk18.green(` * Memory database migrated (${(stats.size / 1024).toFixed(1)} KB)
|
|
146028
146630
|
`));
|
|
146029
146631
|
} catch (err3) {
|
|
@@ -146040,7 +146642,7 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
146040
146642
|
if ((!options.target || options.target === "config") && !options.skipConfig && hasConfig) {
|
|
146041
146643
|
console.log(chalk18.white("6. Migrating configuration..."));
|
|
146042
146644
|
try {
|
|
146043
|
-
const v2ConfigRaw =
|
|
146645
|
+
const v2ConfigRaw = fs32.readFileSync(v2Files.config, "utf-8");
|
|
146044
146646
|
const v2Config = parseJsonFile(v2ConfigRaw, v2Files.config);
|
|
146045
146647
|
const v3Config = {
|
|
146046
146648
|
version: "3.0.0",
|
|
@@ -146076,8 +146678,8 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
146076
146678
|
migrationDate: (/* @__PURE__ */ new Date()).toISOString()
|
|
146077
146679
|
}
|
|
146078
146680
|
};
|
|
146079
|
-
const destConfig =
|
|
146080
|
-
|
|
146681
|
+
const destConfig = path37.join(v3Dir, "config.json");
|
|
146682
|
+
fs32.writeFileSync(destConfig, JSON.stringify(v3Config, null, 2));
|
|
146081
146683
|
console.log(chalk18.green(" * Configuration migrated\n"));
|
|
146082
146684
|
} catch (err3) {
|
|
146083
146685
|
console.log(chalk18.red(` x Config migration failed: ${err3}
|
|
@@ -146093,18 +146695,18 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
146093
146695
|
if ((!options.target || options.target === "memory") && !options.skipPatterns && hasPatterns) {
|
|
146094
146696
|
console.log(chalk18.white("7. Migrating patterns to ReasoningBank..."));
|
|
146095
146697
|
try {
|
|
146096
|
-
const patternFiles =
|
|
146698
|
+
const patternFiles = fs32.readdirSync(v2Files.patterns);
|
|
146097
146699
|
let migratedCount = 0;
|
|
146098
146700
|
for (const file of patternFiles) {
|
|
146099
|
-
const srcPath =
|
|
146100
|
-
const destPath =
|
|
146101
|
-
if (
|
|
146102
|
-
|
|
146701
|
+
const srcPath = path37.join(v2Files.patterns, file);
|
|
146702
|
+
const destPath = path37.join(v3Dir, "reasoning-bank", file);
|
|
146703
|
+
if (fs32.statSync(srcPath).isFile()) {
|
|
146704
|
+
fs32.copyFileSync(srcPath, destPath);
|
|
146103
146705
|
migratedCount++;
|
|
146104
146706
|
}
|
|
146105
146707
|
}
|
|
146106
|
-
const indexPath =
|
|
146107
|
-
|
|
146708
|
+
const indexPath = path37.join(v3Dir, "reasoning-bank", "index.json");
|
|
146709
|
+
fs32.writeFileSync(indexPath, JSON.stringify({
|
|
146108
146710
|
version: "3.0.0",
|
|
146109
146711
|
migratedFrom: "v2",
|
|
146110
146712
|
migratedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -146125,17 +146727,17 @@ function createMigrateCommand(context2, cleanupAndExit2, ensureInitialized2) {
|
|
|
146125
146727
|
if ((!options.target || options.target === "agents") && !options.skipAgents && agentsToMigrate.length > 0) {
|
|
146126
146728
|
console.log(chalk18.white("8. Migrating agent names (ADR-048)..."));
|
|
146127
146729
|
let migratedAgents = 0;
|
|
146128
|
-
const deprecatedDir =
|
|
146129
|
-
if (!
|
|
146130
|
-
|
|
146730
|
+
const deprecatedDir = path37.join(claudeAgentDir, "deprecated");
|
|
146731
|
+
if (!fs32.existsSync(deprecatedDir)) {
|
|
146732
|
+
fs32.mkdirSync(deprecatedDir, { recursive: true });
|
|
146131
146733
|
}
|
|
146132
146734
|
for (const v2Name of agentsToMigrate) {
|
|
146133
146735
|
const v3Name = resolveAgentName(v2Name);
|
|
146134
|
-
const v2FilePath =
|
|
146135
|
-
const v3FilePath =
|
|
146136
|
-
const deprecatedPath =
|
|
146736
|
+
const v2FilePath = path37.join(claudeAgentDir, `${v2Name}.md`);
|
|
146737
|
+
const v3FilePath = path37.join(claudeAgentDir, `${v3Name}.md`);
|
|
146738
|
+
const deprecatedPath = path37.join(deprecatedDir, `${v2Name}.md.v2`);
|
|
146137
146739
|
try {
|
|
146138
|
-
const content =
|
|
146740
|
+
const content = fs32.readFileSync(v2FilePath, "utf-8");
|
|
146139
146741
|
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
146140
146742
|
if (!frontmatterMatch) {
|
|
146141
146743
|
console.log(chalk18.yellow(` ! ${v2Name}: No frontmatter found, skipping`));
|
|
@@ -146163,8 +146765,8 @@ v2_compat:
|
|
|
146163
146765
|
const newContent = `---
|
|
146164
146766
|
${newFrontmatter}
|
|
146165
146767
|
---${body}`;
|
|
146166
|
-
|
|
146167
|
-
|
|
146768
|
+
fs32.writeFileSync(v3FilePath, newContent, "utf-8");
|
|
146769
|
+
fs32.renameSync(v2FilePath, deprecatedPath);
|
|
146168
146770
|
console.log(chalk18.gray(` ${v2Name} -> ${v3Name}`));
|
|
146169
146771
|
migratedAgents++;
|
|
146170
146772
|
} catch (err3) {
|
|
@@ -146185,10 +146787,10 @@ ${newFrontmatter}
|
|
|
146185
146787
|
}
|
|
146186
146788
|
console.log(chalk18.white("9. Validating migration..."));
|
|
146187
146789
|
const validationResults = {
|
|
146188
|
-
v3DirExists:
|
|
146189
|
-
configExists:
|
|
146190
|
-
agentdbExists:
|
|
146191
|
-
reasoningBankExists:
|
|
146790
|
+
v3DirExists: fs32.existsSync(v3Dir),
|
|
146791
|
+
configExists: fs32.existsSync(path37.join(v3Dir, "config.json")),
|
|
146792
|
+
agentdbExists: fs32.existsSync(path37.join(v3Dir, "agentdb")),
|
|
146793
|
+
reasoningBankExists: fs32.existsSync(path37.join(v3Dir, "reasoning-bank"))
|
|
146192
146794
|
};
|
|
146193
146795
|
const allValid = Object.values(validationResults).every((v65) => v65);
|
|
146194
146796
|
if (allValid) {
|
|
@@ -146208,18 +146810,18 @@ ${newFrontmatter}
|
|
|
146208
146810
|
await cleanupAndExit2(0);
|
|
146209
146811
|
});
|
|
146210
146812
|
migrateCmd.command("status").description("Check migration status of current project").option("--json", "Output as JSON").action(async (options) => {
|
|
146211
|
-
const
|
|
146212
|
-
const
|
|
146813
|
+
const fs32 = await import("fs");
|
|
146814
|
+
const path37 = await import("path");
|
|
146213
146815
|
const cwd = process.cwd();
|
|
146214
|
-
const v2Dir =
|
|
146215
|
-
const v3Dir =
|
|
146216
|
-
const claudeAgentDir =
|
|
146217
|
-
const isV2Project =
|
|
146218
|
-
const isV3Project =
|
|
146816
|
+
const v2Dir = path37.join(cwd, ".agentic-qe");
|
|
146817
|
+
const v3Dir = path37.join(cwd, ".aqe");
|
|
146818
|
+
const claudeAgentDir = path37.join(cwd, ".claude", "agents");
|
|
146819
|
+
const isV2Project = fs32.existsSync(v2Dir);
|
|
146820
|
+
const isV3Project = fs32.existsSync(v3Dir);
|
|
146219
146821
|
const agentsToMigrate = [];
|
|
146220
146822
|
const agentsMigrated = [];
|
|
146221
|
-
if (
|
|
146222
|
-
const files =
|
|
146823
|
+
if (fs32.existsSync(claudeAgentDir)) {
|
|
146824
|
+
const files = fs32.readdirSync(claudeAgentDir);
|
|
146223
146825
|
for (const file of files) {
|
|
146224
146826
|
if (file.endsWith(".md") && file.startsWith("qe-")) {
|
|
146225
146827
|
const agentName = file.replace(".md", "");
|
|
@@ -146268,15 +146870,15 @@ ${newFrontmatter}
|
|
|
146268
146870
|
await cleanupAndExit2(0);
|
|
146269
146871
|
});
|
|
146270
146872
|
migrateCmd.command("verify").description("Verify migration integrity").option("--fix", "Attempt to fix issues automatically").action(async (options) => {
|
|
146271
|
-
const
|
|
146272
|
-
const
|
|
146873
|
+
const fs32 = await import("fs");
|
|
146874
|
+
const path37 = await import("path");
|
|
146273
146875
|
console.log(chalk18.bold("\n Verifying Migration...\n"));
|
|
146274
146876
|
const cwd = process.cwd();
|
|
146275
|
-
const v3Dir =
|
|
146276
|
-
const claudeAgentDir =
|
|
146877
|
+
const v3Dir = path37.join(cwd, ".aqe");
|
|
146878
|
+
const claudeAgentDir = path37.join(cwd, ".claude", "agents");
|
|
146277
146879
|
const deprecatedInUse = [];
|
|
146278
|
-
if (
|
|
146279
|
-
const files =
|
|
146880
|
+
if (fs32.existsSync(claudeAgentDir)) {
|
|
146881
|
+
const files = fs32.readdirSync(claudeAgentDir);
|
|
146280
146882
|
for (const file of files) {
|
|
146281
146883
|
if (file.endsWith(".md") && file.startsWith("qe-")) {
|
|
146282
146884
|
const agentName = file.replace(".md", "");
|
|
@@ -146289,8 +146891,8 @@ ${newFrontmatter}
|
|
|
146289
146891
|
const checks = [
|
|
146290
146892
|
{
|
|
146291
146893
|
name: "V3 Directory",
|
|
146292
|
-
passed:
|
|
146293
|
-
message:
|
|
146894
|
+
passed: fs32.existsSync(v3Dir),
|
|
146895
|
+
message: fs32.existsSync(v3Dir) ? "Exists" : "Missing .aqe/"
|
|
146294
146896
|
},
|
|
146295
146897
|
{
|
|
146296
146898
|
name: "Agent Compatibility",
|
|
@@ -146299,7 +146901,7 @@ ${newFrontmatter}
|
|
|
146299
146901
|
},
|
|
146300
146902
|
{
|
|
146301
146903
|
name: "Config Format",
|
|
146302
|
-
passed:
|
|
146904
|
+
passed: fs32.existsSync(path37.join(v3Dir, "config.json")),
|
|
146303
146905
|
message: "Valid v3 config"
|
|
146304
146906
|
}
|
|
146305
146907
|
];
|
|
@@ -146324,15 +146926,15 @@ ${newFrontmatter}
|
|
|
146324
146926
|
await cleanupAndExit2(0);
|
|
146325
146927
|
});
|
|
146326
146928
|
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) => {
|
|
146327
|
-
const
|
|
146328
|
-
const
|
|
146929
|
+
const fs32 = await import("fs");
|
|
146930
|
+
const path37 = await import("path");
|
|
146329
146931
|
const cwd = process.cwd();
|
|
146330
|
-
const backupRoot =
|
|
146331
|
-
if (!
|
|
146932
|
+
const backupRoot = path37.join(cwd, ".aqe-backup");
|
|
146933
|
+
if (!fs32.existsSync(backupRoot)) {
|
|
146332
146934
|
console.log(chalk18.yellow("\n! No backups found.\n"));
|
|
146333
146935
|
return;
|
|
146334
146936
|
}
|
|
146335
|
-
const backups =
|
|
146937
|
+
const backups = fs32.readdirSync(backupRoot).filter((f74) => f74.startsWith("backup-")).sort().reverse();
|
|
146336
146938
|
if (backups.length === 0) {
|
|
146337
146939
|
console.log(chalk18.yellow("\n! No backups found.\n"));
|
|
146338
146940
|
return;
|
|
@@ -146344,8 +146946,8 @@ ${newFrontmatter}
|
|
|
146344
146946
|
console.log(` ${chalk18.cyan(backup)} - ${date.toLocaleString()}`);
|
|
146345
146947
|
}
|
|
146346
146948
|
const targetBackup = options.backupId || backups[0];
|
|
146347
|
-
const backupPath =
|
|
146348
|
-
if (!
|
|
146949
|
+
const backupPath = path37.join(backupRoot, targetBackup);
|
|
146950
|
+
if (!fs32.existsSync(backupPath)) {
|
|
146349
146951
|
console.log(chalk18.red(`
|
|
146350
146952
|
Backup not found: ${targetBackup}
|
|
146351
146953
|
`));
|
|
@@ -146360,21 +146962,21 @@ ${newFrontmatter}
|
|
|
146360
146962
|
console.log(chalk18.bold(`
|
|
146361
146963
|
Rolling back to ${targetBackup}...
|
|
146362
146964
|
`));
|
|
146363
|
-
const v2Backup =
|
|
146364
|
-
const agentsBackup =
|
|
146365
|
-
if (
|
|
146366
|
-
const v2Dir =
|
|
146367
|
-
|
|
146965
|
+
const v2Backup = path37.join(backupPath, ".agentic-qe");
|
|
146966
|
+
const agentsBackup = path37.join(backupPath, ".claude", "agents");
|
|
146967
|
+
if (fs32.existsSync(v2Backup)) {
|
|
146968
|
+
const v2Dir = path37.join(cwd, ".agentic-qe");
|
|
146969
|
+
fs32.cpSync(v2Backup, v2Dir, { recursive: true });
|
|
146368
146970
|
console.log(chalk18.dim(" Restored .agentic-qe/"));
|
|
146369
146971
|
}
|
|
146370
|
-
if (
|
|
146371
|
-
const agentsDir =
|
|
146372
|
-
|
|
146972
|
+
if (fs32.existsSync(agentsBackup)) {
|
|
146973
|
+
const agentsDir = path37.join(cwd, ".claude", "agents");
|
|
146974
|
+
fs32.cpSync(agentsBackup, agentsDir, { recursive: true });
|
|
146373
146975
|
console.log(chalk18.dim(" Restored .claude/agents/"));
|
|
146374
146976
|
}
|
|
146375
|
-
const v3Dir =
|
|
146376
|
-
if (
|
|
146377
|
-
|
|
146977
|
+
const v3Dir = path37.join(cwd, ".aqe");
|
|
146978
|
+
if (fs32.existsSync(v3Dir)) {
|
|
146979
|
+
fs32.rmSync(v3Dir, { recursive: true, force: true });
|
|
146378
146980
|
console.log(chalk18.dim(" Removed .aqe/"));
|
|
146379
146981
|
}
|
|
146380
146982
|
console.log(chalk18.green("\n Rollback complete!\n"));
|
|
@@ -147932,8 +148534,8 @@ function createCompletionsCommand(cleanupAndExit2) {
|
|
|
147932
148534
|
console.log(generateCompletion("powershell"));
|
|
147933
148535
|
});
|
|
147934
148536
|
completionsCmd.command("install").description("Auto-install completions for current shell").option("-s, --shell <shell>", "Target shell (bash|zsh|fish|powershell)").action(async (options) => {
|
|
147935
|
-
const
|
|
147936
|
-
const
|
|
148537
|
+
const fs32 = await import("fs");
|
|
148538
|
+
const path37 = await import("path");
|
|
147937
148539
|
const shellInfo = options.shell ? { name: options.shell, configFile: null, detected: false } : detectShell();
|
|
147938
148540
|
if (shellInfo.name === "unknown") {
|
|
147939
148541
|
console.log(chalk19.red("Could not detect shell. Please specify with --shell option.\n"));
|
|
@@ -147947,11 +148549,11 @@ Installing completions for ${shellInfo.name}...
|
|
|
147947
148549
|
const script = generateCompletion(shellInfo.name);
|
|
147948
148550
|
if (shellInfo.name === "fish") {
|
|
147949
148551
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
147950
|
-
const fishCompletionsDir =
|
|
148552
|
+
const fishCompletionsDir = path37.join(homeDir, ".config", "fish", "completions");
|
|
147951
148553
|
try {
|
|
147952
|
-
|
|
147953
|
-
const completionFile =
|
|
147954
|
-
|
|
148554
|
+
fs32.mkdirSync(fishCompletionsDir, { recursive: true });
|
|
148555
|
+
const completionFile = path37.join(fishCompletionsDir, "aqe.fish");
|
|
148556
|
+
fs32.writeFileSync(completionFile, script);
|
|
147955
148557
|
console.log(chalk19.green(`Completions installed to: ${completionFile}`));
|
|
147956
148558
|
console.log(chalk19.gray("\nRestart your shell or run: source ~/.config/fish/completions/aqe.fish\n"));
|
|
147957
148559
|
} catch (err3) {
|
|
@@ -156391,6 +156993,7 @@ async function syncIncrementalToCloud(since, config) {
|
|
|
156391
156993
|
init_esm_node();
|
|
156392
156994
|
import * as fs29 from "fs";
|
|
156393
156995
|
import * as path29 from "path";
|
|
156996
|
+
init_unified_memory();
|
|
156394
156997
|
init_error_utils();
|
|
156395
156998
|
init_logging();
|
|
156396
156999
|
var logger21 = LoggerFactory.create("pull-agent");
|
|
@@ -156612,7 +157215,7 @@ var PullSyncAgent = class {
|
|
|
156612
157215
|
if (this.config.targetDb) {
|
|
156613
157216
|
return path29.resolve(this.config.targetDb);
|
|
156614
157217
|
}
|
|
156615
|
-
return path29.resolve(
|
|
157218
|
+
return path29.resolve(findProjectRoot(), ".agentic-qe/memory.db");
|
|
156616
157219
|
}
|
|
156617
157220
|
backupLocalDb() {
|
|
156618
157221
|
if (this.config.dryRun) return;
|
|
@@ -158150,11 +158753,11 @@ function createCategoryEngineWrapper(rawEngine) {
|
|
|
158150
158753
|
add_morphism(source, target, name) {
|
|
158151
158754
|
morphisms.push({ source, target, name });
|
|
158152
158755
|
},
|
|
158153
|
-
verify_composition(
|
|
158154
|
-
if (
|
|
158155
|
-
for (let i58 = 0; i58 <
|
|
158156
|
-
const source =
|
|
158157
|
-
const target =
|
|
158756
|
+
verify_composition(path37) {
|
|
158757
|
+
if (path37.length < 2) return true;
|
|
158758
|
+
for (let i58 = 0; i58 < path37.length - 1; i58++) {
|
|
158759
|
+
const source = path37[i58];
|
|
158760
|
+
const target = path37[i58 + 1];
|
|
158158
158761
|
const hasMorphism = morphisms.some((m74) => m74.source === source && m74.target === target);
|
|
158159
158762
|
if (!hasMorphism) return false;
|
|
158160
158763
|
}
|
|
@@ -158269,14 +158872,14 @@ var CategoryAdapter = class {
|
|
|
158269
158872
|
* @param path - Array of type names representing a composition path
|
|
158270
158873
|
* @returns True if the composition is valid
|
|
158271
158874
|
*/
|
|
158272
|
-
verifyComposition(
|
|
158875
|
+
verifyComposition(path37) {
|
|
158273
158876
|
this.ensureInitialized();
|
|
158274
|
-
if (
|
|
158877
|
+
if (path37.length < 2) {
|
|
158275
158878
|
return true;
|
|
158276
158879
|
}
|
|
158277
|
-
const isValid = this.engine.verify_composition(
|
|
158880
|
+
const isValid = this.engine.verify_composition(path37);
|
|
158278
158881
|
this.logger.debug("Verified composition", {
|
|
158279
|
-
path:
|
|
158882
|
+
path: path37,
|
|
158280
158883
|
isValid
|
|
158281
158884
|
});
|
|
158282
158885
|
return isValid;
|
|
@@ -158315,8 +158918,8 @@ var CategoryAdapter = class {
|
|
|
158315
158918
|
for (const element of pipeline11.elements) {
|
|
158316
158919
|
this.addMorphism(element.inputType, element.outputType, element.name);
|
|
158317
158920
|
}
|
|
158318
|
-
const
|
|
158319
|
-
const compositionValid = this.verifyComposition(
|
|
158921
|
+
const path37 = this.buildCompositionPath(pipeline11);
|
|
158922
|
+
const compositionValid = this.verifyComposition(path37);
|
|
158320
158923
|
const mismatches = this.checkTypeConsistency();
|
|
158321
158924
|
const warnings = this.generateWarnings(pipeline11, compositionValid, mismatches);
|
|
158322
158925
|
const durationMs = Date.now() - startTime;
|
|
@@ -158340,17 +158943,17 @@ var CategoryAdapter = class {
|
|
|
158340
158943
|
* Build a composition path from a pipeline
|
|
158341
158944
|
*/
|
|
158342
158945
|
buildCompositionPath(pipeline11) {
|
|
158343
|
-
const
|
|
158946
|
+
const path37 = [pipeline11.inputType];
|
|
158344
158947
|
for (const element of pipeline11.elements) {
|
|
158345
|
-
if (element.inputType !==
|
|
158346
|
-
|
|
158948
|
+
if (element.inputType !== path37[path37.length - 1]) {
|
|
158949
|
+
path37.push(element.inputType);
|
|
158347
158950
|
}
|
|
158348
|
-
|
|
158951
|
+
path37.push(element.outputType);
|
|
158349
158952
|
}
|
|
158350
|
-
if (
|
|
158351
|
-
|
|
158953
|
+
if (path37[path37.length - 1] !== pipeline11.outputType) {
|
|
158954
|
+
path37.push(pipeline11.outputType);
|
|
158352
158955
|
}
|
|
158353
|
-
return
|
|
158956
|
+
return path37;
|
|
158354
158957
|
}
|
|
158355
158958
|
/**
|
|
158356
158959
|
* Infer a schema from a type name
|
|
@@ -159988,8 +160591,8 @@ var WasmLoader = class {
|
|
|
159988
160591
|
})(),
|
|
159989
160592
|
join63(process.cwd(), "node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm")
|
|
159990
160593
|
].filter((p74) => p74 !== null);
|
|
159991
|
-
for (const
|
|
159992
|
-
if (existsSync64(
|
|
160594
|
+
for (const path37 of wasmPaths) {
|
|
160595
|
+
if (existsSync64(path37)) {
|
|
159993
160596
|
return true;
|
|
159994
160597
|
}
|
|
159995
160598
|
}
|
|
@@ -160251,9 +160854,9 @@ var WasmLoader = class {
|
|
|
160251
160854
|
join63(process.cwd(), "node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm")
|
|
160252
160855
|
].filter((p74) => p74 !== null);
|
|
160253
160856
|
let wasmPath = null;
|
|
160254
|
-
for (const
|
|
160255
|
-
if (existsSync64(
|
|
160256
|
-
wasmPath =
|
|
160857
|
+
for (const path37 of wasmPaths) {
|
|
160858
|
+
if (existsSync64(path37)) {
|
|
160859
|
+
wasmPath = path37;
|
|
160257
160860
|
break;
|
|
160258
160861
|
}
|
|
160259
160862
|
}
|
|
@@ -163398,6 +164001,134 @@ function capitalize(s70) {
|
|
|
163398
164001
|
return s70.charAt(0).toUpperCase() + s70.slice(1);
|
|
163399
164002
|
}
|
|
163400
164003
|
|
|
164004
|
+
// src/cli/commands/prove.ts
|
|
164005
|
+
import { Command as Command20 } from "commander";
|
|
164006
|
+
import * as crypto6 from "crypto";
|
|
164007
|
+
import * as fs31 from "fs";
|
|
164008
|
+
import * as path36 from "path";
|
|
164009
|
+
function hashAttestation(data) {
|
|
164010
|
+
const serialized = JSON.stringify(data, null, 0);
|
|
164011
|
+
return crypto6.createHash("sha256").update(serialized).digest("hex");
|
|
164012
|
+
}
|
|
164013
|
+
async function collectMetrics(projectRoot) {
|
|
164014
|
+
const metrics = {
|
|
164015
|
+
testCount: 0,
|
|
164016
|
+
passRate: 0,
|
|
164017
|
+
coveragePercent: 0,
|
|
164018
|
+
vulnerabilities: 0,
|
|
164019
|
+
qualityScore: 0,
|
|
164020
|
+
patternsUsed: 0
|
|
164021
|
+
};
|
|
164022
|
+
try {
|
|
164023
|
+
const junitPath = path36.join(projectRoot, "junit.xml");
|
|
164024
|
+
if (fs31.existsSync(junitPath)) {
|
|
164025
|
+
const content = fs31.readFileSync(junitPath, "utf-8");
|
|
164026
|
+
const testsMatch = content.match(/tests="(\d+)"/);
|
|
164027
|
+
const failsMatch = content.match(/failures="(\d+)"/);
|
|
164028
|
+
if (testsMatch) {
|
|
164029
|
+
metrics.testCount = parseInt(testsMatch[1], 10);
|
|
164030
|
+
const failures = failsMatch ? parseInt(failsMatch[1], 10) : 0;
|
|
164031
|
+
metrics.passRate = metrics.testCount > 0 ? (metrics.testCount - failures) / metrics.testCount * 100 : 0;
|
|
164032
|
+
}
|
|
164033
|
+
}
|
|
164034
|
+
} catch {
|
|
164035
|
+
}
|
|
164036
|
+
try {
|
|
164037
|
+
const coveragePath = path36.join(projectRoot, "coverage", "coverage-summary.json");
|
|
164038
|
+
if (fs31.existsSync(coveragePath)) {
|
|
164039
|
+
const coverage = JSON.parse(fs31.readFileSync(coveragePath, "utf-8"));
|
|
164040
|
+
metrics.coveragePercent = coverage?.total?.lines?.pct ?? 0;
|
|
164041
|
+
}
|
|
164042
|
+
} catch {
|
|
164043
|
+
}
|
|
164044
|
+
try {
|
|
164045
|
+
const dbPath = path36.join(projectRoot, ".agentic-qe", "memory.db");
|
|
164046
|
+
if (fs31.existsSync(dbPath)) {
|
|
164047
|
+
metrics.patternsUsed = 1;
|
|
164048
|
+
}
|
|
164049
|
+
} catch {
|
|
164050
|
+
}
|
|
164051
|
+
metrics.qualityScore = Math.round(
|
|
164052
|
+
metrics.passRate * 0.4 + metrics.coveragePercent * 0.3 + (metrics.vulnerabilities === 0 ? 100 : Math.max(0, 100 - metrics.vulnerabilities * 10)) * 0.3
|
|
164053
|
+
);
|
|
164054
|
+
return metrics;
|
|
164055
|
+
}
|
|
164056
|
+
function buildAttestation(projectRoot, metrics) {
|
|
164057
|
+
const data = {
|
|
164058
|
+
version: "1.0.0",
|
|
164059
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
164060
|
+
projectRoot,
|
|
164061
|
+
attestation: {
|
|
164062
|
+
testsExecuted: metrics.testCount > 0,
|
|
164063
|
+
coverageChecked: metrics.coveragePercent > 0,
|
|
164064
|
+
securityScanned: metrics.vulnerabilities === 0,
|
|
164065
|
+
qualityGatePassed: metrics.qualityScore >= 70
|
|
164066
|
+
},
|
|
164067
|
+
metrics,
|
|
164068
|
+
generatedBy: "agentic-qe prove"
|
|
164069
|
+
};
|
|
164070
|
+
const hash = hashAttestation(data);
|
|
164071
|
+
return { ...data, hash };
|
|
164072
|
+
}
|
|
164073
|
+
function formatMarkdown(att) {
|
|
164074
|
+
return [
|
|
164075
|
+
"# Proof of Quality",
|
|
164076
|
+
"",
|
|
164077
|
+
`**Generated:** ${att.timestamp}`,
|
|
164078
|
+
`**Project:** ${att.projectRoot}`,
|
|
164079
|
+
`**Hash:** \`${att.hash}\``,
|
|
164080
|
+
"",
|
|
164081
|
+
"## Attestation",
|
|
164082
|
+
"",
|
|
164083
|
+
"| Check | Status |",
|
|
164084
|
+
"|-------|--------|",
|
|
164085
|
+
`| Tests Executed | ${att.attestation.testsExecuted ? "PASS" : "FAIL"} |`,
|
|
164086
|
+
`| Coverage Checked | ${att.attestation.coverageChecked ? "PASS" : "FAIL"} |`,
|
|
164087
|
+
`| Security Scanned | ${att.attestation.securityScanned ? "PASS" : "FAIL"} |`,
|
|
164088
|
+
`| Quality Gate | ${att.attestation.qualityGatePassed ? "PASSED" : "FAILED"} |`,
|
|
164089
|
+
"",
|
|
164090
|
+
"## Metrics",
|
|
164091
|
+
"",
|
|
164092
|
+
"| Metric | Value |",
|
|
164093
|
+
"|--------|-------|",
|
|
164094
|
+
`| Tests | ${att.metrics.testCount} |`,
|
|
164095
|
+
`| Pass Rate | ${att.metrics.passRate.toFixed(1)}% |`,
|
|
164096
|
+
`| Coverage | ${att.metrics.coveragePercent.toFixed(1)}% |`,
|
|
164097
|
+
`| Vulnerabilities | ${att.metrics.vulnerabilities} |`,
|
|
164098
|
+
`| Quality Score | ${att.metrics.qualityScore}/100 |`,
|
|
164099
|
+
"",
|
|
164100
|
+
"---",
|
|
164101
|
+
`*${att.generatedBy}*`
|
|
164102
|
+
].join("\n");
|
|
164103
|
+
}
|
|
164104
|
+
async function handleProve(options) {
|
|
164105
|
+
const projectRoot = options.projectRoot ?? process.cwd();
|
|
164106
|
+
const metrics = await collectMetrics(projectRoot);
|
|
164107
|
+
const attestation = buildAttestation(projectRoot, metrics);
|
|
164108
|
+
const content = options.format === "markdown" ? formatMarkdown(attestation) : JSON.stringify(attestation, null, 2);
|
|
164109
|
+
if (options.output) {
|
|
164110
|
+
fs31.writeFileSync(options.output, content);
|
|
164111
|
+
console.log(`Quality attestation written to ${options.output}`);
|
|
164112
|
+
} else {
|
|
164113
|
+
console.log(content);
|
|
164114
|
+
}
|
|
164115
|
+
return attestation;
|
|
164116
|
+
}
|
|
164117
|
+
function createProveCommand(_context, cleanupAndExit2, _ensureInitialized) {
|
|
164118
|
+
return new Command20("prove").description("Generate a verifiable Proof-of-Quality attestation").option("-F, --format <format>", "Output format (json|markdown)", "json").option("-o, --output <path>", "Write attestation to file").action(async (options) => {
|
|
164119
|
+
try {
|
|
164120
|
+
await handleProve({
|
|
164121
|
+
format: options.format,
|
|
164122
|
+
output: options.output
|
|
164123
|
+
});
|
|
164124
|
+
await cleanupAndExit2(0);
|
|
164125
|
+
} catch (error) {
|
|
164126
|
+
console.error("Failed to generate proof-of-quality:", error);
|
|
164127
|
+
await cleanupAndExit2(1);
|
|
164128
|
+
}
|
|
164129
|
+
});
|
|
164130
|
+
}
|
|
164131
|
+
|
|
163401
164132
|
// src/cli/index.ts
|
|
163402
164133
|
var INTERNAL_LOG_PREFIXES = [
|
|
163403
164134
|
"[UnifiedMemory]",
|
|
@@ -163523,10 +164254,10 @@ async function ensureInitializedStrict() {
|
|
|
163523
164254
|
if (context.initialized && context.kernel && context.queen) {
|
|
163524
164255
|
return true;
|
|
163525
164256
|
}
|
|
163526
|
-
const
|
|
163527
|
-
const
|
|
163528
|
-
const configDir =
|
|
163529
|
-
if (!
|
|
164257
|
+
const fs32 = await import("fs");
|
|
164258
|
+
const path37 = await import("path");
|
|
164259
|
+
const configDir = path37.resolve(".agentic-qe");
|
|
164260
|
+
if (!fs32.existsSync(configDir)) {
|
|
163530
164261
|
console.error(chalk33.red("\nError: AQE system not initialized in this directory."));
|
|
163531
164262
|
console.log(chalk33.yellow("Run `aqe init` first to set up this project.\n"));
|
|
163532
164263
|
return false;
|
|
@@ -163581,15 +164312,15 @@ async function cleanupAndExit(code = 0) {
|
|
|
163581
164312
|
}
|
|
163582
164313
|
process.exit(code);
|
|
163583
164314
|
}
|
|
163584
|
-
var program = new
|
|
163585
|
-
var VERSION = true ? "3.7.
|
|
164315
|
+
var program = new Command21();
|
|
164316
|
+
var VERSION = true ? "3.7.16" : "0.0.0-dev";
|
|
163586
164317
|
program.name("aqe").description("Agentic QE - Domain-Driven Quality Engineering").version(VERSION);
|
|
163587
164318
|
var registry2 = createCommandRegistry(context, cleanupAndExit, ensureInitialized, ensureInitializedStrict);
|
|
163588
164319
|
registry2.registerAll(program);
|
|
163589
164320
|
var workflowCmd = program.command("workflow").description("Manage QE workflows and pipelines (ADR-041)");
|
|
163590
164321
|
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) => {
|
|
163591
164322
|
if (!await ensureInitialized()) return;
|
|
163592
|
-
const
|
|
164323
|
+
const fs32 = await import("fs");
|
|
163593
164324
|
const pathModule = await import("path");
|
|
163594
164325
|
const filePath = pathModule.resolve(file);
|
|
163595
164326
|
try {
|
|
@@ -163829,14 +164560,14 @@ workflowCmd.command("list").description("List workflows").option("-s, --schedule
|
|
|
163829
164560
|
}
|
|
163830
164561
|
});
|
|
163831
164562
|
workflowCmd.command("validate <file>").description("Validate a pipeline YAML file").option("-v, --verbose", "Show detailed validation results").action(async (file, options) => {
|
|
163832
|
-
const
|
|
164563
|
+
const fs32 = await import("fs");
|
|
163833
164564
|
const pathModule = await import("path");
|
|
163834
164565
|
const filePath = pathModule.resolve(file);
|
|
163835
164566
|
try {
|
|
163836
164567
|
console.log(chalk33.blue(`
|
|
163837
164568
|
Validating pipeline: ${file}
|
|
163838
164569
|
`));
|
|
163839
|
-
if (!
|
|
164570
|
+
if (!fs32.existsSync(filePath)) {
|
|
163840
164571
|
console.log(chalk33.red(`File not found: ${filePath}`));
|
|
163841
164572
|
await cleanupAndExit(1);
|
|
163842
164573
|
}
|
|
@@ -164029,16 +164760,16 @@ workflowCmd.command("browser-load [template]").description("Load and validate a
|
|
|
164029
164760
|
params.workflowYaml = options.yaml;
|
|
164030
164761
|
} else if (template) {
|
|
164031
164762
|
if (template.endsWith(".yaml") || template.endsWith(".yml")) {
|
|
164032
|
-
const
|
|
164763
|
+
const fs32 = await import("fs");
|
|
164033
164764
|
const pathModule = await import("path");
|
|
164034
164765
|
const filePath = pathModule.resolve(template);
|
|
164035
|
-
if (!
|
|
164766
|
+
if (!fs32.existsSync(filePath)) {
|
|
164036
164767
|
console.log(chalk33.red(`
|
|
164037
164768
|
File not found: ${filePath}
|
|
164038
164769
|
`));
|
|
164039
164770
|
await cleanupAndExit(1);
|
|
164040
164771
|
}
|
|
164041
|
-
params.workflowYaml =
|
|
164772
|
+
params.workflowYaml = fs32.readFileSync(filePath, "utf-8");
|
|
164042
164773
|
} else {
|
|
164043
164774
|
params.templateName = template;
|
|
164044
164775
|
}
|
|
@@ -164121,6 +164852,7 @@ program.addCommand(createHooksCommand());
|
|
|
164121
164852
|
program.addCommand(createLearningCommand());
|
|
164122
164853
|
program.addCommand(createMcpCommand());
|
|
164123
164854
|
program.addCommand(createPlatformCommand());
|
|
164855
|
+
program.addCommand(createProveCommand(context, cleanupAndExit, ensureInitialized));
|
|
164124
164856
|
process.on("SIGINT", async () => {
|
|
164125
164857
|
console.log(chalk33.yellow("\n\nShutting down..."));
|
|
164126
164858
|
console.log(chalk33.green("Shutdown complete\n"));
|