@gluecharm-lab/easyspecs-cli 0.0.26 → 0.0.27
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/commands.md +9 -0
- package/dist/main.cjs +491 -185
- package/dist/main.cjs.map +4 -4
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -960,7 +960,7 @@ var require_command = __commonJS({
|
|
|
960
960
|
var EventEmitter = require("node:events").EventEmitter;
|
|
961
961
|
var childProcess = require("node:child_process");
|
|
962
962
|
var path60 = require("node:path");
|
|
963
|
-
var
|
|
963
|
+
var fs63 = require("node:fs");
|
|
964
964
|
var process2 = require("node:process");
|
|
965
965
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
966
966
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -1893,10 +1893,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1893
1893
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1894
1894
|
function findFile(baseDir, baseName) {
|
|
1895
1895
|
const localBin = path60.resolve(baseDir, baseName);
|
|
1896
|
-
if (
|
|
1896
|
+
if (fs63.existsSync(localBin)) return localBin;
|
|
1897
1897
|
if (sourceExt.includes(path60.extname(baseName))) return void 0;
|
|
1898
1898
|
const foundExt = sourceExt.find(
|
|
1899
|
-
(ext) =>
|
|
1899
|
+
(ext) => fs63.existsSync(`${localBin}${ext}`)
|
|
1900
1900
|
);
|
|
1901
1901
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
1902
1902
|
return void 0;
|
|
@@ -1908,7 +1908,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1908
1908
|
if (this._scriptPath) {
|
|
1909
1909
|
let resolvedScriptPath;
|
|
1910
1910
|
try {
|
|
1911
|
-
resolvedScriptPath =
|
|
1911
|
+
resolvedScriptPath = fs63.realpathSync(this._scriptPath);
|
|
1912
1912
|
} catch (err) {
|
|
1913
1913
|
resolvedScriptPath = this._scriptPath;
|
|
1914
1914
|
}
|
|
@@ -10622,12 +10622,12 @@ var require_dist = __commonJS({
|
|
|
10622
10622
|
throw new Error(`Unknown format "${name}"`);
|
|
10623
10623
|
return f;
|
|
10624
10624
|
};
|
|
10625
|
-
function addFormats2(ajv2, list,
|
|
10625
|
+
function addFormats2(ajv2, list, fs63, exportName) {
|
|
10626
10626
|
var _a;
|
|
10627
10627
|
var _b;
|
|
10628
10628
|
(_a = (_b = ajv2.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
10629
10629
|
for (const f of list)
|
|
10630
|
-
ajv2.addFormat(f,
|
|
10630
|
+
ajv2.addFormat(f, fs63[f]);
|
|
10631
10631
|
}
|
|
10632
10632
|
module2.exports = exports2 = formatsPlugin;
|
|
10633
10633
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -10636,7 +10636,7 @@ var require_dist = __commonJS({
|
|
|
10636
10636
|
});
|
|
10637
10637
|
|
|
10638
10638
|
// src/cli/main.ts
|
|
10639
|
-
var
|
|
10639
|
+
var fs62 = __toESM(require("node:fs"));
|
|
10640
10640
|
var path59 = __toESM(require("node:path"));
|
|
10641
10641
|
|
|
10642
10642
|
// src/cli/exitCodes.ts
|
|
@@ -13192,7 +13192,7 @@ function createFileBackedWorkspaceState(repoRoot) {
|
|
|
13192
13192
|
}
|
|
13193
13193
|
|
|
13194
13194
|
// src/pipelines/synthesis/synthesisPipeline.ts
|
|
13195
|
-
var
|
|
13195
|
+
var fs37 = __toESM(require("fs"));
|
|
13196
13196
|
var path32 = __toESM(require("path"));
|
|
13197
13197
|
|
|
13198
13198
|
// src/analysis/analysisDynamicTestSteps.ts
|
|
@@ -20329,6 +20329,295 @@ function nextAdaptiveMaxAfterCpuSample(p) {
|
|
|
20329
20329
|
return { adaptiveMax: p.priorAdaptiveMax, changed: false };
|
|
20330
20330
|
}
|
|
20331
20331
|
|
|
20332
|
+
// src/hostPoolPeriodicDiagnostics.ts
|
|
20333
|
+
var fs36 = __toESM(require("fs"));
|
|
20334
|
+
var DEFAULT_HOST_POOL_INTERVAL_MS = 45e3;
|
|
20335
|
+
var MAX_ADVICE_TEXT_CHARS = 400;
|
|
20336
|
+
var MAX_FD_ENUM = 4096;
|
|
20337
|
+
var TEMPLATE_MEMORY_KO = "Low free RAM or swap in this worker: lower easyspecs.workstations.maxConcurrentAi (or host concurrency cap), raise Celery worker or container memory if you can, and verify with vmstat or cgroup memory stats.";
|
|
20338
|
+
var TEMPLATE_SCHEDULER_KO = "High load vs CPUs in this worker: lower easyspecs.workstations.maxConcurrentAi and watch earlier [pool] lines for adaptive cap changes; if load stays high while only this task runs, check worker CPU limits or VM CPU steal.";
|
|
20339
|
+
var TEMPLATE_IO_KO = "Elevated I/O wait (Linux /proc delta): check disk saturation with iostat or vmstat; fewer easyspecs concurrent agents help; on a host dedicated to this task, inspect storage latency, disk quotas, or shared volume contention.";
|
|
20340
|
+
var TEMPLATE_LIMITS_KO = "This Node process is near soft FD/process/thread limits: raise ulimit or prlimit for the Celery worker process, or lower easyspecs.workstations.maxConcurrentAi; confirm with /proc/self/limits.";
|
|
20341
|
+
function hintSchedulerFromSnapshot(s) {
|
|
20342
|
+
const p = s.load1PerCpu;
|
|
20343
|
+
if (p === null || !Number.isFinite(p)) {
|
|
20344
|
+
return "UNK";
|
|
20345
|
+
}
|
|
20346
|
+
if (p >= 1.25) {
|
|
20347
|
+
return "KO";
|
|
20348
|
+
}
|
|
20349
|
+
if (p < 1) {
|
|
20350
|
+
return "OK";
|
|
20351
|
+
}
|
|
20352
|
+
return "UNK";
|
|
20353
|
+
}
|
|
20354
|
+
function hintMemoryFrom(platform, s, swap) {
|
|
20355
|
+
const total = s.hostRamTotalB;
|
|
20356
|
+
if (total <= 0) {
|
|
20357
|
+
return "UNK";
|
|
20358
|
+
}
|
|
20359
|
+
const freeRatio = s.hostRamFreeB / total;
|
|
20360
|
+
let ram;
|
|
20361
|
+
if (freeRatio < 0.07) {
|
|
20362
|
+
ram = "KO";
|
|
20363
|
+
} else if (freeRatio < 0.1) {
|
|
20364
|
+
ram = "UNK";
|
|
20365
|
+
} else {
|
|
20366
|
+
ram = "OK";
|
|
20367
|
+
}
|
|
20368
|
+
let swapH = "OK";
|
|
20369
|
+
if (platform === "linux" && swap !== null && swap.swapTotalB > 0) {
|
|
20370
|
+
const sf = swap.swapFreeB / swap.swapTotalB;
|
|
20371
|
+
if (sf < 0.08) {
|
|
20372
|
+
swapH = "KO";
|
|
20373
|
+
} else if (sf < 0.15) {
|
|
20374
|
+
swapH = "UNK";
|
|
20375
|
+
} else {
|
|
20376
|
+
swapH = "OK";
|
|
20377
|
+
}
|
|
20378
|
+
}
|
|
20379
|
+
if (ram === "KO" || swapH === "KO") {
|
|
20380
|
+
return "KO";
|
|
20381
|
+
}
|
|
20382
|
+
if (ram === "UNK" || swapH === "UNK") {
|
|
20383
|
+
return "UNK";
|
|
20384
|
+
}
|
|
20385
|
+
return "OK";
|
|
20386
|
+
}
|
|
20387
|
+
function hintLimitsFrom(sample) {
|
|
20388
|
+
if (sample === null) {
|
|
20389
|
+
return "UNK";
|
|
20390
|
+
}
|
|
20391
|
+
if (sample.truncated) {
|
|
20392
|
+
return "UNK";
|
|
20393
|
+
}
|
|
20394
|
+
const ratios = [];
|
|
20395
|
+
if (sample.fdRatio !== null && Number.isFinite(sample.fdRatio)) {
|
|
20396
|
+
ratios.push(sample.fdRatio);
|
|
20397
|
+
}
|
|
20398
|
+
if (sample.procRatio !== null && Number.isFinite(sample.procRatio)) {
|
|
20399
|
+
ratios.push(sample.procRatio);
|
|
20400
|
+
}
|
|
20401
|
+
if (ratios.length === 0) {
|
|
20402
|
+
return "UNK";
|
|
20403
|
+
}
|
|
20404
|
+
if (ratios.some((r) => r >= 0.85)) {
|
|
20405
|
+
return "KO";
|
|
20406
|
+
}
|
|
20407
|
+
if (ratios.every((r) => r < 0.75)) {
|
|
20408
|
+
return "OK";
|
|
20409
|
+
}
|
|
20410
|
+
return "UNK";
|
|
20411
|
+
}
|
|
20412
|
+
function hintIoFrom(prev, curr) {
|
|
20413
|
+
if (prev === null || curr === null) {
|
|
20414
|
+
return "UNK";
|
|
20415
|
+
}
|
|
20416
|
+
const dTotal = curr.total - prev.total;
|
|
20417
|
+
const dIo = curr.iowait - prev.iowait;
|
|
20418
|
+
if (dTotal <= 0 || !Number.isFinite(dTotal) || !Number.isFinite(dIo)) {
|
|
20419
|
+
return "UNK";
|
|
20420
|
+
}
|
|
20421
|
+
const share = dIo / dTotal;
|
|
20422
|
+
if (!Number.isFinite(share)) {
|
|
20423
|
+
return "UNK";
|
|
20424
|
+
}
|
|
20425
|
+
if (share >= 0.22) {
|
|
20426
|
+
return "KO";
|
|
20427
|
+
}
|
|
20428
|
+
if (share <= 0.12) {
|
|
20429
|
+
return "OK";
|
|
20430
|
+
}
|
|
20431
|
+
return "UNK";
|
|
20432
|
+
}
|
|
20433
|
+
function computeHostPoolHints(input) {
|
|
20434
|
+
return {
|
|
20435
|
+
hintScheduler: hintSchedulerFromSnapshot(input.snapshot),
|
|
20436
|
+
hintMemory: hintMemoryFrom(input.platform, input.snapshot, input.swap),
|
|
20437
|
+
hintLimits: hintLimitsFrom(input.limits),
|
|
20438
|
+
hintIo: hintIoFrom(input.prevStat, input.currStat)
|
|
20439
|
+
};
|
|
20440
|
+
}
|
|
20441
|
+
function tryReadLinuxSwapBytesFromMeminfo(readFileSyncImpl = fs36.readFileSync) {
|
|
20442
|
+
let raw;
|
|
20443
|
+
try {
|
|
20444
|
+
raw = readFileSyncImpl("/proc/meminfo", { encoding: "utf8", flag: "r" });
|
|
20445
|
+
} catch {
|
|
20446
|
+
return null;
|
|
20447
|
+
}
|
|
20448
|
+
let swapTotalKb = null;
|
|
20449
|
+
let swapFreeKb = null;
|
|
20450
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
20451
|
+
const tm = /^\s*SwapTotal:\s+(\d+)\s+kB/i.exec(line);
|
|
20452
|
+
if (tm) {
|
|
20453
|
+
swapTotalKb = Number(tm[1]);
|
|
20454
|
+
}
|
|
20455
|
+
const fm = /^\s*SwapFree:\s+(\d+)\s+kB/i.exec(line);
|
|
20456
|
+
if (fm) {
|
|
20457
|
+
swapFreeKb = Number(fm[1]);
|
|
20458
|
+
}
|
|
20459
|
+
}
|
|
20460
|
+
if (swapTotalKb === null || swapFreeKb === null || !Number.isFinite(swapTotalKb) || !Number.isFinite(swapFreeKb) || swapTotalKb < 0 || swapFreeKb < 0) {
|
|
20461
|
+
return null;
|
|
20462
|
+
}
|
|
20463
|
+
return {
|
|
20464
|
+
swapTotalB: Math.floor(swapTotalKb * 1024),
|
|
20465
|
+
swapFreeB: Math.floor(swapFreeKb * 1024)
|
|
20466
|
+
};
|
|
20467
|
+
}
|
|
20468
|
+
function tryReadLinuxAggregateCpuJiffies(readFileSyncImpl = fs36.readFileSync) {
|
|
20469
|
+
let raw;
|
|
20470
|
+
try {
|
|
20471
|
+
raw = readFileSyncImpl("/proc/stat", { encoding: "utf8", flag: "r" });
|
|
20472
|
+
} catch {
|
|
20473
|
+
return null;
|
|
20474
|
+
}
|
|
20475
|
+
const firstLine = raw.split(/\r?\n/)[0] ?? "";
|
|
20476
|
+
return parseLinuxAggregateCpuLine(firstLine);
|
|
20477
|
+
}
|
|
20478
|
+
function parseLinuxAggregateCpuLine(line) {
|
|
20479
|
+
const t = line.trim();
|
|
20480
|
+
if (!t.startsWith("cpu") || /^cpu\d/.test(t)) {
|
|
20481
|
+
return null;
|
|
20482
|
+
}
|
|
20483
|
+
const parts = t.split(/\s+/);
|
|
20484
|
+
if (parts.length < 6 || parts[0] !== "cpu") {
|
|
20485
|
+
return null;
|
|
20486
|
+
}
|
|
20487
|
+
const nums = [];
|
|
20488
|
+
for (let i = 1; i < parts.length; i++) {
|
|
20489
|
+
const n = Number(parts[i]);
|
|
20490
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
20491
|
+
return null;
|
|
20492
|
+
}
|
|
20493
|
+
nums.push(Math.floor(n));
|
|
20494
|
+
}
|
|
20495
|
+
const total = nums.reduce((a, b) => a + b, 0);
|
|
20496
|
+
const iowait = nums.length >= 5 ? nums[4] : 0;
|
|
20497
|
+
return { total, iowait };
|
|
20498
|
+
}
|
|
20499
|
+
function parseProcSelfLimitsSoft(content, label) {
|
|
20500
|
+
const re = label === "Max open files" ? /^\s*Max open files\s+(\d+)\s+(\d+)/m : /^\s*Max processes\s+(\d+)\s+(\d+)/m;
|
|
20501
|
+
const m = re.exec(content);
|
|
20502
|
+
if (!m) {
|
|
20503
|
+
return null;
|
|
20504
|
+
}
|
|
20505
|
+
const soft = Number(m[1]);
|
|
20506
|
+
return Number.isFinite(soft) && soft > 0 ? soft : null;
|
|
20507
|
+
}
|
|
20508
|
+
function parseProcSelfStatusThreads(content) {
|
|
20509
|
+
const m = /^\s*Threads:\s*(\d+)/m.exec(content);
|
|
20510
|
+
if (!m) {
|
|
20511
|
+
return null;
|
|
20512
|
+
}
|
|
20513
|
+
const n = Number(m[1]);
|
|
20514
|
+
return Number.isFinite(n) && n >= 0 ? n : null;
|
|
20515
|
+
}
|
|
20516
|
+
function trySampleLinuxLimits(platform, readFileSyncImpl = fs36.readFileSync, readdirSyncImpl = fs36.readdirSync) {
|
|
20517
|
+
if (platform !== "linux") {
|
|
20518
|
+
return null;
|
|
20519
|
+
}
|
|
20520
|
+
let limitsRaw;
|
|
20521
|
+
let statusRaw;
|
|
20522
|
+
try {
|
|
20523
|
+
limitsRaw = readFileSyncImpl("/proc/self/limits", { encoding: "utf8", flag: "r" });
|
|
20524
|
+
statusRaw = readFileSyncImpl("/proc/self/status", { encoding: "utf8", flag: "r" });
|
|
20525
|
+
} catch {
|
|
20526
|
+
return null;
|
|
20527
|
+
}
|
|
20528
|
+
const nofileSoft = parseProcSelfLimitsSoft(limitsRaw, "Max open files");
|
|
20529
|
+
const nprocSoft = parseProcSelfLimitsSoft(limitsRaw, "Max processes");
|
|
20530
|
+
const threads = parseProcSelfStatusThreads(statusRaw);
|
|
20531
|
+
let fdCount = 0;
|
|
20532
|
+
let truncated = false;
|
|
20533
|
+
try {
|
|
20534
|
+
const names = readdirSyncImpl("/proc/self/fd");
|
|
20535
|
+
truncated = names.length > MAX_FD_ENUM;
|
|
20536
|
+
fdCount = Math.min(names.length, MAX_FD_ENUM);
|
|
20537
|
+
} catch {
|
|
20538
|
+
return { fdRatio: null, procRatio: null, truncated: true };
|
|
20539
|
+
}
|
|
20540
|
+
const fdRatio = nofileSoft !== null && nofileSoft > 0 ? Math.min(1, fdCount / nofileSoft) : null;
|
|
20541
|
+
const procRatio = nprocSoft !== null && nprocSoft > 0 && threads !== null ? Math.min(1, threads / nprocSoft) : null;
|
|
20542
|
+
return { fdRatio, procRatio, truncated };
|
|
20543
|
+
}
|
|
20544
|
+
function formatHostPoolPeriodicLine(params) {
|
|
20545
|
+
const s = params.snapshot;
|
|
20546
|
+
const load1Str = s.load1 === null ? "unknown" : String(s.load1);
|
|
20547
|
+
const perCpuStr = s.load1PerCpu === null ? "unknown" : String(s.load1PerCpu);
|
|
20548
|
+
const swapPart = params.swap !== null ? ` swapTotalB=${String(params.swap.swapTotalB)} swapFreeB=${String(params.swap.swapFreeB)}` : "";
|
|
20549
|
+
return `[host-pool] activeWorkstations=${String(params.activeWorkstations)} staticMaxConcurrentAi=${String(params.staticMaxConcurrentAi)} adaptiveMaxConcurrentAi=${String(params.adaptiveMaxConcurrentAi)} hostRamTotalB=${String(s.hostRamTotalB)} hostRamFreeB=${String(s.hostRamFreeB)} hostRamUsedB=${String(s.hostRamUsedB)} cpusLogical=${String(s.cpusLogical)} load1=${load1Str} load1PerCpu=${perCpuStr}${swapPart} hintScheduler=${params.hints.hintScheduler} hintMemory=${params.hints.hintMemory} hintLimits=${params.hints.hintLimits} hintIo=${params.hints.hintIo}`;
|
|
20550
|
+
}
|
|
20551
|
+
function anyKo(h) {
|
|
20552
|
+
return h.hintMemory === "KO" || h.hintScheduler === "KO" || h.hintIo === "KO" || h.hintLimits === "KO";
|
|
20553
|
+
}
|
|
20554
|
+
function formatHostPoolRecLine(hints) {
|
|
20555
|
+
if (!anyKo(hints)) {
|
|
20556
|
+
return "[host-pool-rec] kind=none";
|
|
20557
|
+
}
|
|
20558
|
+
const parts = [];
|
|
20559
|
+
if (hints.hintMemory === "KO") {
|
|
20560
|
+
parts.push(TEMPLATE_MEMORY_KO);
|
|
20561
|
+
}
|
|
20562
|
+
if (hints.hintScheduler === "KO") {
|
|
20563
|
+
parts.push(TEMPLATE_SCHEDULER_KO);
|
|
20564
|
+
}
|
|
20565
|
+
if (hints.hintIo === "KO") {
|
|
20566
|
+
parts.push(TEMPLATE_IO_KO);
|
|
20567
|
+
}
|
|
20568
|
+
if (hints.hintLimits === "KO") {
|
|
20569
|
+
parts.push(TEMPLATE_LIMITS_KO);
|
|
20570
|
+
}
|
|
20571
|
+
let text = parts.join(" | ");
|
|
20572
|
+
if (text.length > MAX_ADVICE_TEXT_CHARS) {
|
|
20573
|
+
text = `${text.slice(0, MAX_ADVICE_TEXT_CHARS - 2)} \u2026`;
|
|
20574
|
+
}
|
|
20575
|
+
return `[host-pool-rec] kind=advice text=${text}`;
|
|
20576
|
+
}
|
|
20577
|
+
function createHostPoolTick(deps) {
|
|
20578
|
+
const platform = deps.platform ?? process.platform;
|
|
20579
|
+
const collect = deps.collectHostSnapshotFn ?? collectHostSnapshot;
|
|
20580
|
+
const readFs = deps.readFileSyncFn ?? fs36.readFileSync;
|
|
20581
|
+
const readDir = deps.readdirSyncFn ?? fs36.readdirSync;
|
|
20582
|
+
return () => {
|
|
20583
|
+
const { active, staticMaxConcurrentAi, adaptiveMaxConcurrentAi } = deps.getPoolState();
|
|
20584
|
+
if (active < 1) {
|
|
20585
|
+
return;
|
|
20586
|
+
}
|
|
20587
|
+
const snapshot = collect();
|
|
20588
|
+
let swap = null;
|
|
20589
|
+
let currStat = null;
|
|
20590
|
+
let limits = null;
|
|
20591
|
+
if (platform === "linux") {
|
|
20592
|
+
swap = tryReadLinuxSwapBytesFromMeminfo(readFs);
|
|
20593
|
+
currStat = tryReadLinuxAggregateCpuJiffies(readFs);
|
|
20594
|
+
limits = trySampleLinuxLimits(platform, readFs, readDir);
|
|
20595
|
+
}
|
|
20596
|
+
const hints = computeHostPoolHints({
|
|
20597
|
+
platform,
|
|
20598
|
+
snapshot,
|
|
20599
|
+
swap,
|
|
20600
|
+
limits,
|
|
20601
|
+
prevStat: deps.prevProcStatRef.current,
|
|
20602
|
+
currStat
|
|
20603
|
+
});
|
|
20604
|
+
const metrics = formatHostPoolPeriodicLine({
|
|
20605
|
+
activeWorkstations: active,
|
|
20606
|
+
staticMaxConcurrentAi,
|
|
20607
|
+
adaptiveMaxConcurrentAi,
|
|
20608
|
+
snapshot,
|
|
20609
|
+
hints,
|
|
20610
|
+
swap
|
|
20611
|
+
});
|
|
20612
|
+
const rec = formatHostPoolRecLine(hints);
|
|
20613
|
+
deps.log(metrics);
|
|
20614
|
+
deps.log(rec);
|
|
20615
|
+
if (platform === "linux" && currStat !== null) {
|
|
20616
|
+
deps.prevProcStatRef.current = currStat;
|
|
20617
|
+
}
|
|
20618
|
+
};
|
|
20619
|
+
}
|
|
20620
|
+
|
|
20332
20621
|
// src/pipelines/synthesis/synthesisPipeline.ts
|
|
20333
20622
|
var FE = /^FE-\d+$/;
|
|
20334
20623
|
var UC = /^UC-\d+$/;
|
|
@@ -20341,7 +20630,7 @@ function stripBom2(s) {
|
|
|
20341
20630
|
}
|
|
20342
20631
|
function readJson4(filePath) {
|
|
20343
20632
|
try {
|
|
20344
|
-
const raw = stripBom2(
|
|
20633
|
+
const raw = stripBom2(fs37.readFileSync(filePath, "utf-8"));
|
|
20345
20634
|
return JSON.parse(raw);
|
|
20346
20635
|
} catch {
|
|
20347
20636
|
return null;
|
|
@@ -20436,7 +20725,7 @@ function featureDetailTarget(contextDir2, code, name, slug) {
|
|
|
20436
20725
|
displayName: "Feature detail",
|
|
20437
20726
|
outputBasename: basename17,
|
|
20438
20727
|
taskDescription: `Document feature **${code}** (**${name}**, slug **${slug}**) per \`.gluecharm/context/features-list.json\`: scope, behaviour, main dependencies, entry points, and links to code under the worktree. Write exactly one markdown file at the output path; cite substantive claims with file and line (or range).`,
|
|
20439
|
-
exists:
|
|
20728
|
+
exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
|
|
20440
20729
|
};
|
|
20441
20730
|
}
|
|
20442
20731
|
function viewDetailTarget(row2, contextDir2) {
|
|
@@ -20447,7 +20736,7 @@ function viewDetailTarget(row2, contextDir2) {
|
|
|
20447
20736
|
displayName: "View detail",
|
|
20448
20737
|
outputBasename: basename17,
|
|
20449
20738
|
taskDescription: `Describe view **${row2.code}** (**${row2.name}**, slug **${row2.slug}**) per \`.gluecharm/context/experiences-list.json\`: purpose, layout, controls, navigation, data shown; ground in components and routes.`,
|
|
20450
|
-
exists:
|
|
20739
|
+
exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
|
|
20451
20740
|
};
|
|
20452
20741
|
}
|
|
20453
20742
|
function interactionDetailTarget(viewCode, ix, contextDir2) {
|
|
@@ -20458,7 +20747,7 @@ function interactionDetailTarget(viewCode, ix, contextDir2) {
|
|
|
20458
20747
|
displayName: "Interaction detail",
|
|
20459
20748
|
outputBasename: basename17,
|
|
20460
20749
|
taskDescription: `Document interaction **${ix.code}** (**${ix.name}**) on view **${viewCode}** per \`.gluecharm/context/experiences-list.json\`.`,
|
|
20461
|
-
exists:
|
|
20750
|
+
exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
|
|
20462
20751
|
};
|
|
20463
20752
|
}
|
|
20464
20753
|
function serviceDetailTarget(row2, contextDir2) {
|
|
@@ -20469,7 +20758,7 @@ function serviceDetailTarget(row2, contextDir2) {
|
|
|
20469
20758
|
displayName: "Service detail",
|
|
20470
20759
|
outputBasename: basename17,
|
|
20471
20760
|
taskDescription: `Describe service **${row2.code}** (**${row2.name}**, slug **${row2.slug}**) per \`.gluecharm/context/services-list.json\`: responsibilities, consumers, errors, integration points.`,
|
|
20472
|
-
exists:
|
|
20761
|
+
exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
|
|
20473
20762
|
};
|
|
20474
20763
|
}
|
|
20475
20764
|
function methodDetailTarget(svc, m, contextDir2) {
|
|
@@ -20480,7 +20769,7 @@ function methodDetailTarget(svc, m, contextDir2) {
|
|
|
20480
20769
|
displayName: "Method detail",
|
|
20481
20770
|
outputBasename: basename17,
|
|
20482
20771
|
taskDescription: `Document method **${m.code}** (**${m.name}**) on service **${svc.code}** per \`.gluecharm/context/services-list.json\`.`,
|
|
20483
|
-
exists:
|
|
20772
|
+
exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
|
|
20484
20773
|
};
|
|
20485
20774
|
}
|
|
20486
20775
|
function entityDetailTarget(dmCode, ename, slug, contextDir2) {
|
|
@@ -20491,7 +20780,7 @@ function entityDetailTarget(dmCode, ename, slug, contextDir2) {
|
|
|
20491
20780
|
displayName: "Entity detail",
|
|
20492
20781
|
outputBasename: basename17,
|
|
20493
20782
|
taskDescription: `Describe entity **${dmCode}** (**${ename}**, slug **${slug}**) per \`.gluecharm/context/data-model-list.json\`: lifecycle, invariants, storage, ORM/schema mapping.`,
|
|
20494
|
-
exists:
|
|
20783
|
+
exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
|
|
20495
20784
|
};
|
|
20496
20785
|
}
|
|
20497
20786
|
function fieldDetailTarget(dmCode, fdCode, fname, fSlug, contextDir2) {
|
|
@@ -20502,7 +20791,7 @@ function fieldDetailTarget(dmCode, fdCode, fname, fSlug, contextDir2) {
|
|
|
20502
20791
|
displayName: "Field detail",
|
|
20503
20792
|
outputBasename: basename17,
|
|
20504
20793
|
taskDescription: `Document field **${fdCode}** (**${fname}**) on entity **${dmCode}** per \`.gluecharm/context/${dmCode}-fields-list.json\`. Cite types and constraints with file and line.`,
|
|
20505
|
-
exists:
|
|
20794
|
+
exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
|
|
20506
20795
|
};
|
|
20507
20796
|
}
|
|
20508
20797
|
function toolDetailTarget(row2, contextDir2) {
|
|
@@ -20513,7 +20802,7 @@ function toolDetailTarget(row2, contextDir2) {
|
|
|
20513
20802
|
displayName: "Tool detail",
|
|
20514
20803
|
outputBasename: basename17,
|
|
20515
20804
|
taskDescription: `Describe tool **${row2.code}** (**${row2.name}**, slug **${row2.slug}**) per \`.gluecharm/context/tech-stack-list.json\`: role, version hints, configuration, boundaries.`,
|
|
20516
|
-
exists:
|
|
20805
|
+
exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
|
|
20517
20806
|
};
|
|
20518
20807
|
}
|
|
20519
20808
|
function useCaseDetailTarget(feCode, ucCode, ucName, ucSlug, contextDir2) {
|
|
@@ -20526,7 +20815,7 @@ function useCaseDetailTarget(feCode, ucCode, ucName, ucSlug, contextDir2) {
|
|
|
20526
20815
|
taskDescription: `Document use case **${ucCode}** (**${ucName}**) under feature **${feCode}** per \`.gluecharm/context/${feCode}-use-cases-list.json\`. Do not change stable codes.
|
|
20527
20816
|
|
|
20528
20817
|
Follow bundled agent **agent-md-use-case-detail**: include **## Data inputs and validation** (concrete fields, mandatory vs optional, rules, failure behaviour). **## Code flow** must trace **implementation order** (entrypoint \u2192 validation \u2192 business rules \u2192 persistence \u2192 response) with **real** symbols and files\u2014not generic \u201Cuser does X\u201D. Add a **Mermaid** fenced diagram under Code flow when there are **two or more** implementation stages. **## Evidence index** must cite **each major stage** (validation, persistence, response), not only the outer entrypoint.`,
|
|
20529
|
-
exists:
|
|
20818
|
+
exists: fs37.existsSync(path32.join(contextDir2, ucBase)) && fs37.statSync(path32.join(contextDir2, ucBase)).size > 0
|
|
20530
20819
|
};
|
|
20531
20820
|
}
|
|
20532
20821
|
function scenarioDetailTarget(feCode, ucCode, scCode, scName, contextDir2) {
|
|
@@ -20537,7 +20826,7 @@ function scenarioDetailTarget(feCode, ucCode, scCode, scName, contextDir2) {
|
|
|
20537
20826
|
displayName: "Scenario detail",
|
|
20538
20827
|
outputBasename: basename17,
|
|
20539
20828
|
taskDescription: `Document scenario **${scCode}** (**${scName}**) for **${feCode}** / **${ucCode}** per \`.gluecharm/context/${feCode}_${ucCode}-scenarios-list.json\`. Cite steps with file and line where possible.`,
|
|
20540
|
-
exists:
|
|
20829
|
+
exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
|
|
20541
20830
|
};
|
|
20542
20831
|
}
|
|
20543
20832
|
function parentsDone(item, byId) {
|
|
@@ -21097,6 +21386,20 @@ async function drainWorkstationPool(p) {
|
|
|
21097
21386
|
const intervalMs = p.__testOnlyCpuPressureIntervalMs ?? 3e4;
|
|
21098
21387
|
pressureInterval = setInterval(() => applyCpuPressure(), intervalMs);
|
|
21099
21388
|
}
|
|
21389
|
+
const hostPoolPrevStat = { current: null };
|
|
21390
|
+
const hostPoolTick = createHostPoolTick({
|
|
21391
|
+
log,
|
|
21392
|
+
getPoolState: () => ({
|
|
21393
|
+
active,
|
|
21394
|
+
staticMaxConcurrentAi: staticMaxC,
|
|
21395
|
+
adaptiveMaxConcurrentAi: adaptiveMax
|
|
21396
|
+
}),
|
|
21397
|
+
prevProcStatRef: hostPoolPrevStat
|
|
21398
|
+
});
|
|
21399
|
+
const hostPoolIntervalMs = p.__testOnlyHostPoolIntervalMs ?? DEFAULT_HOST_POOL_INTERVAL_MS;
|
|
21400
|
+
const hostPoolInterval = setInterval(() => {
|
|
21401
|
+
hostPoolTick();
|
|
21402
|
+
}, hostPoolIntervalMs);
|
|
21100
21403
|
try {
|
|
21101
21404
|
while (true) {
|
|
21102
21405
|
while (fifo.length > 0 && active < currentCap() && !abortSignal?.aborted) {
|
|
@@ -21127,6 +21430,7 @@ async function drainWorkstationPool(p) {
|
|
|
21127
21430
|
if (pressureInterval) {
|
|
21128
21431
|
clearInterval(pressureInterval);
|
|
21129
21432
|
}
|
|
21433
|
+
clearInterval(hostPoolInterval);
|
|
21130
21434
|
if (poolAbortListenerRegistered && abortSignal) {
|
|
21131
21435
|
abortSignal.removeEventListener("abort", onPipelineAbort);
|
|
21132
21436
|
}
|
|
@@ -21166,7 +21470,7 @@ async function runSynthesisPipelineDrainFromPreparedWorktree(storageContext, rep
|
|
|
21166
21470
|
offlineLearnAfterSameSessionTrace: getAceOfflineLearnAfterSameSessionTrace(handle.path)
|
|
21167
21471
|
};
|
|
21168
21472
|
const contextDir2 = path32.join(handle.path, ".gluecharm", "context");
|
|
21169
|
-
|
|
21473
|
+
fs37.mkdirSync(contextDir2, { recursive: true });
|
|
21170
21474
|
const initialItems = buildRootItems();
|
|
21171
21475
|
await startArtefactRun(storageContext, repoRoot, handle.path, initialItems);
|
|
21172
21476
|
await cb.onBootstrapReady?.({ worktreeRoot: handle.path, contextDir: contextDir2 });
|
|
@@ -21267,27 +21571,27 @@ async function runSynthesisPipeline(storageContext, repoRoot, workspaceLabel, ex
|
|
|
21267
21571
|
}
|
|
21268
21572
|
|
|
21269
21573
|
// src/workspaceContextPromote.ts
|
|
21270
|
-
var
|
|
21574
|
+
var fs38 = __toESM(require("fs"));
|
|
21271
21575
|
var path33 = __toESM(require("path"));
|
|
21272
21576
|
function promoteContextDirectoryToWorkspaceFs(sourceContextDir, workspaceRootFs) {
|
|
21273
21577
|
const dest = path33.join(workspaceRootFs, ".gluecharm", "context");
|
|
21274
|
-
|
|
21275
|
-
|
|
21578
|
+
fs38.mkdirSync(path33.join(workspaceRootFs, ".gluecharm"), { recursive: true });
|
|
21579
|
+
fs38.mkdirSync(dest, { recursive: true });
|
|
21276
21580
|
let names;
|
|
21277
21581
|
try {
|
|
21278
|
-
names =
|
|
21582
|
+
names = fs38.readdirSync(sourceContextDir);
|
|
21279
21583
|
} catch {
|
|
21280
21584
|
return { filesCopied: 0 };
|
|
21281
21585
|
}
|
|
21282
21586
|
let filesCopied = 0;
|
|
21283
21587
|
for (const name of names) {
|
|
21284
21588
|
const srcPath = path33.join(sourceContextDir, name);
|
|
21285
|
-
if (!
|
|
21589
|
+
if (!fs38.statSync(srcPath).isFile()) {
|
|
21286
21590
|
continue;
|
|
21287
21591
|
}
|
|
21288
|
-
const buf =
|
|
21592
|
+
const buf = fs38.readFileSync(srcPath);
|
|
21289
21593
|
const target = path33.join(dest, name);
|
|
21290
|
-
|
|
21594
|
+
fs38.writeFileSync(target, buf);
|
|
21291
21595
|
filesCopied += 1;
|
|
21292
21596
|
}
|
|
21293
21597
|
return { filesCopied };
|
|
@@ -21947,7 +22251,7 @@ async function runGenerateContextFactory(deps) {
|
|
|
21947
22251
|
}
|
|
21948
22252
|
|
|
21949
22253
|
// src/factory/generateContextFactoryHeadlessHost.ts
|
|
21950
|
-
var
|
|
22254
|
+
var fs47 = __toESM(require("node:fs"));
|
|
21951
22255
|
var path43 = __toESM(require("node:path"));
|
|
21952
22256
|
|
|
21953
22257
|
// src/stores/pipelineRunStore.ts
|
|
@@ -22048,11 +22352,11 @@ async function noteAgentsMaterialized(context) {
|
|
|
22048
22352
|
}
|
|
22049
22353
|
|
|
22050
22354
|
// src/pipelines/remediation/missingWorkstations.ts
|
|
22051
|
-
var
|
|
22355
|
+
var fs40 = __toESM(require("fs"));
|
|
22052
22356
|
var path35 = __toESM(require("path"));
|
|
22053
22357
|
|
|
22054
22358
|
// src/analysis/analysisDetailMarkdownDiscovery.ts
|
|
22055
|
-
var
|
|
22359
|
+
var fs39 = __toESM(require("fs"));
|
|
22056
22360
|
var path34 = __toESM(require("path"));
|
|
22057
22361
|
var SLUG4 = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
22058
22362
|
var FE2 = /^FE-\d+$/;
|
|
@@ -22074,7 +22378,7 @@ var STEM_TO_AGENT = {
|
|
|
22074
22378
|
};
|
|
22075
22379
|
function readJson5(filePath) {
|
|
22076
22380
|
try {
|
|
22077
|
-
let raw =
|
|
22381
|
+
let raw = fs39.readFileSync(filePath, "utf-8");
|
|
22078
22382
|
if (raw.length > 0 && raw.charCodeAt(0) === 65279) {
|
|
22079
22383
|
raw = raw.slice(1);
|
|
22080
22384
|
}
|
|
@@ -22342,7 +22646,7 @@ function fileAndValidationFromKind(kind) {
|
|
|
22342
22646
|
function classifyMissingWorkstationOutputFileStatus(row2, contextDir2, worktreeRoot) {
|
|
22343
22647
|
const abs = path35.join(contextDir2, row2.relativePath);
|
|
22344
22648
|
try {
|
|
22345
|
-
const st =
|
|
22649
|
+
const st = fs40.statSync(abs);
|
|
22346
22650
|
if (!st.isFile()) {
|
|
22347
22651
|
return { kind: "absent", detail: "Path exists but is not a regular file." };
|
|
22348
22652
|
}
|
|
@@ -22380,7 +22684,7 @@ function classifyMissingWorkstationOutputFileStatus(row2, contextDir2, worktreeR
|
|
|
22380
22684
|
};
|
|
22381
22685
|
}
|
|
22382
22686
|
const schemaAbs = path35.join(worktreeRoot, ".opencode", "schemas", "context-lists", schemaBn);
|
|
22383
|
-
if (!
|
|
22687
|
+
if (!fs40.existsSync(schemaAbs)) {
|
|
22384
22688
|
return {
|
|
22385
22689
|
kind: "invalid",
|
|
22386
22690
|
detail: `Schema not found (${schemaBn}). Run **Materialize agents** on this checkout.`
|
|
@@ -22616,7 +22920,7 @@ function listMissingWorkstations(contextDir2, worktreeRoot, snapshot) {
|
|
|
22616
22920
|
}
|
|
22617
22921
|
}
|
|
22618
22922
|
}
|
|
22619
|
-
if (!
|
|
22923
|
+
if (!fs40.existsSync(contextDir2)) {
|
|
22620
22924
|
return [...map.values()].sort((a, b) => a.key.localeCompare(b.key));
|
|
22621
22925
|
}
|
|
22622
22926
|
const dynamic = discoverDynamicAnalysisTestSteps(contextDir2);
|
|
@@ -22797,11 +23101,11 @@ async function runRemediationPipelineMissingPass(p) {
|
|
|
22797
23101
|
|
|
22798
23102
|
// src/pipelines/coverage/coveragePipeline.ts
|
|
22799
23103
|
var import_child_process5 = require("child_process");
|
|
22800
|
-
var
|
|
23104
|
+
var fs42 = __toESM(require("fs"));
|
|
22801
23105
|
var path38 = __toESM(require("path"));
|
|
22802
23106
|
|
|
22803
23107
|
// src/analysis/coverageReferenceValidationSchemaValidate.ts
|
|
22804
|
-
var
|
|
23108
|
+
var fs41 = __toESM(require("fs"));
|
|
22805
23109
|
var path37 = __toESM(require("path"));
|
|
22806
23110
|
var import__5 = __toESM(require__());
|
|
22807
23111
|
function stripUtf8Bom4(s) {
|
|
@@ -22831,7 +23135,7 @@ function getValidate() {
|
|
|
22831
23135
|
return compiledValidate;
|
|
22832
23136
|
}
|
|
22833
23137
|
const schemaPath = bundledCoverageReferenceValidationSchemaPath();
|
|
22834
|
-
const schemaRaw = stripUtf8Bom4(
|
|
23138
|
+
const schemaRaw = stripUtf8Bom4(fs41.readFileSync(schemaPath, "utf-8"));
|
|
22835
23139
|
const schema = JSON.parse(schemaRaw);
|
|
22836
23140
|
const ajv2 = new import__5.default({ allErrors: true, strict: false });
|
|
22837
23141
|
compiledValidate = ajv2.compile(schema);
|
|
@@ -22847,7 +23151,7 @@ function validateCoverageReferenceValidationData(data) {
|
|
|
22847
23151
|
function readAndValidateCoverageReferenceValidationFile(jsonAbsolutePath) {
|
|
22848
23152
|
let raw;
|
|
22849
23153
|
try {
|
|
22850
|
-
raw = stripUtf8Bom4(
|
|
23154
|
+
raw = stripUtf8Bom4(fs41.readFileSync(jsonAbsolutePath, "utf-8"));
|
|
22851
23155
|
} catch (e) {
|
|
22852
23156
|
return {
|
|
22853
23157
|
ok: false,
|
|
@@ -22889,7 +23193,7 @@ var DEFAULT_IGNORE_DIR_BASENAMES = [
|
|
|
22889
23193
|
var GIT_LS_FILES_MAX_BUFFER = 64 * 1024 * 1024;
|
|
22890
23194
|
function tryLoadGitNonIgnoredPathSet(repositoryRootAbs) {
|
|
22891
23195
|
const root = path38.resolve(repositoryRootAbs);
|
|
22892
|
-
if (!
|
|
23196
|
+
if (!fs42.existsSync(path38.join(root, ".git"))) {
|
|
22893
23197
|
return null;
|
|
22894
23198
|
}
|
|
22895
23199
|
const env = { ...process.env, GIT_TERMINAL_PROMPT: "0" };
|
|
@@ -23044,7 +23348,7 @@ function extractEvidenceIndexPathCitations(body) {
|
|
|
23044
23348
|
function listContextFilesRecursive(dir, acc) {
|
|
23045
23349
|
let entries;
|
|
23046
23350
|
try {
|
|
23047
|
-
entries =
|
|
23351
|
+
entries = fs42.readdirSync(dir, { withFileTypes: true });
|
|
23048
23352
|
} catch {
|
|
23049
23353
|
return;
|
|
23050
23354
|
}
|
|
@@ -23062,7 +23366,7 @@ function walkRepositoryFiles(repoRoot, ignoreBasenames, maxBytes, excludedOut, g
|
|
|
23062
23366
|
const walk = (dir) => {
|
|
23063
23367
|
let entries;
|
|
23064
23368
|
try {
|
|
23065
|
-
entries =
|
|
23369
|
+
entries = fs42.readdirSync(dir, { withFileTypes: true });
|
|
23066
23370
|
} catch {
|
|
23067
23371
|
return;
|
|
23068
23372
|
}
|
|
@@ -23092,7 +23396,7 @@ function walkRepositoryFiles(repoRoot, ignoreBasenames, maxBytes, excludedOut, g
|
|
|
23092
23396
|
}
|
|
23093
23397
|
let st;
|
|
23094
23398
|
try {
|
|
23095
|
-
st =
|
|
23399
|
+
st = fs42.statSync(full);
|
|
23096
23400
|
} catch {
|
|
23097
23401
|
continue;
|
|
23098
23402
|
}
|
|
@@ -23102,7 +23406,7 @@ function walkRepositoryFiles(repoRoot, ignoreBasenames, maxBytes, excludedOut, g
|
|
|
23102
23406
|
}
|
|
23103
23407
|
let buf;
|
|
23104
23408
|
try {
|
|
23105
|
-
buf =
|
|
23409
|
+
buf = fs42.readFileSync(full);
|
|
23106
23410
|
} catch {
|
|
23107
23411
|
excludedOut.push({ path: rel, reason: "read error" });
|
|
23108
23412
|
continue;
|
|
@@ -23122,7 +23426,7 @@ function walkRepositoryFiles(repoRoot, ignoreBasenames, maxBytes, excludedOut, g
|
|
|
23122
23426
|
}
|
|
23123
23427
|
function collectReferencesFromContext(contextDirAbs, repositoryRootAbs, warnings) {
|
|
23124
23428
|
const references = [];
|
|
23125
|
-
if (!
|
|
23429
|
+
if (!fs42.existsSync(contextDirAbs)) {
|
|
23126
23430
|
warnings.push(`Context directory missing: ${contextDirAbs}`);
|
|
23127
23431
|
return references;
|
|
23128
23432
|
}
|
|
@@ -23138,7 +23442,7 @@ function collectReferencesFromContext(contextDirAbs, repositoryRootAbs, warnings
|
|
|
23138
23442
|
}
|
|
23139
23443
|
let raw;
|
|
23140
23444
|
try {
|
|
23141
|
-
raw =
|
|
23445
|
+
raw = fs42.readFileSync(abs, "utf-8");
|
|
23142
23446
|
} catch (e) {
|
|
23143
23447
|
warnings.push(`Skip JSON (read error): ${sourceArtefact} \u2014 ${e instanceof Error ? e.message : String(e)}`);
|
|
23144
23448
|
continue;
|
|
@@ -23169,7 +23473,7 @@ function collectReferencesFromContext(contextDirAbs, repositoryRootAbs, warnings
|
|
|
23169
23473
|
if (ext === ".md") {
|
|
23170
23474
|
let text;
|
|
23171
23475
|
try {
|
|
23172
|
-
const buf =
|
|
23476
|
+
const buf = fs42.readFileSync(abs);
|
|
23173
23477
|
text = decodeBufferForLineCount(buf);
|
|
23174
23478
|
} catch (e) {
|
|
23175
23479
|
warnings.push(`Skip markdown (read/decode error): ${sourceArtefact} \u2014 ${e instanceof Error ? e.message : String(e)}`);
|
|
@@ -23226,7 +23530,7 @@ function buildCoverageReferenceValidationDocument(repositoryRootAbs, contextDirA
|
|
|
23226
23530
|
}
|
|
23227
23531
|
const excludedFiles = [];
|
|
23228
23532
|
const gitNonIgnoredPaths = tryLoadGitNonIgnoredPathSet(repoRoot);
|
|
23229
|
-
if (
|
|
23533
|
+
if (fs42.existsSync(path38.join(repoRoot, ".git")) && gitNonIgnoredPaths === null) {
|
|
23230
23534
|
warnings.push(
|
|
23231
23535
|
"Repository has .git but git ls-files failed or git is unavailable; .gitignore / exclude-standard not applied."
|
|
23232
23536
|
);
|
|
@@ -23277,10 +23581,10 @@ function buildCoverageReferenceValidationDocument(repositoryRootAbs, contextDirA
|
|
|
23277
23581
|
function runCoveragePipeline(opts) {
|
|
23278
23582
|
const repoRoot = path38.resolve(opts.repositoryRootAbs);
|
|
23279
23583
|
const contextDir2 = path38.resolve(opts.contextDirAbs);
|
|
23280
|
-
if (!
|
|
23584
|
+
if (!fs42.existsSync(repoRoot)) {
|
|
23281
23585
|
return { ok: false, error: `Repository root does not exist: ${repoRoot}` };
|
|
23282
23586
|
}
|
|
23283
|
-
if (!
|
|
23587
|
+
if (!fs42.existsSync(contextDir2)) {
|
|
23284
23588
|
return {
|
|
23285
23589
|
ok: false,
|
|
23286
23590
|
error: `Missing .gluecharm/context: ${contextDir2}`
|
|
@@ -23302,7 +23606,7 @@ ${schemaCheck.errors.join("\n")}`,
|
|
|
23302
23606
|
if (opts.write) {
|
|
23303
23607
|
try {
|
|
23304
23608
|
const payload = stableStringifyCoverageDocument(document);
|
|
23305
|
-
|
|
23609
|
+
fs42.writeFileSync(outPath, payload, "utf-8");
|
|
23306
23610
|
} catch (e) {
|
|
23307
23611
|
return {
|
|
23308
23612
|
ok: false,
|
|
@@ -23316,11 +23620,11 @@ ${schemaCheck.errors.join("\n")}`,
|
|
|
23316
23620
|
|
|
23317
23621
|
// src/pipelines/remediation/zeroReferenceWorkstationChain.ts
|
|
23318
23622
|
var crypto = __toESM(require("crypto"));
|
|
23319
|
-
var
|
|
23623
|
+
var fs44 = __toESM(require("fs"));
|
|
23320
23624
|
var path40 = __toESM(require("path"));
|
|
23321
23625
|
|
|
23322
23626
|
// src/analysis/zeroReferenceRemediationSchemaValidate.ts
|
|
23323
|
-
var
|
|
23627
|
+
var fs43 = __toESM(require("fs"));
|
|
23324
23628
|
var path39 = __toESM(require("path"));
|
|
23325
23629
|
var import__6 = __toESM(require__());
|
|
23326
23630
|
function stripUtf8Bom5(s) {
|
|
@@ -23342,7 +23646,7 @@ function formatAjvErrors6(errors) {
|
|
|
23342
23646
|
var ajv = new import__6.default({ allErrors: true, strict: false });
|
|
23343
23647
|
function compileSchema(basename17) {
|
|
23344
23648
|
const schemaPath = path39.join(schemasDir(), basename17);
|
|
23345
|
-
const schemaRaw = stripUtf8Bom5(
|
|
23649
|
+
const schemaRaw = stripUtf8Bom5(fs43.readFileSync(schemaPath, "utf-8"));
|
|
23346
23650
|
const schema = JSON.parse(schemaRaw);
|
|
23347
23651
|
return ajv.compile(schema);
|
|
23348
23652
|
}
|
|
@@ -23386,7 +23690,7 @@ var ZERO_REF_STAGING_JSON_TOTAL_ATTEMPTS = 5;
|
|
|
23386
23690
|
var ZERO_REF_STAGING_FILE_PREVIEW_MAX_CHARS = 6e3;
|
|
23387
23691
|
function readStagingOutputPreview(outAbs) {
|
|
23388
23692
|
try {
|
|
23389
|
-
const s =
|
|
23693
|
+
const s = fs44.readFileSync(outAbs, "utf-8");
|
|
23390
23694
|
if (s.length <= ZERO_REF_STAGING_FILE_PREVIEW_MAX_CHARS) {
|
|
23391
23695
|
return s;
|
|
23392
23696
|
}
|
|
@@ -23669,14 +23973,14 @@ function readNonReferencedFilesFromRepositoryRoot(repositoryRootAbs) {
|
|
|
23669
23973
|
return { ok: true, paths, ...generatedAt ? { generatedAt } : {} };
|
|
23670
23974
|
}
|
|
23671
23975
|
function readOrInitRoutingDoc(routingAbs, coverageReferenceGeneratedAt) {
|
|
23672
|
-
if (!
|
|
23976
|
+
if (!fs44.existsSync(routingAbs)) {
|
|
23673
23977
|
return {
|
|
23674
23978
|
schemaVersion: ROUTING_SCHEMA_VERSION,
|
|
23675
23979
|
...coverageReferenceGeneratedAt ? { coverageReferenceGeneratedAt } : {},
|
|
23676
23980
|
records: {}
|
|
23677
23981
|
};
|
|
23678
23982
|
}
|
|
23679
|
-
const raw =
|
|
23983
|
+
const raw = fs44.readFileSync(routingAbs, "utf-8");
|
|
23680
23984
|
const data = JSON.parse(raw);
|
|
23681
23985
|
if (!data.records || typeof data.records !== "object") {
|
|
23682
23986
|
return {
|
|
@@ -23688,10 +23992,10 @@ function readOrInitRoutingDoc(routingAbs, coverageReferenceGeneratedAt) {
|
|
|
23688
23992
|
return data;
|
|
23689
23993
|
}
|
|
23690
23994
|
function readOrInitTriageDoc(triageAbs) {
|
|
23691
|
-
if (!
|
|
23995
|
+
if (!fs44.existsSync(triageAbs)) {
|
|
23692
23996
|
return { schemaVersion: TRIAGE_SCHEMA_VERSION, records: {} };
|
|
23693
23997
|
}
|
|
23694
|
-
const raw =
|
|
23998
|
+
const raw = fs44.readFileSync(triageAbs, "utf-8");
|
|
23695
23999
|
const data = JSON.parse(raw);
|
|
23696
24000
|
if (!data.records || typeof data.records !== "object") {
|
|
23697
24001
|
return { schemaVersion: TRIAGE_SCHEMA_VERSION, records: {} };
|
|
@@ -23742,7 +24046,7 @@ function lineCountRepoFile(worktreeRootAbs, relPosix) {
|
|
|
23742
24046
|
const abs = path40.join(worktreeRootAbs, ...relPosix.split("/"));
|
|
23743
24047
|
let buf;
|
|
23744
24048
|
try {
|
|
23745
|
-
buf =
|
|
24049
|
+
buf = fs44.readFileSync(abs);
|
|
23746
24050
|
} catch {
|
|
23747
24051
|
return 1;
|
|
23748
24052
|
}
|
|
@@ -23796,7 +24100,7 @@ async function applyCoordinationListTriageMerge(input) {
|
|
|
23796
24100
|
const cfg = LIST_MERGE_CFG[input.listKind];
|
|
23797
24101
|
const listPath = path40.join(input.contextDirAbs, cfg.listBasename);
|
|
23798
24102
|
const schemaPath = path40.join(resolveContextListSchemasDir(), cfg.schemaBasename);
|
|
23799
|
-
if (!
|
|
24103
|
+
if (!fs44.existsSync(listPath)) {
|
|
23800
24104
|
return {
|
|
23801
24105
|
ok: false,
|
|
23802
24106
|
message: `${cfg.listBasename} not found \u2014 run coordination step ${LIST_STEP_HINT[input.listKind]} first.`
|
|
@@ -23807,7 +24111,7 @@ async function applyCoordinationListTriageMerge(input) {
|
|
|
23807
24111
|
return withCoordinationListFileLock(listPath, {}, async () => {
|
|
23808
24112
|
let raw;
|
|
23809
24113
|
try {
|
|
23810
|
-
raw =
|
|
24114
|
+
raw = fs44.readFileSync(listPath, "utf-8");
|
|
23811
24115
|
} catch (e) {
|
|
23812
24116
|
return { ok: false, message: e instanceof Error ? e.message : String(e) };
|
|
23813
24117
|
}
|
|
@@ -23875,7 +24179,7 @@ async function applyCoordinationListTriageMerge(input) {
|
|
|
23875
24179
|
});
|
|
23876
24180
|
const tmp = `${listPath}.tmp.${process.pid}`;
|
|
23877
24181
|
try {
|
|
23878
|
-
|
|
24182
|
+
fs44.writeFileSync(tmp, `${JSON.stringify(doc, null, 2)}
|
|
23879
24183
|
`, "utf-8");
|
|
23880
24184
|
} catch (e) {
|
|
23881
24185
|
return { ok: false, message: e instanceof Error ? e.message : String(e) };
|
|
@@ -23883,13 +24187,13 @@ async function applyCoordinationListTriageMerge(input) {
|
|
|
23883
24187
|
const v = validateCoordinationListJson(tmp, schemaPath);
|
|
23884
24188
|
if (!v.ok) {
|
|
23885
24189
|
try {
|
|
23886
|
-
|
|
24190
|
+
fs44.unlinkSync(tmp);
|
|
23887
24191
|
} catch {
|
|
23888
24192
|
}
|
|
23889
24193
|
return { ok: false, message: `${cfg.listBasename} validation failed: ${JSON.stringify(v.failure)}` };
|
|
23890
24194
|
}
|
|
23891
24195
|
try {
|
|
23892
|
-
|
|
24196
|
+
fs44.renameSync(tmp, listPath);
|
|
23893
24197
|
} catch (e) {
|
|
23894
24198
|
return { ok: false, message: e instanceof Error ? e.message : String(e) };
|
|
23895
24199
|
}
|
|
@@ -23899,9 +24203,9 @@ async function applyCoordinationListTriageMerge(input) {
|
|
|
23899
24203
|
}
|
|
23900
24204
|
async function runClassifierAgent(common, contextDirAbs, targetFilePathPosix, workspaceLabel) {
|
|
23901
24205
|
const outAbs = stagingPathForTarget(contextDirAbs, "classifier", targetFilePathPosix);
|
|
23902
|
-
|
|
24206
|
+
fs44.mkdirSync(path40.dirname(outAbs), { recursive: true });
|
|
23903
24207
|
const runDir = path40.join(common.worktreeRoot, ".opencode", "_run");
|
|
23904
|
-
|
|
24208
|
+
fs44.mkdirSync(runDir, { recursive: true });
|
|
23905
24209
|
const outputBasename = path40.basename(outAbs);
|
|
23906
24210
|
const listTaskDescription = [
|
|
23907
24211
|
`Target file (repo-relative, POSIX): **${targetFilePathPosix}**`,
|
|
@@ -23939,7 +24243,7 @@ async function runClassifierAgent(common, contextDirAbs, targetFilePathPosix, wo
|
|
|
23939
24243
|
...repairAppendix ? { repairAppendix } : {}
|
|
23940
24244
|
});
|
|
23941
24245
|
const promptPath = path40.join(runDir, `zero-ref-classify-a${attempt}-${Date.now()}.prompt.txt`);
|
|
23942
|
-
|
|
24246
|
+
fs44.writeFileSync(promptPath, body, "utf-8");
|
|
23943
24247
|
const argv = expandArgvTemplate4(common.argvTemplate, {
|
|
23944
24248
|
promptFile: promptPath,
|
|
23945
24249
|
agentId: ZERO_REF_CLASSIFY_AGENT_STEM,
|
|
@@ -23966,7 +24270,7 @@ async function runClassifierAgent(common, contextDirAbs, targetFilePathPosix, wo
|
|
|
23966
24270
|
const canRetry = attempt < ZERO_REF_STAGING_JSON_TOTAL_ATTEMPTS - 1;
|
|
23967
24271
|
let st;
|
|
23968
24272
|
try {
|
|
23969
|
-
st =
|
|
24273
|
+
st = fs44.statSync(outAbs);
|
|
23970
24274
|
} catch {
|
|
23971
24275
|
st = void 0;
|
|
23972
24276
|
}
|
|
@@ -23988,7 +24292,7 @@ async function runClassifierAgent(common, contextDirAbs, targetFilePathPosix, wo
|
|
|
23988
24292
|
}
|
|
23989
24293
|
let parsed;
|
|
23990
24294
|
try {
|
|
23991
|
-
parsed = JSON.parse(
|
|
24295
|
+
parsed = JSON.parse(fs44.readFileSync(outAbs, "utf-8"));
|
|
23992
24296
|
} catch (e) {
|
|
23993
24297
|
const msg = e instanceof Error ? e.message : String(e);
|
|
23994
24298
|
lastFailureMessage = `Classifier output not valid JSON: ${msg}`;
|
|
@@ -24073,7 +24377,7 @@ async function runMarkdownReferenceAgent(common, contextDirAbs, targetFilePathPo
|
|
|
24073
24377
|
const mdAbs = path40.join(contextDirAbs, mdBasename);
|
|
24074
24378
|
const agentStem = which === "project" ? ZERO_REF_ADD_REF_PROJECT_AGENT_STEM : ZERO_REF_ADD_REF_ARCH_AGENT_STEM;
|
|
24075
24379
|
const runDir = path40.join(common.worktreeRoot, ".opencode", "_run");
|
|
24076
|
-
|
|
24380
|
+
fs44.mkdirSync(runDir, { recursive: true });
|
|
24077
24381
|
const lines = [
|
|
24078
24382
|
`# SRS-30 \u2014 Add reference to ${mdBasename}`,
|
|
24079
24383
|
``,
|
|
@@ -24089,7 +24393,7 @@ async function runMarkdownReferenceAgent(common, contextDirAbs, targetFilePathPo
|
|
|
24089
24393
|
`- Do not remove unrelated content; append or extend the most appropriate section.`
|
|
24090
24394
|
];
|
|
24091
24395
|
const promptPath = path40.join(runDir, `zero-ref-md-${which}-${Date.now()}.prompt.txt`);
|
|
24092
|
-
|
|
24396
|
+
fs44.writeFileSync(promptPath, lines.join("\n"), "utf-8");
|
|
24093
24397
|
const argv = expandArgvTemplate4(common.argvTemplate, {
|
|
24094
24398
|
promptFile: promptPath,
|
|
24095
24399
|
agentId: agentStem,
|
|
@@ -24116,9 +24420,9 @@ async function runMarkdownReferenceAgent(common, contextDirAbs, targetFilePathPo
|
|
|
24116
24420
|
async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathPosix, routingSummary, workspaceLabel, triageScope) {
|
|
24117
24421
|
const meta = TRIAGE_SCOPE_META[triageScope];
|
|
24118
24422
|
const outAbs = stagingPathForTarget(contextDirAbs, "triage", targetFilePathPosix);
|
|
24119
|
-
|
|
24423
|
+
fs44.mkdirSync(path40.dirname(outAbs), { recursive: true });
|
|
24120
24424
|
const runDir = path40.join(common.worktreeRoot, ".opencode", "_run");
|
|
24121
|
-
|
|
24425
|
+
fs44.mkdirSync(runDir, { recursive: true });
|
|
24122
24426
|
const outputBasename = path40.basename(outAbs);
|
|
24123
24427
|
const listTaskDescription = [
|
|
24124
24428
|
`Target file: **${targetFilePathPosix}** (${workspaceLabel})`,
|
|
@@ -24150,7 +24454,7 @@ async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathP
|
|
|
24150
24454
|
...repairAppendix ? { repairAppendix } : {}
|
|
24151
24455
|
});
|
|
24152
24456
|
const promptPath = path40.join(runDir, `zero-ref-triage-a${attempt}-${Date.now()}.prompt.txt`);
|
|
24153
|
-
|
|
24457
|
+
fs44.writeFileSync(promptPath, body, "utf-8");
|
|
24154
24458
|
const argv = expandArgvTemplate4(common.argvTemplate, {
|
|
24155
24459
|
promptFile: promptPath,
|
|
24156
24460
|
agentId: ZERO_REF_TRIAGE_COORD_AGENT_STEM,
|
|
@@ -24177,7 +24481,7 @@ async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathP
|
|
|
24177
24481
|
const canRetry = attempt < ZERO_REF_STAGING_JSON_TOTAL_ATTEMPTS - 1;
|
|
24178
24482
|
let st;
|
|
24179
24483
|
try {
|
|
24180
|
-
st =
|
|
24484
|
+
st = fs44.statSync(outAbs);
|
|
24181
24485
|
} catch {
|
|
24182
24486
|
st = void 0;
|
|
24183
24487
|
}
|
|
@@ -24199,7 +24503,7 @@ async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathP
|
|
|
24199
24503
|
}
|
|
24200
24504
|
let parsed;
|
|
24201
24505
|
try {
|
|
24202
|
-
parsed = JSON.parse(
|
|
24506
|
+
parsed = JSON.parse(fs44.readFileSync(outAbs, "utf-8"));
|
|
24203
24507
|
} catch (e) {
|
|
24204
24508
|
const msg = e instanceof Error ? e.message : String(e);
|
|
24205
24509
|
lastFailureMessage = `Triage output not valid JSON: ${msg}`;
|
|
@@ -24255,7 +24559,7 @@ async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathP
|
|
|
24255
24559
|
return { ok: false, message: lastFailureMessage, stagingPath: outAbs };
|
|
24256
24560
|
}
|
|
24257
24561
|
try {
|
|
24258
|
-
|
|
24562
|
+
fs44.writeFileSync(outAbs, `${JSON.stringify(parsed, null, 2)}
|
|
24259
24563
|
`, "utf-8");
|
|
24260
24564
|
} catch {
|
|
24261
24565
|
}
|
|
@@ -24273,7 +24577,7 @@ async function runOneUnreferencedFilePipeline(p) {
|
|
|
24273
24577
|
}
|
|
24274
24578
|
let stagingParsed;
|
|
24275
24579
|
try {
|
|
24276
|
-
stagingParsed = JSON.parse(
|
|
24580
|
+
stagingParsed = JSON.parse(fs44.readFileSync(cr.stagingPath, "utf-8"));
|
|
24277
24581
|
} catch (e) {
|
|
24278
24582
|
return { ok: false, message: String(e) };
|
|
24279
24583
|
}
|
|
@@ -24289,8 +24593,8 @@ async function runOneUnreferencedFilePipeline(p) {
|
|
|
24289
24593
|
if (!s.ok) {
|
|
24290
24594
|
throw new Error(s.errors.join("; "));
|
|
24291
24595
|
}
|
|
24292
|
-
|
|
24293
|
-
|
|
24596
|
+
fs44.mkdirSync(path40.dirname(routingAbs), { recursive: true });
|
|
24597
|
+
fs44.writeFileSync(routingAbs, s.json, "utf-8");
|
|
24294
24598
|
});
|
|
24295
24599
|
const routing = stagingParsed.routing;
|
|
24296
24600
|
const routingSummary = typeof stagingParsed.projectRelationSummary === "string" ? stagingParsed.projectRelationSummary : "";
|
|
@@ -24321,7 +24625,7 @@ async function runOneUnreferencedFilePipeline(p) {
|
|
|
24321
24625
|
}
|
|
24322
24626
|
let triageParsed;
|
|
24323
24627
|
try {
|
|
24324
|
-
triageParsed = JSON.parse(
|
|
24628
|
+
triageParsed = JSON.parse(fs44.readFileSync(tr.stagingPath, "utf-8"));
|
|
24325
24629
|
} catch (e) {
|
|
24326
24630
|
return { ok: false, message: String(e) };
|
|
24327
24631
|
}
|
|
@@ -24338,8 +24642,8 @@ async function runOneUnreferencedFilePipeline(p) {
|
|
|
24338
24642
|
if (!s.ok) {
|
|
24339
24643
|
throw new Error(s.errors.join("; "));
|
|
24340
24644
|
}
|
|
24341
|
-
|
|
24342
|
-
|
|
24645
|
+
fs44.mkdirSync(path40.dirname(triageAbs), { recursive: true });
|
|
24646
|
+
fs44.writeFileSync(triageAbs, s.json, "utf-8");
|
|
24343
24647
|
});
|
|
24344
24648
|
const decision = triageParsed.decision;
|
|
24345
24649
|
if (decision === "new_item" || decision === "enrich_existing") {
|
|
@@ -24427,7 +24731,7 @@ async function runRemediationPipelineZeroRefPass(p) {
|
|
|
24427
24731
|
}
|
|
24428
24732
|
|
|
24429
24733
|
// src/pipelines/coverage/coverageExecutionReport.ts
|
|
24430
|
-
var
|
|
24734
|
+
var fs45 = __toESM(require("fs"));
|
|
24431
24735
|
var path41 = __toESM(require("path"));
|
|
24432
24736
|
var REFERENCE_COVERAGE_EXECUTION_REPORT_BASENAME = "reference-coverage-execution-report.md";
|
|
24433
24737
|
function inlineMdText(s) {
|
|
@@ -24524,7 +24828,7 @@ function collectNoActionRowsFromRoutingDoc(doc) {
|
|
|
24524
24828
|
return rows;
|
|
24525
24829
|
}
|
|
24526
24830
|
function readRoutingDocFromDisk(routingAbs) {
|
|
24527
|
-
if (!
|
|
24831
|
+
if (!fs45.existsSync(routingAbs)) {
|
|
24528
24832
|
return {
|
|
24529
24833
|
ok: true,
|
|
24530
24834
|
doc: { schemaVersion: "1", records: {} }
|
|
@@ -24532,7 +24836,7 @@ function readRoutingDocFromDisk(routingAbs) {
|
|
|
24532
24836
|
}
|
|
24533
24837
|
let raw;
|
|
24534
24838
|
try {
|
|
24535
|
-
raw =
|
|
24839
|
+
raw = fs45.readFileSync(routingAbs, "utf-8");
|
|
24536
24840
|
} catch (e) {
|
|
24537
24841
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
24538
24842
|
}
|
|
@@ -24572,20 +24876,20 @@ async function runCoverageExecutionReport(p) {
|
|
|
24572
24876
|
}
|
|
24573
24877
|
let previous;
|
|
24574
24878
|
try {
|
|
24575
|
-
if (
|
|
24576
|
-
previous =
|
|
24879
|
+
if (fs45.existsSync(outAbs)) {
|
|
24880
|
+
previous = fs45.readFileSync(outAbs, "utf-8");
|
|
24577
24881
|
}
|
|
24578
24882
|
} catch {
|
|
24579
24883
|
previous = void 0;
|
|
24580
24884
|
}
|
|
24581
24885
|
try {
|
|
24582
|
-
|
|
24583
|
-
|
|
24886
|
+
fs45.mkdirSync(path41.dirname(outAbs), { recursive: true });
|
|
24887
|
+
fs45.writeFileSync(outAbs, md, "utf-8");
|
|
24584
24888
|
} catch (e) {
|
|
24585
24889
|
const msg = e instanceof Error ? e.message : String(e);
|
|
24586
24890
|
if (previous !== void 0) {
|
|
24587
24891
|
try {
|
|
24588
|
-
|
|
24892
|
+
fs45.writeFileSync(outAbs, previous, "utf-8");
|
|
24589
24893
|
} catch {
|
|
24590
24894
|
}
|
|
24591
24895
|
}
|
|
@@ -24596,7 +24900,7 @@ async function runCoverageExecutionReport(p) {
|
|
|
24596
24900
|
}
|
|
24597
24901
|
|
|
24598
24902
|
// src/gluecharm/minimalGluecharmLayout.ts
|
|
24599
|
-
var
|
|
24903
|
+
var fs46 = __toESM(require("node:fs"));
|
|
24600
24904
|
var path42 = __toESM(require("node:path"));
|
|
24601
24905
|
var MINIMAL_GLUECHARM_RELATIVE_DIRS = [
|
|
24602
24906
|
[".gluecharm", "docs", "srs"],
|
|
@@ -24609,7 +24913,7 @@ function ensureMinimalGluecharmLayoutNode(repoRootAbs) {
|
|
|
24609
24913
|
for (const segments of MINIMAL_GLUECHARM_RELATIVE_DIRS) {
|
|
24610
24914
|
const dir = path42.join(root, ...segments);
|
|
24611
24915
|
try {
|
|
24612
|
-
|
|
24916
|
+
fs46.mkdirSync(dir, { recursive: true });
|
|
24613
24917
|
} catch (e) {
|
|
24614
24918
|
const err = e;
|
|
24615
24919
|
const msg = e instanceof Error ? e.message : String(e);
|
|
@@ -24991,13 +25295,13 @@ function buildFactoryDepsHeadless(input) {
|
|
|
24991
25295
|
},
|
|
24992
25296
|
runPrepareAnalysisWorktree: async (resume) => {
|
|
24993
25297
|
if (resume) {
|
|
24994
|
-
if (adHocWorktree &&
|
|
25298
|
+
if (adHocWorktree && fs47.existsSync(path43.join(adHocWorktree.path, ".git"))) {
|
|
24995
25299
|
return { ok: true };
|
|
24996
25300
|
}
|
|
24997
25301
|
const snap = readAnalysisWorkspaceSnapshot(storageContext);
|
|
24998
25302
|
const wtPath = snap?.adHocWorktreePath?.trim();
|
|
24999
25303
|
const repo = snap?.adHocRepositoryRoot?.trim() || repoRoot;
|
|
25000
|
-
if (wtPath &&
|
|
25304
|
+
if (wtPath && fs47.existsSync(path43.join(wtPath, ".git"))) {
|
|
25001
25305
|
adHocWorktree = attachWorktreeHandle(wtPath, repo);
|
|
25002
25306
|
macroSourceBranch = snap?.adHocSourceBranchAtCreation;
|
|
25003
25307
|
macroFinalize = () => {
|
|
@@ -25222,7 +25526,7 @@ function stderrLinesForFactoryFailures(failures, exitCode) {
|
|
|
25222
25526
|
var path48 = __toESM(require("node:path"));
|
|
25223
25527
|
|
|
25224
25528
|
// src/factory/updateContext/updateContextBaseline.ts
|
|
25225
|
-
var
|
|
25529
|
+
var fs48 = __toESM(require("node:fs"));
|
|
25226
25530
|
var path44 = __toESM(require("node:path"));
|
|
25227
25531
|
function isValidIso(s) {
|
|
25228
25532
|
const t = Date.parse(s);
|
|
@@ -25233,7 +25537,7 @@ function maxMtimeRegularFilesUnderDir(dirAbs) {
|
|
|
25233
25537
|
const walk = (d) => {
|
|
25234
25538
|
let entries;
|
|
25235
25539
|
try {
|
|
25236
|
-
entries =
|
|
25540
|
+
entries = fs48.readdirSync(d, { withFileTypes: true });
|
|
25237
25541
|
} catch {
|
|
25238
25542
|
return;
|
|
25239
25543
|
}
|
|
@@ -25243,7 +25547,7 @@ function maxMtimeRegularFilesUnderDir(dirAbs) {
|
|
|
25243
25547
|
walk(p);
|
|
25244
25548
|
} else if (e.isFile()) {
|
|
25245
25549
|
try {
|
|
25246
|
-
const st =
|
|
25550
|
+
const st = fs48.statSync(p);
|
|
25247
25551
|
const m = st.mtimeMs;
|
|
25248
25552
|
if (best === null || m > best) {
|
|
25249
25553
|
best = m;
|
|
@@ -25265,7 +25569,7 @@ function resolveUpdateContextBaseline(repoRootAbs, repoConfig) {
|
|
|
25265
25569
|
return { baselineIsoUtc: new Date(last).toISOString(), source: "lastRunAt" };
|
|
25266
25570
|
}
|
|
25267
25571
|
const ctxDir = path44.join(repoRootAbs, ".gluecharm", "context");
|
|
25268
|
-
if (!
|
|
25572
|
+
if (!fs48.existsSync(ctxDir)) {
|
|
25269
25573
|
return null;
|
|
25270
25574
|
}
|
|
25271
25575
|
const maxMs = maxMtimeRegularFilesUnderDir(ctxDir);
|
|
@@ -25288,7 +25592,7 @@ function persistUpdateContextLastRunAt(repoRootAbs, isoUtc) {
|
|
|
25288
25592
|
|
|
25289
25593
|
// src/factory/updateContext/updateContextGitWindow.ts
|
|
25290
25594
|
var import_node_child_process3 = require("node:child_process");
|
|
25291
|
-
var
|
|
25595
|
+
var fs49 = __toESM(require("node:fs"));
|
|
25292
25596
|
var path45 = __toESM(require("node:path"));
|
|
25293
25597
|
var GIT_ENV = { ...process.env, GIT_TERMINAL_PROMPT: "0" };
|
|
25294
25598
|
function gitLines(repoRootAbs, args) {
|
|
@@ -25314,7 +25618,7 @@ function parseGitLogIso(line) {
|
|
|
25314
25618
|
}
|
|
25315
25619
|
function discoverCommitWindowAndTouchedPaths(repoRootAbs, baselineIsoUtc) {
|
|
25316
25620
|
const root = path45.resolve(repoRootAbs);
|
|
25317
|
-
if (!
|
|
25621
|
+
if (!fs49.existsSync(path45.join(root, ".git"))) {
|
|
25318
25622
|
return { ok: false, error: "Not a git repository (missing .git)." };
|
|
25319
25623
|
}
|
|
25320
25624
|
const baselineMs = Date.parse(baselineIsoUtc);
|
|
@@ -25379,7 +25683,7 @@ function filterPathsExistingInWorktree(worktreeRootAbs, pathsPosix) {
|
|
|
25379
25683
|
const rel = p.replace(/\\/g, "/");
|
|
25380
25684
|
const abs = path45.join(root, ...rel.split("/"));
|
|
25381
25685
|
try {
|
|
25382
|
-
if (
|
|
25686
|
+
if (fs49.existsSync(abs) && fs49.statSync(abs).isFile()) {
|
|
25383
25687
|
out.push(rel);
|
|
25384
25688
|
}
|
|
25385
25689
|
} catch {
|
|
@@ -25389,7 +25693,7 @@ function filterPathsExistingInWorktree(worktreeRootAbs, pathsPosix) {
|
|
|
25389
25693
|
}
|
|
25390
25694
|
|
|
25391
25695
|
// src/factory/updateContext/updateContextReport.ts
|
|
25392
|
-
var
|
|
25696
|
+
var fs50 = __toESM(require("node:fs"));
|
|
25393
25697
|
var path46 = __toESM(require("node:path"));
|
|
25394
25698
|
var CHANGES_SINCE_DATE_BASENAME = "changes-since-date.md";
|
|
25395
25699
|
function renderChangesSinceDateMarkdown(p) {
|
|
@@ -25431,9 +25735,9 @@ function renderChangesSinceDateMarkdown(p) {
|
|
|
25431
25735
|
}
|
|
25432
25736
|
function writeChangesSinceDateReport(contextDirAbs, body) {
|
|
25433
25737
|
try {
|
|
25434
|
-
|
|
25738
|
+
fs50.mkdirSync(contextDirAbs, { recursive: true });
|
|
25435
25739
|
const target = path46.join(contextDirAbs, CHANGES_SINCE_DATE_BASENAME);
|
|
25436
|
-
|
|
25740
|
+
fs50.writeFileSync(target, body, "utf-8");
|
|
25437
25741
|
return { ok: true };
|
|
25438
25742
|
} catch (e) {
|
|
25439
25743
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
@@ -25441,13 +25745,13 @@ function writeChangesSinceDateReport(contextDirAbs, body) {
|
|
|
25441
25745
|
}
|
|
25442
25746
|
|
|
25443
25747
|
// src/factory/updateContext/updateContextSeedCheck.ts
|
|
25444
|
-
var
|
|
25748
|
+
var fs51 = __toESM(require("node:fs"));
|
|
25445
25749
|
var path47 = __toESM(require("node:path"));
|
|
25446
25750
|
var INDEX_BASENAME = "index-application-context.json";
|
|
25447
25751
|
var CHANGES_REPORT = "changes-since-date.md";
|
|
25448
25752
|
function tryParseJsonFile(abs) {
|
|
25449
25753
|
try {
|
|
25450
|
-
const raw =
|
|
25754
|
+
const raw = fs51.readFileSync(abs, "utf-8");
|
|
25451
25755
|
JSON.parse(raw);
|
|
25452
25756
|
return true;
|
|
25453
25757
|
} catch {
|
|
@@ -25455,16 +25759,16 @@ function tryParseJsonFile(abs) {
|
|
|
25455
25759
|
}
|
|
25456
25760
|
}
|
|
25457
25761
|
function isWorktreeContextSeeded(contextDirAbs) {
|
|
25458
|
-
if (!
|
|
25762
|
+
if (!fs51.existsSync(contextDirAbs)) {
|
|
25459
25763
|
return false;
|
|
25460
25764
|
}
|
|
25461
25765
|
const indexAbs = path47.join(contextDirAbs, INDEX_BASENAME);
|
|
25462
|
-
if (
|
|
25766
|
+
if (fs51.existsSync(indexAbs) && fs51.statSync(indexAbs).isFile() && tryParseJsonFile(indexAbs)) {
|
|
25463
25767
|
return true;
|
|
25464
25768
|
}
|
|
25465
25769
|
let names;
|
|
25466
25770
|
try {
|
|
25467
|
-
names =
|
|
25771
|
+
names = fs51.readdirSync(contextDirAbs);
|
|
25468
25772
|
} catch {
|
|
25469
25773
|
return false;
|
|
25470
25774
|
}
|
|
@@ -25478,7 +25782,7 @@ function isWorktreeContextSeeded(contextDirAbs) {
|
|
|
25478
25782
|
}
|
|
25479
25783
|
const p = path47.join(contextDirAbs, name);
|
|
25480
25784
|
try {
|
|
25481
|
-
if (
|
|
25785
|
+
if (fs51.statSync(p).isFile()) {
|
|
25482
25786
|
distinct.add(name);
|
|
25483
25787
|
}
|
|
25484
25788
|
} catch {
|
|
@@ -25780,11 +26084,11 @@ async function runUpdateContextFactory(deps) {
|
|
|
25780
26084
|
}
|
|
25781
26085
|
|
|
25782
26086
|
// src/factory/contextDrift/runContextDriftFactory.ts
|
|
25783
|
-
var
|
|
26087
|
+
var fs57 = __toESM(require("node:fs"));
|
|
25784
26088
|
var path53 = __toESM(require("node:path"));
|
|
25785
26089
|
|
|
25786
26090
|
// src/factory/contextDrift/contextDriftManifest.ts
|
|
25787
|
-
var
|
|
26091
|
+
var fs52 = __toESM(require("node:fs"));
|
|
25788
26092
|
var path49 = __toESM(require("node:path"));
|
|
25789
26093
|
var MAX_REFERENCE_BYTES = 256 * 1024;
|
|
25790
26094
|
var MAX_EVIDENCE_FILES = 300;
|
|
@@ -25793,7 +26097,7 @@ var MAX_EXCERPT = 4e3;
|
|
|
25793
26097
|
function readFileLimited(abs, maxBytes) {
|
|
25794
26098
|
let buf;
|
|
25795
26099
|
try {
|
|
25796
|
-
buf =
|
|
26100
|
+
buf = fs52.readFileSync(abs);
|
|
25797
26101
|
} catch {
|
|
25798
26102
|
return { text: "", truncated: false };
|
|
25799
26103
|
}
|
|
@@ -25806,14 +26110,14 @@ function collectEvidencePaths(repoRoot) {
|
|
|
25806
26110
|
const roots = ["src", "test", "tests", "packages", ".gluecharm", "scripts"];
|
|
25807
26111
|
for (const rel of roots) {
|
|
25808
26112
|
const abs = path49.join(repoRoot, rel);
|
|
25809
|
-
if (!
|
|
26113
|
+
if (!fs52.existsSync(abs)) {
|
|
25810
26114
|
continue;
|
|
25811
26115
|
}
|
|
25812
26116
|
walkFiles(abs, repoRoot, out, 0);
|
|
25813
26117
|
}
|
|
25814
26118
|
for (const leaf of ["package.json", "tsconfig.json"]) {
|
|
25815
26119
|
const abs = path49.join(repoRoot, leaf);
|
|
25816
|
-
if (
|
|
26120
|
+
if (fs52.existsSync(abs) && fs52.statSync(abs).isFile()) {
|
|
25817
26121
|
const r = path49.relative(repoRoot, abs).split(path49.sep).join("/");
|
|
25818
26122
|
out.push(r);
|
|
25819
26123
|
}
|
|
@@ -25831,7 +26135,7 @@ function walkFiles(dir, repoRoot, out, depth) {
|
|
|
25831
26135
|
}
|
|
25832
26136
|
let entries;
|
|
25833
26137
|
try {
|
|
25834
|
-
entries =
|
|
26138
|
+
entries = fs52.readdirSync(dir, { withFileTypes: true });
|
|
25835
26139
|
} catch {
|
|
25836
26140
|
return;
|
|
25837
26141
|
}
|
|
@@ -25868,7 +26172,7 @@ function buildComparisonManifest(args) {
|
|
|
25868
26172
|
const evidenceFiles = [];
|
|
25869
26173
|
for (const rel of evidencePathsTrimmed) {
|
|
25870
26174
|
const abs = path49.join(args.worktreeRoot, ...rel.split("/"));
|
|
25871
|
-
const st =
|
|
26175
|
+
const st = fs52.existsSync(abs) ? fs52.statSync(abs) : null;
|
|
25872
26176
|
const size = st && st.isFile() ? st.size : 0;
|
|
25873
26177
|
const { text, truncated } = readFileLimited(abs, MAX_EVIDENCE_READ);
|
|
25874
26178
|
const excerpt = truncated ? `${text.slice(0, MAX_EXCERPT)}
|
|
@@ -25890,7 +26194,7 @@ function buildComparisonManifest(args) {
|
|
|
25890
26194
|
}
|
|
25891
26195
|
|
|
25892
26196
|
// src/factory/contextDrift/contextDriftAgent.ts
|
|
25893
|
-
var
|
|
26197
|
+
var fs53 = __toESM(require("node:fs"));
|
|
25894
26198
|
var path50 = __toESM(require("node:path"));
|
|
25895
26199
|
|
|
25896
26200
|
// src/factory/contextDrift/contextDriftPayload.ts
|
|
@@ -26037,16 +26341,16 @@ function buildDriftPrompt(args) {
|
|
|
26037
26341
|
}
|
|
26038
26342
|
async function runDriftComparisonOpenCode(args) {
|
|
26039
26343
|
const runDir = path50.join(args.worktreeRoot, ".opencode", "_run");
|
|
26040
|
-
|
|
26344
|
+
fs53.mkdirSync(runDir, { recursive: true });
|
|
26041
26345
|
const manifestPath = path50.join(runDir, "context-drift-manifest.json");
|
|
26042
26346
|
const outputPath = path50.join(runDir, "context-drift-payload.json");
|
|
26043
|
-
|
|
26347
|
+
fs53.writeFileSync(manifestPath, `${JSON.stringify(args.manifestObject, null, 2)}
|
|
26044
26348
|
`, "utf8");
|
|
26045
|
-
if (
|
|
26046
|
-
|
|
26349
|
+
if (fs53.existsSync(outputPath)) {
|
|
26350
|
+
fs53.unlinkSync(outputPath);
|
|
26047
26351
|
}
|
|
26048
26352
|
const promptPath = path50.join(runDir, `context-drift-${Date.now()}.prompt.txt`);
|
|
26049
|
-
|
|
26353
|
+
fs53.writeFileSync(
|
|
26050
26354
|
promptPath,
|
|
26051
26355
|
buildDriftPrompt({
|
|
26052
26356
|
worktreeRoot: args.worktreeRoot,
|
|
@@ -26088,7 +26392,7 @@ async function runDriftComparisonOpenCode(args) {
|
|
|
26088
26392
|
}
|
|
26089
26393
|
let raw;
|
|
26090
26394
|
try {
|
|
26091
|
-
const txt =
|
|
26395
|
+
const txt = fs53.readFileSync(outputPath, "utf8");
|
|
26092
26396
|
raw = JSON.parse(txt);
|
|
26093
26397
|
} catch (e) {
|
|
26094
26398
|
return {
|
|
@@ -26105,7 +26409,7 @@ async function runDriftComparisonOpenCode(args) {
|
|
|
26105
26409
|
|
|
26106
26410
|
// src/factory/contextDrift/contextDriftPaths.ts
|
|
26107
26411
|
var crypto2 = __toESM(require("node:crypto"));
|
|
26108
|
-
var
|
|
26412
|
+
var fs54 = __toESM(require("node:fs"));
|
|
26109
26413
|
var path51 = __toESM(require("node:path"));
|
|
26110
26414
|
var DRIFT_CONTEXT_SUBDIR = path51.join(".gluecharm", "context", "drift");
|
|
26111
26415
|
function sanitizeSlug(raw) {
|
|
@@ -26144,7 +26448,7 @@ function maybeDedupeSlug(slug, referenceRelPosix) {
|
|
|
26144
26448
|
function discoverReferenceBundle(worktreeRoot, referenceAbsInWorktree) {
|
|
26145
26449
|
let st;
|
|
26146
26450
|
try {
|
|
26147
|
-
st =
|
|
26451
|
+
st = fs54.statSync(referenceAbsInWorktree);
|
|
26148
26452
|
} catch {
|
|
26149
26453
|
return { ok: false, error: `Reference path not found in analysis worktree: ${referenceAbsInWorktree}` };
|
|
26150
26454
|
}
|
|
@@ -26165,7 +26469,7 @@ function discoverReferenceBundle(worktreeRoot, referenceAbsInWorktree) {
|
|
|
26165
26469
|
}
|
|
26166
26470
|
let entries;
|
|
26167
26471
|
try {
|
|
26168
|
-
entries =
|
|
26472
|
+
entries = fs54.readdirSync(dir, { withFileTypes: true });
|
|
26169
26473
|
} catch {
|
|
26170
26474
|
return;
|
|
26171
26475
|
}
|
|
@@ -26190,7 +26494,7 @@ function discoverReferenceBundle(worktreeRoot, referenceAbsInWorktree) {
|
|
|
26190
26494
|
}
|
|
26191
26495
|
function pickReferenceRootDocument(args) {
|
|
26192
26496
|
if (args.indexOverrideAbs) {
|
|
26193
|
-
if (!
|
|
26497
|
+
if (!fs54.existsSync(args.indexOverrideAbs) || !args.indexOverrideAbs.endsWith(".md")) {
|
|
26194
26498
|
return { ok: false, error: "--index must point to an existing .md file under the repo." };
|
|
26195
26499
|
}
|
|
26196
26500
|
return { ok: true, path: args.indexOverrideAbs };
|
|
@@ -26201,7 +26505,7 @@ function pickReferenceRootDocument(args) {
|
|
|
26201
26505
|
const dir = args.referenceAbsInWorktree;
|
|
26202
26506
|
for (const name of ["index.md", "README.md"]) {
|
|
26203
26507
|
const p = path51.join(dir, name);
|
|
26204
|
-
if (
|
|
26508
|
+
if (fs54.existsSync(p) && fs54.statSync(p).isFile()) {
|
|
26205
26509
|
return { ok: true, path: p };
|
|
26206
26510
|
}
|
|
26207
26511
|
}
|
|
@@ -26218,13 +26522,13 @@ function toPosixPath(p) {
|
|
|
26218
26522
|
}
|
|
26219
26523
|
|
|
26220
26524
|
// src/factory/contextDrift/contextDriftIndex.ts
|
|
26221
|
-
var
|
|
26525
|
+
var fs55 = __toESM(require("node:fs"));
|
|
26222
26526
|
var START = "<!-- easyspecs-drift-links:start -->";
|
|
26223
26527
|
var END = "<!-- easyspecs-drift-links:end -->";
|
|
26224
26528
|
function patchReferenceIndexWithDriftLink(args) {
|
|
26225
26529
|
let body;
|
|
26226
26530
|
try {
|
|
26227
|
-
body =
|
|
26531
|
+
body = fs55.readFileSync(args.referenceRootAbsolute, "utf8");
|
|
26228
26532
|
} catch (e) {
|
|
26229
26533
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
26230
26534
|
}
|
|
@@ -26245,7 +26549,7 @@ ${block}
|
|
|
26245
26549
|
`;
|
|
26246
26550
|
}
|
|
26247
26551
|
try {
|
|
26248
|
-
|
|
26552
|
+
fs55.writeFileSync(args.referenceRootAbsolute, next, "utf8");
|
|
26249
26553
|
} catch (e) {
|
|
26250
26554
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
26251
26555
|
}
|
|
@@ -26256,13 +26560,13 @@ function escapeRe(s) {
|
|
|
26256
26560
|
}
|
|
26257
26561
|
|
|
26258
26562
|
// src/factory/contextDrift/contextDriftPromote.ts
|
|
26259
|
-
var
|
|
26563
|
+
var fs56 = __toESM(require("node:fs"));
|
|
26260
26564
|
var path52 = __toESM(require("node:path"));
|
|
26261
26565
|
function copyWorktreeFileToWorkspace(args) {
|
|
26262
26566
|
const src = path52.join(args.worktreeRoot, ...args.relativePosix.split("/"));
|
|
26263
26567
|
const dest = path52.join(args.workspaceRoot, ...args.relativePosix.split("/"));
|
|
26264
|
-
|
|
26265
|
-
|
|
26568
|
+
fs56.mkdirSync(path52.dirname(dest), { recursive: true });
|
|
26569
|
+
fs56.copyFileSync(src, dest);
|
|
26266
26570
|
}
|
|
26267
26571
|
|
|
26268
26572
|
// src/factory/contextDrift/runContextDriftFactory.ts
|
|
@@ -26281,7 +26585,7 @@ async function runContextDriftFactory(deps) {
|
|
|
26281
26585
|
};
|
|
26282
26586
|
}
|
|
26283
26587
|
const refAbsWorkspace = resolved.abs;
|
|
26284
|
-
if (!
|
|
26588
|
+
if (!fs57.existsSync(refAbsWorkspace)) {
|
|
26285
26589
|
return {
|
|
26286
26590
|
exitOk: false,
|
|
26287
26591
|
ok: false,
|
|
@@ -26294,7 +26598,7 @@ async function runContextDriftFactory(deps) {
|
|
|
26294
26598
|
let indexOverrideAbsWorkspace;
|
|
26295
26599
|
if (deps.indexOverrideArg?.trim()) {
|
|
26296
26600
|
const ir = resolveInsideRepo(deps.repoRootAbs, deps.indexOverrideArg.trim());
|
|
26297
|
-
if (!ir.ok || !
|
|
26601
|
+
if (!ir.ok || !fs57.existsSync(ir.abs)) {
|
|
26298
26602
|
return {
|
|
26299
26603
|
exitOk: false,
|
|
26300
26604
|
ok: false,
|
|
@@ -26312,7 +26616,7 @@ async function runContextDriftFactory(deps) {
|
|
|
26312
26616
|
ok: true,
|
|
26313
26617
|
code: "DRY_RUN",
|
|
26314
26618
|
...baseMeta,
|
|
26315
|
-
referenceRootDocument: toPosixPath(path53.relative(deps.repoRootAbs, refAbsWorkspace)) + (
|
|
26619
|
+
referenceRootDocument: toPosixPath(path53.relative(deps.repoRootAbs, refAbsWorkspace)) + (fs57.statSync(refAbsWorkspace).isDirectory() ? "/" : ""),
|
|
26316
26620
|
driftReportPath: null,
|
|
26317
26621
|
analysisWorktreeRoot: "",
|
|
26318
26622
|
promoted: false,
|
|
@@ -26381,7 +26685,7 @@ async function runContextDriftFactory(deps) {
|
|
|
26381
26685
|
}
|
|
26382
26686
|
const indexWt = indexOverrideAbsWorkspace ? path53.join(wt, ...path53.relative(deps.repoRootAbs, indexOverrideAbsWorkspace).split(path53.sep)) : void 0;
|
|
26383
26687
|
const rootPick = pickReferenceRootDocument({
|
|
26384
|
-
referencePathIsFile:
|
|
26688
|
+
referencePathIsFile: fs57.statSync(refAbsWt).isFile(),
|
|
26385
26689
|
referenceAbsInWorktree: refAbsWt,
|
|
26386
26690
|
bundleFiles: bundle.bundleFiles,
|
|
26387
26691
|
indexOverrideAbs: indexWt
|
|
@@ -26408,7 +26712,7 @@ async function runContextDriftFactory(deps) {
|
|
|
26408
26712
|
slug = maybeDedupeSlug(slug, refRel);
|
|
26409
26713
|
const driftBase = driftFilename(slug, runDate);
|
|
26410
26714
|
const driftDirWt = path53.join(wt, DRIFT_CONTEXT_SUBDIR);
|
|
26411
|
-
|
|
26715
|
+
fs57.mkdirSync(driftDirWt, { recursive: true });
|
|
26412
26716
|
const driftAbsWt = path53.join(driftDirWt, driftBase);
|
|
26413
26717
|
let payload;
|
|
26414
26718
|
if (deps.testOnlyFixturePayload) {
|
|
@@ -26445,7 +26749,7 @@ async function runContextDriftFactory(deps) {
|
|
|
26445
26749
|
manifestTruncation: manifest.truncation
|
|
26446
26750
|
});
|
|
26447
26751
|
try {
|
|
26448
|
-
|
|
26752
|
+
fs57.writeFileSync(driftAbsWt, md, "utf8");
|
|
26449
26753
|
} catch (e) {
|
|
26450
26754
|
finalizeWt?.();
|
|
26451
26755
|
return {
|
|
@@ -26524,7 +26828,7 @@ async function runContextDriftFactory(deps) {
|
|
|
26524
26828
|
}
|
|
26525
26829
|
|
|
26526
26830
|
// src/analysis/coordinationDuplicatesDiagnosis.ts
|
|
26527
|
-
var
|
|
26831
|
+
var fs58 = __toESM(require("fs"));
|
|
26528
26832
|
var path54 = __toESM(require("path"));
|
|
26529
26833
|
var import__7 = __toESM(require__());
|
|
26530
26834
|
var COORDINATION_DUPLICATES_REPORT_BASENAME = "coordination-duplicates-report.json";
|
|
@@ -26561,11 +26865,11 @@ function looksLikeCoordinationDetailMarkdownBasename(basename17) {
|
|
|
26561
26865
|
}
|
|
26562
26866
|
function loadRawFeatureRows(contextDirAbs) {
|
|
26563
26867
|
const p = path54.join(contextDirAbs, "features-list.json");
|
|
26564
|
-
if (!
|
|
26868
|
+
if (!fs58.existsSync(p)) {
|
|
26565
26869
|
return [];
|
|
26566
26870
|
}
|
|
26567
26871
|
try {
|
|
26568
|
-
const raw = stripUtf8Bom6(
|
|
26872
|
+
const raw = stripUtf8Bom6(fs58.readFileSync(p, "utf-8"));
|
|
26569
26873
|
const doc = JSON.parse(raw);
|
|
26570
26874
|
return Array.isArray(doc.features) ? doc.features : [];
|
|
26571
26875
|
} catch {
|
|
@@ -26600,7 +26904,7 @@ function findOrphanCoordinationMarkdown(contextDirAbs) {
|
|
|
26600
26904
|
const featureRows = loadRawFeatureRows(contextDirAbs);
|
|
26601
26905
|
let dirents;
|
|
26602
26906
|
try {
|
|
26603
|
-
dirents =
|
|
26907
|
+
dirents = fs58.readdirSync(contextDirAbs, { withFileTypes: true });
|
|
26604
26908
|
} catch {
|
|
26605
26909
|
return [];
|
|
26606
26910
|
}
|
|
@@ -26854,13 +27158,13 @@ function buildCoordinationDuplicatesReport(input) {
|
|
|
26854
27158
|
const duplicateGroups = [];
|
|
26855
27159
|
for (const entry of COORDINATION_LIST_SCAN_ENTRIES) {
|
|
26856
27160
|
const filePath = path54.join(input.contextDirAbsolute, entry.basename);
|
|
26857
|
-
if (!
|
|
27161
|
+
if (!fs58.existsSync(filePath)) {
|
|
26858
27162
|
lists.push({ basename: entry.basename, status: "missing" });
|
|
26859
27163
|
continue;
|
|
26860
27164
|
}
|
|
26861
27165
|
let raw;
|
|
26862
27166
|
try {
|
|
26863
|
-
raw = stripUtf8Bom6(
|
|
27167
|
+
raw = stripUtf8Bom6(fs58.readFileSync(filePath, "utf-8"));
|
|
26864
27168
|
} catch (e) {
|
|
26865
27169
|
lists.push({
|
|
26866
27170
|
basename: entry.basename,
|
|
@@ -26909,7 +27213,7 @@ function validateReportData(data) {
|
|
|
26909
27213
|
if (!validateReportCompiled) {
|
|
26910
27214
|
const ajv2 = new import__7.default({ allErrors: true, strict: false });
|
|
26911
27215
|
const schemaPath = path54.join(resolveContextListSchemasDir(), "coordination-duplicates-report.schema.json");
|
|
26912
|
-
const schemaRaw = stripUtf8Bom6(
|
|
27216
|
+
const schemaRaw = stripUtf8Bom6(fs58.readFileSync(schemaPath, "utf-8"));
|
|
26913
27217
|
validateReportCompiled = ajv2.compile(JSON.parse(schemaRaw));
|
|
26914
27218
|
}
|
|
26915
27219
|
if (validateReportCompiled(data)) {
|
|
@@ -26932,15 +27236,15 @@ function runCoordinationDuplicatesDiagnosis(input) {
|
|
|
26932
27236
|
`;
|
|
26933
27237
|
const tmp = `${outPath}.tmp.${process.pid}`;
|
|
26934
27238
|
try {
|
|
26935
|
-
|
|
27239
|
+
fs58.writeFileSync(tmp, payload, "utf-8");
|
|
26936
27240
|
} catch (e) {
|
|
26937
27241
|
return { ok: false, message: e instanceof Error ? e.message : String(e) };
|
|
26938
27242
|
}
|
|
26939
27243
|
try {
|
|
26940
|
-
|
|
27244
|
+
fs58.renameSync(tmp, outPath);
|
|
26941
27245
|
} catch (e) {
|
|
26942
27246
|
try {
|
|
26943
|
-
|
|
27247
|
+
fs58.unlinkSync(tmp);
|
|
26944
27248
|
} catch {
|
|
26945
27249
|
}
|
|
26946
27250
|
return { ok: false, message: e instanceof Error ? e.message : String(e) };
|
|
@@ -26974,7 +27278,7 @@ function runCoordinationDuplicatesDiagnosis(input) {
|
|
|
26974
27278
|
}
|
|
26975
27279
|
|
|
26976
27280
|
// src/pipelines/download/downloadPipeline.ts
|
|
26977
|
-
var
|
|
27281
|
+
var fs59 = __toESM(require("node:fs"));
|
|
26978
27282
|
var path55 = __toESM(require("node:path"));
|
|
26979
27283
|
var SRS_DISCOVERY_BATCH_GET_CHUNK_SIZE = 200;
|
|
26980
27284
|
function isRecord7(v) {
|
|
@@ -27080,19 +27384,19 @@ function chunkIds(ids, size) {
|
|
|
27080
27384
|
return out;
|
|
27081
27385
|
}
|
|
27082
27386
|
function clearContextDirectoryForCloudReplace(contextDirAbs) {
|
|
27083
|
-
if (!
|
|
27387
|
+
if (!fs59.existsSync(contextDirAbs) || !fs59.statSync(contextDirAbs).isDirectory()) {
|
|
27084
27388
|
return { filesRemoved: 0 };
|
|
27085
27389
|
}
|
|
27086
27390
|
const preserveAbs = path55.resolve(contextDirAbs, UPLOAD_TARGET_FILENAME);
|
|
27087
27391
|
const preserveSet = /* @__PURE__ */ new Set();
|
|
27088
|
-
if (
|
|
27392
|
+
if (fs59.existsSync(preserveAbs) && fs59.statSync(preserveAbs).isFile()) {
|
|
27089
27393
|
preserveSet.add(preserveAbs);
|
|
27090
27394
|
}
|
|
27091
27395
|
let filesRemoved = 0;
|
|
27092
27396
|
const walkRm = (dir) => {
|
|
27093
27397
|
let entries;
|
|
27094
27398
|
try {
|
|
27095
|
-
entries =
|
|
27399
|
+
entries = fs59.readdirSync(dir, { withFileTypes: true });
|
|
27096
27400
|
} catch {
|
|
27097
27401
|
return;
|
|
27098
27402
|
}
|
|
@@ -27101,7 +27405,7 @@ function clearContextDirectoryForCloudReplace(contextDirAbs) {
|
|
|
27101
27405
|
if (e.isDirectory()) {
|
|
27102
27406
|
walkRm(full);
|
|
27103
27407
|
try {
|
|
27104
|
-
|
|
27408
|
+
fs59.rmdirSync(full);
|
|
27105
27409
|
} catch {
|
|
27106
27410
|
}
|
|
27107
27411
|
} else if (e.isFile()) {
|
|
@@ -27110,7 +27414,7 @@ function clearContextDirectoryForCloudReplace(contextDirAbs) {
|
|
|
27110
27414
|
continue;
|
|
27111
27415
|
}
|
|
27112
27416
|
try {
|
|
27113
|
-
|
|
27417
|
+
fs59.unlinkSync(abs);
|
|
27114
27418
|
filesRemoved += 1;
|
|
27115
27419
|
} catch {
|
|
27116
27420
|
}
|
|
@@ -27189,15 +27493,15 @@ async function runDownloadPipeline(opts) {
|
|
|
27189
27493
|
failed.push({ id, name, message: "Unsafe or invalid name for local path." });
|
|
27190
27494
|
continue;
|
|
27191
27495
|
}
|
|
27192
|
-
|
|
27193
|
-
const exists =
|
|
27496
|
+
fs59.mkdirSync(path55.dirname(outAbs), { recursive: true });
|
|
27497
|
+
const exists = fs59.existsSync(outAbs);
|
|
27194
27498
|
if (exists && !opts.force && !opts.replaceFromCloud) {
|
|
27195
27499
|
skipped += 1;
|
|
27196
27500
|
log?.(`[pipeline:download] skip existing ${name} (use --force to overwrite).`);
|
|
27197
27501
|
continue;
|
|
27198
27502
|
}
|
|
27199
27503
|
try {
|
|
27200
|
-
|
|
27504
|
+
fs59.writeFileSync(outAbs, bodyText, "utf8");
|
|
27201
27505
|
downloaded += 1;
|
|
27202
27506
|
succeededIds[outAbs] = id;
|
|
27203
27507
|
} catch (e) {
|
|
@@ -27368,7 +27672,7 @@ function createAuthenticatedRequestJson(deps) {
|
|
|
27368
27672
|
}
|
|
27369
27673
|
|
|
27370
27674
|
// src/cli/cliSession.ts
|
|
27371
|
-
var
|
|
27675
|
+
var fs60 = __toESM(require("node:fs"));
|
|
27372
27676
|
var os6 = __toESM(require("node:os"));
|
|
27373
27677
|
var path56 = __toESM(require("node:path"));
|
|
27374
27678
|
function defaultSessionPath() {
|
|
@@ -27413,10 +27717,10 @@ function effectiveCliSessionPath() {
|
|
|
27413
27717
|
function readCliSession() {
|
|
27414
27718
|
const p = effectiveCliSessionPath();
|
|
27415
27719
|
try {
|
|
27416
|
-
if (!
|
|
27720
|
+
if (!fs60.existsSync(p)) {
|
|
27417
27721
|
return void 0;
|
|
27418
27722
|
}
|
|
27419
|
-
const j = JSON.parse(
|
|
27723
|
+
const j = JSON.parse(fs60.readFileSync(p, "utf8"));
|
|
27420
27724
|
const apiBaseUrl = typeof j.apiBaseUrl === "string" ? j.apiBaseUrl.trim() : "";
|
|
27421
27725
|
const accessToken = typeof j.accessToken === "string" ? j.accessToken : "";
|
|
27422
27726
|
const refreshToken = typeof j.refreshToken === "string" ? j.refreshToken : "";
|
|
@@ -27430,20 +27734,20 @@ function readCliSession() {
|
|
|
27430
27734
|
}
|
|
27431
27735
|
function writeCliSession(s) {
|
|
27432
27736
|
const p = effectiveCliSessionPath();
|
|
27433
|
-
|
|
27434
|
-
|
|
27737
|
+
fs60.mkdirSync(path56.dirname(p), { recursive: true });
|
|
27738
|
+
fs60.writeFileSync(p, `${JSON.stringify(s, null, 2)}
|
|
27435
27739
|
`, "utf8");
|
|
27436
27740
|
}
|
|
27437
27741
|
function clearCliSession() {
|
|
27438
27742
|
const p = effectiveCliSessionPath();
|
|
27439
27743
|
try {
|
|
27440
|
-
|
|
27744
|
+
fs60.unlinkSync(p);
|
|
27441
27745
|
} catch {
|
|
27442
27746
|
}
|
|
27443
27747
|
}
|
|
27444
27748
|
|
|
27445
27749
|
// src/analysis/acePendingTraces.ts
|
|
27446
|
-
var
|
|
27750
|
+
var fs61 = __toESM(require("fs"));
|
|
27447
27751
|
var path57 = __toESM(require("path"));
|
|
27448
27752
|
function normalizeAceTraceRelativePath(rel) {
|
|
27449
27753
|
return rel.split(/[/\\]/).join("/");
|
|
@@ -27451,12 +27755,12 @@ function normalizeAceTraceRelativePath(rel) {
|
|
|
27451
27755
|
function readCompletedTraceRelativePaths(contextDir2) {
|
|
27452
27756
|
const set = /* @__PURE__ */ new Set();
|
|
27453
27757
|
const jsonlPath = aceConsolidatedSessionsJsonlPath(contextDir2);
|
|
27454
|
-
if (!
|
|
27758
|
+
if (!fs61.existsSync(jsonlPath)) {
|
|
27455
27759
|
return set;
|
|
27456
27760
|
}
|
|
27457
27761
|
let raw;
|
|
27458
27762
|
try {
|
|
27459
|
-
raw =
|
|
27763
|
+
raw = fs61.readFileSync(jsonlPath, "utf8");
|
|
27460
27764
|
} catch {
|
|
27461
27765
|
return set;
|
|
27462
27766
|
}
|
|
@@ -27487,7 +27791,7 @@ function readCompletedTraceRelativePaths(contextDir2) {
|
|
|
27487
27791
|
}
|
|
27488
27792
|
function listPendingAceTraceFiles(contextDir2, worktreeRoot) {
|
|
27489
27793
|
const traceSchema = opencodeAceSchemaPath(worktreeRoot, ACE_SCHEMA_TRACE);
|
|
27490
|
-
if (!
|
|
27794
|
+
if (!fs61.existsSync(traceSchema)) {
|
|
27491
27795
|
return [];
|
|
27492
27796
|
}
|
|
27493
27797
|
const completed = readCompletedTraceRelativePaths(contextDir2);
|
|
@@ -27791,7 +28095,9 @@ var TAG_SGR = {
|
|
|
27791
28095
|
"zero-ref": "\x1B[91m",
|
|
27792
28096
|
ace: "\x1B[95m",
|
|
27793
28097
|
cli: "\x1B[90m",
|
|
27794
|
-
EasySpecs: "\x1B[93m"
|
|
28098
|
+
EasySpecs: "\x1B[93m",
|
|
28099
|
+
"host-pool": "\x1B[36m",
|
|
28100
|
+
"host-pool-rec": "\x1B[90m"
|
|
27795
28101
|
};
|
|
27796
28102
|
function tagOpenSgr(tag) {
|
|
27797
28103
|
const direct = TAG_SGR[tag];
|
|
@@ -27832,7 +28138,7 @@ function phaseFamilyForTag(tag) {
|
|
|
27832
28138
|
if (tag.startsWith("pipeline:")) {
|
|
27833
28139
|
return "meta";
|
|
27834
28140
|
}
|
|
27835
|
-
if (tag === "pool" || tag === "queue" || tag === "worktree" || tag === "context") {
|
|
28141
|
+
if (tag === "pool" || tag === "queue" || tag === "worktree" || tag === "context" || tag === "host-pool" || tag === "host-pool-rec") {
|
|
27836
28142
|
return "orch";
|
|
27837
28143
|
}
|
|
27838
28144
|
if (Object.prototype.hasOwnProperty.call(TAG_SGR, tag)) {
|
|
@@ -28091,7 +28397,7 @@ function formatCliStderrLine(line, useAnsi) {
|
|
|
28091
28397
|
}
|
|
28092
28398
|
|
|
28093
28399
|
// src/cli/main.ts
|
|
28094
|
-
var PKG_VERSION = "0.0.
|
|
28400
|
+
var PKG_VERSION = "0.0.27";
|
|
28095
28401
|
function isNonEmptyFactoryFailureArray(x) {
|
|
28096
28402
|
if (!Array.isArray(x) || x.length === 0) {
|
|
28097
28403
|
return false;
|
|
@@ -28223,7 +28529,7 @@ function resolveAnalysisRoot(repoRoot, rootKind, worktreePath) {
|
|
|
28223
28529
|
return repoRoot;
|
|
28224
28530
|
}
|
|
28225
28531
|
const wt = worktreePath?.trim();
|
|
28226
|
-
if (wt &&
|
|
28532
|
+
if (wt && fs62.existsSync(path59.join(wt, ".git"))) {
|
|
28227
28533
|
return path59.resolve(wt);
|
|
28228
28534
|
}
|
|
28229
28535
|
throw new Error("worktree mode requires --worktree <path> to an existing analysis checkout.");
|
|
@@ -28232,14 +28538,14 @@ function resolveAdHocCheckoutRoot(_repoRoot, storage, worktreeFlag) {
|
|
|
28232
28538
|
const w = worktreeFlag?.trim();
|
|
28233
28539
|
if (w) {
|
|
28234
28540
|
const abs = path59.resolve(w);
|
|
28235
|
-
if (
|
|
28541
|
+
if (fs62.existsSync(path59.join(abs, ".git"))) {
|
|
28236
28542
|
return abs;
|
|
28237
28543
|
}
|
|
28238
28544
|
throw new Error(`Invalid --worktree (not a git checkout): ${abs}`);
|
|
28239
28545
|
}
|
|
28240
28546
|
const snap = readAnalysisWorkspaceSnapshot(storage);
|
|
28241
28547
|
const p = snap?.adHocWorktreePath?.trim();
|
|
28242
|
-
if (p &&
|
|
28548
|
+
if (p && fs62.existsSync(path59.join(p, ".git"))) {
|
|
28243
28549
|
return p;
|
|
28244
28550
|
}
|
|
28245
28551
|
throw new Error("No analysis checkout: run `easyspecs-cli run synthesis` first or pass `--worktree <path>`.");
|
|
@@ -28562,7 +28868,7 @@ async function main() {
|
|
|
28562
28868
|
process.exit(ExitCode.usage);
|
|
28563
28869
|
}
|
|
28564
28870
|
const agentsDir = resolveOpenCodeAgentsDir(repoRoot, repoConfig);
|
|
28565
|
-
const agentsOk =
|
|
28871
|
+
const agentsOk = fs62.existsSync(agentsDir);
|
|
28566
28872
|
const oc = getOpenCodeReadiness({
|
|
28567
28873
|
executable: merged.openCodeExecutable,
|
|
28568
28874
|
skipCredentialsCheck: merged.openCodeSkipCredentialsCheck,
|
|
@@ -29078,7 +29384,7 @@ async function main() {
|
|
|
29078
29384
|
const wt = snap?.adHocWorktreePath?.trim();
|
|
29079
29385
|
if (wt) {
|
|
29080
29386
|
const sourceCtx = path59.join(wt, ".gluecharm", "context");
|
|
29081
|
-
if (
|
|
29387
|
+
if (fs62.existsSync(sourceCtx)) {
|
|
29082
29388
|
const n = promoteContextDirectoryToWorkspaceFs(sourceCtx, repoRoot);
|
|
29083
29389
|
logErr(flags, `[pipeline:analysis] promoted ${String(n.filesCopied)} file(s) \u2192 ${repoRoot}`);
|
|
29084
29390
|
} else {
|
|
@@ -29248,12 +29554,12 @@ async function main() {
|
|
|
29248
29554
|
if (pos[1] === "republish") {
|
|
29249
29555
|
const fromCfg = repoConfig.easyspecs?.upload?.contextDirectory?.trim();
|
|
29250
29556
|
const resolvedOverride = fromCfg && fromCfg.length > 0 ? path59.isAbsolute(fromCfg) ? path59.normalize(fromCfg) : path59.resolve(repoRoot, fromCfg) : "";
|
|
29251
|
-
if (resolvedOverride &&
|
|
29557
|
+
if (resolvedOverride && fs62.existsSync(path59.join(resolvedOverride, ".."))) {
|
|
29252
29558
|
ctxDir = resolvedOverride;
|
|
29253
29559
|
} else {
|
|
29254
29560
|
const storage = createFileBackedWorkspaceState(repoRoot);
|
|
29255
29561
|
const snap = readAnalysisWorkspaceSnapshot(storage);
|
|
29256
|
-
const wt = snap?.adHocWorktreePath &&
|
|
29562
|
+
const wt = snap?.adHocWorktreePath && fs62.existsSync(path59.join(snap.adHocWorktreePath, ".gluecharm", "context")) ? path59.join(snap.adHocWorktreePath, ".gluecharm", "context") : "";
|
|
29257
29563
|
if (!wt) {
|
|
29258
29564
|
finish(ExitCode.misconfiguration, {
|
|
29259
29565
|
ok: false,
|
|
@@ -29371,16 +29677,16 @@ async function main() {
|
|
|
29371
29677
|
}
|
|
29372
29678
|
if (pos[0] === "ace" && pos[1] === "clear") {
|
|
29373
29679
|
const learnings = path59.join(repoRoot, ".gluecharm", "context", "learnings");
|
|
29374
|
-
if (!
|
|
29680
|
+
if (!fs62.existsSync(learnings)) {
|
|
29375
29681
|
finish(ExitCode.ok, { ok: true, message: "nothing to clear" });
|
|
29376
29682
|
}
|
|
29377
|
-
|
|
29683
|
+
fs62.rmSync(learnings, { recursive: true, force: true });
|
|
29378
29684
|
finish(ExitCode.ok, { ok: true, message: `cleared ${learnings}` });
|
|
29379
29685
|
}
|
|
29380
29686
|
if (pos[0] === "ace" && pos[1] === "learn") {
|
|
29381
29687
|
requireOpenCode(merged, flags);
|
|
29382
29688
|
const { worktree } = parseWorktreeFlag(pos.slice(2));
|
|
29383
|
-
const root = worktree &&
|
|
29689
|
+
const root = worktree && fs62.existsSync(path59.join(worktree, ".opencode", "schemas", "ace")) ? worktree : repoRoot;
|
|
29384
29690
|
const contextDir2 = path59.join(root, ".gluecharm", "context");
|
|
29385
29691
|
const traces = listAceTraceFiles(contextDir2);
|
|
29386
29692
|
if (traces.length === 0) {
|
|
@@ -29405,7 +29711,7 @@ async function main() {
|
|
|
29405
29711
|
if (pos[0] === "ace" && pos[1] === "auto-learn") {
|
|
29406
29712
|
requireOpenCode(merged, flags);
|
|
29407
29713
|
const { worktree } = parseWorktreeFlag(pos.slice(2));
|
|
29408
|
-
const root = worktree &&
|
|
29714
|
+
const root = worktree && fs62.existsSync(path59.join(worktree, ".git")) ? worktree : repoRoot;
|
|
29409
29715
|
const contextDir2 = path59.join(root, ".gluecharm", "context");
|
|
29410
29716
|
const pending = listPendingAceTraceFiles(contextDir2, root);
|
|
29411
29717
|
if (pending.length === 0) {
|