@gluecharm-lab/easyspecs-cli 0.0.26 → 0.0.28

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