@gluecharm-lab/easyspecs-cli 0.2.1 → 0.3.0

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
@@ -959,7 +959,7 @@ var require_command = __commonJS({
959
959
  "node_modules/commander/lib/command.js"(exports2) {
960
960
  var EventEmitter = require("node:events").EventEmitter;
961
961
  var childProcess = require("node:child_process");
962
- var path61 = require("node:path");
962
+ var path62 = require("node:path");
963
963
  var fs64 = require("node:fs");
964
964
  var process2 = require("node:process");
965
965
  var { Argument: Argument2, humanReadableArgName } = require_argument();
@@ -1892,9 +1892,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
1892
1892
  let launchWithNode = false;
1893
1893
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1894
1894
  function findFile(baseDir, baseName) {
1895
- const localBin = path61.resolve(baseDir, baseName);
1895
+ const localBin = path62.resolve(baseDir, baseName);
1896
1896
  if (fs64.existsSync(localBin)) return localBin;
1897
- if (sourceExt.includes(path61.extname(baseName))) return void 0;
1897
+ if (sourceExt.includes(path62.extname(baseName))) return void 0;
1898
1898
  const foundExt = sourceExt.find(
1899
1899
  (ext) => fs64.existsSync(`${localBin}${ext}`)
1900
1900
  );
@@ -1912,17 +1912,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
1912
1912
  } catch (err) {
1913
1913
  resolvedScriptPath = this._scriptPath;
1914
1914
  }
1915
- executableDir = path61.resolve(
1916
- path61.dirname(resolvedScriptPath),
1915
+ executableDir = path62.resolve(
1916
+ path62.dirname(resolvedScriptPath),
1917
1917
  executableDir
1918
1918
  );
1919
1919
  }
1920
1920
  if (executableDir) {
1921
1921
  let localFile = findFile(executableDir, executableFile);
1922
1922
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
1923
- const legacyName = path61.basename(
1923
+ const legacyName = path62.basename(
1924
1924
  this._scriptPath,
1925
- path61.extname(this._scriptPath)
1925
+ path62.extname(this._scriptPath)
1926
1926
  );
1927
1927
  if (legacyName !== this._name) {
1928
1928
  localFile = findFile(
@@ -1933,7 +1933,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1933
1933
  }
1934
1934
  executableFile = localFile || executableFile;
1935
1935
  }
1936
- launchWithNode = sourceExt.includes(path61.extname(executableFile));
1936
+ launchWithNode = sourceExt.includes(path62.extname(executableFile));
1937
1937
  let proc;
1938
1938
  if (process2.platform !== "win32") {
1939
1939
  if (launchWithNode) {
@@ -2773,7 +2773,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2773
2773
  * @return {Command}
2774
2774
  */
2775
2775
  nameFromFilename(filename) {
2776
- this._name = path61.basename(filename, path61.extname(filename));
2776
+ this._name = path62.basename(filename, path62.extname(filename));
2777
2777
  return this;
2778
2778
  }
2779
2779
  /**
@@ -2787,9 +2787,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
2787
2787
  * @param {string} [path]
2788
2788
  * @return {(string|null|Command)}
2789
2789
  */
2790
- executableDir(path62) {
2791
- if (path62 === void 0) return this._executableDir;
2792
- this._executableDir = path62;
2790
+ executableDir(path63) {
2791
+ if (path63 === void 0) return this._executableDir;
2792
+ this._executableDir = path63;
2793
2793
  return this;
2794
2794
  }
2795
2795
  /**
@@ -5244,8 +5244,8 @@ var require_resolve = __commonJS({
5244
5244
  }
5245
5245
  return count;
5246
5246
  }
5247
- function getFullPath(resolver, id = "", normalize8) {
5248
- if (normalize8 !== false)
5247
+ function getFullPath(resolver, id = "", normalize9) {
5248
+ if (normalize9 !== false)
5249
5249
  id = normalizeId(id);
5250
5250
  const p = resolver.parse(id);
5251
5251
  return _getFullPath(resolver, p);
@@ -5993,7 +5993,7 @@ var require_compile = __commonJS({
5993
5993
  const schOrFunc = root.refs[ref];
5994
5994
  if (schOrFunc)
5995
5995
  return schOrFunc;
5996
- let _sch = resolve23.call(this, root, ref);
5996
+ let _sch = resolve24.call(this, root, ref);
5997
5997
  if (_sch === void 0) {
5998
5998
  const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
5999
5999
  const { schemaId } = this.opts;
@@ -6020,7 +6020,7 @@ var require_compile = __commonJS({
6020
6020
  function sameSchemaEnv(s1, s2) {
6021
6021
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
6022
6022
  }
6023
- function resolve23(root, ref) {
6023
+ function resolve24(root, ref) {
6024
6024
  let sch;
6025
6025
  while (typeof (sch = this.refs[ref]) == "string")
6026
6026
  ref = sch;
@@ -6235,8 +6235,8 @@ var require_utils = __commonJS({
6235
6235
  }
6236
6236
  return ind;
6237
6237
  }
6238
- function removeDotSegments(path61) {
6239
- let input = path61;
6238
+ function removeDotSegments(path62) {
6239
+ let input = path62;
6240
6240
  const output = [];
6241
6241
  let nextSlash = -1;
6242
6242
  let len = 0;
@@ -6435,8 +6435,8 @@ var require_schemes = __commonJS({
6435
6435
  wsComponent.secure = void 0;
6436
6436
  }
6437
6437
  if (wsComponent.resourceName) {
6438
- const [path61, query] = wsComponent.resourceName.split("?");
6439
- wsComponent.path = path61 && path61 !== "/" ? path61 : void 0;
6438
+ const [path62, query] = wsComponent.resourceName.split("?");
6439
+ wsComponent.path = path62 && path62 !== "/" ? path62 : void 0;
6440
6440
  wsComponent.query = query;
6441
6441
  wsComponent.resourceName = void 0;
6442
6442
  }
@@ -6585,7 +6585,7 @@ var require_fast_uri = __commonJS({
6585
6585
  "use strict";
6586
6586
  var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = require_utils();
6587
6587
  var { SCHEMES, getSchemeHandler } = require_schemes();
6588
- function normalize8(uri, options) {
6588
+ function normalize9(uri, options) {
6589
6589
  if (typeof uri === "string") {
6590
6590
  uri = /** @type {T} */
6591
6591
  serialize(parse(uri, options), options);
@@ -6595,7 +6595,7 @@ var require_fast_uri = __commonJS({
6595
6595
  }
6596
6596
  return uri;
6597
6597
  }
6598
- function resolve23(baseURI, relativeURI, options) {
6598
+ function resolve24(baseURI, relativeURI, options) {
6599
6599
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
6600
6600
  const resolved = resolveComponent(parse(baseURI, schemelessOptions), parse(relativeURI, schemelessOptions), schemelessOptions, true);
6601
6601
  schemelessOptions.skipEscape = true;
@@ -6821,8 +6821,8 @@ var require_fast_uri = __commonJS({
6821
6821
  }
6822
6822
  var fastUri = {
6823
6823
  SCHEMES,
6824
- normalize: normalize8,
6825
- resolve: resolve23,
6824
+ normalize: normalize9,
6825
+ resolve: resolve24,
6826
6826
  resolveComponent,
6827
6827
  equal,
6828
6828
  serialize,
@@ -10637,7 +10637,7 @@ var require_dist = __commonJS({
10637
10637
 
10638
10638
  // src/cli/main.ts
10639
10639
  var fs63 = __toESM(require("node:fs"));
10640
- var path60 = __toESM(require("node:path"));
10640
+ var path61 = __toESM(require("node:path"));
10641
10641
 
10642
10642
  // src/cli/exitCodes.ts
10643
10643
  var OsExit = {
@@ -10778,9 +10778,9 @@ function describeExitCode(code) {
10778
10778
  case OsExit.readinessOpenCodeCredentials:
10779
10779
  return "OpenCode credentials not ready for factory run.";
10780
10780
  case OsExit.readinessOpenCodeModel:
10781
- return "OpenCode default model is not configured \u2014 add a model in repo `opencode.json` or `easyspecs.openCodeRuntime.providers`.";
10781
+ return "OpenCode default model is not configured \u2014 add `model` (or equivalent) in repo `opencode.json` / `opencode.jsonc`, global `~/.config/opencode/opencode.json`, `OPENCODE_CONFIG` / `OPENCODE_CONFIG_DIR`, managed config (see OpenCode docs), or `easyspecs.openCodeRuntime.providers`.";
10782
10782
  case OsExit.readinessOpenCodeMandatoryConfig:
10783
- return "Mandatory OpenCode project config is missing \u2014 create `opencode.json` at the repository / analysis root.";
10783
+ return "Readiness gate (d) reserved \u2014 repo-root `opencode.json` is optional when OpenCode is installed, credentials are ready, and a model is configured.";
10784
10784
  default:
10785
10785
  return `Non-zero exit (${String(code)}) \u2014 see stderr and any JSON \`error\` field for detail.`;
10786
10786
  }
@@ -12687,7 +12687,7 @@ function stringifyForSrs13Debug(value) {
12687
12687
  return truncateForSrs13DebugLog(String(value));
12688
12688
  }
12689
12689
  }
12690
- function logSrs13HttpDebug(log, path61, method, requestBody, error) {
12690
+ function logSrs13HttpDebug(log, path62, method, requestBody, error) {
12691
12691
  if (!log) {
12692
12692
  return;
12693
12693
  }
@@ -12697,7 +12697,7 @@ function logSrs13HttpDebug(log, path61, method, requestBody, error) {
12697
12697
  } catch {
12698
12698
  bodyBytes = 0;
12699
12699
  }
12700
- log(`[pipeline:upload] debug ${method} ${path61} \u2014 request body ~${bodyBytes} bytes (JSON below):`);
12700
+ log(`[pipeline:upload] debug ${method} ${path62} \u2014 request body ~${bodyBytes} bytes (JSON below):`);
12701
12701
  log(stringifyForSrs13Debug(requestBody));
12702
12702
  const raw = httpApiResponseBody(error);
12703
12703
  const status = error && typeof error === "object" && "status" in error ? Number(error.status) : void 0;
@@ -14394,9 +14394,9 @@ function parsePsRssDarwinKilobytes(stdout) {
14394
14394
  return n;
14395
14395
  }
14396
14396
  function readLinuxPidRssBytes(pid) {
14397
- const path61 = `/proc/${pid}/status`;
14397
+ const path62 = `/proc/${pid}/status`;
14398
14398
  try {
14399
- const content = fs18.readFileSync(path61, "utf8");
14399
+ const content = fs18.readFileSync(path62, "utf8");
14400
14400
  const kb = parseVmRssKilobytesFromProcStatus(content);
14401
14401
  if (kb === null) {
14402
14402
  return { kind: "unknown", reason: "VmRSS_missing" };
@@ -14497,7 +14497,16 @@ var PROVIDER_ENV_KEYS = [
14497
14497
  "OPENAI_API_KEY",
14498
14498
  "OPENROUTER_API_KEY",
14499
14499
  "GOOGLE_API_KEY",
14500
- "OPENCODE_API_KEY"
14500
+ "GEMINI_API_KEY",
14501
+ "GOOGLE_GENERATIVE_AI_API_KEY",
14502
+ "OPENCODE_API_KEY",
14503
+ "MISTRAL_API_KEY",
14504
+ "GROQ_API_KEY",
14505
+ "COHERE_API_KEY",
14506
+ "XAI_API_KEY",
14507
+ "DEEPSEEK_API_KEY",
14508
+ "AZURE_OPENAI_API_KEY",
14509
+ "AWS_BEARER_TOKEN_BEDROCK"
14501
14510
  ];
14502
14511
  function hasProviderEnvConfigured() {
14503
14512
  for (const k of PROVIDER_ENV_KEYS) {
@@ -14584,9 +14593,9 @@ function runOpenCodeAgent(cwd, args, options) {
14584
14593
  log?.(`${procTag} command: ${formatCliCommandForLog(cmd, args)}`);
14585
14594
  log?.(`${procTag} cwd: ${JSON.stringify(cwd)}`);
14586
14595
  log?.(`${procTag} argv: ${JSON.stringify(args)}`);
14587
- return new Promise((resolve23) => {
14596
+ return new Promise((resolve24) => {
14588
14597
  if (sig?.aborted) {
14589
- resolve23({ ok: false, message: "Stopped by user.", cancelled: true });
14598
+ resolve24({ ok: false, message: "Stopped by user.", cancelled: true });
14590
14599
  return;
14591
14600
  }
14592
14601
  const spawnEnv = options?.childEnv && Object.keys(options.childEnv).length > 0 ? { ...process.env, ...options.childEnv } : process.env;
@@ -14681,7 +14690,7 @@ ${truncateForDiag(outBody, DIAG_STDOUT_MAX)}`);
14681
14690
  if (diag) {
14682
14691
  finishDiag(diag.label, diag.code, diag.dumpStreams);
14683
14692
  }
14684
- resolve23(result);
14693
+ resolve24(result);
14685
14694
  };
14686
14695
  let onAbort;
14687
14696
  const clearAbortHandler = () => {
@@ -21405,8 +21414,8 @@ async function drainWorkstationPool(p) {
21405
21414
  const artefactRunId = readArtefactRunSnapshot(storageContext)?.runId ?? "unknown-run";
21406
21415
  let active = 0;
21407
21416
  let wake;
21408
- const waitTurn = () => new Promise((resolve23) => {
21409
- wake = resolve23;
21417
+ const waitTurn = () => new Promise((resolve24) => {
21418
+ wake = resolve24;
21410
21419
  });
21411
21420
  const persist = async () => {
21412
21421
  const items = {};
@@ -21767,30 +21776,81 @@ var FACTORY_PIPELINE_EXIT_CONDITIONS = {
21767
21776
 
21768
21777
  // src/readiness/factoryReadiness.ts
21769
21778
  var fs39 = __toESM(require("node:fs"));
21779
+ var path35 = __toESM(require("node:path"));
21780
+
21781
+ // src/readiness/openCodeConfigCandidates.ts
21770
21782
  var os6 = __toESM(require("node:os"));
21771
21783
  var path34 = __toESM(require("node:path"));
21772
- var MANDATORY_OPEN_CODE_CONFIG_REL_PATHS = ["opencode.json"];
21773
- var READINESS_OPENCODE_NOT_INSTALLED = "READINESS_OPENCODE_NOT_INSTALLED";
21774
- var READINESS_OPENCODE_CREDENTIALS = "READINESS_OPENCODE_CREDENTIALS";
21775
- var READINESS_OPENCODE_MODEL = "READINESS_OPENCODE_MODEL";
21776
- var READINESS_OPENCODE_MANDATORY_CONFIG = "READINESS_OPENCODE_MANDATORY_CONFIG";
21777
- function userOpenCodeConfigPath() {
21784
+ function openCodeUserConfigDir() {
21778
21785
  if (process.platform === "win32") {
21779
21786
  const base = process.env.APPDATA || path34.join(os6.homedir(), "AppData", "Roaming");
21780
- return path34.join(base, "opencode", "config.json");
21787
+ return path34.join(base, "opencode");
21781
21788
  }
21782
21789
  const xdg = process.env.XDG_CONFIG_HOME?.trim();
21783
21790
  const cfgRoot = xdg && xdg.length > 0 ? xdg : path34.join(os6.homedir(), ".config");
21784
- return path34.join(cfgRoot, "opencode", "config.json");
21791
+ return path34.join(cfgRoot, "opencode");
21785
21792
  }
21786
- function buildOpenCodeConfigInventory(analysisRootAbs) {
21793
+ function managedOpenCodeConfigDir() {
21794
+ if (process.platform === "darwin") {
21795
+ return "/Library/Application Support/opencode";
21796
+ }
21797
+ if (process.platform === "linux") {
21798
+ return path34.join("/etc", "opencode");
21799
+ }
21800
+ if (process.platform === "win32") {
21801
+ const pd = process.env.ProgramData?.trim() || "C:\\ProgramData";
21802
+ return path34.join(pd, "opencode");
21803
+ }
21804
+ return void 0;
21805
+ }
21806
+ function pushConfigBasenames(out, dir) {
21807
+ const d = path34.normalize(dir);
21808
+ out.push(path34.join(d, "opencode.json"));
21809
+ out.push(path34.join(d, "opencode.jsonc"));
21810
+ out.push(path34.join(d, "config.json"));
21811
+ }
21812
+ function dedupeStablePaths(paths) {
21813
+ const seen = /* @__PURE__ */ new Set();
21814
+ const out = [];
21815
+ for (const p of paths) {
21816
+ const n = path34.normalize(p.trim());
21817
+ if (n.length === 0 || seen.has(n)) {
21818
+ continue;
21819
+ }
21820
+ seen.add(n);
21821
+ out.push(n);
21822
+ }
21823
+ return out;
21824
+ }
21825
+ function openCodeJsonModelFileCandidates(analysisRootAbs) {
21787
21826
  const root = path34.resolve(analysisRootAbs);
21788
- const list = [
21789
- { path: path34.join(root, "opencode.json"), exists: false },
21790
- { path: path34.join(root, ".opencode", "config.json"), exists: false },
21791
- { path: userOpenCodeConfigPath(), exists: false }
21792
- ];
21793
- return list.map((e) => ({ ...e, exists: fs39.existsSync(e.path) }));
21827
+ const acc = [];
21828
+ const oc = process.env.OPENCODE_CONFIG?.trim();
21829
+ if (oc) {
21830
+ acc.push(path34.resolve(oc));
21831
+ }
21832
+ pushConfigBasenames(acc, root);
21833
+ pushConfigBasenames(acc, path34.join(root, ".opencode"));
21834
+ const ocd = process.env.OPENCODE_CONFIG_DIR?.trim();
21835
+ if (ocd) {
21836
+ pushConfigBasenames(acc, path34.resolve(ocd));
21837
+ }
21838
+ pushConfigBasenames(acc, openCodeUserConfigDir());
21839
+ pushConfigBasenames(acc, path34.join(os6.homedir(), ".opencode"));
21840
+ const managed = managedOpenCodeConfigDir();
21841
+ if (managed) {
21842
+ pushConfigBasenames(acc, managed);
21843
+ }
21844
+ return dedupeStablePaths(acc);
21845
+ }
21846
+
21847
+ // src/readiness/factoryReadiness.ts
21848
+ var MANDATORY_OPEN_CODE_CONFIG_REL_PATHS = ["opencode.json"];
21849
+ var READINESS_OPENCODE_NOT_INSTALLED = "READINESS_OPENCODE_NOT_INSTALLED";
21850
+ var READINESS_OPENCODE_CREDENTIALS = "READINESS_OPENCODE_CREDENTIALS";
21851
+ var READINESS_OPENCODE_MODEL = "READINESS_OPENCODE_MODEL";
21852
+ function buildOpenCodeConfigInventory(analysisRootAbs) {
21853
+ return openCodeJsonModelFileCandidates(analysisRootAbs).map((p) => ({ path: p, exists: fs39.existsSync(p) }));
21794
21854
  }
21795
21855
  function defaultModelFromEasyspecsConfig(cfg) {
21796
21856
  const providers = cfg.easyspecs?.openCodeRuntime?.providers;
@@ -21835,6 +21895,40 @@ function extractModelFromOpenCodeJson(data) {
21835
21895
  }
21836
21896
  return void 0;
21837
21897
  }
21898
+ function parseOpenCodeConfigText(raw) {
21899
+ const t = raw.trim();
21900
+ if (!t) {
21901
+ return void 0;
21902
+ }
21903
+ try {
21904
+ return JSON.parse(t);
21905
+ } catch {
21906
+ const noBlock = t.replace(/\/\*[\s\S]*?\*\//g, "");
21907
+ const noLine = noBlock.replace(/^\s*\/\/[^\n\r]*/gm, "");
21908
+ try {
21909
+ return JSON.parse(noLine);
21910
+ } catch {
21911
+ return void 0;
21912
+ }
21913
+ }
21914
+ }
21915
+ function modelFromOpencodeConfigContentEnv() {
21916
+ const v = process.env.OPENCODE_CONFIG_CONTENT?.trim();
21917
+ if (!v) {
21918
+ return void 0;
21919
+ }
21920
+ const data = parseOpenCodeConfigText(v);
21921
+ return data !== void 0 ? extractModelFromOpenCodeJson(data) : void 0;
21922
+ }
21923
+ function tryModelFromConfigFile(absPath) {
21924
+ try {
21925
+ const txt = fs39.readFileSync(absPath, "utf-8");
21926
+ const data = parseOpenCodeConfigText(txt);
21927
+ return data !== void 0 ? extractModelFromOpenCodeJson(data) : void 0;
21928
+ } catch {
21929
+ return void 0;
21930
+ }
21931
+ }
21838
21932
  function sanitizeModelSummary(raw) {
21839
21933
  const t = raw.trim();
21840
21934
  if (!t) {
@@ -21854,15 +21948,15 @@ function resolveModelFromContext(ctx) {
21854
21948
  if (fromCfg) {
21855
21949
  return { configured: true, summary: sanitizeModelSummary(fromCfg) };
21856
21950
  }
21857
- const p = path34.join(path34.resolve(ctx.analysisRootAbs), "opencode.json");
21858
- try {
21859
- const txt = fs39.readFileSync(p, "utf-8");
21860
- const data = JSON.parse(txt);
21861
- const m = extractModelFromOpenCodeJson(data);
21951
+ const fromInline = modelFromOpencodeConfigContentEnv();
21952
+ if (fromInline) {
21953
+ return { configured: true, summary: sanitizeModelSummary(fromInline) };
21954
+ }
21955
+ for (const p of openCodeJsonModelFileCandidates(ctx.analysisRootAbs)) {
21956
+ const m = tryModelFromConfigFile(p);
21862
21957
  if (m) {
21863
21958
  return { configured: true, summary: sanitizeModelSummary(m) };
21864
21959
  }
21865
- } catch {
21866
21960
  }
21867
21961
  return { configured: false, summary: "(not configured)" };
21868
21962
  }
@@ -21874,7 +21968,7 @@ function buildReadinessProbeFacts(ctx) {
21874
21968
  });
21875
21969
  const openCodeConfigFiles = buildOpenCodeConfigInventory(ctx.analysisRootAbs);
21876
21970
  const mandatoryOk = MANDATORY_OPEN_CODE_CONFIG_REL_PATHS.every((rel) => {
21877
- const abs = path34.join(path34.resolve(ctx.analysisRootAbs), rel);
21971
+ const abs = path35.join(path35.resolve(ctx.analysisRootAbs), rel);
21878
21972
  return fs39.existsSync(abs);
21879
21973
  });
21880
21974
  const model = resolveModelFromContext(ctx);
@@ -21898,7 +21992,8 @@ function buildReadinessLineBlock(facts, ctx) {
21898
21992
  `repoRoot=${ctx.repoRootAbs}`,
21899
21993
  `apiBaseUrl=${apiDisp}`,
21900
21994
  `opencode installed=${String(facts.installed)} credentialsReady=${String(facts.credentialsReady)}`,
21901
- `opencode modelConfigured=${String(facts.modelConfigured)} modelSummary=${facts.modelSummary}`
21995
+ `opencode modelConfigured=${String(facts.modelConfigured)} modelSummary=${facts.modelSummary}`,
21996
+ `mandatoryRepoOpenCodeJsonPathsOk=${String(facts.mandatoryConfigPathsOk)} (informational)`
21902
21997
  ];
21903
21998
  for (const e of facts.openCodeConfigFiles) {
21904
21999
  lines.push(`opencodeConfigFile ${e.path} exists=${String(e.exists)}`);
@@ -21931,14 +22026,6 @@ function evaluateReadinessGates(facts) {
21931
22026
  readinessReasonCode: READINESS_OPENCODE_MODEL
21932
22027
  };
21933
22028
  }
21934
- if (!facts.mandatoryConfigPathsOk) {
21935
- return {
21936
- ok: false,
21937
- gate: "d",
21938
- exitCode: OsExit.readinessOpenCodeMandatoryConfig,
21939
- readinessReasonCode: READINESS_OPENCODE_MANDATORY_CONFIG
21940
- };
21941
- }
21942
22029
  return { ok: true };
21943
22030
  }
21944
22031
  function buildReadinessJsonFields(facts) {
@@ -22204,7 +22291,7 @@ function sleepUntilAborted(ms, signal) {
22204
22291
  if (signal.aborted) {
22205
22292
  return Promise.reject(new DOMException("The operation was aborted.", "AbortError"));
22206
22293
  }
22207
- return new Promise((resolve23, reject) => {
22294
+ return new Promise((resolve24, reject) => {
22208
22295
  const onAbort = () => {
22209
22296
  clearTimeout(t);
22210
22297
  signal.removeEventListener("abort", onAbort);
@@ -22212,7 +22299,7 @@ function sleepUntilAborted(ms, signal) {
22212
22299
  };
22213
22300
  const t = setTimeout(() => {
22214
22301
  signal.removeEventListener("abort", onAbort);
22215
- resolve23();
22302
+ resolve24();
22216
22303
  }, ms);
22217
22304
  signal.addEventListener("abort", onAbort, { once: true });
22218
22305
  });
@@ -22711,7 +22798,7 @@ async function runGenerateContextFactory(deps) {
22711
22798
 
22712
22799
  // src/factory/generateContextFactoryHeadlessHost.ts
22713
22800
  var fs48 = __toESM(require("node:fs"));
22714
- var path44 = __toESM(require("node:path"));
22801
+ var path45 = __toESM(require("node:path"));
22715
22802
 
22716
22803
  // src/stores/pipelineRunStore.ts
22717
22804
  var STORAGE_KEY2 = SRS53_PIPELINE_RUN_KEY_V2;
@@ -22812,11 +22899,11 @@ async function noteAgentsMaterialized(context) {
22812
22899
 
22813
22900
  // src/pipelines/remediation/missingWorkstations.ts
22814
22901
  var fs41 = __toESM(require("fs"));
22815
- var path36 = __toESM(require("path"));
22902
+ var path37 = __toESM(require("path"));
22816
22903
 
22817
22904
  // src/analysis/analysisDetailMarkdownDiscovery.ts
22818
22905
  var fs40 = __toESM(require("fs"));
22819
- var path35 = __toESM(require("path"));
22906
+ var path36 = __toESM(require("path"));
22820
22907
  var SLUG4 = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
22821
22908
  var FE2 = /^FE-\d+$/;
22822
22909
  var UC2 = /^UC-\d+$/;
@@ -22878,7 +22965,7 @@ function expectedFeatureDetailBasenameFromRow(row2) {
22878
22965
  return `${code}-${slug}.md`;
22879
22966
  }
22880
22967
  function ctxPath(contextDir2, basename17) {
22881
- return path35.join(contextDir2, basename17);
22968
+ return path36.join(contextDir2, basename17);
22882
22969
  }
22883
22970
  function pushTarget(targets, stem, outputBasename, taskDescription, contextDir2) {
22884
22971
  const meta = STEM_TO_AGENT[stem];
@@ -22894,7 +22981,7 @@ function pushTarget(targets, stem, outputBasename, taskDescription, contextDir2)
22894
22981
  function discoverDetailMarkdownGroups(contextDir2) {
22895
22982
  const groups = [];
22896
22983
  const featureTargets = [];
22897
- const flPath = path35.join(contextDir2, "features-list.json");
22984
+ const flPath = path36.join(contextDir2, "features-list.json");
22898
22985
  const fl = readJson5(flPath);
22899
22986
  const features = Array.isArray(fl?.features) ? fl.features : [];
22900
22987
  for (const row2 of features) {
@@ -22924,7 +23011,7 @@ function discoverDetailMarkdownGroups(contextDir2) {
22924
23011
  if (!FE2.test(feCode)) {
22925
23012
  continue;
22926
23013
  }
22927
- const ucListPath = path35.join(contextDir2, `${feCode}-use-cases-list.json`);
23014
+ const ucListPath = path36.join(contextDir2, `${feCode}-use-cases-list.json`);
22928
23015
  const ucFile = readJson5(ucListPath);
22929
23016
  const ucs = Array.isArray(ucFile?.useCases) ? ucFile.useCases : [];
22930
23017
  for (const ucRow of ucs) {
@@ -22944,7 +23031,7 @@ function discoverDetailMarkdownGroups(contextDir2) {
22944
23031
  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.`,
22945
23032
  contextDir2
22946
23033
  );
22947
- const scPath = path35.join(contextDir2, `${feCode}_${ucCode}-scenarios-list.json`);
23034
+ const scPath = path36.join(contextDir2, `${feCode}_${ucCode}-scenarios-list.json`);
22948
23035
  const scFile = readJson5(scPath);
22949
23036
  const scs = Array.isArray(scFile?.scenarios) ? scFile.scenarios : [];
22950
23037
  for (const scRow of scs) {
@@ -23015,7 +23102,7 @@ Follow bundled agent **agent-md-use-case-detail**: include **## Data inputs and
23015
23102
  groups.push({ id: "detail-services", label: "Detail markdown \u2014 Services", targets: svcTargets });
23016
23103
  groups.push({ id: "detail-methods", label: "Detail markdown \u2014 Methods", targets: meTargets });
23017
23104
  const entTargets = [];
23018
- const dmPath = path35.join(contextDir2, "data-model-list.json");
23105
+ const dmPath = path36.join(contextDir2, "data-model-list.json");
23019
23106
  const dmFile = readJson5(dmPath);
23020
23107
  const ents = Array.isArray(dmFile?.entities) ? dmFile.entities : [];
23021
23108
  for (const erow of ents) {
@@ -23044,7 +23131,7 @@ Follow bundled agent **agent-md-use-case-detail**: include **## Data inputs and
23044
23131
  if (!DM2.test(dmCode)) {
23045
23132
  continue;
23046
23133
  }
23047
- const flPath2 = path35.join(contextDir2, `${dmCode}-fields-list.json`);
23134
+ const flPath2 = path36.join(contextDir2, `${dmCode}-fields-list.json`);
23048
23135
  const flFile = readJson5(flPath2);
23049
23136
  const flds = Array.isArray(flFile?.fields) ? flFile.fields : [];
23050
23137
  for (const frow of flds) {
@@ -23103,7 +23190,7 @@ function fileAndValidationFromKind(kind) {
23103
23190
  return { filePresentYesNo: "no", validationYesNo: "na" };
23104
23191
  }
23105
23192
  function classifyMissingWorkstationOutputFileStatus(row2, contextDir2, worktreeRoot) {
23106
- const abs = path36.join(contextDir2, row2.relativePath);
23193
+ const abs = path37.join(contextDir2, row2.relativePath);
23107
23194
  try {
23108
23195
  const st = fs41.statSync(abs);
23109
23196
  if (!st.isFile()) {
@@ -23142,7 +23229,7 @@ function classifyMissingWorkstationOutputFileStatus(row2, contextDir2, worktreeR
23142
23229
  detail: "Unknown coordination list basename \u2014 no JSON Schema mapping."
23143
23230
  };
23144
23231
  }
23145
- const schemaAbs = path36.join(worktreeRoot, ".opencode", "schemas", "context-lists", schemaBn);
23232
+ const schemaAbs = path37.join(worktreeRoot, ".opencode", "schemas", "context-lists", schemaBn);
23146
23233
  if (!fs41.existsSync(schemaAbs)) {
23147
23234
  return {
23148
23235
  kind: "invalid",
@@ -23172,7 +23259,7 @@ function classifyWorkstationOutputOnDisk(item, contextDir2, worktreeRoot) {
23172
23259
  return classifyMissingWorkstationOutputFileStatus(row2, contextDir2, worktreeRoot).kind;
23173
23260
  }
23174
23261
  function isWorkstationRunSnapshotForWorktree(snapshot, worktreeRoot) {
23175
- return !!(snapshot && snapshot.overallStatus !== "running" && snapshot.overallStatus !== "idle" && path36.resolve(snapshot.analysisRoot) === path36.resolve(worktreeRoot));
23262
+ return !!(snapshot && snapshot.overallStatus !== "running" && snapshot.overallStatus !== "idle" && path37.resolve(snapshot.analysisRoot) === path37.resolve(worktreeRoot));
23176
23263
  }
23177
23264
  function expectedBasenameForCoordPayload(p) {
23178
23265
  const { step, listTarget } = p;
@@ -23246,10 +23333,10 @@ function labelContextForCoordPayload(p) {
23246
23333
  }
23247
23334
  function contextPathForWorkItem(item, contextDir2) {
23248
23335
  if (item.kind === "markdown") {
23249
- return path36.join(contextDir2, item.payload.outputBasename);
23336
+ return path37.join(contextDir2, item.payload.outputBasename);
23250
23337
  }
23251
23338
  const bn = expectedBasenameForCoordPayload(item.payload);
23252
- return bn ? path36.join(contextDir2, bn) : null;
23339
+ return bn ? path37.join(contextDir2, bn) : null;
23253
23340
  }
23254
23341
  function syntheticRunnerId(key) {
23255
23342
  return `remediation:${key}`;
@@ -23259,7 +23346,7 @@ function rowFromSkippedItem(item, contextDir2) {
23259
23346
  return null;
23260
23347
  }
23261
23348
  const abs = contextPathForWorkItem(item, contextDir2);
23262
- const rel = abs ? path36.basename(abs) : item.kind === "markdown" ? item.payload.outputBasename : item.id;
23349
+ const rel = abs ? path37.basename(abs) : item.kind === "markdown" ? item.payload.outputBasename : item.id;
23263
23350
  if (abs && nonEmptyContextFile(abs)) {
23264
23351
  return null;
23265
23352
  }
@@ -23434,7 +23521,7 @@ function toMissingWorkstationUiRows(rows, contextDir2, worktreeRoot) {
23434
23521
  }
23435
23522
 
23436
23523
  // src/pipelines/remediation/missingWorkstationsPool.ts
23437
- var path37 = __toESM(require("path"));
23524
+ var path38 = __toESM(require("path"));
23438
23525
  function reconcileSkippedWorkItemsWithDisk(byId, contextDir2, worktreeRoot) {
23439
23526
  for (const item of byId.values()) {
23440
23527
  if (item.status !== "skipped") {
@@ -23494,7 +23581,7 @@ async function runRemediationPipelineMissingPass(p) {
23494
23581
  onItemComplete,
23495
23582
  sourceBranchAtWorktreeCreation
23496
23583
  } = p;
23497
- const contextDir2 = path37.join(worktreeRoot, ".gluecharm", "context");
23584
+ const contextDir2 = path38.join(worktreeRoot, ".gluecharm", "context");
23498
23585
  const snap = readArtefactRunSnapshot(storageContext);
23499
23586
  const snapOk = isWorkstationRunSnapshotForWorktree(snap, worktreeRoot);
23500
23587
  let byId;
@@ -23561,17 +23648,17 @@ async function runRemediationPipelineMissingPass(p) {
23561
23648
  // src/pipelines/coverage/coveragePipeline.ts
23562
23649
  var import_child_process5 = require("child_process");
23563
23650
  var fs43 = __toESM(require("fs"));
23564
- var path39 = __toESM(require("path"));
23651
+ var path40 = __toESM(require("path"));
23565
23652
 
23566
23653
  // src/analysis/coverageReferenceValidationSchemaValidate.ts
23567
23654
  var fs42 = __toESM(require("fs"));
23568
- var path38 = __toESM(require("path"));
23655
+ var path39 = __toESM(require("path"));
23569
23656
  var import__5 = __toESM(require__());
23570
23657
  function stripUtf8Bom4(s) {
23571
23658
  return s.length > 0 && s.charCodeAt(0) === 65279 ? s.slice(1) : s;
23572
23659
  }
23573
23660
  function bundledCoverageReferenceValidationSchemaPath() {
23574
- return path38.join(
23661
+ return path39.join(
23575
23662
  resolveRepoResourcesRoot(),
23576
23663
  "schemas",
23577
23664
  "context-lists",
@@ -23651,8 +23738,8 @@ var DEFAULT_IGNORE_DIR_BASENAMES = [
23651
23738
  ];
23652
23739
  var GIT_LS_FILES_MAX_BUFFER = 64 * 1024 * 1024;
23653
23740
  function tryLoadGitNonIgnoredPathSet(repositoryRootAbs) {
23654
- const root = path39.resolve(repositoryRootAbs);
23655
- if (!fs43.existsSync(path39.join(root, ".git"))) {
23741
+ const root = path40.resolve(repositoryRootAbs);
23742
+ if (!fs43.existsSync(path40.join(root, ".git"))) {
23656
23743
  return null;
23657
23744
  }
23658
23745
  const env = { ...process.env, GIT_TERMINAL_PROMPT: "0" };
@@ -23720,12 +23807,12 @@ var REFERENCE_COVERAGE_IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
23720
23807
  ".emf"
23721
23808
  ]);
23722
23809
  function isReferenceCoverageExcludedImagePath(relPosix) {
23723
- const ext = path39.extname(relPosix).toLowerCase();
23810
+ const ext = path40.extname(relPosix).toLowerCase();
23724
23811
  return ext.length > 0 && REFERENCE_COVERAGE_IMAGE_EXTENSIONS.has(ext);
23725
23812
  }
23726
23813
  var REFERENCE_COVERAGE_EXCLUDED_FILE_BASENAMES = /* @__PURE__ */ new Set([".gitignore"]);
23727
23814
  function isReferenceCoverageExcludedDefaultBasename(relPosix) {
23728
- const base = path39.basename(relPosix.replace(/\\/g, "/")).toLowerCase();
23815
+ const base = path40.basename(relPosix.replace(/\\/g, "/")).toLowerCase();
23729
23816
  return REFERENCE_COVERAGE_EXCLUDED_FILE_BASENAMES.has(base);
23730
23817
  }
23731
23818
  function decodeBufferForLineCount(buf) {
@@ -23762,12 +23849,12 @@ function normalizeRepoRelativePath(repoRoot, raw) {
23762
23849
  if (!trimmed || trimmed.includes("\0")) {
23763
23850
  return null;
23764
23851
  }
23765
- const abs = path39.resolve(repoRoot, trimmed);
23766
- const rel = path39.relative(repoRoot, abs);
23767
- if (rel.startsWith("..") || path39.isAbsolute(rel)) {
23852
+ const abs = path40.resolve(repoRoot, trimmed);
23853
+ const rel = path40.relative(repoRoot, abs);
23854
+ if (rel.startsWith("..") || path40.isAbsolute(rel)) {
23768
23855
  return null;
23769
23856
  }
23770
- return rel.split(path39.sep).join("/");
23857
+ return rel.split(path40.sep).join("/");
23771
23858
  }
23772
23859
  function collectJsonSourceReferences(node, out) {
23773
23860
  if (node === null || typeof node !== "object") {
@@ -23812,7 +23899,7 @@ function listContextFilesRecursive(dir, acc) {
23812
23899
  return;
23813
23900
  }
23814
23901
  for (const e of entries) {
23815
- const full = path39.join(dir, e.name);
23902
+ const full = path40.join(dir, e.name);
23816
23903
  if (e.isDirectory()) {
23817
23904
  listContextFilesRecursive(full, acc);
23818
23905
  } else if (e.isFile()) {
@@ -23833,8 +23920,8 @@ function walkRepositoryFiles(repoRoot, ignoreBasenames, maxBytes, excludedOut, g
23833
23920
  if (ignoreBasenames.has(e.name)) {
23834
23921
  continue;
23835
23922
  }
23836
- const full = path39.join(dir, e.name);
23837
- const rel = path39.relative(repoRoot, full).split(path39.sep).join("/");
23923
+ const full = path40.join(dir, e.name);
23924
+ const rel = path40.relative(repoRoot, full).split(path40.sep).join("/");
23838
23925
  if (rel.startsWith("..")) {
23839
23926
  continue;
23840
23927
  }
@@ -23892,9 +23979,9 @@ function collectReferencesFromContext(contextDirAbs, repositoryRootAbs, warnings
23892
23979
  const allFiles = [];
23893
23980
  listContextFilesRecursive(contextDirAbs, allFiles);
23894
23981
  for (const abs of allFiles) {
23895
- const ext = path39.extname(abs).toLowerCase();
23896
- const base = path39.basename(abs);
23897
- const sourceArtefact = path39.relative(contextDirAbs, abs).split(path39.sep).join("/");
23982
+ const ext = path40.extname(abs).toLowerCase();
23983
+ const base = path40.basename(abs);
23984
+ const sourceArtefact = path40.relative(contextDirAbs, abs).split(path40.sep).join("/");
23898
23985
  if (ext === ".json") {
23899
23986
  if (SKIP_CONTEXT_JSON.has(base)) {
23900
23987
  continue;
@@ -23976,12 +24063,12 @@ function sortReferenceRows(a, b) {
23976
24063
  return (a.startLine ?? 0) - (b.startLine ?? 0);
23977
24064
  }
23978
24065
  function buildCoverageReferenceValidationDocument(repositoryRootAbs, contextDirAbs, options) {
23979
- const repoRoot = path39.resolve(repositoryRootAbs);
24066
+ const repoRoot = path40.resolve(repositoryRootAbs);
23980
24067
  const warnings = [];
23981
24068
  const ignoreDirs = [...DEFAULT_IGNORE_DIR_BASENAMES];
23982
24069
  const ignoreSet = new Set(ignoreDirs);
23983
24070
  const maxBytes = options?.maxFileBytes ?? MAX_FILE_BYTES;
23984
- const references = collectReferencesFromContext(path39.resolve(contextDirAbs), repoRoot, warnings);
24071
+ const references = collectReferencesFromContext(path40.resolve(contextDirAbs), repoRoot, warnings);
23985
24072
  references.sort(sortReferenceRows);
23986
24073
  const referencedSet = /* @__PURE__ */ new Set();
23987
24074
  for (const r of references) {
@@ -23989,7 +24076,7 @@ function buildCoverageReferenceValidationDocument(repositoryRootAbs, contextDirA
23989
24076
  }
23990
24077
  const excludedFiles = [];
23991
24078
  const gitNonIgnoredPaths = tryLoadGitNonIgnoredPathSet(repoRoot);
23992
- if (fs43.existsSync(path39.join(repoRoot, ".git")) && gitNonIgnoredPaths === null) {
24079
+ if (fs43.existsSync(path40.join(repoRoot, ".git")) && gitNonIgnoredPaths === null) {
23993
24080
  warnings.push(
23994
24081
  "Repository has .git but git ls-files failed or git is unavailable; .gitignore / exclude-standard not applied."
23995
24082
  );
@@ -24038,8 +24125,8 @@ function buildCoverageReferenceValidationDocument(repositoryRootAbs, contextDirA
24038
24125
  return { document: doc, warnings };
24039
24126
  }
24040
24127
  function runCoveragePipeline(opts) {
24041
- const repoRoot = path39.resolve(opts.repositoryRootAbs);
24042
- const contextDir2 = path39.resolve(opts.contextDirAbs);
24128
+ const repoRoot = path40.resolve(opts.repositoryRootAbs);
24129
+ const contextDir2 = path40.resolve(opts.contextDirAbs);
24043
24130
  if (!fs43.existsSync(repoRoot)) {
24044
24131
  return { ok: false, error: `Repository root does not exist: ${repoRoot}` };
24045
24132
  }
@@ -24061,7 +24148,7 @@ ${schemaCheck.errors.join("\n")}`,
24061
24148
  warnings
24062
24149
  };
24063
24150
  }
24064
- const outPath = path39.join(contextDir2, COVERAGE_REFERENCE_VALIDATION_BASENAME);
24151
+ const outPath = path40.join(contextDir2, COVERAGE_REFERENCE_VALIDATION_BASENAME);
24065
24152
  if (opts.write) {
24066
24153
  try {
24067
24154
  const payload = stableStringifyCoverageDocument(document);
@@ -24080,11 +24167,11 @@ ${schemaCheck.errors.join("\n")}`,
24080
24167
  // src/pipelines/remediation/zeroReferenceWorkstationChain.ts
24081
24168
  var crypto = __toESM(require("crypto"));
24082
24169
  var fs45 = __toESM(require("fs"));
24083
- var path41 = __toESM(require("path"));
24170
+ var path42 = __toESM(require("path"));
24084
24171
 
24085
24172
  // src/analysis/zeroReferenceRemediationSchemaValidate.ts
24086
24173
  var fs44 = __toESM(require("fs"));
24087
- var path40 = __toESM(require("path"));
24174
+ var path41 = __toESM(require("path"));
24088
24175
  var import__6 = __toESM(require__());
24089
24176
  function stripUtf8Bom5(s) {
24090
24177
  return s.length > 0 && s.charCodeAt(0) === 65279 ? s.slice(1) : s;
@@ -24104,7 +24191,7 @@ function formatAjvErrors6(errors) {
24104
24191
  }
24105
24192
  var ajv = new import__6.default({ allErrors: true, strict: false });
24106
24193
  function compileSchema(basename17) {
24107
- const schemaPath = path40.join(schemasDir(), basename17);
24194
+ const schemaPath = path41.join(schemasDir(), basename17);
24108
24195
  const schemaRaw = stripUtf8Bom5(fs44.readFileSync(schemaPath, "utf-8"));
24109
24196
  const schema = JSON.parse(schemaRaw);
24110
24197
  return ajv.compile(schema);
@@ -24399,17 +24486,17 @@ function expandArgvTemplate4(template, vars) {
24399
24486
  });
24400
24487
  }
24401
24488
  function schemaRef2(worktreeRoot, schemaBasename) {
24402
- return path41.join(worktreeRoot, ".opencode", "schemas", "context-lists", schemaBasename);
24489
+ return path42.join(worktreeRoot, ".opencode", "schemas", "context-lists", schemaBasename);
24403
24490
  }
24404
24491
  function stagingDir(contextDirAbs) {
24405
- return path41.join(contextDirAbs, "_zero-ref-staging");
24492
+ return path42.join(contextDirAbs, "_zero-ref-staging");
24406
24493
  }
24407
24494
  function stagingPathForTarget(contextDirAbs, kind, targetFilePathPosix) {
24408
24495
  const h = crypto.createHash("sha256").update(targetFilePathPosix, "utf8").digest("hex").slice(0, 16);
24409
- return path41.join(stagingDir(contextDirAbs), `${kind}-${h}.json`);
24496
+ return path42.join(stagingDir(contextDirAbs), `${kind}-${h}.json`);
24410
24497
  }
24411
24498
  function readNonReferencedFilesFromRepositoryRoot(repositoryRootAbs) {
24412
- const p = path41.join(repositoryRootAbs, ".gluecharm", "context", "coverage-reference-validation.json");
24499
+ const p = path42.join(repositoryRootAbs, ".gluecharm", "context", "coverage-reference-validation.json");
24413
24500
  const r = readAndValidateCoverageReferenceValidationFile(p);
24414
24501
  if (!r.ok) {
24415
24502
  return { ok: false, error: r.errors.join("; ") };
@@ -24502,7 +24589,7 @@ function slugifyFeatureLabel(s) {
24502
24589
  return t.length > 0 ? t : "feature";
24503
24590
  }
24504
24591
  function lineCountRepoFile(worktreeRootAbs, relPosix) {
24505
- const abs = path41.join(worktreeRootAbs, ...relPosix.split("/"));
24592
+ const abs = path42.join(worktreeRootAbs, ...relPosix.split("/"));
24506
24593
  let buf;
24507
24594
  try {
24508
24595
  buf = fs45.readFileSync(abs);
@@ -24557,8 +24644,8 @@ var LIST_STEP_HINT = {
24557
24644
  };
24558
24645
  async function applyCoordinationListTriageMerge(input) {
24559
24646
  const cfg = LIST_MERGE_CFG[input.listKind];
24560
- const listPath = path41.join(input.contextDirAbs, cfg.listBasename);
24561
- const schemaPath = path41.join(resolveContextListSchemasDir(), cfg.schemaBasename);
24647
+ const listPath = path42.join(input.contextDirAbs, cfg.listBasename);
24648
+ const schemaPath = path42.join(resolveContextListSchemasDir(), cfg.schemaBasename);
24562
24649
  if (!fs45.existsSync(listPath)) {
24563
24650
  return {
24564
24651
  ok: false,
@@ -24662,10 +24749,10 @@ async function applyCoordinationListTriageMerge(input) {
24662
24749
  }
24663
24750
  async function runClassifierAgent(common, contextDirAbs, targetFilePathPosix, workspaceLabel) {
24664
24751
  const outAbs = stagingPathForTarget(contextDirAbs, "classifier", targetFilePathPosix);
24665
- fs45.mkdirSync(path41.dirname(outAbs), { recursive: true });
24666
- const runDir = path41.join(common.worktreeRoot, ".opencode", "_run");
24752
+ fs45.mkdirSync(path42.dirname(outAbs), { recursive: true });
24753
+ const runDir = path42.join(common.worktreeRoot, ".opencode", "_run");
24667
24754
  fs45.mkdirSync(runDir, { recursive: true });
24668
- const outputBasename = path41.basename(outAbs);
24755
+ const outputBasename = path42.basename(outAbs);
24669
24756
  const listTaskDescription = [
24670
24757
  `Target file (repo-relative, POSIX): **${targetFilePathPosix}**`,
24671
24758
  `Workspace label hint: **${workspaceLabel}**.`,
@@ -24701,7 +24788,7 @@ async function runClassifierAgent(common, contextDirAbs, targetFilePathPosix, wo
24701
24788
  parentContextBlock: "",
24702
24789
  ...repairAppendix ? { repairAppendix } : {}
24703
24790
  });
24704
- const promptPath = path41.join(runDir, `zero-ref-classify-a${attempt}-${Date.now()}.prompt.txt`);
24791
+ const promptPath = path42.join(runDir, `zero-ref-classify-a${attempt}-${Date.now()}.prompt.txt`);
24705
24792
  fs45.writeFileSync(promptPath, body, "utf-8");
24706
24793
  const argv = expandArgvTemplate4(common.argvTemplate, {
24707
24794
  promptFile: promptPath,
@@ -24833,9 +24920,9 @@ var TRIAGE_SCOPE_META = {
24833
24920
  };
24834
24921
  async function runMarkdownReferenceAgent(common, contextDirAbs, targetFilePathPosix, routingSummary, which) {
24835
24922
  const mdBasename = which === "project" ? "project.md" : "architecture.md";
24836
- const mdAbs = path41.join(contextDirAbs, mdBasename);
24923
+ const mdAbs = path42.join(contextDirAbs, mdBasename);
24837
24924
  const agentStem = which === "project" ? ZERO_REF_ADD_REF_PROJECT_AGENT_STEM : ZERO_REF_ADD_REF_ARCH_AGENT_STEM;
24838
- const runDir = path41.join(common.worktreeRoot, ".opencode", "_run");
24925
+ const runDir = path42.join(common.worktreeRoot, ".opencode", "_run");
24839
24926
  fs45.mkdirSync(runDir, { recursive: true });
24840
24927
  const lines = [
24841
24928
  `# SRS-30 \u2014 Add reference to ${mdBasename}`,
@@ -24851,7 +24938,7 @@ async function runMarkdownReferenceAgent(common, contextDirAbs, targetFilePathPo
24851
24938
  `- If the file is short, \`${targetFilePathPosix}:1-<lastLine>\` is acceptable.`,
24852
24939
  `- Do not remove unrelated content; append or extend the most appropriate section.`
24853
24940
  ];
24854
- const promptPath = path41.join(runDir, `zero-ref-md-${which}-${Date.now()}.prompt.txt`);
24941
+ const promptPath = path42.join(runDir, `zero-ref-md-${which}-${Date.now()}.prompt.txt`);
24855
24942
  fs45.writeFileSync(promptPath, lines.join("\n"), "utf-8");
24856
24943
  const argv = expandArgvTemplate4(common.argvTemplate, {
24857
24944
  promptFile: promptPath,
@@ -24879,10 +24966,10 @@ async function runMarkdownReferenceAgent(common, contextDirAbs, targetFilePathPo
24879
24966
  async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathPosix, routingSummary, workspaceLabel, triageScope) {
24880
24967
  const meta = TRIAGE_SCOPE_META[triageScope];
24881
24968
  const outAbs = stagingPathForTarget(contextDirAbs, "triage", targetFilePathPosix);
24882
- fs45.mkdirSync(path41.dirname(outAbs), { recursive: true });
24883
- const runDir = path41.join(common.worktreeRoot, ".opencode", "_run");
24969
+ fs45.mkdirSync(path42.dirname(outAbs), { recursive: true });
24970
+ const runDir = path42.join(common.worktreeRoot, ".opencode", "_run");
24884
24971
  fs45.mkdirSync(runDir, { recursive: true });
24885
- const outputBasename = path41.basename(outAbs);
24972
+ const outputBasename = path42.basename(outAbs);
24886
24973
  const listTaskDescription = [
24887
24974
  `Target file: **${targetFilePathPosix}** (${workspaceLabel})`,
24888
24975
  "**Classifier summary:**",
@@ -24912,7 +24999,7 @@ async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathP
24912
24999
  parentContextBlock: "",
24913
25000
  ...repairAppendix ? { repairAppendix } : {}
24914
25001
  });
24915
- const promptPath = path41.join(runDir, `zero-ref-triage-a${attempt}-${Date.now()}.prompt.txt`);
25002
+ const promptPath = path42.join(runDir, `zero-ref-triage-a${attempt}-${Date.now()}.prompt.txt`);
24916
25003
  fs45.writeFileSync(promptPath, body, "utf-8");
24917
25004
  const argv = expandArgvTemplate4(common.argvTemplate, {
24918
25005
  promptFile: promptPath,
@@ -25027,8 +25114,8 @@ async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathP
25027
25114
  return { ok: false, message: lastFailureMessage, stagingPath: outAbs };
25028
25115
  }
25029
25116
  async function runOneUnreferencedFilePipeline(p) {
25030
- const routingAbs = path41.join(p.contextDirAbs, ZERO_REF_ROUTING_BASENAME);
25031
- const triageAbs = path41.join(p.contextDirAbs, ZERO_REF_TRIAGE_BASENAME);
25117
+ const routingAbs = path42.join(p.contextDirAbs, ZERO_REF_ROUTING_BASENAME);
25118
+ const triageAbs = path42.join(p.contextDirAbs, ZERO_REF_TRIAGE_BASENAME);
25032
25119
  const key = p.targetFilePathPosix;
25033
25120
  const cr = await runClassifierAgent(p, p.contextDirAbs, key, p.workspaceLabel);
25034
25121
  if (!cr.ok) {
@@ -25052,7 +25139,7 @@ async function runOneUnreferencedFilePipeline(p) {
25052
25139
  if (!s.ok) {
25053
25140
  throw new Error(s.errors.join("; "));
25054
25141
  }
25055
- fs45.mkdirSync(path41.dirname(routingAbs), { recursive: true });
25142
+ fs45.mkdirSync(path42.dirname(routingAbs), { recursive: true });
25056
25143
  fs45.writeFileSync(routingAbs, s.json, "utf-8");
25057
25144
  });
25058
25145
  const routing = stagingParsed.routing;
@@ -25101,7 +25188,7 @@ async function runOneUnreferencedFilePipeline(p) {
25101
25188
  if (!s.ok) {
25102
25189
  throw new Error(s.errors.join("; "));
25103
25190
  }
25104
- fs45.mkdirSync(path41.dirname(triageAbs), { recursive: true });
25191
+ fs45.mkdirSync(path42.dirname(triageAbs), { recursive: true });
25105
25192
  fs45.writeFileSync(triageAbs, s.json, "utf-8");
25106
25193
  });
25107
25194
  const decision = triageParsed.decision;
@@ -25129,11 +25216,11 @@ async function runOneUnreferencedFilePipeline(p) {
25129
25216
  return { ok: true, message: `Triage ${decision}.` };
25130
25217
  }
25131
25218
  async function runRemediationPipelineZeroRefPass(p) {
25132
- const contextDirAbs = path41.join(p.worktreeRoot, ".gluecharm", "context");
25219
+ const contextDirAbs = path42.join(p.worktreeRoot, ".gluecharm", "context");
25133
25220
  const covRoot = p.coverageRepositoryRootAbs ?? p.workspaceRootAbs;
25134
25221
  const cov = readNonReferencedFilesFromRepositoryRoot(covRoot);
25135
25222
  const coverageAt = cov.ok ? cov.generatedAt : void 0;
25136
- const workspaceLabel = path41.basename(p.worktreeRoot);
25223
+ const workspaceLabel = path42.basename(p.worktreeRoot);
25137
25224
  const routingMutex = new AsyncMutex();
25138
25225
  const triageMutex = new AsyncMutex();
25139
25226
  const paths = [...p.paths];
@@ -25191,7 +25278,7 @@ async function runRemediationPipelineZeroRefPass(p) {
25191
25278
 
25192
25279
  // src/pipelines/coverage/coverageExecutionReport.ts
25193
25280
  var fs46 = __toESM(require("fs"));
25194
- var path42 = __toESM(require("path"));
25281
+ var path43 = __toESM(require("path"));
25195
25282
  var REFERENCE_COVERAGE_EXECUTION_REPORT_BASENAME = "reference-coverage-execution-report.md";
25196
25283
  function inlineMdText(s) {
25197
25284
  const t = s.replace(/\r\n/g, "\n").replace(/\n/g, " ").trim();
@@ -25315,10 +25402,10 @@ async function runCoverageExecutionReport(p) {
25315
25402
  if (p.abortSignal?.aborted) {
25316
25403
  return { ok: false, error: "Stopped.", cancelled: true };
25317
25404
  }
25318
- const contextDirAbs = path42.join(p.repositoryRootAbs, ".gluecharm", "context");
25319
- const coverageAbs = path42.join(contextDirAbs, "coverage-reference-validation.json");
25320
- const routingAbs = path42.join(contextDirAbs, "zero-reference-routing.json");
25321
- const outAbs = path42.join(contextDirAbs, REFERENCE_COVERAGE_EXECUTION_REPORT_BASENAME);
25405
+ const contextDirAbs = path43.join(p.repositoryRootAbs, ".gluecharm", "context");
25406
+ const coverageAbs = path43.join(contextDirAbs, "coverage-reference-validation.json");
25407
+ const routingAbs = path43.join(contextDirAbs, "zero-reference-routing.json");
25408
+ const outAbs = path43.join(contextDirAbs, REFERENCE_COVERAGE_EXECUTION_REPORT_BASENAME);
25322
25409
  const cov = readAndValidateCoverageReferenceValidationFile(coverageAbs);
25323
25410
  if (!cov.ok) {
25324
25411
  return { ok: false, error: `Coverage JSON: ${cov.errors.join("; ")}` };
@@ -25342,7 +25429,7 @@ async function runCoverageExecutionReport(p) {
25342
25429
  previous = void 0;
25343
25430
  }
25344
25431
  try {
25345
- fs46.mkdirSync(path42.dirname(outAbs), { recursive: true });
25432
+ fs46.mkdirSync(path43.dirname(outAbs), { recursive: true });
25346
25433
  fs46.writeFileSync(outAbs, md, "utf-8");
25347
25434
  } catch (e) {
25348
25435
  const msg = e instanceof Error ? e.message : String(e);
@@ -25360,7 +25447,7 @@ async function runCoverageExecutionReport(p) {
25360
25447
 
25361
25448
  // src/gluecharm/minimalGluecharmLayout.ts
25362
25449
  var fs47 = __toESM(require("node:fs"));
25363
- var path43 = __toESM(require("node:path"));
25450
+ var path44 = __toESM(require("node:path"));
25364
25451
  var MINIMAL_GLUECHARM_RELATIVE_DIRS = [
25365
25452
  [".gluecharm", "docs", "srs"],
25366
25453
  [".gluecharm", "content"],
@@ -25368,9 +25455,9 @@ var MINIMAL_GLUECHARM_RELATIVE_DIRS = [
25368
25455
  [".gluecharm", "context"]
25369
25456
  ];
25370
25457
  function ensureMinimalGluecharmLayoutNode(repoRootAbs) {
25371
- const root = path43.resolve(repoRootAbs);
25458
+ const root = path44.resolve(repoRootAbs);
25372
25459
  for (const segments of MINIMAL_GLUECHARM_RELATIVE_DIRS) {
25373
- const dir = path43.join(root, ...segments);
25460
+ const dir = path44.join(root, ...segments);
25374
25461
  try {
25375
25462
  fs47.mkdirSync(dir, { recursive: true });
25376
25463
  } catch (e) {
@@ -25502,7 +25589,7 @@ function buildFactoryDepsHeadless(input) {
25502
25589
  if (!layout.ok) {
25503
25590
  return { ok: false, error: layout.error };
25504
25591
  }
25505
- const ctxDir = path44.join(ar, ".gluecharm", "context");
25592
+ const ctxDir = path45.join(ar, ".gluecharm", "context");
25506
25593
  const snap = readArtefactRunSnapshot(storageContext);
25507
25594
  const rows = listMissingWorkstations(ctxDir, ar, snap);
25508
25595
  if (rows.length === 0) {
@@ -25516,7 +25603,7 @@ function buildFactoryDepsHeadless(input) {
25516
25603
  storageContext,
25517
25604
  repositoryRoot: repoRoot,
25518
25605
  worktreeRoot: ar,
25519
- workspaceLabel: path44.basename(ar),
25606
+ workspaceLabel: path45.basename(ar),
25520
25607
  oc: {
25521
25608
  ...oc,
25522
25609
  aceEnabled: getAceAnalysisEnabledForCheckout(ar),
@@ -25544,7 +25631,7 @@ function buildFactoryDepsHeadless(input) {
25544
25631
  }
25545
25632
  try {
25546
25633
  await startPipelineRun(storageContext, repoRoot);
25547
- const folderName = path44.basename(repoRoot);
25634
+ const folderName = path45.basename(repoRoot);
25548
25635
  const oc = buildOpenCodeOptions(handle.path);
25549
25636
  const result = await runSynthesisPipelineDrainFromPreparedWorktree(
25550
25637
  storageContext,
@@ -25601,7 +25688,7 @@ function buildFactoryDepsHeadless(input) {
25601
25688
  if (!ar) {
25602
25689
  return 0;
25603
25690
  }
25604
- const ctxDir = path44.join(ar, ".gluecharm", "context");
25691
+ const ctxDir = path45.join(ar, ".gluecharm", "context");
25605
25692
  const snap = readArtefactRunSnapshot(storageContext);
25606
25693
  return listMissingWorkstations(ctxDir, ar, snap).length;
25607
25694
  };
@@ -25614,7 +25701,7 @@ function buildFactoryDepsHeadless(input) {
25614
25701
  if (!layout.ok) {
25615
25702
  return { ok: false, message: layout.error };
25616
25703
  }
25617
- const contextDir2 = path44.join(ar, ".gluecharm", "context");
25704
+ const contextDir2 = path45.join(ar, ".gluecharm", "context");
25618
25705
  log(`[factory] reference coverage (worktree) \u2014 ${ar}`);
25619
25706
  const res = runCoveragePipeline({
25620
25707
  repositoryRootAbs: ar,
@@ -25674,7 +25761,7 @@ function buildFactoryDepsHeadless(input) {
25674
25761
  diagnosticLog: log
25675
25762
  });
25676
25763
  if (res.ok) {
25677
- return { ok: true, message: `Report: ${path44.basename(res.outputAbsolutePath)}` };
25764
+ return { ok: true, message: `Report: ${path45.basename(res.outputAbsolutePath)}` };
25678
25765
  }
25679
25766
  if (res.cancelled) {
25680
25767
  return { ok: false, cancelled: true, message: "Report generation stopped." };
@@ -25690,7 +25777,7 @@ function buildFactoryDepsHeadless(input) {
25690
25777
  if (!lmLayout.ok) {
25691
25778
  return { ok: false, message: lmLayout.error };
25692
25779
  }
25693
- const contextDir2 = path44.join(snap.adHocWorktreePath, ".gluecharm", "context");
25780
+ const contextDir2 = path45.join(snap.adHocWorktreePath, ".gluecharm", "context");
25694
25781
  const linkGraph = runLinkMappingPipeline(contextDir2, { log });
25695
25782
  if (!linkGraph.ok) {
25696
25783
  return { ok: false, message: linkGraph.error };
@@ -25706,7 +25793,7 @@ function buildFactoryDepsHeadless(input) {
25706
25793
  if (!idxLayout.ok) {
25707
25794
  return { ok: false, message: idxLayout.error };
25708
25795
  }
25709
- const contextDir2 = path44.join(snap.adHocWorktreePath, ".gluecharm", "context");
25796
+ const contextDir2 = path45.join(snap.adHocWorktreePath, ".gluecharm", "context");
25710
25797
  try {
25711
25798
  writeIndexApplicationContext(contextDir2, void 0, {
25712
25799
  sourceBranchAtWorktreeCreation: snap.adHocSourceBranchAtCreation
@@ -25761,13 +25848,13 @@ function buildFactoryDepsHeadless(input) {
25761
25848
  },
25762
25849
  runPrepareAnalysisWorktree: async (resume) => {
25763
25850
  if (resume) {
25764
- if (adHocWorktree && fs48.existsSync(path44.join(adHocWorktree.path, ".git"))) {
25851
+ if (adHocWorktree && fs48.existsSync(path45.join(adHocWorktree.path, ".git"))) {
25765
25852
  return { ok: true };
25766
25853
  }
25767
25854
  const snap = readAnalysisWorkspaceSnapshot(storageContext);
25768
25855
  const wtPath = snap?.adHocWorktreePath?.trim();
25769
25856
  const repo = snap?.adHocRepositoryRoot?.trim() || repoRoot;
25770
- if (wtPath && fs48.existsSync(path44.join(wtPath, ".git"))) {
25857
+ if (wtPath && fs48.existsSync(path45.join(wtPath, ".git"))) {
25771
25858
  adHocWorktree = resolveAnalysisCheckoutHandle(wtPath, repo);
25772
25859
  macroSourceBranch = snap?.adHocSourceBranchAtCreation;
25773
25860
  macroFinalize = () => {
@@ -25985,11 +26072,11 @@ function stderrLinesForFactoryFailures(failures, exitCode) {
25985
26072
  }
25986
26073
 
25987
26074
  // src/factory/updateContext/runUpdateContextFactory.ts
25988
- var path49 = __toESM(require("node:path"));
26075
+ var path50 = __toESM(require("node:path"));
25989
26076
 
25990
26077
  // src/factory/updateContext/updateContextBaseline.ts
25991
26078
  var fs49 = __toESM(require("node:fs"));
25992
- var path45 = __toESM(require("node:path"));
26079
+ var path46 = __toESM(require("node:path"));
25993
26080
  function isValidIso(s) {
25994
26081
  const t = Date.parse(s);
25995
26082
  return Number.isFinite(t);
@@ -26004,7 +26091,7 @@ function maxMtimeRegularFilesUnderDir(dirAbs) {
26004
26091
  return;
26005
26092
  }
26006
26093
  for (const e of entries) {
26007
- const p = path45.join(d, e.name);
26094
+ const p = path46.join(d, e.name);
26008
26095
  if (e.isDirectory()) {
26009
26096
  walk(p);
26010
26097
  } else if (e.isFile()) {
@@ -26030,7 +26117,7 @@ function resolveUpdateContextBaseline(repoRootAbs, repoConfig) {
26030
26117
  if (last.length > 0 && isValidIso(last)) {
26031
26118
  return { baselineIsoUtc: new Date(last).toISOString(), source: "lastRunAt" };
26032
26119
  }
26033
- const ctxDir = path45.join(repoRootAbs, ".gluecharm", "context");
26120
+ const ctxDir = path46.join(repoRootAbs, ".gluecharm", "context");
26034
26121
  if (!fs49.existsSync(ctxDir)) {
26035
26122
  return null;
26036
26123
  }
@@ -26055,7 +26142,7 @@ function persistUpdateContextLastRunAt(repoRootAbs, isoUtc) {
26055
26142
  // src/factory/updateContext/updateContextGitWindow.ts
26056
26143
  var import_node_child_process3 = require("node:child_process");
26057
26144
  var fs50 = __toESM(require("node:fs"));
26058
- var path46 = __toESM(require("node:path"));
26145
+ var path47 = __toESM(require("node:path"));
26059
26146
  var GIT_ENV = { ...process.env, GIT_TERMINAL_PROMPT: "0" };
26060
26147
  function gitLines(repoRootAbs, args) {
26061
26148
  const r = (0, import_node_child_process3.execFileSync)("git", ["-c", "core.quotepath=false", ...args], {
@@ -26079,8 +26166,8 @@ function parseGitLogIso(line) {
26079
26166
  return { hash, iso };
26080
26167
  }
26081
26168
  function discoverCommitWindowAndTouchedPaths(repoRootAbs, baselineIsoUtc) {
26082
- const root = path46.resolve(repoRootAbs);
26083
- if (!fs50.existsSync(path46.join(root, ".git"))) {
26169
+ const root = path47.resolve(repoRootAbs);
26170
+ if (!fs50.existsSync(path47.join(root, ".git"))) {
26084
26171
  return { ok: false, error: "Not a git repository (missing .git)." };
26085
26172
  }
26086
26173
  const baselineMs = Date.parse(baselineIsoUtc);
@@ -26139,11 +26226,11 @@ function discoverCommitWindowAndTouchedPaths(repoRootAbs, baselineIsoUtc) {
26139
26226
  };
26140
26227
  }
26141
26228
  function filterPathsExistingInWorktree(worktreeRootAbs, pathsPosix) {
26142
- const root = path46.resolve(worktreeRootAbs);
26229
+ const root = path47.resolve(worktreeRootAbs);
26143
26230
  const out = [];
26144
26231
  for (const p of pathsPosix) {
26145
26232
  const rel = p.replace(/\\/g, "/");
26146
- const abs = path46.join(root, ...rel.split("/"));
26233
+ const abs = path47.join(root, ...rel.split("/"));
26147
26234
  try {
26148
26235
  if (fs50.existsSync(abs) && fs50.statSync(abs).isFile()) {
26149
26236
  out.push(rel);
@@ -26156,7 +26243,7 @@ function filterPathsExistingInWorktree(worktreeRootAbs, pathsPosix) {
26156
26243
 
26157
26244
  // src/factory/updateContext/updateContextReport.ts
26158
26245
  var fs51 = __toESM(require("node:fs"));
26159
- var path47 = __toESM(require("node:path"));
26246
+ var path48 = __toESM(require("node:path"));
26160
26247
  var CHANGES_SINCE_DATE_BASENAME = "changes-since-date.md";
26161
26248
  function renderChangesSinceDateMarkdown(p) {
26162
26249
  const lines = [
@@ -26198,7 +26285,7 @@ function renderChangesSinceDateMarkdown(p) {
26198
26285
  function writeChangesSinceDateReport(contextDirAbs, body) {
26199
26286
  try {
26200
26287
  fs51.mkdirSync(contextDirAbs, { recursive: true });
26201
- const target = path47.join(contextDirAbs, CHANGES_SINCE_DATE_BASENAME);
26288
+ const target = path48.join(contextDirAbs, CHANGES_SINCE_DATE_BASENAME);
26202
26289
  fs51.writeFileSync(target, body, "utf-8");
26203
26290
  return { ok: true };
26204
26291
  } catch (e) {
@@ -26208,7 +26295,7 @@ function writeChangesSinceDateReport(contextDirAbs, body) {
26208
26295
 
26209
26296
  // src/factory/updateContext/updateContextSeedCheck.ts
26210
26297
  var fs52 = __toESM(require("node:fs"));
26211
- var path48 = __toESM(require("node:path"));
26298
+ var path49 = __toESM(require("node:path"));
26212
26299
  var INDEX_BASENAME = "index-application-context.json";
26213
26300
  var CHANGES_REPORT = "changes-since-date.md";
26214
26301
  function tryParseJsonFile(abs) {
@@ -26224,7 +26311,7 @@ function isWorktreeContextSeeded(contextDirAbs) {
26224
26311
  if (!fs52.existsSync(contextDirAbs)) {
26225
26312
  return false;
26226
26313
  }
26227
- const indexAbs = path48.join(contextDirAbs, INDEX_BASENAME);
26314
+ const indexAbs = path49.join(contextDirAbs, INDEX_BASENAME);
26228
26315
  if (fs52.existsSync(indexAbs) && fs52.statSync(indexAbs).isFile() && tryParseJsonFile(indexAbs)) {
26229
26316
  return true;
26230
26317
  }
@@ -26242,7 +26329,7 @@ function isWorktreeContextSeeded(contextDirAbs) {
26242
26329
  if (!name.endsWith(".md") && !name.endsWith(".json")) {
26243
26330
  continue;
26244
26331
  }
26245
- const p = path48.join(contextDirAbs, name);
26332
+ const p = path49.join(contextDirAbs, name);
26246
26333
  try {
26247
26334
  if (fs52.statSync(p).isFile()) {
26248
26335
  distinct.add(name);
@@ -26256,7 +26343,7 @@ function isWorktreeContextSeeded(contextDirAbs) {
26256
26343
  // src/factory/updateContext/runUpdateContextFactory.ts
26257
26344
  var REMEDIATION_CHUNK_MAX = 40;
26258
26345
  function contextDirUnderRoot(wtRoot) {
26259
- return path49.join(wtRoot, ".gluecharm", "context");
26346
+ return path50.join(wtRoot, ".gluecharm", "context");
26260
26347
  }
26261
26348
  async function runUpdateContextFactory(deps) {
26262
26349
  const inPlace = deps.inPlace === true;
@@ -26587,11 +26674,11 @@ async function runUpdateContextFactory(deps) {
26587
26674
 
26588
26675
  // src/factory/contextDrift/runContextDriftFactory.ts
26589
26676
  var fs58 = __toESM(require("node:fs"));
26590
- var path54 = __toESM(require("node:path"));
26677
+ var path55 = __toESM(require("node:path"));
26591
26678
 
26592
26679
  // src/factory/contextDrift/contextDriftManifest.ts
26593
26680
  var fs53 = __toESM(require("node:fs"));
26594
- var path50 = __toESM(require("node:path"));
26681
+ var path51 = __toESM(require("node:path"));
26595
26682
  var MAX_REFERENCE_BYTES = 256 * 1024;
26596
26683
  var MAX_EVIDENCE_FILES = 300;
26597
26684
  var MAX_EVIDENCE_READ = 512 * 1024;
@@ -26611,16 +26698,16 @@ function collectEvidencePaths(repoRoot) {
26611
26698
  const out = [];
26612
26699
  const roots = ["src", "test", "tests", "packages", ".gluecharm", "scripts"];
26613
26700
  for (const rel of roots) {
26614
- const abs = path50.join(repoRoot, rel);
26701
+ const abs = path51.join(repoRoot, rel);
26615
26702
  if (!fs53.existsSync(abs)) {
26616
26703
  continue;
26617
26704
  }
26618
26705
  walkFiles(abs, repoRoot, out, 0);
26619
26706
  }
26620
26707
  for (const leaf of ["package.json", "tsconfig.json"]) {
26621
- const abs = path50.join(repoRoot, leaf);
26708
+ const abs = path51.join(repoRoot, leaf);
26622
26709
  if (fs53.existsSync(abs) && fs53.statSync(abs).isFile()) {
26623
- const r = path50.relative(repoRoot, abs).split(path50.sep).join("/");
26710
+ const r = path51.relative(repoRoot, abs).split(path51.sep).join("/");
26624
26711
  out.push(r);
26625
26712
  }
26626
26713
  }
@@ -26645,13 +26732,13 @@ function walkFiles(dir, repoRoot, out, depth) {
26645
26732
  if (e.name === "node_modules" || e.name === ".git" || e.name === "dist" || e.name === "out") {
26646
26733
  continue;
26647
26734
  }
26648
- const full = path50.join(dir, e.name);
26735
+ const full = path51.join(dir, e.name);
26649
26736
  if (e.isDirectory()) {
26650
26737
  walkFiles(full, repoRoot, out, depth + 1);
26651
26738
  } else if (e.isFile()) {
26652
- const ext = path50.extname(e.name).toLowerCase();
26739
+ const ext = path51.extname(e.name).toLowerCase();
26653
26740
  if ([".ts", ".tsx", ".js", ".mjs", ".cjs", ".json", ".md", ".yaml", ".yml"].includes(ext) || e.name === "Dockerfile") {
26654
- const rel = path50.relative(repoRoot, full).split(path50.sep).join("/");
26741
+ const rel = path51.relative(repoRoot, full).split(path51.sep).join("/");
26655
26742
  out.push(rel);
26656
26743
  }
26657
26744
  }
@@ -26661,7 +26748,7 @@ function buildComparisonManifest(args) {
26661
26748
  const references = [];
26662
26749
  let referenceTruncated = false;
26663
26750
  for (const abs of args.bundleAbsFiles) {
26664
- const rel = path50.relative(args.worktreeRoot, abs).split(path50.sep).join("/");
26751
+ const rel = path51.relative(args.worktreeRoot, abs).split(path51.sep).join("/");
26665
26752
  const { text, truncated } = readFileLimited(abs, MAX_REFERENCE_BYTES);
26666
26753
  references.push({ path: rel, content: text, truncated });
26667
26754
  if (truncated) {
@@ -26673,7 +26760,7 @@ function buildComparisonManifest(args) {
26673
26760
  const omitted = Math.max(0, allEvidence.length - evidencePathsTrimmed.length);
26674
26761
  const evidenceFiles = [];
26675
26762
  for (const rel of evidencePathsTrimmed) {
26676
- const abs = path50.join(args.worktreeRoot, ...rel.split("/"));
26763
+ const abs = path51.join(args.worktreeRoot, ...rel.split("/"));
26677
26764
  const st = fs53.existsSync(abs) ? fs53.statSync(abs) : null;
26678
26765
  const size = st && st.isFile() ? st.size : 0;
26679
26766
  const { text, truncated } = readFileLimited(abs, MAX_EVIDENCE_READ);
@@ -26684,7 +26771,7 @@ function buildComparisonManifest(args) {
26684
26771
  }
26685
26772
  return {
26686
26773
  runDate: args.runDate,
26687
- referenceRelPaths: args.bundleAbsFiles.map((a) => path50.relative(args.worktreeRoot, a).split(path50.sep).join("/")),
26774
+ referenceRelPaths: args.bundleAbsFiles.map((a) => path51.relative(args.worktreeRoot, a).split(path51.sep).join("/")),
26688
26775
  references,
26689
26776
  evidenceFiles,
26690
26777
  evidencePathsOnly: [],
@@ -26697,7 +26784,7 @@ function buildComparisonManifest(args) {
26697
26784
 
26698
26785
  // src/factory/contextDrift/contextDriftAgent.ts
26699
26786
  var fs54 = __toESM(require("node:fs"));
26700
- var path51 = __toESM(require("node:path"));
26787
+ var path52 = __toESM(require("node:path"));
26701
26788
 
26702
26789
  // src/factory/contextDrift/contextDriftPayload.ts
26703
26790
  function isNonEmptyString2(v) {
@@ -26842,16 +26929,16 @@ function buildDriftPrompt(args) {
26842
26929
  ].join("\n");
26843
26930
  }
26844
26931
  async function runDriftComparisonOpenCode(args) {
26845
- const runDir = path51.join(args.worktreeRoot, ".opencode", "_run");
26932
+ const runDir = path52.join(args.worktreeRoot, ".opencode", "_run");
26846
26933
  fs54.mkdirSync(runDir, { recursive: true });
26847
- const manifestPath = path51.join(runDir, "context-drift-manifest.json");
26848
- const outputPath = path51.join(runDir, "context-drift-payload.json");
26934
+ const manifestPath = path52.join(runDir, "context-drift-manifest.json");
26935
+ const outputPath = path52.join(runDir, "context-drift-payload.json");
26849
26936
  fs54.writeFileSync(manifestPath, `${JSON.stringify(args.manifestObject, null, 2)}
26850
26937
  `, "utf8");
26851
26938
  if (fs54.existsSync(outputPath)) {
26852
26939
  fs54.unlinkSync(outputPath);
26853
26940
  }
26854
- const promptPath = path51.join(runDir, `context-drift-${Date.now()}.prompt.txt`);
26941
+ const promptPath = path52.join(runDir, `context-drift-${Date.now()}.prompt.txt`);
26855
26942
  fs54.writeFileSync(
26856
26943
  promptPath,
26857
26944
  buildDriftPrompt({
@@ -26869,7 +26956,7 @@ async function runDriftComparisonOpenCode(args) {
26869
26956
  });
26870
26957
  const title = buildOpenCodeSessionTitle({
26871
26958
  runId: "context-drift",
26872
- workItemId: path51.basename(args.worktreeRoot).slice(0, 24) || "wt",
26959
+ workItemId: path52.basename(args.worktreeRoot).slice(0, 24) || "wt",
26873
26960
  stepLabel: "context-drift"
26874
26961
  });
26875
26962
  const argv = injectPrimaryOpenCodeSessionArgv(expanded, title);
@@ -26912,8 +26999,8 @@ async function runDriftComparisonOpenCode(args) {
26912
26999
  // src/factory/contextDrift/contextDriftPaths.ts
26913
27000
  var crypto2 = __toESM(require("node:crypto"));
26914
27001
  var fs55 = __toESM(require("node:fs"));
26915
- var path52 = __toESM(require("node:path"));
26916
- var DRIFT_CONTEXT_SUBDIR = path52.join(".gluecharm", "context", "drift");
27002
+ var path53 = __toESM(require("node:path"));
27003
+ var DRIFT_CONTEXT_SUBDIR = path53.join(".gluecharm", "context", "drift");
26917
27004
  function sanitizeSlug(raw) {
26918
27005
  const s = raw.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
26919
27006
  return s.length > 0 ? s : "drift";
@@ -26922,9 +27009,9 @@ function utcDateString(d) {
26922
27009
  return d.toISOString().slice(0, 10);
26923
27010
  }
26924
27011
  function resolveInsideRepo(repoRootAbs, userPath) {
26925
- const abs = path52.isAbsolute(userPath) ? path52.normalize(userPath) : path52.resolve(repoRootAbs, userPath);
26926
- const rel = path52.relative(repoRootAbs, abs);
26927
- if (rel.startsWith("..") || path52.isAbsolute(rel)) {
27012
+ const abs = path53.isAbsolute(userPath) ? path53.normalize(userPath) : path53.resolve(repoRootAbs, userPath);
27013
+ const rel = path53.relative(repoRootAbs, abs);
27014
+ if (rel.startsWith("..") || path53.isAbsolute(rel)) {
26928
27015
  return { ok: false };
26929
27016
  }
26930
27017
  return { ok: true, abs };
@@ -26934,7 +27021,7 @@ function computeSlug(args) {
26934
27021
  return sanitizeSlug(args.label.trim());
26935
27022
  }
26936
27023
  const r = resolveInsideRepo(args.repoRootAbs, args.referencePath);
26937
- const base = r.ok ? path52.basename(r.abs) : path52.basename(args.referencePath);
27024
+ const base = r.ok ? path53.basename(r.abs) : path53.basename(args.referencePath);
26938
27025
  return sanitizeSlug(base);
26939
27026
  }
26940
27027
  function driftFilename(slug, runDate) {
@@ -26976,7 +27063,7 @@ function discoverReferenceBundle(worktreeRoot, referenceAbsInWorktree) {
26976
27063
  return;
26977
27064
  }
26978
27065
  for (const e of entries) {
26979
- const full = path52.join(dir, e.name);
27066
+ const full = path53.join(dir, e.name);
26980
27067
  if (e.isDirectory()) {
26981
27068
  if (e.name === "node_modules" || e.name === ".git") {
26982
27069
  continue;
@@ -27006,7 +27093,7 @@ function pickReferenceRootDocument(args) {
27006
27093
  }
27007
27094
  const dir = args.referenceAbsInWorktree;
27008
27095
  for (const name of ["index.md", "README.md"]) {
27009
- const p = path52.join(dir, name);
27096
+ const p = path53.join(dir, name);
27010
27097
  if (fs55.existsSync(p) && fs55.statSync(p).isFile()) {
27011
27098
  return { ok: true, path: p };
27012
27099
  }
@@ -27017,10 +27104,10 @@ function pickReferenceRootDocument(args) {
27017
27104
  };
27018
27105
  }
27019
27106
  function toWorktreeRelative(worktreeRoot, absolute) {
27020
- return path52.relative(worktreeRoot, absolute).split(path52.sep).join("/");
27107
+ return path53.relative(worktreeRoot, absolute).split(path53.sep).join("/");
27021
27108
  }
27022
27109
  function toPosixPath(p) {
27023
- return p.split(path52.sep).join("/");
27110
+ return p.split(path53.sep).join("/");
27024
27111
  }
27025
27112
 
27026
27113
  // src/factory/contextDrift/contextDriftIndex.ts
@@ -27063,19 +27150,19 @@ function escapeRe(s) {
27063
27150
 
27064
27151
  // src/factory/contextDrift/contextDriftPromote.ts
27065
27152
  var fs57 = __toESM(require("node:fs"));
27066
- var path53 = __toESM(require("node:path"));
27153
+ var path54 = __toESM(require("node:path"));
27067
27154
  function copyWorktreeFileToWorkspace(args) {
27068
- const wt = path53.resolve(args.worktreeRoot);
27069
- const ws = path53.resolve(args.workspaceRoot);
27155
+ const wt = path54.resolve(args.worktreeRoot);
27156
+ const ws = path54.resolve(args.workspaceRoot);
27070
27157
  if (wt === ws) {
27071
27158
  return;
27072
27159
  }
27073
- const src = path53.join(args.worktreeRoot, ...args.relativePosix.split("/"));
27074
- const dest = path53.join(args.workspaceRoot, ...args.relativePosix.split("/"));
27075
- if (path53.resolve(src) === path53.resolve(dest)) {
27160
+ const src = path54.join(args.worktreeRoot, ...args.relativePosix.split("/"));
27161
+ const dest = path54.join(args.workspaceRoot, ...args.relativePosix.split("/"));
27162
+ if (path54.resolve(src) === path54.resolve(dest)) {
27076
27163
  return;
27077
27164
  }
27078
- fs57.mkdirSync(path53.dirname(dest), { recursive: true });
27165
+ fs57.mkdirSync(path54.dirname(dest), { recursive: true });
27079
27166
  fs57.copyFileSync(src, dest);
27080
27167
  }
27081
27168
 
@@ -27131,7 +27218,7 @@ async function runContextDriftFactory(deps) {
27131
27218
  ok: true,
27132
27219
  code: "DRY_RUN",
27133
27220
  ...baseMeta,
27134
- referenceRootDocument: toPosixPath(path54.relative(deps.repoRootAbs, refAbsWorkspace)) + (fs58.statSync(refAbsWorkspace).isDirectory() ? "/" : ""),
27221
+ referenceRootDocument: toPosixPath(path55.relative(deps.repoRootAbs, refAbsWorkspace)) + (fs58.statSync(refAbsWorkspace).isDirectory() ? "/" : ""),
27135
27222
  driftReportPath: null,
27136
27223
  analysisWorktreeRoot: "",
27137
27224
  promoted: false,
@@ -27188,8 +27275,8 @@ async function runContextDriftFactory(deps) {
27188
27275
  const handle = prep.handle;
27189
27276
  const finalizeWt = prep.finalize;
27190
27277
  const wt = handle.path;
27191
- const refRel = path54.relative(deps.repoRootAbs, refAbsWorkspace).split(path54.sep).join("/");
27192
- const refAbsWt = path54.join(wt, ...refRel.split("/"));
27278
+ const refRel = path55.relative(deps.repoRootAbs, refAbsWorkspace).split(path55.sep).join("/");
27279
+ const refAbsWt = path55.join(wt, ...refRel.split("/"));
27193
27280
  try {
27194
27281
  materializeOpenCodeAgentsWithAce(deps.agentsDirFs, wt, {
27195
27282
  enabled: getAceAnalysisEnabledForCheckout(wt),
@@ -27228,7 +27315,7 @@ async function runContextDriftFactory(deps) {
27228
27315
  ...baseMeta
27229
27316
  };
27230
27317
  }
27231
- const indexWt = indexOverrideAbsWorkspace ? path54.join(wt, ...path54.relative(deps.repoRootAbs, indexOverrideAbsWorkspace).split(path54.sep)) : void 0;
27318
+ const indexWt = indexOverrideAbsWorkspace ? path55.join(wt, ...path55.relative(deps.repoRootAbs, indexOverrideAbsWorkspace).split(path55.sep)) : void 0;
27232
27319
  const rootPick = pickReferenceRootDocument({
27233
27320
  referencePathIsFile: fs58.statSync(refAbsWt).isFile(),
27234
27321
  referenceAbsInWorktree: refAbsWt,
@@ -27256,9 +27343,9 @@ async function runContextDriftFactory(deps) {
27256
27343
  let slug = computeSlug({ label: deps.label, referencePath: deps.referencePathArg, repoRootAbs: deps.repoRootAbs });
27257
27344
  slug = maybeDedupeSlug(slug, refRel);
27258
27345
  const driftBase = driftFilename(slug, runDate);
27259
- const driftDirWt = path54.join(wt, DRIFT_CONTEXT_SUBDIR);
27346
+ const driftDirWt = path55.join(wt, DRIFT_CONTEXT_SUBDIR);
27260
27347
  fs58.mkdirSync(driftDirWt, { recursive: true });
27261
- const driftAbsWt = path54.join(driftDirWt, driftBase);
27348
+ const driftAbsWt = path55.join(driftDirWt, driftBase);
27262
27349
  let payload;
27263
27350
  if (deps.testOnlyFixturePayload) {
27264
27351
  payload = deps.testOnlyFixturePayload;
@@ -27307,7 +27394,7 @@ async function runContextDriftFactory(deps) {
27307
27394
  ...baseMeta
27308
27395
  };
27309
27396
  }
27310
- const driftRelFromRootDir = path54.relative(path54.dirname(refRootAbsWt), driftAbsWt).split(path54.sep).join("/");
27397
+ const driftRelFromRootDir = path55.relative(path55.dirname(refRootAbsWt), driftAbsWt).split(path55.sep).join("/");
27311
27398
  const linkRes = patchReferenceIndexWithDriftLink({
27312
27399
  referenceRootAbsolute: refRootAbsWt,
27313
27400
  relativeLinkFromRootToDrift: driftRelFromRootDir,
@@ -27326,8 +27413,8 @@ async function runContextDriftFactory(deps) {
27326
27413
  ...baseMeta
27327
27414
  };
27328
27415
  }
27329
- const driftRelPosix = toPosixPath(path54.relative(wt, driftAbsWt));
27330
- const rootRelPosix = toPosixPath(path54.relative(wt, refRootAbsWt));
27416
+ const driftRelPosix = toPosixPath(path55.relative(wt, driftAbsWt));
27417
+ const rootRelPosix = toPosixPath(path55.relative(wt, refRootAbsWt));
27331
27418
  const promoteEffective = deps.merged.promoteContextToWorkspace !== false;
27332
27419
  if (promoteEffective && !inPlace) {
27333
27420
  try {
@@ -27357,7 +27444,7 @@ async function runContextDriftFactory(deps) {
27357
27444
  } else if (promoteEffective && inPlace) {
27358
27445
  deps.log("[context-drift] in-place analysis \u2014 promote skipped (artefacts already under repository root)");
27359
27446
  }
27360
- const driftReportPathFs = promoteEffective ? path54.join(deps.repoRootAbs, ...driftRelPosix.split("/")) : driftAbsWt;
27447
+ const driftReportPathFs = promoteEffective ? path55.join(deps.repoRootAbs, ...driftRelPosix.split("/")) : driftAbsWt;
27361
27448
  return {
27362
27449
  exitOk: true,
27363
27450
  ok: true,
@@ -27376,7 +27463,7 @@ async function runContextDriftFactory(deps) {
27376
27463
 
27377
27464
  // src/analysis/coordinationDuplicatesDiagnosis.ts
27378
27465
  var fs59 = __toESM(require("fs"));
27379
- var path55 = __toESM(require("path"));
27466
+ var path56 = __toESM(require("path"));
27380
27467
  var import__7 = __toESM(require__());
27381
27468
  var COORDINATION_DUPLICATES_REPORT_BASENAME = "coordination-duplicates-report.json";
27382
27469
  var COORDINATION_LIST_SCAN_ENTRIES = [
@@ -27402,7 +27489,7 @@ var RE_MD_DM_FD = /^DM-\d+_FD-\d+-.+\.md$/i;
27402
27489
  var RE_MD_DM = /^DM-\d+-.+\.md$/i;
27403
27490
  var RE_MD_TS = /^TS-\d+-.+\.md$/i;
27404
27491
  function looksLikeCoordinationDetailMarkdownBasename(basename17) {
27405
- if (!basename17 || basename17 !== path55.basename(basename17) || !/\.md$/i.test(basename17)) {
27492
+ if (!basename17 || basename17 !== path56.basename(basename17) || !/\.md$/i.test(basename17)) {
27406
27493
  return false;
27407
27494
  }
27408
27495
  if (STAPLE_CONTEXT_MARKDOWN_BASENAMES.has(basename17)) {
@@ -27411,7 +27498,7 @@ function looksLikeCoordinationDetailMarkdownBasename(basename17) {
27411
27498
  return RE_MD_FE_UC_SC.test(basename17) || RE_MD_FE_UC_SLUG.test(basename17) || RE_MD_FE_UC_PLAIN.test(basename17) || RE_MD_FE_FEATURE.test(basename17) || RE_MD_XP_BH.test(basename17) || RE_MD_XP_VIEW.test(basename17) || RE_MD_SV_ME.test(basename17) || RE_MD_SV.test(basename17) || RE_MD_DM_FD.test(basename17) || RE_MD_DM.test(basename17) || RE_MD_TS.test(basename17);
27412
27499
  }
27413
27500
  function loadRawFeatureRows(contextDirAbs) {
27414
- const p = path55.join(contextDirAbs, "features-list.json");
27501
+ const p = path56.join(contextDirAbs, "features-list.json");
27415
27502
  if (!fs59.existsSync(p)) {
27416
27503
  return [];
27417
27504
  }
@@ -27704,7 +27791,7 @@ function buildCoordinationDuplicatesReport(input) {
27704
27791
  const lists = [];
27705
27792
  const duplicateGroups = [];
27706
27793
  for (const entry of COORDINATION_LIST_SCAN_ENTRIES) {
27707
- const filePath = path55.join(input.contextDirAbsolute, entry.basename);
27794
+ const filePath = path56.join(input.contextDirAbsolute, entry.basename);
27708
27795
  if (!fs59.existsSync(filePath)) {
27709
27796
  lists.push({ basename: entry.basename, status: "missing" });
27710
27797
  continue;
@@ -27759,7 +27846,7 @@ var validateReportCompiled;
27759
27846
  function validateReportData(data) {
27760
27847
  if (!validateReportCompiled) {
27761
27848
  const ajv2 = new import__7.default({ allErrors: true, strict: false });
27762
- const schemaPath = path55.join(resolveContextListSchemasDir(), "coordination-duplicates-report.schema.json");
27849
+ const schemaPath = path56.join(resolveContextListSchemasDir(), "coordination-duplicates-report.schema.json");
27763
27850
  const schemaRaw = stripUtf8Bom6(fs59.readFileSync(schemaPath, "utf-8"));
27764
27851
  validateReportCompiled = ajv2.compile(JSON.parse(schemaRaw));
27765
27852
  }
@@ -27778,7 +27865,7 @@ function runCoordinationDuplicatesDiagnosis(input) {
27778
27865
  if (!v.ok) {
27779
27866
  return { ok: false, message: `Report validation failed: ${v.errors.join("; ")}` };
27780
27867
  }
27781
- const outPath = path55.join(input.contextDirAbsolute, COORDINATION_DUPLICATES_REPORT_BASENAME);
27868
+ const outPath = path56.join(input.contextDirAbsolute, COORDINATION_DUPLICATES_REPORT_BASENAME);
27782
27869
  const payload = `${JSON.stringify(report, null, 2)}
27783
27870
  `;
27784
27871
  const tmp = `${outPath}.tmp.${process.pid}`;
@@ -27826,7 +27913,7 @@ function runCoordinationDuplicatesDiagnosis(input) {
27826
27913
 
27827
27914
  // src/pipelines/download/downloadPipeline.ts
27828
27915
  var fs60 = __toESM(require("node:fs"));
27829
- var path56 = __toESM(require("node:path"));
27916
+ var path57 = __toESM(require("node:path"));
27830
27917
  var SRS_DISCOVERY_BATCH_GET_CHUNK_SIZE = 200;
27831
27918
  function isRecord7(v) {
27832
27919
  return Boolean(v) && typeof v === "object" && !Array.isArray(v);
@@ -27916,9 +28003,9 @@ function resolveSafeContextOutputPath(contextDirAbs, nameRaw) {
27916
28003
  return null;
27917
28004
  }
27918
28005
  }
27919
- const resolved = path56.resolve(contextDirAbs, ...segments);
27920
- const rel = path56.relative(contextDirAbs, resolved);
27921
- if (rel.startsWith("..") || path56.isAbsolute(rel)) {
28006
+ const resolved = path57.resolve(contextDirAbs, ...segments);
28007
+ const rel = path57.relative(contextDirAbs, resolved);
28008
+ if (rel.startsWith("..") || path57.isAbsolute(rel)) {
27922
28009
  return null;
27923
28010
  }
27924
28011
  return resolved;
@@ -27934,7 +28021,7 @@ function clearContextDirectoryForCloudReplace(contextDirAbs) {
27934
28021
  if (!fs60.existsSync(contextDirAbs) || !fs60.statSync(contextDirAbs).isDirectory()) {
27935
28022
  return { filesRemoved: 0 };
27936
28023
  }
27937
- const preserveAbs = path56.resolve(contextDirAbs, UPLOAD_TARGET_FILENAME);
28024
+ const preserveAbs = path57.resolve(contextDirAbs, UPLOAD_TARGET_FILENAME);
27938
28025
  const preserveSet = /* @__PURE__ */ new Set();
27939
28026
  if (fs60.existsSync(preserveAbs) && fs60.statSync(preserveAbs).isFile()) {
27940
28027
  preserveSet.add(preserveAbs);
@@ -27948,7 +28035,7 @@ function clearContextDirectoryForCloudReplace(contextDirAbs) {
27948
28035
  return;
27949
28036
  }
27950
28037
  for (const e of entries) {
27951
- const full = path56.join(dir, e.name);
28038
+ const full = path57.join(dir, e.name);
27952
28039
  if (e.isDirectory()) {
27953
28040
  walkRm(full);
27954
28041
  try {
@@ -27956,7 +28043,7 @@ function clearContextDirectoryForCloudReplace(contextDirAbs) {
27956
28043
  } catch {
27957
28044
  }
27958
28045
  } else if (e.isFile()) {
27959
- const abs = path56.resolve(full);
28046
+ const abs = path57.resolve(full);
27960
28047
  if (preserveSet.has(abs)) {
27961
28048
  continue;
27962
28049
  }
@@ -28029,7 +28116,7 @@ async function runDownloadPipeline(opts) {
28029
28116
  failed.push({ id, message: "Missing name on srs_discovery node." });
28030
28117
  continue;
28031
28118
  }
28032
- if (name === UPLOAD_TARGET_FILENAME || path56.basename(name) === UPLOAD_TARGET_FILENAME) {
28119
+ if (name === UPLOAD_TARGET_FILENAME || path57.basename(name) === UPLOAD_TARGET_FILENAME) {
28033
28120
  skipped += 1;
28034
28121
  log?.(`[pipeline:download] skip ${name} (upload target row).`);
28035
28122
  continue;
@@ -28040,7 +28127,7 @@ async function runDownloadPipeline(opts) {
28040
28127
  failed.push({ id, name, message: "Unsafe or invalid name for local path." });
28041
28128
  continue;
28042
28129
  }
28043
- fs60.mkdirSync(path56.dirname(outAbs), { recursive: true });
28130
+ fs60.mkdirSync(path57.dirname(outAbs), { recursive: true });
28044
28131
  const exists = fs60.existsSync(outAbs);
28045
28132
  if (exists && !opts.force && !opts.replaceFromCloud) {
28046
28133
  skipped += 1;
@@ -28123,12 +28210,12 @@ function toFetchErrorMessage(e) {
28123
28210
 
28124
28211
  // src/auth/gluecharmContentNegotiation.ts
28125
28212
  var GLUECHARM_WS_LEGACY_JSON = "application/vnd.gluecharm.v1.ws-legacy+json";
28126
- function pathWithoutQuery(path61) {
28127
- const q = path61.indexOf("?");
28128
- return q === -1 ? path61 : path61.slice(0, q);
28213
+ function pathWithoutQuery(path62) {
28214
+ const q = path62.indexOf("?");
28215
+ return q === -1 ? path62 : path62.slice(0, q);
28129
28216
  }
28130
- function isGluecharmContentApiPath(path61) {
28131
- const p = pathWithoutQuery(path61);
28217
+ function isGluecharmContentApiPath(path62) {
28218
+ const p = pathWithoutQuery(path62);
28132
28219
  return p.startsWith("/api/content/") || p.startsWith("/api/batch/content/");
28133
28220
  }
28134
28221
  function gluecharmContentHeaders(method) {
@@ -28166,7 +28253,7 @@ async function fetchWithTimeout2(url, init, fetchImpl, timeoutMs, externalSignal
28166
28253
  }
28167
28254
  function createAuthenticatedRequestJson(deps) {
28168
28255
  const fetchImpl = deps.fetchImpl ?? fetch;
28169
- async function requestJson(path61, options = {}) {
28256
+ async function requestJson(path62, options = {}) {
28170
28257
  const base = deps.getApiBaseUrl();
28171
28258
  if (!base) {
28172
28259
  const err = { status: 0, message: "easyspecs.apiBaseUrl is not configured." };
@@ -28174,7 +28261,7 @@ function createAuthenticatedRequestJson(deps) {
28174
28261
  }
28175
28262
  const method = options.method ?? "GET";
28176
28263
  const headers = { ...options.headers };
28177
- if (isGluecharmContentApiPath(path61)) {
28264
+ if (isGluecharmContentApiPath(path62)) {
28178
28265
  Object.assign(headers, gluecharmContentHeaders(method));
28179
28266
  } else {
28180
28267
  if (!headers.Accept) {
@@ -28188,7 +28275,7 @@ function createAuthenticatedRequestJson(deps) {
28188
28275
  if (options.withAuth !== false && access) {
28189
28276
  headers.Authorization = `Bearer ${access}`;
28190
28277
  }
28191
- const url = `${base}${path61}`;
28278
+ const url = `${base}${path62}`;
28192
28279
  const timeoutMs = options.timeoutMs ?? API_TIMEOUT_MS;
28193
28280
  const response = await fetchWithTimeout2(
28194
28281
  url,
@@ -28209,7 +28296,7 @@ function createAuthenticatedRequestJson(deps) {
28209
28296
  if (shouldRetryUnauthorized) {
28210
28297
  const refreshed = await deps.refreshSession();
28211
28298
  if (refreshed) {
28212
- return requestJson(path61, { ...options, retryOnUnauthorized: false });
28299
+ return requestJson(path62, { ...options, retryOnUnauthorized: false });
28213
28300
  }
28214
28301
  }
28215
28302
  const fallback = payload == null ? `${response.statusText || "HTTP error"} (response body empty or not JSON)` : "Request failed.";
@@ -28221,13 +28308,13 @@ function createAuthenticatedRequestJson(deps) {
28221
28308
  // src/cli/cliSession.ts
28222
28309
  var fs61 = __toESM(require("node:fs"));
28223
28310
  var os7 = __toESM(require("node:os"));
28224
- var path57 = __toESM(require("node:path"));
28311
+ var path58 = __toESM(require("node:path"));
28225
28312
  function defaultSessionPath() {
28226
- return path57.join(os7.homedir(), ".easyspecs", "cli-session.json");
28313
+ return path58.join(os7.homedir(), ".easyspecs", "cli-session.json");
28227
28314
  }
28228
28315
  var configSessionPath;
28229
28316
  function setCliSessionPathFromConfig(absPath) {
28230
- configSessionPath = absPath?.trim() ? path57.resolve(absPath) : void 0;
28317
+ configSessionPath = absPath?.trim() ? path58.resolve(absPath) : void 0;
28231
28318
  }
28232
28319
  function applyCliSessionPathFromRepoConfig(repoRoot, cfg) {
28233
28320
  const raw = cfg.easyspecs?.cliSessionPath?.trim();
@@ -28235,7 +28322,7 @@ function applyCliSessionPathFromRepoConfig(repoRoot, cfg) {
28235
28322
  setCliSessionPathFromConfig(void 0);
28236
28323
  return;
28237
28324
  }
28238
- const abs = path57.isAbsolute(raw) ? raw : path57.join(repoRoot, raw);
28325
+ const abs = path58.isAbsolute(raw) ? raw : path58.join(repoRoot, raw);
28239
28326
  setCliSessionPathFromConfig(abs);
28240
28327
  }
28241
28328
  function normalizeCliSessionPathForConfig(repoRoot, raw) {
@@ -28243,15 +28330,15 @@ function normalizeCliSessionPathForConfig(repoRoot, raw) {
28243
28330
  if (!t) {
28244
28331
  return "";
28245
28332
  }
28246
- const resolvedRepo = path57.resolve(repoRoot);
28247
- const abs = path57.isAbsolute(t) ? path57.normalize(t) : path57.resolve(resolvedRepo, t);
28248
- const rel = path57.relative(resolvedRepo, abs);
28333
+ const resolvedRepo = path58.resolve(repoRoot);
28334
+ const abs = path58.isAbsolute(t) ? path58.normalize(t) : path58.resolve(resolvedRepo, t);
28335
+ const rel = path58.relative(resolvedRepo, abs);
28249
28336
  if (rel === "") {
28250
28337
  return abs;
28251
28338
  }
28252
- const underRepo = !rel.startsWith("..") && !path57.isAbsolute(rel);
28339
+ const underRepo = !rel.startsWith("..") && !path58.isAbsolute(rel);
28253
28340
  if (underRepo) {
28254
- return rel.split(path57.sep).join("/");
28341
+ return rel.split(path58.sep).join("/");
28255
28342
  }
28256
28343
  return abs;
28257
28344
  }
@@ -28281,7 +28368,7 @@ function readCliSession() {
28281
28368
  }
28282
28369
  function writeCliSession(s) {
28283
28370
  const p = effectiveCliSessionPath();
28284
- fs61.mkdirSync(path57.dirname(p), { recursive: true });
28371
+ fs61.mkdirSync(path58.dirname(p), { recursive: true });
28285
28372
  fs61.writeFileSync(p, `${JSON.stringify(s, null, 2)}
28286
28373
  `, "utf8");
28287
28374
  }
@@ -28295,7 +28382,7 @@ function clearCliSession() {
28295
28382
 
28296
28383
  // src/analysis/acePendingTraces.ts
28297
28384
  var fs62 = __toESM(require("fs"));
28298
- var path58 = __toESM(require("path"));
28385
+ var path59 = __toESM(require("path"));
28299
28386
  function normalizeAceTraceRelativePath(rel) {
28300
28387
  return rel.split(/[/\\]/).join("/");
28301
28388
  }
@@ -28345,7 +28432,7 @@ function listPendingAceTraceFiles(contextDir2, worktreeRoot) {
28345
28432
  const allAbs = listAceTraceFiles(contextDir2);
28346
28433
  const pending = [];
28347
28434
  for (const abs of allAbs) {
28348
- const rel = normalizeAceTraceRelativePath(path58.relative(contextDir2, abs));
28435
+ const rel = normalizeAceTraceRelativePath(path59.relative(contextDir2, abs));
28349
28436
  const v = validateAceJsonFile(abs, traceSchema);
28350
28437
  if (!v.ok) {
28351
28438
  continue;
@@ -28360,7 +28447,7 @@ function listPendingAceTraceFiles(contextDir2, worktreeRoot) {
28360
28447
  }
28361
28448
 
28362
28449
  // src/analysis/aceAutoLearnPool.ts
28363
- var path59 = __toESM(require("path"));
28450
+ var path60 = __toESM(require("path"));
28364
28451
  function clampConcurrency2(n) {
28365
28452
  if (!Number.isFinite(n)) {
28366
28453
  return DEFAULT_MAX_CONCURRENT_AI;
@@ -28395,8 +28482,8 @@ async function runAceAutoLearnPool(p) {
28395
28482
  };
28396
28483
  const currentCap = () => Math.min(staticMaxC, adaptiveMax);
28397
28484
  let wake;
28398
- const waitTurn = () => new Promise((resolve23) => {
28399
- wake = resolve23;
28485
+ const waitTurn = () => new Promise((resolve24) => {
28486
+ wake = resolve24;
28400
28487
  });
28401
28488
  const pump = () => {
28402
28489
  wake?.();
@@ -28418,7 +28505,7 @@ async function runAceAutoLearnPool(p) {
28418
28505
  poolAbortListenerRegistered = true;
28419
28506
  }
28420
28507
  }
28421
- const traceRel = (abs) => path59.relative(contextDir2, abs).split(path59.sep).join("/");
28508
+ const traceRel = (abs) => path60.relative(contextDir2, abs).split(path60.sep).join("/");
28422
28509
  const runOne = async (traceAbs) => {
28423
28510
  if (abortSignal?.aborted) {
28424
28511
  active -= 1;
@@ -28949,7 +29036,7 @@ function formatCliStderrLine(line, useAnsi) {
28949
29036
  }
28950
29037
 
28951
29038
  // src/cli/main.ts
28952
- var PKG_VERSION = "0.2.1";
29039
+ var PKG_VERSION = "0.3.0";
28953
29040
  function isNonEmptyFactoryFailureArray(x) {
28954
29041
  if (!Array.isArray(x) || x.length === 0) {
28955
29042
  return false;
@@ -29091,23 +29178,23 @@ function resolveAnalysisRoot(repoRoot, rootKind, worktreePath) {
29091
29178
  return repoRoot;
29092
29179
  }
29093
29180
  const wt = worktreePath?.trim();
29094
- if (wt && fs63.existsSync(path60.join(wt, ".git"))) {
29095
- return path60.resolve(wt);
29181
+ if (wt && fs63.existsSync(path61.join(wt, ".git"))) {
29182
+ return path61.resolve(wt);
29096
29183
  }
29097
29184
  throw new Error("worktree mode requires --worktree <path> to an existing analysis checkout.");
29098
29185
  }
29099
29186
  function resolveAdHocCheckoutRoot(_repoRoot, storage, worktreeFlag) {
29100
29187
  const w = worktreeFlag?.trim();
29101
29188
  if (w) {
29102
- const abs = path60.resolve(w);
29103
- if (fs63.existsSync(path60.join(abs, ".git"))) {
29189
+ const abs = path61.resolve(w);
29190
+ if (fs63.existsSync(path61.join(abs, ".git"))) {
29104
29191
  return abs;
29105
29192
  }
29106
29193
  throw new Error(`Invalid --worktree (not a git checkout): ${abs}`);
29107
29194
  }
29108
29195
  const snap = readAnalysisWorkspaceSnapshot(storage);
29109
29196
  const p = snap?.adHocWorktreePath?.trim();
29110
- if (p && fs63.existsSync(path60.join(p, ".git"))) {
29197
+ if (p && fs63.existsSync(path61.join(p, ".git"))) {
29111
29198
  return p;
29112
29199
  }
29113
29200
  throw new Error("No analysis checkout: run `easyspecs-cli run synthesis` first or pass `--worktree <path>`.");
@@ -29134,7 +29221,7 @@ async function runResumeRemediationPool(storage, repoRoot, analysisRoot, merged,
29134
29221
  requireOpenCode(merged, flags);
29135
29222
  const agentsDir = resolveOpenCodeAgentsDir(repoRoot, repoConfig);
29136
29223
  assertAgentsDirExists(agentsDir);
29137
- const ctxDir = path60.join(analysisRoot, ".gluecharm", "context");
29224
+ const ctxDir = path61.join(analysisRoot, ".gluecharm", "context");
29138
29225
  const snap = readArtefactRunSnapshot(storage);
29139
29226
  const rows = listMissingWorkstations(ctxDir, analysisRoot, snap);
29140
29227
  if (rows.length === 0) {
@@ -29152,7 +29239,7 @@ async function runResumeRemediationPool(storage, repoRoot, analysisRoot, merged,
29152
29239
  storageContext: storage,
29153
29240
  repositoryRoot: repoRoot,
29154
29241
  worktreeRoot: analysisRoot,
29155
- workspaceLabel: path60.basename(analysisRoot),
29242
+ workspaceLabel: path61.basename(analysisRoot),
29156
29243
  oc,
29157
29244
  log: (line) => logErr(flags, line),
29158
29245
  abortSignal: void 0,
@@ -29329,17 +29416,17 @@ async function main() {
29329
29416
  { easyspecs: { defaultGitRemoteUrl: url } },
29330
29417
  { warnMigration: (m) => logErr(flags, `[EasySpecs] ${m}`) }
29331
29418
  );
29332
- const path61 = easyspecsConfigPath(repoRoot);
29419
+ const path62 = easyspecsConfigPath(repoRoot);
29333
29420
  if (flags.json) {
29334
29421
  printJsonLine({
29335
29422
  command: "config set-git-remote",
29336
29423
  durationMs: Date.now() - t0,
29337
29424
  ok: true,
29338
- path: path61,
29425
+ path: path62,
29339
29426
  defaultGitRemoteUrl: cfg.easyspecs?.defaultGitRemoteUrl ?? ""
29340
29427
  });
29341
29428
  } else {
29342
- console.log(`Updated ${path61} \u2014 easyspecs.defaultGitRemoteUrl`);
29429
+ console.log(`Updated ${path62} \u2014 easyspecs.defaultGitRemoteUrl`);
29343
29430
  }
29344
29431
  process.exit(ExitCode.ok);
29345
29432
  } catch (e) {
@@ -29372,7 +29459,7 @@ async function main() {
29372
29459
  applyCliSessionPathFromRepoConfig(repoRoot, repoConfig);
29373
29460
  if (flags.sessionPath?.trim()) {
29374
29461
  const sp = flags.sessionPath.trim();
29375
- const abs = path60.isAbsolute(sp) ? path60.normalize(sp) : path60.resolve(repoRoot, sp);
29462
+ const abs = path61.isAbsolute(sp) ? path61.normalize(sp) : path61.resolve(repoRoot, sp);
29376
29463
  setCliSessionPathFromConfig(abs);
29377
29464
  }
29378
29465
  const apiResolved = initApiBaseUrlForCli(repoRoot, flags, repoConfig);
@@ -29613,7 +29700,7 @@ async function main() {
29613
29700
  const result = await runSynthesisPipeline(
29614
29701
  storage,
29615
29702
  repoRoot,
29616
- path60.basename(repoRoot),
29703
+ path61.basename(repoRoot),
29617
29704
  agentsDir,
29618
29705
  {
29619
29706
  ...merged.pipelineOpenCode
@@ -29668,7 +29755,7 @@ async function main() {
29668
29755
  if (sub === "reference-coverage") {
29669
29756
  const rootAbs = resolveAnalysisRoot(repoRoot, rootKind, worktree);
29670
29757
  requireMinimalGluecharmLayoutAt(rootAbs);
29671
- const contextDir2 = path60.join(rootAbs, ".gluecharm", "context");
29758
+ const contextDir2 = path61.join(rootAbs, ".gluecharm", "context");
29672
29759
  const res = runCoveragePipeline({
29673
29760
  repositoryRootAbs: rootAbs,
29674
29761
  contextDirAbs: contextDir2,
@@ -29691,7 +29778,7 @@ async function main() {
29691
29778
  if (sub === "coordination-duplicates") {
29692
29779
  const rootAbs = resolveAnalysisRoot(repoRoot, rootKind, worktree);
29693
29780
  requireMinimalGluecharmLayoutAt(rootAbs);
29694
- const contextDir2 = path60.join(rootAbs, ".gluecharm", "context");
29781
+ const contextDir2 = path61.join(rootAbs, ".gluecharm", "context");
29695
29782
  const res = runCoordinationDuplicatesDiagnosis({
29696
29783
  contextDirAbsolute: contextDir2,
29697
29784
  sourceRoot: rootKind === "worktree" ? "worktree" : "workspace"
@@ -29727,7 +29814,7 @@ async function main() {
29727
29814
  if (sub === "missing-artefacts") {
29728
29815
  const rootAbs = resolveAnalysisRoot(repoRoot, rootKind, worktree);
29729
29816
  requireMinimalGluecharmLayoutAt(rootAbs);
29730
- const ctxDir = path60.join(rootAbs, ".gluecharm", "context");
29817
+ const ctxDir = path61.join(rootAbs, ".gluecharm", "context");
29731
29818
  const storage = createFileBackedWorkspaceState(repoRoot);
29732
29819
  const snap = readArtefactRunSnapshot(storage);
29733
29820
  const rows = listMissingWorkstations(ctxDir, rootAbs, snap);
@@ -29777,7 +29864,7 @@ async function main() {
29777
29864
  });
29778
29865
  const bad = poolRes.cancelled || poolRes.failures > 0;
29779
29866
  if (!bad) {
29780
- const ctxDir = path60.join(analysisRoot, ".gluecharm", "context");
29867
+ const ctxDir = path61.join(analysisRoot, ".gluecharm", "context");
29781
29868
  const lg = runLinkMappingPipeline(ctxDir, { log: (line) => logErr(flags, line) });
29782
29869
  if (!lg.ok) {
29783
29870
  finish(OsExit.diagnoseZeroReferenceLinkMapping, {
@@ -29807,7 +29894,7 @@ async function main() {
29807
29894
  const worktree = wtExplicit ?? wtFromRoot;
29808
29895
  const rootAbs = resolveAnalysisRoot(repoRoot, rootKind, worktree);
29809
29896
  requireMinimalGluecharmLayoutAt(rootAbs);
29810
- const contextDir2 = path60.join(rootAbs, ".gluecharm", "context");
29897
+ const contextDir2 = path61.join(rootAbs, ".gluecharm", "context");
29811
29898
  const res = runLinkMappingPipeline(contextDir2, {
29812
29899
  log: (line) => logErr(flags, line)
29813
29900
  });
@@ -29985,8 +30072,8 @@ async function main() {
29985
30072
  const snap = readAnalysisWorkspaceSnapshot(storage);
29986
30073
  const wt = snap?.adHocWorktreePath?.trim();
29987
30074
  if (wt) {
29988
- const sourceCtx = path60.join(wt, ".gluecharm", "context");
29989
- if (path60.resolve(wt) === path60.resolve(repoRoot)) {
30075
+ const sourceCtx = path61.join(wt, ".gluecharm", "context");
30076
+ if (path61.resolve(wt) === path61.resolve(repoRoot)) {
29990
30077
  logErr(
29991
30078
  flags,
29992
30079
  "[pipeline:analysis] promote skipped (in-place: analysis checkout is the repository root)"
@@ -30088,10 +30175,10 @@ async function main() {
30088
30175
  finish(ExitCode.usage, { ok: false, error: `unknown download context flag: ${a}` });
30089
30176
  }
30090
30177
  requireMinimalGluecharmLayoutAt(repoRoot);
30091
- const ctxDir = path60.resolve(path60.join(repoRoot, ".gluecharm", "context"));
30092
- const gluecharmParent = path60.dirname(ctxDir);
30093
- if (path60.basename(gluecharmParent) === ".gluecharm" && path60.basename(ctxDir) === "context") {
30094
- requireMinimalGluecharmLayoutAt(path60.dirname(gluecharmParent));
30178
+ const ctxDir = path61.resolve(path61.join(repoRoot, ".gluecharm", "context"));
30179
+ const gluecharmParent = path61.dirname(ctxDir);
30180
+ if (path61.basename(gluecharmParent) === ".gluecharm" && path61.basename(ctxDir) === "context") {
30181
+ requireMinimalGluecharmLayoutAt(path61.dirname(gluecharmParent));
30095
30182
  }
30096
30183
  const appIdRaw = getEasyspecsProjectIdFromRepoConfig(repoConfig)?.trim();
30097
30184
  if (!appIdRaw) {
@@ -30174,16 +30261,16 @@ async function main() {
30174
30261
  }
30175
30262
  const sess = sessRaw;
30176
30263
  requireMinimalGluecharmLayoutAt(repoRoot);
30177
- let ctxDir = path60.join(repoRoot, ".gluecharm", "context");
30264
+ let ctxDir = path61.join(repoRoot, ".gluecharm", "context");
30178
30265
  if (pos[1] === "republish") {
30179
30266
  const fromCfg = repoConfig.easyspecs?.upload?.contextDirectory?.trim();
30180
- const resolvedOverride = fromCfg && fromCfg.length > 0 ? path60.isAbsolute(fromCfg) ? path60.normalize(fromCfg) : path60.resolve(repoRoot, fromCfg) : "";
30181
- if (resolvedOverride && fs63.existsSync(path60.join(resolvedOverride, ".."))) {
30267
+ const resolvedOverride = fromCfg && fromCfg.length > 0 ? path61.isAbsolute(fromCfg) ? path61.normalize(fromCfg) : path61.resolve(repoRoot, fromCfg) : "";
30268
+ if (resolvedOverride && fs63.existsSync(path61.join(resolvedOverride, ".."))) {
30182
30269
  ctxDir = resolvedOverride;
30183
30270
  } else {
30184
30271
  const storage = createFileBackedWorkspaceState(repoRoot);
30185
30272
  const snap = readAnalysisWorkspaceSnapshot(storage);
30186
- const wt = snap?.adHocWorktreePath && fs63.existsSync(path60.join(snap.adHocWorktreePath, ".gluecharm", "context")) ? path60.join(snap.adHocWorktreePath, ".gluecharm", "context") : "";
30273
+ const wt = snap?.adHocWorktreePath && fs63.existsSync(path61.join(snap.adHocWorktreePath, ".gluecharm", "context")) ? path61.join(snap.adHocWorktreePath, ".gluecharm", "context") : "";
30187
30274
  if (!wt) {
30188
30275
  finish(ExitCode.misconfiguration, {
30189
30276
  ok: false,
@@ -30193,10 +30280,10 @@ async function main() {
30193
30280
  ctxDir = wt;
30194
30281
  }
30195
30282
  }
30196
- const ctxResolved = path60.resolve(ctxDir);
30197
- const gluecharmParent = path60.dirname(ctxResolved);
30198
- if (path60.basename(gluecharmParent) === ".gluecharm" && path60.basename(ctxResolved) === "context") {
30199
- requireMinimalGluecharmLayoutAt(path60.dirname(gluecharmParent));
30283
+ const ctxResolved = path61.resolve(ctxDir);
30284
+ const gluecharmParent = path61.dirname(ctxResolved);
30285
+ if (path61.basename(gluecharmParent) === ".gluecharm" && path61.basename(ctxResolved) === "context") {
30286
+ requireMinimalGluecharmLayoutAt(path61.dirname(gluecharmParent));
30200
30287
  }
30201
30288
  const appIdRaw = getEasyspecsProjectIdFromRepoConfig(repoConfig)?.trim();
30202
30289
  if (!appIdRaw) {
@@ -30300,7 +30387,7 @@ async function main() {
30300
30387
  finish(failed ? ExitCode.upload : ExitCode.ok, primary);
30301
30388
  }
30302
30389
  if (pos[0] === "ace" && pos[1] === "clear") {
30303
- const learnings = path60.join(repoRoot, ".gluecharm", "context", "learnings");
30390
+ const learnings = path61.join(repoRoot, ".gluecharm", "context", "learnings");
30304
30391
  if (!fs63.existsSync(learnings)) {
30305
30392
  finish(ExitCode.ok, { ok: true, message: "nothing to clear" });
30306
30393
  }
@@ -30310,8 +30397,8 @@ async function main() {
30310
30397
  if (pos[0] === "ace" && pos[1] === "learn") {
30311
30398
  requireOpenCode(merged, flags);
30312
30399
  const { worktree } = parseWorktreeFlag(pos.slice(2));
30313
- const root = worktree && fs63.existsSync(path60.join(worktree, ".opencode", "schemas", "ace")) ? worktree : repoRoot;
30314
- const contextDir2 = path60.join(root, ".gluecharm", "context");
30400
+ const root = worktree && fs63.existsSync(path61.join(worktree, ".opencode", "schemas", "ace")) ? worktree : repoRoot;
30401
+ const contextDir2 = path61.join(root, ".gluecharm", "context");
30315
30402
  const traces = listAceTraceFiles(contextDir2);
30316
30403
  if (traces.length === 0) {
30317
30404
  finish(ExitCode.ok, { ok: true, message: "no traces", traceCount: 0 });
@@ -30335,8 +30422,8 @@ async function main() {
30335
30422
  if (pos[0] === "ace" && pos[1] === "auto-learn") {
30336
30423
  requireOpenCode(merged, flags);
30337
30424
  const { worktree } = parseWorktreeFlag(pos.slice(2));
30338
- const root = worktree && fs63.existsSync(path60.join(worktree, ".git")) ? worktree : repoRoot;
30339
- const contextDir2 = path60.join(root, ".gluecharm", "context");
30425
+ const root = worktree && fs63.existsSync(path61.join(worktree, ".git")) ? worktree : repoRoot;
30426
+ const contextDir2 = path61.join(root, ".gluecharm", "context");
30340
30427
  const pending = listPendingAceTraceFiles(contextDir2, root);
30341
30428
  if (pending.length === 0) {
30342
30429
  finish(ExitCode.ok, { ok: true, pending: 0 });