@gluecharm-lab/easyspecs-cli 0.0.25 → 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/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 fs62 = require("node:fs");
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 (fs62.existsSync(localBin)) return localBin;
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) => fs62.existsSync(`${localBin}${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 = fs62.realpathSync(this._scriptPath);
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, fs62, exportName) {
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, fs62[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 fs61 = __toESM(require("node:fs"));
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 fs36 = __toESM(require("fs"));
13195
+ var fs37 = __toESM(require("fs"));
13196
13196
  var path32 = __toESM(require("path"));
13197
13197
 
13198
13198
  // src/analysis/analysisDynamicTestSteps.ts
@@ -20320,14 +20320,304 @@ function nextAdaptiveMaxAfterCpuSample(p) {
20320
20320
  if (p.activeRunningCount < 1 || !Number.isFinite(p.ratio) || p.ratio <= threshold) {
20321
20321
  return { adaptiveMax: p.priorAdaptiveMax, changed: false };
20322
20322
  }
20323
- const candidate = Math.max(1, p.activeRunningCount - 1);
20324
- const next = Math.min(p.priorAdaptiveMax, candidate);
20323
+ const stepDown = Math.max(1, p.priorAdaptiveMax - 1);
20324
+ const backpressure = p.activeRunningCount <= 1 ? stepDown : Math.max(1, p.activeRunningCount - 1);
20325
+ const next = Math.min(p.priorAdaptiveMax, stepDown, backpressure);
20325
20326
  if (next < p.priorAdaptiveMax) {
20326
20327
  return { adaptiveMax: next, changed: true };
20327
20328
  }
20328
20329
  return { adaptiveMax: p.priorAdaptiveMax, changed: false };
20329
20330
  }
20330
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
+
20331
20621
  // src/pipelines/synthesis/synthesisPipeline.ts
20332
20622
  var FE = /^FE-\d+$/;
20333
20623
  var UC = /^UC-\d+$/;
@@ -20340,7 +20630,7 @@ function stripBom2(s) {
20340
20630
  }
20341
20631
  function readJson4(filePath) {
20342
20632
  try {
20343
- const raw = stripBom2(fs36.readFileSync(filePath, "utf-8"));
20633
+ const raw = stripBom2(fs37.readFileSync(filePath, "utf-8"));
20344
20634
  return JSON.parse(raw);
20345
20635
  } catch {
20346
20636
  return null;
@@ -20435,7 +20725,7 @@ function featureDetailTarget(contextDir2, code, name, slug) {
20435
20725
  displayName: "Feature detail",
20436
20726
  outputBasename: basename17,
20437
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).`,
20438
- exists: fs36.existsSync(path32.join(contextDir2, basename17)) && fs36.statSync(path32.join(contextDir2, basename17)).size > 0
20728
+ exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
20439
20729
  };
20440
20730
  }
20441
20731
  function viewDetailTarget(row2, contextDir2) {
@@ -20446,7 +20736,7 @@ function viewDetailTarget(row2, contextDir2) {
20446
20736
  displayName: "View detail",
20447
20737
  outputBasename: basename17,
20448
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.`,
20449
- exists: fs36.existsSync(path32.join(contextDir2, basename17)) && fs36.statSync(path32.join(contextDir2, basename17)).size > 0
20739
+ exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
20450
20740
  };
20451
20741
  }
20452
20742
  function interactionDetailTarget(viewCode, ix, contextDir2) {
@@ -20457,7 +20747,7 @@ function interactionDetailTarget(viewCode, ix, contextDir2) {
20457
20747
  displayName: "Interaction detail",
20458
20748
  outputBasename: basename17,
20459
20749
  taskDescription: `Document interaction **${ix.code}** (**${ix.name}**) on view **${viewCode}** per \`.gluecharm/context/experiences-list.json\`.`,
20460
- exists: fs36.existsSync(path32.join(contextDir2, basename17)) && fs36.statSync(path32.join(contextDir2, basename17)).size > 0
20750
+ exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
20461
20751
  };
20462
20752
  }
20463
20753
  function serviceDetailTarget(row2, contextDir2) {
@@ -20468,7 +20758,7 @@ function serviceDetailTarget(row2, contextDir2) {
20468
20758
  displayName: "Service detail",
20469
20759
  outputBasename: basename17,
20470
20760
  taskDescription: `Describe service **${row2.code}** (**${row2.name}**, slug **${row2.slug}**) per \`.gluecharm/context/services-list.json\`: responsibilities, consumers, errors, integration points.`,
20471
- exists: fs36.existsSync(path32.join(contextDir2, basename17)) && fs36.statSync(path32.join(contextDir2, basename17)).size > 0
20761
+ exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
20472
20762
  };
20473
20763
  }
20474
20764
  function methodDetailTarget(svc, m, contextDir2) {
@@ -20479,7 +20769,7 @@ function methodDetailTarget(svc, m, contextDir2) {
20479
20769
  displayName: "Method detail",
20480
20770
  outputBasename: basename17,
20481
20771
  taskDescription: `Document method **${m.code}** (**${m.name}**) on service **${svc.code}** per \`.gluecharm/context/services-list.json\`.`,
20482
- exists: fs36.existsSync(path32.join(contextDir2, basename17)) && fs36.statSync(path32.join(contextDir2, basename17)).size > 0
20772
+ exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
20483
20773
  };
20484
20774
  }
20485
20775
  function entityDetailTarget(dmCode, ename, slug, contextDir2) {
@@ -20490,7 +20780,7 @@ function entityDetailTarget(dmCode, ename, slug, contextDir2) {
20490
20780
  displayName: "Entity detail",
20491
20781
  outputBasename: basename17,
20492
20782
  taskDescription: `Describe entity **${dmCode}** (**${ename}**, slug **${slug}**) per \`.gluecharm/context/data-model-list.json\`: lifecycle, invariants, storage, ORM/schema mapping.`,
20493
- exists: fs36.existsSync(path32.join(contextDir2, basename17)) && fs36.statSync(path32.join(contextDir2, basename17)).size > 0
20783
+ exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
20494
20784
  };
20495
20785
  }
20496
20786
  function fieldDetailTarget(dmCode, fdCode, fname, fSlug, contextDir2) {
@@ -20501,7 +20791,7 @@ function fieldDetailTarget(dmCode, fdCode, fname, fSlug, contextDir2) {
20501
20791
  displayName: "Field detail",
20502
20792
  outputBasename: basename17,
20503
20793
  taskDescription: `Document field **${fdCode}** (**${fname}**) on entity **${dmCode}** per \`.gluecharm/context/${dmCode}-fields-list.json\`. Cite types and constraints with file and line.`,
20504
- exists: fs36.existsSync(path32.join(contextDir2, basename17)) && fs36.statSync(path32.join(contextDir2, basename17)).size > 0
20794
+ exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
20505
20795
  };
20506
20796
  }
20507
20797
  function toolDetailTarget(row2, contextDir2) {
@@ -20512,7 +20802,7 @@ function toolDetailTarget(row2, contextDir2) {
20512
20802
  displayName: "Tool detail",
20513
20803
  outputBasename: basename17,
20514
20804
  taskDescription: `Describe tool **${row2.code}** (**${row2.name}**, slug **${row2.slug}**) per \`.gluecharm/context/tech-stack-list.json\`: role, version hints, configuration, boundaries.`,
20515
- exists: fs36.existsSync(path32.join(contextDir2, basename17)) && fs36.statSync(path32.join(contextDir2, basename17)).size > 0
20805
+ exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
20516
20806
  };
20517
20807
  }
20518
20808
  function useCaseDetailTarget(feCode, ucCode, ucName, ucSlug, contextDir2) {
@@ -20525,7 +20815,7 @@ function useCaseDetailTarget(feCode, ucCode, ucName, ucSlug, contextDir2) {
20525
20815
  taskDescription: `Document use case **${ucCode}** (**${ucName}**) under feature **${feCode}** per \`.gluecharm/context/${feCode}-use-cases-list.json\`. Do not change stable codes.
20526
20816
 
20527
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.`,
20528
- exists: fs36.existsSync(path32.join(contextDir2, ucBase)) && fs36.statSync(path32.join(contextDir2, ucBase)).size > 0
20818
+ exists: fs37.existsSync(path32.join(contextDir2, ucBase)) && fs37.statSync(path32.join(contextDir2, ucBase)).size > 0
20529
20819
  };
20530
20820
  }
20531
20821
  function scenarioDetailTarget(feCode, ucCode, scCode, scName, contextDir2) {
@@ -20536,7 +20826,7 @@ function scenarioDetailTarget(feCode, ucCode, scCode, scName, contextDir2) {
20536
20826
  displayName: "Scenario detail",
20537
20827
  outputBasename: basename17,
20538
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.`,
20539
- exists: fs36.existsSync(path32.join(contextDir2, basename17)) && fs36.statSync(path32.join(contextDir2, basename17)).size > 0
20829
+ exists: fs37.existsSync(path32.join(contextDir2, basename17)) && fs37.statSync(path32.join(contextDir2, basename17)).size > 0
20540
20830
  };
20541
20831
  }
20542
20832
  function parentsDone(item, byId) {
@@ -21096,6 +21386,20 @@ async function drainWorkstationPool(p) {
21096
21386
  const intervalMs = p.__testOnlyCpuPressureIntervalMs ?? 3e4;
21097
21387
  pressureInterval = setInterval(() => applyCpuPressure(), intervalMs);
21098
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);
21099
21403
  try {
21100
21404
  while (true) {
21101
21405
  while (fifo.length > 0 && active < currentCap() && !abortSignal?.aborted) {
@@ -21126,6 +21430,7 @@ async function drainWorkstationPool(p) {
21126
21430
  if (pressureInterval) {
21127
21431
  clearInterval(pressureInterval);
21128
21432
  }
21433
+ clearInterval(hostPoolInterval);
21129
21434
  if (poolAbortListenerRegistered && abortSignal) {
21130
21435
  abortSignal.removeEventListener("abort", onPipelineAbort);
21131
21436
  }
@@ -21165,7 +21470,7 @@ async function runSynthesisPipelineDrainFromPreparedWorktree(storageContext, rep
21165
21470
  offlineLearnAfterSameSessionTrace: getAceOfflineLearnAfterSameSessionTrace(handle.path)
21166
21471
  };
21167
21472
  const contextDir2 = path32.join(handle.path, ".gluecharm", "context");
21168
- fs36.mkdirSync(contextDir2, { recursive: true });
21473
+ fs37.mkdirSync(contextDir2, { recursive: true });
21169
21474
  const initialItems = buildRootItems();
21170
21475
  await startArtefactRun(storageContext, repoRoot, handle.path, initialItems);
21171
21476
  await cb.onBootstrapReady?.({ worktreeRoot: handle.path, contextDir: contextDir2 });
@@ -21266,27 +21571,27 @@ async function runSynthesisPipeline(storageContext, repoRoot, workspaceLabel, ex
21266
21571
  }
21267
21572
 
21268
21573
  // src/workspaceContextPromote.ts
21269
- var fs37 = __toESM(require("fs"));
21574
+ var fs38 = __toESM(require("fs"));
21270
21575
  var path33 = __toESM(require("path"));
21271
21576
  function promoteContextDirectoryToWorkspaceFs(sourceContextDir, workspaceRootFs) {
21272
21577
  const dest = path33.join(workspaceRootFs, ".gluecharm", "context");
21273
- fs37.mkdirSync(path33.join(workspaceRootFs, ".gluecharm"), { recursive: true });
21274
- fs37.mkdirSync(dest, { recursive: true });
21578
+ fs38.mkdirSync(path33.join(workspaceRootFs, ".gluecharm"), { recursive: true });
21579
+ fs38.mkdirSync(dest, { recursive: true });
21275
21580
  let names;
21276
21581
  try {
21277
- names = fs37.readdirSync(sourceContextDir);
21582
+ names = fs38.readdirSync(sourceContextDir);
21278
21583
  } catch {
21279
21584
  return { filesCopied: 0 };
21280
21585
  }
21281
21586
  let filesCopied = 0;
21282
21587
  for (const name of names) {
21283
21588
  const srcPath = path33.join(sourceContextDir, name);
21284
- if (!fs37.statSync(srcPath).isFile()) {
21589
+ if (!fs38.statSync(srcPath).isFile()) {
21285
21590
  continue;
21286
21591
  }
21287
- const buf = fs37.readFileSync(srcPath);
21592
+ const buf = fs38.readFileSync(srcPath);
21288
21593
  const target = path33.join(dest, name);
21289
- fs37.writeFileSync(target, buf);
21594
+ fs38.writeFileSync(target, buf);
21290
21595
  filesCopied += 1;
21291
21596
  }
21292
21597
  return { filesCopied };
@@ -21946,7 +22251,7 @@ async function runGenerateContextFactory(deps) {
21946
22251
  }
21947
22252
 
21948
22253
  // src/factory/generateContextFactoryHeadlessHost.ts
21949
- var fs46 = __toESM(require("node:fs"));
22254
+ var fs47 = __toESM(require("node:fs"));
21950
22255
  var path43 = __toESM(require("node:path"));
21951
22256
 
21952
22257
  // src/stores/pipelineRunStore.ts
@@ -22047,11 +22352,11 @@ async function noteAgentsMaterialized(context) {
22047
22352
  }
22048
22353
 
22049
22354
  // src/pipelines/remediation/missingWorkstations.ts
22050
- var fs39 = __toESM(require("fs"));
22355
+ var fs40 = __toESM(require("fs"));
22051
22356
  var path35 = __toESM(require("path"));
22052
22357
 
22053
22358
  // src/analysis/analysisDetailMarkdownDiscovery.ts
22054
- var fs38 = __toESM(require("fs"));
22359
+ var fs39 = __toESM(require("fs"));
22055
22360
  var path34 = __toESM(require("path"));
22056
22361
  var SLUG4 = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
22057
22362
  var FE2 = /^FE-\d+$/;
@@ -22073,7 +22378,7 @@ var STEM_TO_AGENT = {
22073
22378
  };
22074
22379
  function readJson5(filePath) {
22075
22380
  try {
22076
- let raw = fs38.readFileSync(filePath, "utf-8");
22381
+ let raw = fs39.readFileSync(filePath, "utf-8");
22077
22382
  if (raw.length > 0 && raw.charCodeAt(0) === 65279) {
22078
22383
  raw = raw.slice(1);
22079
22384
  }
@@ -22341,7 +22646,7 @@ function fileAndValidationFromKind(kind) {
22341
22646
  function classifyMissingWorkstationOutputFileStatus(row2, contextDir2, worktreeRoot) {
22342
22647
  const abs = path35.join(contextDir2, row2.relativePath);
22343
22648
  try {
22344
- const st = fs39.statSync(abs);
22649
+ const st = fs40.statSync(abs);
22345
22650
  if (!st.isFile()) {
22346
22651
  return { kind: "absent", detail: "Path exists but is not a regular file." };
22347
22652
  }
@@ -22379,7 +22684,7 @@ function classifyMissingWorkstationOutputFileStatus(row2, contextDir2, worktreeR
22379
22684
  };
22380
22685
  }
22381
22686
  const schemaAbs = path35.join(worktreeRoot, ".opencode", "schemas", "context-lists", schemaBn);
22382
- if (!fs39.existsSync(schemaAbs)) {
22687
+ if (!fs40.existsSync(schemaAbs)) {
22383
22688
  return {
22384
22689
  kind: "invalid",
22385
22690
  detail: `Schema not found (${schemaBn}). Run **Materialize agents** on this checkout.`
@@ -22615,7 +22920,7 @@ function listMissingWorkstations(contextDir2, worktreeRoot, snapshot) {
22615
22920
  }
22616
22921
  }
22617
22922
  }
22618
- if (!fs39.existsSync(contextDir2)) {
22923
+ if (!fs40.existsSync(contextDir2)) {
22619
22924
  return [...map.values()].sort((a, b) => a.key.localeCompare(b.key));
22620
22925
  }
22621
22926
  const dynamic = discoverDynamicAnalysisTestSteps(contextDir2);
@@ -22796,11 +23101,11 @@ async function runRemediationPipelineMissingPass(p) {
22796
23101
 
22797
23102
  // src/pipelines/coverage/coveragePipeline.ts
22798
23103
  var import_child_process5 = require("child_process");
22799
- var fs41 = __toESM(require("fs"));
23104
+ var fs42 = __toESM(require("fs"));
22800
23105
  var path38 = __toESM(require("path"));
22801
23106
 
22802
23107
  // src/analysis/coverageReferenceValidationSchemaValidate.ts
22803
- var fs40 = __toESM(require("fs"));
23108
+ var fs41 = __toESM(require("fs"));
22804
23109
  var path37 = __toESM(require("path"));
22805
23110
  var import__5 = __toESM(require__());
22806
23111
  function stripUtf8Bom4(s) {
@@ -22830,7 +23135,7 @@ function getValidate() {
22830
23135
  return compiledValidate;
22831
23136
  }
22832
23137
  const schemaPath = bundledCoverageReferenceValidationSchemaPath();
22833
- const schemaRaw = stripUtf8Bom4(fs40.readFileSync(schemaPath, "utf-8"));
23138
+ const schemaRaw = stripUtf8Bom4(fs41.readFileSync(schemaPath, "utf-8"));
22834
23139
  const schema = JSON.parse(schemaRaw);
22835
23140
  const ajv2 = new import__5.default({ allErrors: true, strict: false });
22836
23141
  compiledValidate = ajv2.compile(schema);
@@ -22846,7 +23151,7 @@ function validateCoverageReferenceValidationData(data) {
22846
23151
  function readAndValidateCoverageReferenceValidationFile(jsonAbsolutePath) {
22847
23152
  let raw;
22848
23153
  try {
22849
- raw = stripUtf8Bom4(fs40.readFileSync(jsonAbsolutePath, "utf-8"));
23154
+ raw = stripUtf8Bom4(fs41.readFileSync(jsonAbsolutePath, "utf-8"));
22850
23155
  } catch (e) {
22851
23156
  return {
22852
23157
  ok: false,
@@ -22888,7 +23193,7 @@ var DEFAULT_IGNORE_DIR_BASENAMES = [
22888
23193
  var GIT_LS_FILES_MAX_BUFFER = 64 * 1024 * 1024;
22889
23194
  function tryLoadGitNonIgnoredPathSet(repositoryRootAbs) {
22890
23195
  const root = path38.resolve(repositoryRootAbs);
22891
- if (!fs41.existsSync(path38.join(root, ".git"))) {
23196
+ if (!fs42.existsSync(path38.join(root, ".git"))) {
22892
23197
  return null;
22893
23198
  }
22894
23199
  const env = { ...process.env, GIT_TERMINAL_PROMPT: "0" };
@@ -23043,7 +23348,7 @@ function extractEvidenceIndexPathCitations(body) {
23043
23348
  function listContextFilesRecursive(dir, acc) {
23044
23349
  let entries;
23045
23350
  try {
23046
- entries = fs41.readdirSync(dir, { withFileTypes: true });
23351
+ entries = fs42.readdirSync(dir, { withFileTypes: true });
23047
23352
  } catch {
23048
23353
  return;
23049
23354
  }
@@ -23061,7 +23366,7 @@ function walkRepositoryFiles(repoRoot, ignoreBasenames, maxBytes, excludedOut, g
23061
23366
  const walk = (dir) => {
23062
23367
  let entries;
23063
23368
  try {
23064
- entries = fs41.readdirSync(dir, { withFileTypes: true });
23369
+ entries = fs42.readdirSync(dir, { withFileTypes: true });
23065
23370
  } catch {
23066
23371
  return;
23067
23372
  }
@@ -23091,7 +23396,7 @@ function walkRepositoryFiles(repoRoot, ignoreBasenames, maxBytes, excludedOut, g
23091
23396
  }
23092
23397
  let st;
23093
23398
  try {
23094
- st = fs41.statSync(full);
23399
+ st = fs42.statSync(full);
23095
23400
  } catch {
23096
23401
  continue;
23097
23402
  }
@@ -23101,7 +23406,7 @@ function walkRepositoryFiles(repoRoot, ignoreBasenames, maxBytes, excludedOut, g
23101
23406
  }
23102
23407
  let buf;
23103
23408
  try {
23104
- buf = fs41.readFileSync(full);
23409
+ buf = fs42.readFileSync(full);
23105
23410
  } catch {
23106
23411
  excludedOut.push({ path: rel, reason: "read error" });
23107
23412
  continue;
@@ -23121,7 +23426,7 @@ function walkRepositoryFiles(repoRoot, ignoreBasenames, maxBytes, excludedOut, g
23121
23426
  }
23122
23427
  function collectReferencesFromContext(contextDirAbs, repositoryRootAbs, warnings) {
23123
23428
  const references = [];
23124
- if (!fs41.existsSync(contextDirAbs)) {
23429
+ if (!fs42.existsSync(contextDirAbs)) {
23125
23430
  warnings.push(`Context directory missing: ${contextDirAbs}`);
23126
23431
  return references;
23127
23432
  }
@@ -23137,7 +23442,7 @@ function collectReferencesFromContext(contextDirAbs, repositoryRootAbs, warnings
23137
23442
  }
23138
23443
  let raw;
23139
23444
  try {
23140
- raw = fs41.readFileSync(abs, "utf-8");
23445
+ raw = fs42.readFileSync(abs, "utf-8");
23141
23446
  } catch (e) {
23142
23447
  warnings.push(`Skip JSON (read error): ${sourceArtefact} \u2014 ${e instanceof Error ? e.message : String(e)}`);
23143
23448
  continue;
@@ -23168,7 +23473,7 @@ function collectReferencesFromContext(contextDirAbs, repositoryRootAbs, warnings
23168
23473
  if (ext === ".md") {
23169
23474
  let text;
23170
23475
  try {
23171
- const buf = fs41.readFileSync(abs);
23476
+ const buf = fs42.readFileSync(abs);
23172
23477
  text = decodeBufferForLineCount(buf);
23173
23478
  } catch (e) {
23174
23479
  warnings.push(`Skip markdown (read/decode error): ${sourceArtefact} \u2014 ${e instanceof Error ? e.message : String(e)}`);
@@ -23225,7 +23530,7 @@ function buildCoverageReferenceValidationDocument(repositoryRootAbs, contextDirA
23225
23530
  }
23226
23531
  const excludedFiles = [];
23227
23532
  const gitNonIgnoredPaths = tryLoadGitNonIgnoredPathSet(repoRoot);
23228
- if (fs41.existsSync(path38.join(repoRoot, ".git")) && gitNonIgnoredPaths === null) {
23533
+ if (fs42.existsSync(path38.join(repoRoot, ".git")) && gitNonIgnoredPaths === null) {
23229
23534
  warnings.push(
23230
23535
  "Repository has .git but git ls-files failed or git is unavailable; .gitignore / exclude-standard not applied."
23231
23536
  );
@@ -23276,10 +23581,10 @@ function buildCoverageReferenceValidationDocument(repositoryRootAbs, contextDirA
23276
23581
  function runCoveragePipeline(opts) {
23277
23582
  const repoRoot = path38.resolve(opts.repositoryRootAbs);
23278
23583
  const contextDir2 = path38.resolve(opts.contextDirAbs);
23279
- if (!fs41.existsSync(repoRoot)) {
23584
+ if (!fs42.existsSync(repoRoot)) {
23280
23585
  return { ok: false, error: `Repository root does not exist: ${repoRoot}` };
23281
23586
  }
23282
- if (!fs41.existsSync(contextDir2)) {
23587
+ if (!fs42.existsSync(contextDir2)) {
23283
23588
  return {
23284
23589
  ok: false,
23285
23590
  error: `Missing .gluecharm/context: ${contextDir2}`
@@ -23301,7 +23606,7 @@ ${schemaCheck.errors.join("\n")}`,
23301
23606
  if (opts.write) {
23302
23607
  try {
23303
23608
  const payload = stableStringifyCoverageDocument(document);
23304
- fs41.writeFileSync(outPath, payload, "utf-8");
23609
+ fs42.writeFileSync(outPath, payload, "utf-8");
23305
23610
  } catch (e) {
23306
23611
  return {
23307
23612
  ok: false,
@@ -23315,11 +23620,11 @@ ${schemaCheck.errors.join("\n")}`,
23315
23620
 
23316
23621
  // src/pipelines/remediation/zeroReferenceWorkstationChain.ts
23317
23622
  var crypto = __toESM(require("crypto"));
23318
- var fs43 = __toESM(require("fs"));
23623
+ var fs44 = __toESM(require("fs"));
23319
23624
  var path40 = __toESM(require("path"));
23320
23625
 
23321
23626
  // src/analysis/zeroReferenceRemediationSchemaValidate.ts
23322
- var fs42 = __toESM(require("fs"));
23627
+ var fs43 = __toESM(require("fs"));
23323
23628
  var path39 = __toESM(require("path"));
23324
23629
  var import__6 = __toESM(require__());
23325
23630
  function stripUtf8Bom5(s) {
@@ -23341,7 +23646,7 @@ function formatAjvErrors6(errors) {
23341
23646
  var ajv = new import__6.default({ allErrors: true, strict: false });
23342
23647
  function compileSchema(basename17) {
23343
23648
  const schemaPath = path39.join(schemasDir(), basename17);
23344
- const schemaRaw = stripUtf8Bom5(fs42.readFileSync(schemaPath, "utf-8"));
23649
+ const schemaRaw = stripUtf8Bom5(fs43.readFileSync(schemaPath, "utf-8"));
23345
23650
  const schema = JSON.parse(schemaRaw);
23346
23651
  return ajv.compile(schema);
23347
23652
  }
@@ -23385,7 +23690,7 @@ var ZERO_REF_STAGING_JSON_TOTAL_ATTEMPTS = 5;
23385
23690
  var ZERO_REF_STAGING_FILE_PREVIEW_MAX_CHARS = 6e3;
23386
23691
  function readStagingOutputPreview(outAbs) {
23387
23692
  try {
23388
- const s = fs43.readFileSync(outAbs, "utf-8");
23693
+ const s = fs44.readFileSync(outAbs, "utf-8");
23389
23694
  if (s.length <= ZERO_REF_STAGING_FILE_PREVIEW_MAX_CHARS) {
23390
23695
  return s;
23391
23696
  }
@@ -23668,14 +23973,14 @@ function readNonReferencedFilesFromRepositoryRoot(repositoryRootAbs) {
23668
23973
  return { ok: true, paths, ...generatedAt ? { generatedAt } : {} };
23669
23974
  }
23670
23975
  function readOrInitRoutingDoc(routingAbs, coverageReferenceGeneratedAt) {
23671
- if (!fs43.existsSync(routingAbs)) {
23976
+ if (!fs44.existsSync(routingAbs)) {
23672
23977
  return {
23673
23978
  schemaVersion: ROUTING_SCHEMA_VERSION,
23674
23979
  ...coverageReferenceGeneratedAt ? { coverageReferenceGeneratedAt } : {},
23675
23980
  records: {}
23676
23981
  };
23677
23982
  }
23678
- const raw = fs43.readFileSync(routingAbs, "utf-8");
23983
+ const raw = fs44.readFileSync(routingAbs, "utf-8");
23679
23984
  const data = JSON.parse(raw);
23680
23985
  if (!data.records || typeof data.records !== "object") {
23681
23986
  return {
@@ -23687,10 +23992,10 @@ function readOrInitRoutingDoc(routingAbs, coverageReferenceGeneratedAt) {
23687
23992
  return data;
23688
23993
  }
23689
23994
  function readOrInitTriageDoc(triageAbs) {
23690
- if (!fs43.existsSync(triageAbs)) {
23995
+ if (!fs44.existsSync(triageAbs)) {
23691
23996
  return { schemaVersion: TRIAGE_SCHEMA_VERSION, records: {} };
23692
23997
  }
23693
- const raw = fs43.readFileSync(triageAbs, "utf-8");
23998
+ const raw = fs44.readFileSync(triageAbs, "utf-8");
23694
23999
  const data = JSON.parse(raw);
23695
24000
  if (!data.records || typeof data.records !== "object") {
23696
24001
  return { schemaVersion: TRIAGE_SCHEMA_VERSION, records: {} };
@@ -23741,7 +24046,7 @@ function lineCountRepoFile(worktreeRootAbs, relPosix) {
23741
24046
  const abs = path40.join(worktreeRootAbs, ...relPosix.split("/"));
23742
24047
  let buf;
23743
24048
  try {
23744
- buf = fs43.readFileSync(abs);
24049
+ buf = fs44.readFileSync(abs);
23745
24050
  } catch {
23746
24051
  return 1;
23747
24052
  }
@@ -23795,7 +24100,7 @@ async function applyCoordinationListTriageMerge(input) {
23795
24100
  const cfg = LIST_MERGE_CFG[input.listKind];
23796
24101
  const listPath = path40.join(input.contextDirAbs, cfg.listBasename);
23797
24102
  const schemaPath = path40.join(resolveContextListSchemasDir(), cfg.schemaBasename);
23798
- if (!fs43.existsSync(listPath)) {
24103
+ if (!fs44.existsSync(listPath)) {
23799
24104
  return {
23800
24105
  ok: false,
23801
24106
  message: `${cfg.listBasename} not found \u2014 run coordination step ${LIST_STEP_HINT[input.listKind]} first.`
@@ -23806,7 +24111,7 @@ async function applyCoordinationListTriageMerge(input) {
23806
24111
  return withCoordinationListFileLock(listPath, {}, async () => {
23807
24112
  let raw;
23808
24113
  try {
23809
- raw = fs43.readFileSync(listPath, "utf-8");
24114
+ raw = fs44.readFileSync(listPath, "utf-8");
23810
24115
  } catch (e) {
23811
24116
  return { ok: false, message: e instanceof Error ? e.message : String(e) };
23812
24117
  }
@@ -23874,7 +24179,7 @@ async function applyCoordinationListTriageMerge(input) {
23874
24179
  });
23875
24180
  const tmp = `${listPath}.tmp.${process.pid}`;
23876
24181
  try {
23877
- fs43.writeFileSync(tmp, `${JSON.stringify(doc, null, 2)}
24182
+ fs44.writeFileSync(tmp, `${JSON.stringify(doc, null, 2)}
23878
24183
  `, "utf-8");
23879
24184
  } catch (e) {
23880
24185
  return { ok: false, message: e instanceof Error ? e.message : String(e) };
@@ -23882,13 +24187,13 @@ async function applyCoordinationListTriageMerge(input) {
23882
24187
  const v = validateCoordinationListJson(tmp, schemaPath);
23883
24188
  if (!v.ok) {
23884
24189
  try {
23885
- fs43.unlinkSync(tmp);
24190
+ fs44.unlinkSync(tmp);
23886
24191
  } catch {
23887
24192
  }
23888
24193
  return { ok: false, message: `${cfg.listBasename} validation failed: ${JSON.stringify(v.failure)}` };
23889
24194
  }
23890
24195
  try {
23891
- fs43.renameSync(tmp, listPath);
24196
+ fs44.renameSync(tmp, listPath);
23892
24197
  } catch (e) {
23893
24198
  return { ok: false, message: e instanceof Error ? e.message : String(e) };
23894
24199
  }
@@ -23898,9 +24203,9 @@ async function applyCoordinationListTriageMerge(input) {
23898
24203
  }
23899
24204
  async function runClassifierAgent(common, contextDirAbs, targetFilePathPosix, workspaceLabel) {
23900
24205
  const outAbs = stagingPathForTarget(contextDirAbs, "classifier", targetFilePathPosix);
23901
- fs43.mkdirSync(path40.dirname(outAbs), { recursive: true });
24206
+ fs44.mkdirSync(path40.dirname(outAbs), { recursive: true });
23902
24207
  const runDir = path40.join(common.worktreeRoot, ".opencode", "_run");
23903
- fs43.mkdirSync(runDir, { recursive: true });
24208
+ fs44.mkdirSync(runDir, { recursive: true });
23904
24209
  const outputBasename = path40.basename(outAbs);
23905
24210
  const listTaskDescription = [
23906
24211
  `Target file (repo-relative, POSIX): **${targetFilePathPosix}**`,
@@ -23938,7 +24243,7 @@ async function runClassifierAgent(common, contextDirAbs, targetFilePathPosix, wo
23938
24243
  ...repairAppendix ? { repairAppendix } : {}
23939
24244
  });
23940
24245
  const promptPath = path40.join(runDir, `zero-ref-classify-a${attempt}-${Date.now()}.prompt.txt`);
23941
- fs43.writeFileSync(promptPath, body, "utf-8");
24246
+ fs44.writeFileSync(promptPath, body, "utf-8");
23942
24247
  const argv = expandArgvTemplate4(common.argvTemplate, {
23943
24248
  promptFile: promptPath,
23944
24249
  agentId: ZERO_REF_CLASSIFY_AGENT_STEM,
@@ -23965,7 +24270,7 @@ async function runClassifierAgent(common, contextDirAbs, targetFilePathPosix, wo
23965
24270
  const canRetry = attempt < ZERO_REF_STAGING_JSON_TOTAL_ATTEMPTS - 1;
23966
24271
  let st;
23967
24272
  try {
23968
- st = fs43.statSync(outAbs);
24273
+ st = fs44.statSync(outAbs);
23969
24274
  } catch {
23970
24275
  st = void 0;
23971
24276
  }
@@ -23987,7 +24292,7 @@ async function runClassifierAgent(common, contextDirAbs, targetFilePathPosix, wo
23987
24292
  }
23988
24293
  let parsed;
23989
24294
  try {
23990
- parsed = JSON.parse(fs43.readFileSync(outAbs, "utf-8"));
24295
+ parsed = JSON.parse(fs44.readFileSync(outAbs, "utf-8"));
23991
24296
  } catch (e) {
23992
24297
  const msg = e instanceof Error ? e.message : String(e);
23993
24298
  lastFailureMessage = `Classifier output not valid JSON: ${msg}`;
@@ -24072,7 +24377,7 @@ async function runMarkdownReferenceAgent(common, contextDirAbs, targetFilePathPo
24072
24377
  const mdAbs = path40.join(contextDirAbs, mdBasename);
24073
24378
  const agentStem = which === "project" ? ZERO_REF_ADD_REF_PROJECT_AGENT_STEM : ZERO_REF_ADD_REF_ARCH_AGENT_STEM;
24074
24379
  const runDir = path40.join(common.worktreeRoot, ".opencode", "_run");
24075
- fs43.mkdirSync(runDir, { recursive: true });
24380
+ fs44.mkdirSync(runDir, { recursive: true });
24076
24381
  const lines = [
24077
24382
  `# SRS-30 \u2014 Add reference to ${mdBasename}`,
24078
24383
  ``,
@@ -24088,7 +24393,7 @@ async function runMarkdownReferenceAgent(common, contextDirAbs, targetFilePathPo
24088
24393
  `- Do not remove unrelated content; append or extend the most appropriate section.`
24089
24394
  ];
24090
24395
  const promptPath = path40.join(runDir, `zero-ref-md-${which}-${Date.now()}.prompt.txt`);
24091
- fs43.writeFileSync(promptPath, lines.join("\n"), "utf-8");
24396
+ fs44.writeFileSync(promptPath, lines.join("\n"), "utf-8");
24092
24397
  const argv = expandArgvTemplate4(common.argvTemplate, {
24093
24398
  promptFile: promptPath,
24094
24399
  agentId: agentStem,
@@ -24115,9 +24420,9 @@ async function runMarkdownReferenceAgent(common, contextDirAbs, targetFilePathPo
24115
24420
  async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathPosix, routingSummary, workspaceLabel, triageScope) {
24116
24421
  const meta = TRIAGE_SCOPE_META[triageScope];
24117
24422
  const outAbs = stagingPathForTarget(contextDirAbs, "triage", targetFilePathPosix);
24118
- fs43.mkdirSync(path40.dirname(outAbs), { recursive: true });
24423
+ fs44.mkdirSync(path40.dirname(outAbs), { recursive: true });
24119
24424
  const runDir = path40.join(common.worktreeRoot, ".opencode", "_run");
24120
- fs43.mkdirSync(runDir, { recursive: true });
24425
+ fs44.mkdirSync(runDir, { recursive: true });
24121
24426
  const outputBasename = path40.basename(outAbs);
24122
24427
  const listTaskDescription = [
24123
24428
  `Target file: **${targetFilePathPosix}** (${workspaceLabel})`,
@@ -24149,7 +24454,7 @@ async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathP
24149
24454
  ...repairAppendix ? { repairAppendix } : {}
24150
24455
  });
24151
24456
  const promptPath = path40.join(runDir, `zero-ref-triage-a${attempt}-${Date.now()}.prompt.txt`);
24152
- fs43.writeFileSync(promptPath, body, "utf-8");
24457
+ fs44.writeFileSync(promptPath, body, "utf-8");
24153
24458
  const argv = expandArgvTemplate4(common.argvTemplate, {
24154
24459
  promptFile: promptPath,
24155
24460
  agentId: ZERO_REF_TRIAGE_COORD_AGENT_STEM,
@@ -24176,7 +24481,7 @@ async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathP
24176
24481
  const canRetry = attempt < ZERO_REF_STAGING_JSON_TOTAL_ATTEMPTS - 1;
24177
24482
  let st;
24178
24483
  try {
24179
- st = fs43.statSync(outAbs);
24484
+ st = fs44.statSync(outAbs);
24180
24485
  } catch {
24181
24486
  st = void 0;
24182
24487
  }
@@ -24198,7 +24503,7 @@ async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathP
24198
24503
  }
24199
24504
  let parsed;
24200
24505
  try {
24201
- parsed = JSON.parse(fs43.readFileSync(outAbs, "utf-8"));
24506
+ parsed = JSON.parse(fs44.readFileSync(outAbs, "utf-8"));
24202
24507
  } catch (e) {
24203
24508
  const msg = e instanceof Error ? e.message : String(e);
24204
24509
  lastFailureMessage = `Triage output not valid JSON: ${msg}`;
@@ -24254,7 +24559,7 @@ async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathP
24254
24559
  return { ok: false, message: lastFailureMessage, stagingPath: outAbs };
24255
24560
  }
24256
24561
  try {
24257
- fs43.writeFileSync(outAbs, `${JSON.stringify(parsed, null, 2)}
24562
+ fs44.writeFileSync(outAbs, `${JSON.stringify(parsed, null, 2)}
24258
24563
  `, "utf-8");
24259
24564
  } catch {
24260
24565
  }
@@ -24272,7 +24577,7 @@ async function runOneUnreferencedFilePipeline(p) {
24272
24577
  }
24273
24578
  let stagingParsed;
24274
24579
  try {
24275
- stagingParsed = JSON.parse(fs43.readFileSync(cr.stagingPath, "utf-8"));
24580
+ stagingParsed = JSON.parse(fs44.readFileSync(cr.stagingPath, "utf-8"));
24276
24581
  } catch (e) {
24277
24582
  return { ok: false, message: String(e) };
24278
24583
  }
@@ -24288,8 +24593,8 @@ async function runOneUnreferencedFilePipeline(p) {
24288
24593
  if (!s.ok) {
24289
24594
  throw new Error(s.errors.join("; "));
24290
24595
  }
24291
- fs43.mkdirSync(path40.dirname(routingAbs), { recursive: true });
24292
- fs43.writeFileSync(routingAbs, s.json, "utf-8");
24596
+ fs44.mkdirSync(path40.dirname(routingAbs), { recursive: true });
24597
+ fs44.writeFileSync(routingAbs, s.json, "utf-8");
24293
24598
  });
24294
24599
  const routing = stagingParsed.routing;
24295
24600
  const routingSummary = typeof stagingParsed.projectRelationSummary === "string" ? stagingParsed.projectRelationSummary : "";
@@ -24320,7 +24625,7 @@ async function runOneUnreferencedFilePipeline(p) {
24320
24625
  }
24321
24626
  let triageParsed;
24322
24627
  try {
24323
- triageParsed = JSON.parse(fs43.readFileSync(tr.stagingPath, "utf-8"));
24628
+ triageParsed = JSON.parse(fs44.readFileSync(tr.stagingPath, "utf-8"));
24324
24629
  } catch (e) {
24325
24630
  return { ok: false, message: String(e) };
24326
24631
  }
@@ -24337,8 +24642,8 @@ async function runOneUnreferencedFilePipeline(p) {
24337
24642
  if (!s.ok) {
24338
24643
  throw new Error(s.errors.join("; "));
24339
24644
  }
24340
- fs43.mkdirSync(path40.dirname(triageAbs), { recursive: true });
24341
- fs43.writeFileSync(triageAbs, s.json, "utf-8");
24645
+ fs44.mkdirSync(path40.dirname(triageAbs), { recursive: true });
24646
+ fs44.writeFileSync(triageAbs, s.json, "utf-8");
24342
24647
  });
24343
24648
  const decision = triageParsed.decision;
24344
24649
  if (decision === "new_item" || decision === "enrich_existing") {
@@ -24426,7 +24731,7 @@ async function runRemediationPipelineZeroRefPass(p) {
24426
24731
  }
24427
24732
 
24428
24733
  // src/pipelines/coverage/coverageExecutionReport.ts
24429
- var fs44 = __toESM(require("fs"));
24734
+ var fs45 = __toESM(require("fs"));
24430
24735
  var path41 = __toESM(require("path"));
24431
24736
  var REFERENCE_COVERAGE_EXECUTION_REPORT_BASENAME = "reference-coverage-execution-report.md";
24432
24737
  function inlineMdText(s) {
@@ -24523,7 +24828,7 @@ function collectNoActionRowsFromRoutingDoc(doc) {
24523
24828
  return rows;
24524
24829
  }
24525
24830
  function readRoutingDocFromDisk(routingAbs) {
24526
- if (!fs44.existsSync(routingAbs)) {
24831
+ if (!fs45.existsSync(routingAbs)) {
24527
24832
  return {
24528
24833
  ok: true,
24529
24834
  doc: { schemaVersion: "1", records: {} }
@@ -24531,7 +24836,7 @@ function readRoutingDocFromDisk(routingAbs) {
24531
24836
  }
24532
24837
  let raw;
24533
24838
  try {
24534
- raw = fs44.readFileSync(routingAbs, "utf-8");
24839
+ raw = fs45.readFileSync(routingAbs, "utf-8");
24535
24840
  } catch (e) {
24536
24841
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
24537
24842
  }
@@ -24571,20 +24876,20 @@ async function runCoverageExecutionReport(p) {
24571
24876
  }
24572
24877
  let previous;
24573
24878
  try {
24574
- if (fs44.existsSync(outAbs)) {
24575
- previous = fs44.readFileSync(outAbs, "utf-8");
24879
+ if (fs45.existsSync(outAbs)) {
24880
+ previous = fs45.readFileSync(outAbs, "utf-8");
24576
24881
  }
24577
24882
  } catch {
24578
24883
  previous = void 0;
24579
24884
  }
24580
24885
  try {
24581
- fs44.mkdirSync(path41.dirname(outAbs), { recursive: true });
24582
- fs44.writeFileSync(outAbs, md, "utf-8");
24886
+ fs45.mkdirSync(path41.dirname(outAbs), { recursive: true });
24887
+ fs45.writeFileSync(outAbs, md, "utf-8");
24583
24888
  } catch (e) {
24584
24889
  const msg = e instanceof Error ? e.message : String(e);
24585
24890
  if (previous !== void 0) {
24586
24891
  try {
24587
- fs44.writeFileSync(outAbs, previous, "utf-8");
24892
+ fs45.writeFileSync(outAbs, previous, "utf-8");
24588
24893
  } catch {
24589
24894
  }
24590
24895
  }
@@ -24595,7 +24900,7 @@ async function runCoverageExecutionReport(p) {
24595
24900
  }
24596
24901
 
24597
24902
  // src/gluecharm/minimalGluecharmLayout.ts
24598
- var fs45 = __toESM(require("node:fs"));
24903
+ var fs46 = __toESM(require("node:fs"));
24599
24904
  var path42 = __toESM(require("node:path"));
24600
24905
  var MINIMAL_GLUECHARM_RELATIVE_DIRS = [
24601
24906
  [".gluecharm", "docs", "srs"],
@@ -24608,7 +24913,7 @@ function ensureMinimalGluecharmLayoutNode(repoRootAbs) {
24608
24913
  for (const segments of MINIMAL_GLUECHARM_RELATIVE_DIRS) {
24609
24914
  const dir = path42.join(root, ...segments);
24610
24915
  try {
24611
- fs45.mkdirSync(dir, { recursive: true });
24916
+ fs46.mkdirSync(dir, { recursive: true });
24612
24917
  } catch (e) {
24613
24918
  const err = e;
24614
24919
  const msg = e instanceof Error ? e.message : String(e);
@@ -24990,13 +25295,13 @@ function buildFactoryDepsHeadless(input) {
24990
25295
  },
24991
25296
  runPrepareAnalysisWorktree: async (resume) => {
24992
25297
  if (resume) {
24993
- if (adHocWorktree && fs46.existsSync(path43.join(adHocWorktree.path, ".git"))) {
25298
+ if (adHocWorktree && fs47.existsSync(path43.join(adHocWorktree.path, ".git"))) {
24994
25299
  return { ok: true };
24995
25300
  }
24996
25301
  const snap = readAnalysisWorkspaceSnapshot(storageContext);
24997
25302
  const wtPath = snap?.adHocWorktreePath?.trim();
24998
25303
  const repo = snap?.adHocRepositoryRoot?.trim() || repoRoot;
24999
- if (wtPath && fs46.existsSync(path43.join(wtPath, ".git"))) {
25304
+ if (wtPath && fs47.existsSync(path43.join(wtPath, ".git"))) {
25000
25305
  adHocWorktree = attachWorktreeHandle(wtPath, repo);
25001
25306
  macroSourceBranch = snap?.adHocSourceBranchAtCreation;
25002
25307
  macroFinalize = () => {
@@ -25221,7 +25526,7 @@ function stderrLinesForFactoryFailures(failures, exitCode) {
25221
25526
  var path48 = __toESM(require("node:path"));
25222
25527
 
25223
25528
  // src/factory/updateContext/updateContextBaseline.ts
25224
- var fs47 = __toESM(require("node:fs"));
25529
+ var fs48 = __toESM(require("node:fs"));
25225
25530
  var path44 = __toESM(require("node:path"));
25226
25531
  function isValidIso(s) {
25227
25532
  const t = Date.parse(s);
@@ -25232,7 +25537,7 @@ function maxMtimeRegularFilesUnderDir(dirAbs) {
25232
25537
  const walk = (d) => {
25233
25538
  let entries;
25234
25539
  try {
25235
- entries = fs47.readdirSync(d, { withFileTypes: true });
25540
+ entries = fs48.readdirSync(d, { withFileTypes: true });
25236
25541
  } catch {
25237
25542
  return;
25238
25543
  }
@@ -25242,7 +25547,7 @@ function maxMtimeRegularFilesUnderDir(dirAbs) {
25242
25547
  walk(p);
25243
25548
  } else if (e.isFile()) {
25244
25549
  try {
25245
- const st = fs47.statSync(p);
25550
+ const st = fs48.statSync(p);
25246
25551
  const m = st.mtimeMs;
25247
25552
  if (best === null || m > best) {
25248
25553
  best = m;
@@ -25264,7 +25569,7 @@ function resolveUpdateContextBaseline(repoRootAbs, repoConfig) {
25264
25569
  return { baselineIsoUtc: new Date(last).toISOString(), source: "lastRunAt" };
25265
25570
  }
25266
25571
  const ctxDir = path44.join(repoRootAbs, ".gluecharm", "context");
25267
- if (!fs47.existsSync(ctxDir)) {
25572
+ if (!fs48.existsSync(ctxDir)) {
25268
25573
  return null;
25269
25574
  }
25270
25575
  const maxMs = maxMtimeRegularFilesUnderDir(ctxDir);
@@ -25287,7 +25592,7 @@ function persistUpdateContextLastRunAt(repoRootAbs, isoUtc) {
25287
25592
 
25288
25593
  // src/factory/updateContext/updateContextGitWindow.ts
25289
25594
  var import_node_child_process3 = require("node:child_process");
25290
- var fs48 = __toESM(require("node:fs"));
25595
+ var fs49 = __toESM(require("node:fs"));
25291
25596
  var path45 = __toESM(require("node:path"));
25292
25597
  var GIT_ENV = { ...process.env, GIT_TERMINAL_PROMPT: "0" };
25293
25598
  function gitLines(repoRootAbs, args) {
@@ -25313,7 +25618,7 @@ function parseGitLogIso(line) {
25313
25618
  }
25314
25619
  function discoverCommitWindowAndTouchedPaths(repoRootAbs, baselineIsoUtc) {
25315
25620
  const root = path45.resolve(repoRootAbs);
25316
- if (!fs48.existsSync(path45.join(root, ".git"))) {
25621
+ if (!fs49.existsSync(path45.join(root, ".git"))) {
25317
25622
  return { ok: false, error: "Not a git repository (missing .git)." };
25318
25623
  }
25319
25624
  const baselineMs = Date.parse(baselineIsoUtc);
@@ -25378,7 +25683,7 @@ function filterPathsExistingInWorktree(worktreeRootAbs, pathsPosix) {
25378
25683
  const rel = p.replace(/\\/g, "/");
25379
25684
  const abs = path45.join(root, ...rel.split("/"));
25380
25685
  try {
25381
- if (fs48.existsSync(abs) && fs48.statSync(abs).isFile()) {
25686
+ if (fs49.existsSync(abs) && fs49.statSync(abs).isFile()) {
25382
25687
  out.push(rel);
25383
25688
  }
25384
25689
  } catch {
@@ -25388,7 +25693,7 @@ function filterPathsExistingInWorktree(worktreeRootAbs, pathsPosix) {
25388
25693
  }
25389
25694
 
25390
25695
  // src/factory/updateContext/updateContextReport.ts
25391
- var fs49 = __toESM(require("node:fs"));
25696
+ var fs50 = __toESM(require("node:fs"));
25392
25697
  var path46 = __toESM(require("node:path"));
25393
25698
  var CHANGES_SINCE_DATE_BASENAME = "changes-since-date.md";
25394
25699
  function renderChangesSinceDateMarkdown(p) {
@@ -25430,9 +25735,9 @@ function renderChangesSinceDateMarkdown(p) {
25430
25735
  }
25431
25736
  function writeChangesSinceDateReport(contextDirAbs, body) {
25432
25737
  try {
25433
- fs49.mkdirSync(contextDirAbs, { recursive: true });
25738
+ fs50.mkdirSync(contextDirAbs, { recursive: true });
25434
25739
  const target = path46.join(contextDirAbs, CHANGES_SINCE_DATE_BASENAME);
25435
- fs49.writeFileSync(target, body, "utf-8");
25740
+ fs50.writeFileSync(target, body, "utf-8");
25436
25741
  return { ok: true };
25437
25742
  } catch (e) {
25438
25743
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
@@ -25440,13 +25745,13 @@ function writeChangesSinceDateReport(contextDirAbs, body) {
25440
25745
  }
25441
25746
 
25442
25747
  // src/factory/updateContext/updateContextSeedCheck.ts
25443
- var fs50 = __toESM(require("node:fs"));
25748
+ var fs51 = __toESM(require("node:fs"));
25444
25749
  var path47 = __toESM(require("node:path"));
25445
25750
  var INDEX_BASENAME = "index-application-context.json";
25446
25751
  var CHANGES_REPORT = "changes-since-date.md";
25447
25752
  function tryParseJsonFile(abs) {
25448
25753
  try {
25449
- const raw = fs50.readFileSync(abs, "utf-8");
25754
+ const raw = fs51.readFileSync(abs, "utf-8");
25450
25755
  JSON.parse(raw);
25451
25756
  return true;
25452
25757
  } catch {
@@ -25454,16 +25759,16 @@ function tryParseJsonFile(abs) {
25454
25759
  }
25455
25760
  }
25456
25761
  function isWorktreeContextSeeded(contextDirAbs) {
25457
- if (!fs50.existsSync(contextDirAbs)) {
25762
+ if (!fs51.existsSync(contextDirAbs)) {
25458
25763
  return false;
25459
25764
  }
25460
25765
  const indexAbs = path47.join(contextDirAbs, INDEX_BASENAME);
25461
- if (fs50.existsSync(indexAbs) && fs50.statSync(indexAbs).isFile() && tryParseJsonFile(indexAbs)) {
25766
+ if (fs51.existsSync(indexAbs) && fs51.statSync(indexAbs).isFile() && tryParseJsonFile(indexAbs)) {
25462
25767
  return true;
25463
25768
  }
25464
25769
  let names;
25465
25770
  try {
25466
- names = fs50.readdirSync(contextDirAbs);
25771
+ names = fs51.readdirSync(contextDirAbs);
25467
25772
  } catch {
25468
25773
  return false;
25469
25774
  }
@@ -25477,7 +25782,7 @@ function isWorktreeContextSeeded(contextDirAbs) {
25477
25782
  }
25478
25783
  const p = path47.join(contextDirAbs, name);
25479
25784
  try {
25480
- if (fs50.statSync(p).isFile()) {
25785
+ if (fs51.statSync(p).isFile()) {
25481
25786
  distinct.add(name);
25482
25787
  }
25483
25788
  } catch {
@@ -25779,11 +26084,11 @@ async function runUpdateContextFactory(deps) {
25779
26084
  }
25780
26085
 
25781
26086
  // src/factory/contextDrift/runContextDriftFactory.ts
25782
- var fs56 = __toESM(require("node:fs"));
26087
+ var fs57 = __toESM(require("node:fs"));
25783
26088
  var path53 = __toESM(require("node:path"));
25784
26089
 
25785
26090
  // src/factory/contextDrift/contextDriftManifest.ts
25786
- var fs51 = __toESM(require("node:fs"));
26091
+ var fs52 = __toESM(require("node:fs"));
25787
26092
  var path49 = __toESM(require("node:path"));
25788
26093
  var MAX_REFERENCE_BYTES = 256 * 1024;
25789
26094
  var MAX_EVIDENCE_FILES = 300;
@@ -25792,7 +26097,7 @@ var MAX_EXCERPT = 4e3;
25792
26097
  function readFileLimited(abs, maxBytes) {
25793
26098
  let buf;
25794
26099
  try {
25795
- buf = fs51.readFileSync(abs);
26100
+ buf = fs52.readFileSync(abs);
25796
26101
  } catch {
25797
26102
  return { text: "", truncated: false };
25798
26103
  }
@@ -25805,14 +26110,14 @@ function collectEvidencePaths(repoRoot) {
25805
26110
  const roots = ["src", "test", "tests", "packages", ".gluecharm", "scripts"];
25806
26111
  for (const rel of roots) {
25807
26112
  const abs = path49.join(repoRoot, rel);
25808
- if (!fs51.existsSync(abs)) {
26113
+ if (!fs52.existsSync(abs)) {
25809
26114
  continue;
25810
26115
  }
25811
26116
  walkFiles(abs, repoRoot, out, 0);
25812
26117
  }
25813
26118
  for (const leaf of ["package.json", "tsconfig.json"]) {
25814
26119
  const abs = path49.join(repoRoot, leaf);
25815
- if (fs51.existsSync(abs) && fs51.statSync(abs).isFile()) {
26120
+ if (fs52.existsSync(abs) && fs52.statSync(abs).isFile()) {
25816
26121
  const r = path49.relative(repoRoot, abs).split(path49.sep).join("/");
25817
26122
  out.push(r);
25818
26123
  }
@@ -25830,7 +26135,7 @@ function walkFiles(dir, repoRoot, out, depth) {
25830
26135
  }
25831
26136
  let entries;
25832
26137
  try {
25833
- entries = fs51.readdirSync(dir, { withFileTypes: true });
26138
+ entries = fs52.readdirSync(dir, { withFileTypes: true });
25834
26139
  } catch {
25835
26140
  return;
25836
26141
  }
@@ -25867,7 +26172,7 @@ function buildComparisonManifest(args) {
25867
26172
  const evidenceFiles = [];
25868
26173
  for (const rel of evidencePathsTrimmed) {
25869
26174
  const abs = path49.join(args.worktreeRoot, ...rel.split("/"));
25870
- const st = fs51.existsSync(abs) ? fs51.statSync(abs) : null;
26175
+ const st = fs52.existsSync(abs) ? fs52.statSync(abs) : null;
25871
26176
  const size = st && st.isFile() ? st.size : 0;
25872
26177
  const { text, truncated } = readFileLimited(abs, MAX_EVIDENCE_READ);
25873
26178
  const excerpt = truncated ? `${text.slice(0, MAX_EXCERPT)}
@@ -25889,7 +26194,7 @@ function buildComparisonManifest(args) {
25889
26194
  }
25890
26195
 
25891
26196
  // src/factory/contextDrift/contextDriftAgent.ts
25892
- var fs52 = __toESM(require("node:fs"));
26197
+ var fs53 = __toESM(require("node:fs"));
25893
26198
  var path50 = __toESM(require("node:path"));
25894
26199
 
25895
26200
  // src/factory/contextDrift/contextDriftPayload.ts
@@ -26036,16 +26341,16 @@ function buildDriftPrompt(args) {
26036
26341
  }
26037
26342
  async function runDriftComparisonOpenCode(args) {
26038
26343
  const runDir = path50.join(args.worktreeRoot, ".opencode", "_run");
26039
- fs52.mkdirSync(runDir, { recursive: true });
26344
+ fs53.mkdirSync(runDir, { recursive: true });
26040
26345
  const manifestPath = path50.join(runDir, "context-drift-manifest.json");
26041
26346
  const outputPath = path50.join(runDir, "context-drift-payload.json");
26042
- fs52.writeFileSync(manifestPath, `${JSON.stringify(args.manifestObject, null, 2)}
26347
+ fs53.writeFileSync(manifestPath, `${JSON.stringify(args.manifestObject, null, 2)}
26043
26348
  `, "utf8");
26044
- if (fs52.existsSync(outputPath)) {
26045
- fs52.unlinkSync(outputPath);
26349
+ if (fs53.existsSync(outputPath)) {
26350
+ fs53.unlinkSync(outputPath);
26046
26351
  }
26047
26352
  const promptPath = path50.join(runDir, `context-drift-${Date.now()}.prompt.txt`);
26048
- fs52.writeFileSync(
26353
+ fs53.writeFileSync(
26049
26354
  promptPath,
26050
26355
  buildDriftPrompt({
26051
26356
  worktreeRoot: args.worktreeRoot,
@@ -26087,7 +26392,7 @@ async function runDriftComparisonOpenCode(args) {
26087
26392
  }
26088
26393
  let raw;
26089
26394
  try {
26090
- const txt = fs52.readFileSync(outputPath, "utf8");
26395
+ const txt = fs53.readFileSync(outputPath, "utf8");
26091
26396
  raw = JSON.parse(txt);
26092
26397
  } catch (e) {
26093
26398
  return {
@@ -26104,7 +26409,7 @@ async function runDriftComparisonOpenCode(args) {
26104
26409
 
26105
26410
  // src/factory/contextDrift/contextDriftPaths.ts
26106
26411
  var crypto2 = __toESM(require("node:crypto"));
26107
- var fs53 = __toESM(require("node:fs"));
26412
+ var fs54 = __toESM(require("node:fs"));
26108
26413
  var path51 = __toESM(require("node:path"));
26109
26414
  var DRIFT_CONTEXT_SUBDIR = path51.join(".gluecharm", "context", "drift");
26110
26415
  function sanitizeSlug(raw) {
@@ -26143,7 +26448,7 @@ function maybeDedupeSlug(slug, referenceRelPosix) {
26143
26448
  function discoverReferenceBundle(worktreeRoot, referenceAbsInWorktree) {
26144
26449
  let st;
26145
26450
  try {
26146
- st = fs53.statSync(referenceAbsInWorktree);
26451
+ st = fs54.statSync(referenceAbsInWorktree);
26147
26452
  } catch {
26148
26453
  return { ok: false, error: `Reference path not found in analysis worktree: ${referenceAbsInWorktree}` };
26149
26454
  }
@@ -26164,7 +26469,7 @@ function discoverReferenceBundle(worktreeRoot, referenceAbsInWorktree) {
26164
26469
  }
26165
26470
  let entries;
26166
26471
  try {
26167
- entries = fs53.readdirSync(dir, { withFileTypes: true });
26472
+ entries = fs54.readdirSync(dir, { withFileTypes: true });
26168
26473
  } catch {
26169
26474
  return;
26170
26475
  }
@@ -26189,7 +26494,7 @@ function discoverReferenceBundle(worktreeRoot, referenceAbsInWorktree) {
26189
26494
  }
26190
26495
  function pickReferenceRootDocument(args) {
26191
26496
  if (args.indexOverrideAbs) {
26192
- if (!fs53.existsSync(args.indexOverrideAbs) || !args.indexOverrideAbs.endsWith(".md")) {
26497
+ if (!fs54.existsSync(args.indexOverrideAbs) || !args.indexOverrideAbs.endsWith(".md")) {
26193
26498
  return { ok: false, error: "--index must point to an existing .md file under the repo." };
26194
26499
  }
26195
26500
  return { ok: true, path: args.indexOverrideAbs };
@@ -26200,7 +26505,7 @@ function pickReferenceRootDocument(args) {
26200
26505
  const dir = args.referenceAbsInWorktree;
26201
26506
  for (const name of ["index.md", "README.md"]) {
26202
26507
  const p = path51.join(dir, name);
26203
- if (fs53.existsSync(p) && fs53.statSync(p).isFile()) {
26508
+ if (fs54.existsSync(p) && fs54.statSync(p).isFile()) {
26204
26509
  return { ok: true, path: p };
26205
26510
  }
26206
26511
  }
@@ -26217,13 +26522,13 @@ function toPosixPath(p) {
26217
26522
  }
26218
26523
 
26219
26524
  // src/factory/contextDrift/contextDriftIndex.ts
26220
- var fs54 = __toESM(require("node:fs"));
26525
+ var fs55 = __toESM(require("node:fs"));
26221
26526
  var START = "<!-- easyspecs-drift-links:start -->";
26222
26527
  var END = "<!-- easyspecs-drift-links:end -->";
26223
26528
  function patchReferenceIndexWithDriftLink(args) {
26224
26529
  let body;
26225
26530
  try {
26226
- body = fs54.readFileSync(args.referenceRootAbsolute, "utf8");
26531
+ body = fs55.readFileSync(args.referenceRootAbsolute, "utf8");
26227
26532
  } catch (e) {
26228
26533
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
26229
26534
  }
@@ -26244,7 +26549,7 @@ ${block}
26244
26549
  `;
26245
26550
  }
26246
26551
  try {
26247
- fs54.writeFileSync(args.referenceRootAbsolute, next, "utf8");
26552
+ fs55.writeFileSync(args.referenceRootAbsolute, next, "utf8");
26248
26553
  } catch (e) {
26249
26554
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
26250
26555
  }
@@ -26255,13 +26560,13 @@ function escapeRe(s) {
26255
26560
  }
26256
26561
 
26257
26562
  // src/factory/contextDrift/contextDriftPromote.ts
26258
- var fs55 = __toESM(require("node:fs"));
26563
+ var fs56 = __toESM(require("node:fs"));
26259
26564
  var path52 = __toESM(require("node:path"));
26260
26565
  function copyWorktreeFileToWorkspace(args) {
26261
26566
  const src = path52.join(args.worktreeRoot, ...args.relativePosix.split("/"));
26262
26567
  const dest = path52.join(args.workspaceRoot, ...args.relativePosix.split("/"));
26263
- fs55.mkdirSync(path52.dirname(dest), { recursive: true });
26264
- fs55.copyFileSync(src, dest);
26568
+ fs56.mkdirSync(path52.dirname(dest), { recursive: true });
26569
+ fs56.copyFileSync(src, dest);
26265
26570
  }
26266
26571
 
26267
26572
  // src/factory/contextDrift/runContextDriftFactory.ts
@@ -26280,7 +26585,7 @@ async function runContextDriftFactory(deps) {
26280
26585
  };
26281
26586
  }
26282
26587
  const refAbsWorkspace = resolved.abs;
26283
- if (!fs56.existsSync(refAbsWorkspace)) {
26588
+ if (!fs57.existsSync(refAbsWorkspace)) {
26284
26589
  return {
26285
26590
  exitOk: false,
26286
26591
  ok: false,
@@ -26293,7 +26598,7 @@ async function runContextDriftFactory(deps) {
26293
26598
  let indexOverrideAbsWorkspace;
26294
26599
  if (deps.indexOverrideArg?.trim()) {
26295
26600
  const ir = resolveInsideRepo(deps.repoRootAbs, deps.indexOverrideArg.trim());
26296
- if (!ir.ok || !fs56.existsSync(ir.abs)) {
26601
+ if (!ir.ok || !fs57.existsSync(ir.abs)) {
26297
26602
  return {
26298
26603
  exitOk: false,
26299
26604
  ok: false,
@@ -26311,7 +26616,7 @@ async function runContextDriftFactory(deps) {
26311
26616
  ok: true,
26312
26617
  code: "DRY_RUN",
26313
26618
  ...baseMeta,
26314
- referenceRootDocument: toPosixPath(path53.relative(deps.repoRootAbs, refAbsWorkspace)) + (fs56.statSync(refAbsWorkspace).isDirectory() ? "/" : ""),
26619
+ referenceRootDocument: toPosixPath(path53.relative(deps.repoRootAbs, refAbsWorkspace)) + (fs57.statSync(refAbsWorkspace).isDirectory() ? "/" : ""),
26315
26620
  driftReportPath: null,
26316
26621
  analysisWorktreeRoot: "",
26317
26622
  promoted: false,
@@ -26380,7 +26685,7 @@ async function runContextDriftFactory(deps) {
26380
26685
  }
26381
26686
  const indexWt = indexOverrideAbsWorkspace ? path53.join(wt, ...path53.relative(deps.repoRootAbs, indexOverrideAbsWorkspace).split(path53.sep)) : void 0;
26382
26687
  const rootPick = pickReferenceRootDocument({
26383
- referencePathIsFile: fs56.statSync(refAbsWt).isFile(),
26688
+ referencePathIsFile: fs57.statSync(refAbsWt).isFile(),
26384
26689
  referenceAbsInWorktree: refAbsWt,
26385
26690
  bundleFiles: bundle.bundleFiles,
26386
26691
  indexOverrideAbs: indexWt
@@ -26407,7 +26712,7 @@ async function runContextDriftFactory(deps) {
26407
26712
  slug = maybeDedupeSlug(slug, refRel);
26408
26713
  const driftBase = driftFilename(slug, runDate);
26409
26714
  const driftDirWt = path53.join(wt, DRIFT_CONTEXT_SUBDIR);
26410
- fs56.mkdirSync(driftDirWt, { recursive: true });
26715
+ fs57.mkdirSync(driftDirWt, { recursive: true });
26411
26716
  const driftAbsWt = path53.join(driftDirWt, driftBase);
26412
26717
  let payload;
26413
26718
  if (deps.testOnlyFixturePayload) {
@@ -26444,7 +26749,7 @@ async function runContextDriftFactory(deps) {
26444
26749
  manifestTruncation: manifest.truncation
26445
26750
  });
26446
26751
  try {
26447
- fs56.writeFileSync(driftAbsWt, md, "utf8");
26752
+ fs57.writeFileSync(driftAbsWt, md, "utf8");
26448
26753
  } catch (e) {
26449
26754
  finalizeWt?.();
26450
26755
  return {
@@ -26523,7 +26828,7 @@ async function runContextDriftFactory(deps) {
26523
26828
  }
26524
26829
 
26525
26830
  // src/analysis/coordinationDuplicatesDiagnosis.ts
26526
- var fs57 = __toESM(require("fs"));
26831
+ var fs58 = __toESM(require("fs"));
26527
26832
  var path54 = __toESM(require("path"));
26528
26833
  var import__7 = __toESM(require__());
26529
26834
  var COORDINATION_DUPLICATES_REPORT_BASENAME = "coordination-duplicates-report.json";
@@ -26560,11 +26865,11 @@ function looksLikeCoordinationDetailMarkdownBasename(basename17) {
26560
26865
  }
26561
26866
  function loadRawFeatureRows(contextDirAbs) {
26562
26867
  const p = path54.join(contextDirAbs, "features-list.json");
26563
- if (!fs57.existsSync(p)) {
26868
+ if (!fs58.existsSync(p)) {
26564
26869
  return [];
26565
26870
  }
26566
26871
  try {
26567
- const raw = stripUtf8Bom6(fs57.readFileSync(p, "utf-8"));
26872
+ const raw = stripUtf8Bom6(fs58.readFileSync(p, "utf-8"));
26568
26873
  const doc = JSON.parse(raw);
26569
26874
  return Array.isArray(doc.features) ? doc.features : [];
26570
26875
  } catch {
@@ -26599,7 +26904,7 @@ function findOrphanCoordinationMarkdown(contextDirAbs) {
26599
26904
  const featureRows = loadRawFeatureRows(contextDirAbs);
26600
26905
  let dirents;
26601
26906
  try {
26602
- dirents = fs57.readdirSync(contextDirAbs, { withFileTypes: true });
26907
+ dirents = fs58.readdirSync(contextDirAbs, { withFileTypes: true });
26603
26908
  } catch {
26604
26909
  return [];
26605
26910
  }
@@ -26853,13 +27158,13 @@ function buildCoordinationDuplicatesReport(input) {
26853
27158
  const duplicateGroups = [];
26854
27159
  for (const entry of COORDINATION_LIST_SCAN_ENTRIES) {
26855
27160
  const filePath = path54.join(input.contextDirAbsolute, entry.basename);
26856
- if (!fs57.existsSync(filePath)) {
27161
+ if (!fs58.existsSync(filePath)) {
26857
27162
  lists.push({ basename: entry.basename, status: "missing" });
26858
27163
  continue;
26859
27164
  }
26860
27165
  let raw;
26861
27166
  try {
26862
- raw = stripUtf8Bom6(fs57.readFileSync(filePath, "utf-8"));
27167
+ raw = stripUtf8Bom6(fs58.readFileSync(filePath, "utf-8"));
26863
27168
  } catch (e) {
26864
27169
  lists.push({
26865
27170
  basename: entry.basename,
@@ -26908,7 +27213,7 @@ function validateReportData(data) {
26908
27213
  if (!validateReportCompiled) {
26909
27214
  const ajv2 = new import__7.default({ allErrors: true, strict: false });
26910
27215
  const schemaPath = path54.join(resolveContextListSchemasDir(), "coordination-duplicates-report.schema.json");
26911
- const schemaRaw = stripUtf8Bom6(fs57.readFileSync(schemaPath, "utf-8"));
27216
+ const schemaRaw = stripUtf8Bom6(fs58.readFileSync(schemaPath, "utf-8"));
26912
27217
  validateReportCompiled = ajv2.compile(JSON.parse(schemaRaw));
26913
27218
  }
26914
27219
  if (validateReportCompiled(data)) {
@@ -26931,15 +27236,15 @@ function runCoordinationDuplicatesDiagnosis(input) {
26931
27236
  `;
26932
27237
  const tmp = `${outPath}.tmp.${process.pid}`;
26933
27238
  try {
26934
- fs57.writeFileSync(tmp, payload, "utf-8");
27239
+ fs58.writeFileSync(tmp, payload, "utf-8");
26935
27240
  } catch (e) {
26936
27241
  return { ok: false, message: e instanceof Error ? e.message : String(e) };
26937
27242
  }
26938
27243
  try {
26939
- fs57.renameSync(tmp, outPath);
27244
+ fs58.renameSync(tmp, outPath);
26940
27245
  } catch (e) {
26941
27246
  try {
26942
- fs57.unlinkSync(tmp);
27247
+ fs58.unlinkSync(tmp);
26943
27248
  } catch {
26944
27249
  }
26945
27250
  return { ok: false, message: e instanceof Error ? e.message : String(e) };
@@ -26973,7 +27278,7 @@ function runCoordinationDuplicatesDiagnosis(input) {
26973
27278
  }
26974
27279
 
26975
27280
  // src/pipelines/download/downloadPipeline.ts
26976
- var fs58 = __toESM(require("node:fs"));
27281
+ var fs59 = __toESM(require("node:fs"));
26977
27282
  var path55 = __toESM(require("node:path"));
26978
27283
  var SRS_DISCOVERY_BATCH_GET_CHUNK_SIZE = 200;
26979
27284
  function isRecord7(v) {
@@ -27079,19 +27384,19 @@ function chunkIds(ids, size) {
27079
27384
  return out;
27080
27385
  }
27081
27386
  function clearContextDirectoryForCloudReplace(contextDirAbs) {
27082
- if (!fs58.existsSync(contextDirAbs) || !fs58.statSync(contextDirAbs).isDirectory()) {
27387
+ if (!fs59.existsSync(contextDirAbs) || !fs59.statSync(contextDirAbs).isDirectory()) {
27083
27388
  return { filesRemoved: 0 };
27084
27389
  }
27085
27390
  const preserveAbs = path55.resolve(contextDirAbs, UPLOAD_TARGET_FILENAME);
27086
27391
  const preserveSet = /* @__PURE__ */ new Set();
27087
- if (fs58.existsSync(preserveAbs) && fs58.statSync(preserveAbs).isFile()) {
27392
+ if (fs59.existsSync(preserveAbs) && fs59.statSync(preserveAbs).isFile()) {
27088
27393
  preserveSet.add(preserveAbs);
27089
27394
  }
27090
27395
  let filesRemoved = 0;
27091
27396
  const walkRm = (dir) => {
27092
27397
  let entries;
27093
27398
  try {
27094
- entries = fs58.readdirSync(dir, { withFileTypes: true });
27399
+ entries = fs59.readdirSync(dir, { withFileTypes: true });
27095
27400
  } catch {
27096
27401
  return;
27097
27402
  }
@@ -27100,7 +27405,7 @@ function clearContextDirectoryForCloudReplace(contextDirAbs) {
27100
27405
  if (e.isDirectory()) {
27101
27406
  walkRm(full);
27102
27407
  try {
27103
- fs58.rmdirSync(full);
27408
+ fs59.rmdirSync(full);
27104
27409
  } catch {
27105
27410
  }
27106
27411
  } else if (e.isFile()) {
@@ -27109,7 +27414,7 @@ function clearContextDirectoryForCloudReplace(contextDirAbs) {
27109
27414
  continue;
27110
27415
  }
27111
27416
  try {
27112
- fs58.unlinkSync(abs);
27417
+ fs59.unlinkSync(abs);
27113
27418
  filesRemoved += 1;
27114
27419
  } catch {
27115
27420
  }
@@ -27188,15 +27493,15 @@ async function runDownloadPipeline(opts) {
27188
27493
  failed.push({ id, name, message: "Unsafe or invalid name for local path." });
27189
27494
  continue;
27190
27495
  }
27191
- fs58.mkdirSync(path55.dirname(outAbs), { recursive: true });
27192
- const exists = fs58.existsSync(outAbs);
27496
+ fs59.mkdirSync(path55.dirname(outAbs), { recursive: true });
27497
+ const exists = fs59.existsSync(outAbs);
27193
27498
  if (exists && !opts.force && !opts.replaceFromCloud) {
27194
27499
  skipped += 1;
27195
27500
  log?.(`[pipeline:download] skip existing ${name} (use --force to overwrite).`);
27196
27501
  continue;
27197
27502
  }
27198
27503
  try {
27199
- fs58.writeFileSync(outAbs, bodyText, "utf8");
27504
+ fs59.writeFileSync(outAbs, bodyText, "utf8");
27200
27505
  downloaded += 1;
27201
27506
  succeededIds[outAbs] = id;
27202
27507
  } catch (e) {
@@ -27367,7 +27672,7 @@ function createAuthenticatedRequestJson(deps) {
27367
27672
  }
27368
27673
 
27369
27674
  // src/cli/cliSession.ts
27370
- var fs59 = __toESM(require("node:fs"));
27675
+ var fs60 = __toESM(require("node:fs"));
27371
27676
  var os6 = __toESM(require("node:os"));
27372
27677
  var path56 = __toESM(require("node:path"));
27373
27678
  function defaultSessionPath() {
@@ -27412,10 +27717,10 @@ function effectiveCliSessionPath() {
27412
27717
  function readCliSession() {
27413
27718
  const p = effectiveCliSessionPath();
27414
27719
  try {
27415
- if (!fs59.existsSync(p)) {
27720
+ if (!fs60.existsSync(p)) {
27416
27721
  return void 0;
27417
27722
  }
27418
- const j = JSON.parse(fs59.readFileSync(p, "utf8"));
27723
+ const j = JSON.parse(fs60.readFileSync(p, "utf8"));
27419
27724
  const apiBaseUrl = typeof j.apiBaseUrl === "string" ? j.apiBaseUrl.trim() : "";
27420
27725
  const accessToken = typeof j.accessToken === "string" ? j.accessToken : "";
27421
27726
  const refreshToken = typeof j.refreshToken === "string" ? j.refreshToken : "";
@@ -27429,20 +27734,20 @@ function readCliSession() {
27429
27734
  }
27430
27735
  function writeCliSession(s) {
27431
27736
  const p = effectiveCliSessionPath();
27432
- fs59.mkdirSync(path56.dirname(p), { recursive: true });
27433
- fs59.writeFileSync(p, `${JSON.stringify(s, null, 2)}
27737
+ fs60.mkdirSync(path56.dirname(p), { recursive: true });
27738
+ fs60.writeFileSync(p, `${JSON.stringify(s, null, 2)}
27434
27739
  `, "utf8");
27435
27740
  }
27436
27741
  function clearCliSession() {
27437
27742
  const p = effectiveCliSessionPath();
27438
27743
  try {
27439
- fs59.unlinkSync(p);
27744
+ fs60.unlinkSync(p);
27440
27745
  } catch {
27441
27746
  }
27442
27747
  }
27443
27748
 
27444
27749
  // src/analysis/acePendingTraces.ts
27445
- var fs60 = __toESM(require("fs"));
27750
+ var fs61 = __toESM(require("fs"));
27446
27751
  var path57 = __toESM(require("path"));
27447
27752
  function normalizeAceTraceRelativePath(rel) {
27448
27753
  return rel.split(/[/\\]/).join("/");
@@ -27450,12 +27755,12 @@ function normalizeAceTraceRelativePath(rel) {
27450
27755
  function readCompletedTraceRelativePaths(contextDir2) {
27451
27756
  const set = /* @__PURE__ */ new Set();
27452
27757
  const jsonlPath = aceConsolidatedSessionsJsonlPath(contextDir2);
27453
- if (!fs60.existsSync(jsonlPath)) {
27758
+ if (!fs61.existsSync(jsonlPath)) {
27454
27759
  return set;
27455
27760
  }
27456
27761
  let raw;
27457
27762
  try {
27458
- raw = fs60.readFileSync(jsonlPath, "utf8");
27763
+ raw = fs61.readFileSync(jsonlPath, "utf8");
27459
27764
  } catch {
27460
27765
  return set;
27461
27766
  }
@@ -27486,7 +27791,7 @@ function readCompletedTraceRelativePaths(contextDir2) {
27486
27791
  }
27487
27792
  function listPendingAceTraceFiles(contextDir2, worktreeRoot) {
27488
27793
  const traceSchema = opencodeAceSchemaPath(worktreeRoot, ACE_SCHEMA_TRACE);
27489
- if (!fs60.existsSync(traceSchema)) {
27794
+ if (!fs61.existsSync(traceSchema)) {
27490
27795
  return [];
27491
27796
  }
27492
27797
  const completed = readCompletedTraceRelativePaths(contextDir2);
@@ -27790,7 +28095,9 @@ var TAG_SGR = {
27790
28095
  "zero-ref": "\x1B[91m",
27791
28096
  ace: "\x1B[95m",
27792
28097
  cli: "\x1B[90m",
27793
- EasySpecs: "\x1B[93m"
28098
+ EasySpecs: "\x1B[93m",
28099
+ "host-pool": "\x1B[36m",
28100
+ "host-pool-rec": "\x1B[90m"
27794
28101
  };
27795
28102
  function tagOpenSgr(tag) {
27796
28103
  const direct = TAG_SGR[tag];
@@ -27831,7 +28138,7 @@ function phaseFamilyForTag(tag) {
27831
28138
  if (tag.startsWith("pipeline:")) {
27832
28139
  return "meta";
27833
28140
  }
27834
- 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") {
27835
28142
  return "orch";
27836
28143
  }
27837
28144
  if (Object.prototype.hasOwnProperty.call(TAG_SGR, tag)) {
@@ -28090,7 +28397,7 @@ function formatCliStderrLine(line, useAnsi) {
28090
28397
  }
28091
28398
 
28092
28399
  // src/cli/main.ts
28093
- var PKG_VERSION = "0.0.25";
28400
+ var PKG_VERSION = "0.0.27";
28094
28401
  function isNonEmptyFactoryFailureArray(x) {
28095
28402
  if (!Array.isArray(x) || x.length === 0) {
28096
28403
  return false;
@@ -28222,7 +28529,7 @@ function resolveAnalysisRoot(repoRoot, rootKind, worktreePath) {
28222
28529
  return repoRoot;
28223
28530
  }
28224
28531
  const wt = worktreePath?.trim();
28225
- if (wt && fs61.existsSync(path59.join(wt, ".git"))) {
28532
+ if (wt && fs62.existsSync(path59.join(wt, ".git"))) {
28226
28533
  return path59.resolve(wt);
28227
28534
  }
28228
28535
  throw new Error("worktree mode requires --worktree <path> to an existing analysis checkout.");
@@ -28231,14 +28538,14 @@ function resolveAdHocCheckoutRoot(_repoRoot, storage, worktreeFlag) {
28231
28538
  const w = worktreeFlag?.trim();
28232
28539
  if (w) {
28233
28540
  const abs = path59.resolve(w);
28234
- if (fs61.existsSync(path59.join(abs, ".git"))) {
28541
+ if (fs62.existsSync(path59.join(abs, ".git"))) {
28235
28542
  return abs;
28236
28543
  }
28237
28544
  throw new Error(`Invalid --worktree (not a git checkout): ${abs}`);
28238
28545
  }
28239
28546
  const snap = readAnalysisWorkspaceSnapshot(storage);
28240
28547
  const p = snap?.adHocWorktreePath?.trim();
28241
- if (p && fs61.existsSync(path59.join(p, ".git"))) {
28548
+ if (p && fs62.existsSync(path59.join(p, ".git"))) {
28242
28549
  return p;
28243
28550
  }
28244
28551
  throw new Error("No analysis checkout: run `easyspecs-cli run synthesis` first or pass `--worktree <path>`.");
@@ -28561,13 +28868,14 @@ async function main() {
28561
28868
  process.exit(ExitCode.usage);
28562
28869
  }
28563
28870
  const agentsDir = resolveOpenCodeAgentsDir(repoRoot, repoConfig);
28564
- const agentsOk = fs61.existsSync(agentsDir);
28871
+ const agentsOk = fs62.existsSync(agentsDir);
28565
28872
  const oc = getOpenCodeReadiness({
28566
28873
  executable: merged.openCodeExecutable,
28567
28874
  skipCredentialsCheck: merged.openCodeSkipCredentialsCheck,
28568
28875
  providerEnvFromConfig: merged.openCodeChildEnv
28569
28876
  });
28570
28877
  const lines = [
28878
+ `cliVersion=${PKG_VERSION}`,
28571
28879
  `repoRoot=${repoRoot}`,
28572
28880
  `apiBaseUrl=${apiResolved || "(empty \u2014 stub auth only)"}`,
28573
28881
  `opencode installed=${String(oc.installed)} credentialsReady=${String(oc.credentialsReady)}`,
@@ -28587,6 +28895,7 @@ async function main() {
28587
28895
  const envelope = { ok: true };
28588
28896
  if (modes.readiness) {
28589
28897
  envelope.lines = lines;
28898
+ envelope.cliVersion = PKG_VERSION;
28590
28899
  }
28591
28900
  if (modes.inspectConfig) {
28592
28901
  envelope.config = inspectPayload;
@@ -29075,7 +29384,7 @@ async function main() {
29075
29384
  const wt = snap?.adHocWorktreePath?.trim();
29076
29385
  if (wt) {
29077
29386
  const sourceCtx = path59.join(wt, ".gluecharm", "context");
29078
- if (fs61.existsSync(sourceCtx)) {
29387
+ if (fs62.existsSync(sourceCtx)) {
29079
29388
  const n = promoteContextDirectoryToWorkspaceFs(sourceCtx, repoRoot);
29080
29389
  logErr(flags, `[pipeline:analysis] promoted ${String(n.filesCopied)} file(s) \u2192 ${repoRoot}`);
29081
29390
  } else {
@@ -29245,12 +29554,12 @@ async function main() {
29245
29554
  if (pos[1] === "republish") {
29246
29555
  const fromCfg = repoConfig.easyspecs?.upload?.contextDirectory?.trim();
29247
29556
  const resolvedOverride = fromCfg && fromCfg.length > 0 ? path59.isAbsolute(fromCfg) ? path59.normalize(fromCfg) : path59.resolve(repoRoot, fromCfg) : "";
29248
- if (resolvedOverride && fs61.existsSync(path59.join(resolvedOverride, ".."))) {
29557
+ if (resolvedOverride && fs62.existsSync(path59.join(resolvedOverride, ".."))) {
29249
29558
  ctxDir = resolvedOverride;
29250
29559
  } else {
29251
29560
  const storage = createFileBackedWorkspaceState(repoRoot);
29252
29561
  const snap = readAnalysisWorkspaceSnapshot(storage);
29253
- const wt = snap?.adHocWorktreePath && fs61.existsSync(path59.join(snap.adHocWorktreePath, ".gluecharm", "context")) ? path59.join(snap.adHocWorktreePath, ".gluecharm", "context") : "";
29562
+ const wt = snap?.adHocWorktreePath && fs62.existsSync(path59.join(snap.adHocWorktreePath, ".gluecharm", "context")) ? path59.join(snap.adHocWorktreePath, ".gluecharm", "context") : "";
29254
29563
  if (!wt) {
29255
29564
  finish(ExitCode.misconfiguration, {
29256
29565
  ok: false,
@@ -29368,16 +29677,16 @@ async function main() {
29368
29677
  }
29369
29678
  if (pos[0] === "ace" && pos[1] === "clear") {
29370
29679
  const learnings = path59.join(repoRoot, ".gluecharm", "context", "learnings");
29371
- if (!fs61.existsSync(learnings)) {
29680
+ if (!fs62.existsSync(learnings)) {
29372
29681
  finish(ExitCode.ok, { ok: true, message: "nothing to clear" });
29373
29682
  }
29374
- fs61.rmSync(learnings, { recursive: true, force: true });
29683
+ fs62.rmSync(learnings, { recursive: true, force: true });
29375
29684
  finish(ExitCode.ok, { ok: true, message: `cleared ${learnings}` });
29376
29685
  }
29377
29686
  if (pos[0] === "ace" && pos[1] === "learn") {
29378
29687
  requireOpenCode(merged, flags);
29379
29688
  const { worktree } = parseWorktreeFlag(pos.slice(2));
29380
- const root = worktree && fs61.existsSync(path59.join(worktree, ".opencode", "schemas", "ace")) ? worktree : repoRoot;
29689
+ const root = worktree && fs62.existsSync(path59.join(worktree, ".opencode", "schemas", "ace")) ? worktree : repoRoot;
29381
29690
  const contextDir2 = path59.join(root, ".gluecharm", "context");
29382
29691
  const traces = listAceTraceFiles(contextDir2);
29383
29692
  if (traces.length === 0) {
@@ -29402,7 +29711,7 @@ async function main() {
29402
29711
  if (pos[0] === "ace" && pos[1] === "auto-learn") {
29403
29712
  requireOpenCode(merged, flags);
29404
29713
  const { worktree } = parseWorktreeFlag(pos.slice(2));
29405
- const root = worktree && fs61.existsSync(path59.join(worktree, ".git")) ? worktree : repoRoot;
29714
+ const root = worktree && fs62.existsSync(path59.join(worktree, ".git")) ? worktree : repoRoot;
29406
29715
  const contextDir2 = path59.join(root, ".gluecharm", "context");
29407
29716
  const pending = listPendingAceTraceFiles(contextDir2, root);
29408
29717
  if (pending.length === 0) {