@mrciphersmith/keryx 0.3.31 → 0.3.33

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.
Files changed (4) hide show
  1. package/README.md +4 -1
  2. package/dist/cli.js +1911 -1658
  3. package/dist/core.js +850 -702
  4. package/package.json +1 -1
package/dist/core.js CHANGED
@@ -3390,16 +3390,16 @@ var init_exfil = __esm(() => {
3390
3390
  // src/lib/contained-path.ts
3391
3391
  import { lstat as lstat2, realpath } from "fs/promises";
3392
3392
  import { existsSync, lstatSync, realpathSync } from "fs";
3393
- import path16 from "path";
3393
+ import path17 from "path";
3394
3394
  function resolveProjectRoot(startDir) {
3395
- let current = path16.resolve(startDir);
3395
+ let current = path17.resolve(startDir);
3396
3396
  for (;; ) {
3397
- if (existsSync(path16.join(current, ".metaproject")) || existsSync(path16.join(current, ".git"))) {
3397
+ if (existsSync(path17.join(current, ".metaproject")) || existsSync(path17.join(current, ".git"))) {
3398
3398
  return current;
3399
3399
  }
3400
- const parent = path16.dirname(current);
3400
+ const parent = path17.dirname(current);
3401
3401
  if (parent === current) {
3402
- return path16.resolve(startDir);
3402
+ return path17.resolve(startDir);
3403
3403
  }
3404
3404
  current = parent;
3405
3405
  }
@@ -3408,11 +3408,11 @@ function isInside(root, candidate) {
3408
3408
  if (candidate === root) {
3409
3409
  return true;
3410
3410
  }
3411
- const relative = path16.relative(root, candidate);
3412
- if (relative.length === 0 || path16.isAbsolute(relative)) {
3411
+ const relative = path17.relative(root, candidate);
3412
+ if (relative.length === 0 || path17.isAbsolute(relative)) {
3413
3413
  return false;
3414
3414
  }
3415
- return relative !== ".." && !relative.startsWith(`..${path16.sep}`);
3415
+ return relative !== ".." && !relative.startsWith(`..${path17.sep}`);
3416
3416
  }
3417
3417
  async function resolveContainedPath(projectRoot, candidate) {
3418
3418
  try {
@@ -3423,8 +3423,8 @@ async function resolveContainedPath(projectRoot, candidate) {
3423
3423
  } catch {
3424
3424
  return { ok: false, reason: "not-found", message: `no such file or directory: ${candidate}` };
3425
3425
  }
3426
- const rootReal = await realpath(projectRoot).catch(() => path16.resolve(projectRoot));
3427
- const absolute = path16.resolve(rootReal, candidate);
3426
+ const rootReal = await realpath(projectRoot).catch(() => path17.resolve(projectRoot));
3427
+ const absolute = path17.resolve(rootReal, candidate);
3428
3428
  const real = await realpath(absolute).catch(() => null);
3429
3429
  const effective = real ?? absolute;
3430
3430
  if (!isInside(rootReal, effective)) {
@@ -3764,16 +3764,16 @@ var init_schemas = __esm(() => {
3764
3764
  });
3765
3765
 
3766
3766
  // src/security/config.ts
3767
- import path17 from "path";
3767
+ import path18 from "path";
3768
3768
  import { createHash as createHash3 } from "crypto";
3769
3769
  function securityProjectRoot(cwd) {
3770
3770
  return resolveProjectRoot(cwd);
3771
3771
  }
3772
3772
  function securityDataRoot(cwd) {
3773
- return path17.join(securityProjectRoot(cwd), ".metaproject", "data", "security");
3773
+ return path18.join(securityProjectRoot(cwd), ".metaproject", "data", "security");
3774
3774
  }
3775
3775
  function configPath(cwd) {
3776
- return path17.join(securityProjectRoot(cwd), ".metaproject", "security.config.json");
3776
+ return path18.join(securityProjectRoot(cwd), ".metaproject", "security.config.json");
3777
3777
  }
3778
3778
  function mergePolicy(base, override) {
3779
3779
  const merged = {
@@ -4381,7 +4381,7 @@ var init_entropy_gate = __esm(() => {
4381
4381
  });
4382
4382
 
4383
4383
  // src/security/redact.ts
4384
- import path18 from "path";
4384
+ import path19 from "path";
4385
4385
  import { createHmac, randomBytes as randomBytes2 } from "crypto";
4386
4386
  import { mkdir as mkdir4, readFile as readFile11, writeFile as writeFile3, chmod as chmod2 } from "fs/promises";
4387
4387
  function maskFor(match) {
@@ -4461,11 +4461,11 @@ function redactSensitiveText(text) {
4461
4461
  return applyRedaction(text, matches);
4462
4462
  }
4463
4463
  function keyDir(cwd) {
4464
- return path18.join(securityDataRoot(cwd), "raw");
4464
+ return path19.join(securityDataRoot(cwd), "raw");
4465
4465
  }
4466
4466
  async function getHmacKey(cwd) {
4467
4467
  const dir = keyDir(cwd);
4468
- const file = path18.join(dir, KEY_FILE);
4468
+ const file = path19.join(dir, KEY_FILE);
4469
4469
  if (await pathExists(file)) {
4470
4470
  const existing = (await readFile11(file, "utf8")).trim();
4471
4471
  if (existing.length > 0) {
@@ -5033,9 +5033,9 @@ var init_output_validation = __esm(() => {
5033
5033
  });
5034
5034
 
5035
5035
  // src/assets/lock.ts
5036
- import path19 from "path";
5036
+ import path20 from "path";
5037
5037
  function lockPath(cwd) {
5038
- return path19.join(cwd, ".metaproject", "assets.lock.json");
5038
+ return path20.join(cwd, ".metaproject", "assets.lock.json");
5039
5039
  }
5040
5040
  function normalizeLock(parsed) {
5041
5041
  const assets = {};
@@ -5090,16 +5090,16 @@ var init_lock = __esm(() => {
5090
5090
  import { createHash as createHash4 } from "crypto";
5091
5091
  import { readFile as readFile12 } from "fs/promises";
5092
5092
  import os2 from "os";
5093
- import path20 from "path";
5093
+ import path21 from "path";
5094
5094
  function assetCacheDir() {
5095
5095
  const override = process.env.KERYX_ASSET_CACHE;
5096
5096
  if (override && override.length > 0) {
5097
5097
  return override;
5098
5098
  }
5099
- return path20.join(os2.homedir(), ".cache", "keryx", "assets");
5099
+ return path21.join(os2.homedir(), ".cache", "keryx", "assets");
5100
5100
  }
5101
5101
  function cacheAssetPath(id) {
5102
- return path20.join(assetCacheDir(), id);
5102
+ return path21.join(assetCacheDir(), id);
5103
5103
  }
5104
5104
  async function sha256File(file) {
5105
5105
  const buffer = await readFile12(file);
@@ -5151,9 +5151,9 @@ var init_warn_once = __esm(() => {
5151
5151
  });
5152
5152
 
5153
5153
  // src/capability/seam.ts
5154
- import path21 from "path";
5154
+ import path22 from "path";
5155
5155
  async function isCapabilityEnabled(cwd, id) {
5156
- const manifestPath = path21.join(cwd, ".metaproject", "metaproject.json");
5156
+ const manifestPath = path22.join(cwd, ".metaproject", "metaproject.json");
5157
5157
  if (!await pathExists(manifestPath)) {
5158
5158
  return false;
5159
5159
  }
@@ -5792,7 +5792,7 @@ var init_resolve = __esm(() => {
5792
5792
  });
5793
5793
 
5794
5794
  // src/security/report.ts
5795
- import path22 from "path";
5795
+ import path23 from "path";
5796
5796
  import { mkdir as mkdir5, writeFile as writeFile4 } from "fs/promises";
5797
5797
  function tally(values) {
5798
5798
  const counts = {};
@@ -5912,26 +5912,26 @@ function renderFindings(findings) {
5912
5912
  `);
5913
5913
  }
5914
5914
  function artifactsDir(cwd) {
5915
- return path22.join(securityDataRoot(cwd), "artifacts");
5915
+ return path23.join(securityDataRoot(cwd), "artifacts");
5916
5916
  }
5917
5917
  async function writeSecurityArtifacts(cwd, report, config) {
5918
5918
  const dir = artifactsDir(cwd);
5919
5919
  await mkdir5(dir, { recursive: true });
5920
5920
  const committable = toCommittableReport(report);
5921
- const markdown = path22.join(dir, "latest.md");
5922
- const json = path22.join(dir, "latest.json");
5921
+ const markdown = path23.join(dir, "latest.md");
5922
+ const json = path23.join(dir, "latest.json");
5923
5923
  await writeFile4(markdown, renderReportMarkdown(committable), "utf8");
5924
5924
  await writeFile4(json, `${JSON.stringify(committable, null, 2)}
5925
5925
  `, "utf8");
5926
5926
  if (config.storeHashes) {
5927
- const rawDir = path22.join(securityDataRoot(cwd), "raw");
5927
+ const rawDir = path23.join(securityDataRoot(cwd), "raw");
5928
5928
  await mkdir5(rawDir, { recursive: true });
5929
- await writeFile4(path22.join(rawDir, "report.local.json"), `${JSON.stringify(report, null, 2)}
5929
+ await writeFile4(path23.join(rawDir, "report.local.json"), `${JSON.stringify(report, null, 2)}
5930
5930
  `, "utf8");
5931
5931
  }
5932
5932
  return {
5933
- markdownPath: path22.relative(cwd, markdown),
5934
- jsonPath: path22.relative(cwd, json)
5933
+ markdownPath: path23.relative(cwd, markdown),
5934
+ jsonPath: path23.relative(cwd, json)
5935
5935
  };
5936
5936
  }
5937
5937
  var SCHEMA_VERSION = 1;
@@ -5940,13 +5940,13 @@ var init_report2 = __esm(() => {
5940
5940
  });
5941
5941
 
5942
5942
  // src/security/incidents.ts
5943
- import path23 from "path";
5943
+ import path24 from "path";
5944
5944
  import { appendFile as appendFile2, mkdir as mkdir6, readFile as readFile13 } from "fs/promises";
5945
5945
  function incidentsDir(cwd) {
5946
- return path23.join(securityDataRoot(cwd), "incidents");
5946
+ return path24.join(securityDataRoot(cwd), "incidents");
5947
5947
  }
5948
5948
  function incidentsFile(cwd) {
5949
- return path23.join(incidentsDir(cwd), "incidents.jsonl");
5949
+ return path24.join(incidentsDir(cwd), "incidents.jsonl");
5950
5950
  }
5951
5951
  async function appendIncident(cwd, entry) {
5952
5952
  const dir = incidentsDir(cwd);
@@ -5965,7 +5965,7 @@ var init_incidents = __esm(() => {
5965
5965
  });
5966
5966
 
5967
5967
  // src/security/self-protect.ts
5968
- import path24 from "path";
5968
+ import path25 from "path";
5969
5969
  import { mkdir as mkdir7, readFile as readFile14, writeFile as writeFile5 } from "fs/promises";
5970
5970
  function currentState(config) {
5971
5971
  const policies = {};
@@ -6024,7 +6024,7 @@ function evaluateSelfProtection(config, previous, now = new Date().toISOString()
6024
6024
  return { warnings, incidents, findings, checksumMatch: checksum.match };
6025
6025
  }
6026
6026
  function stateFile(cwd) {
6027
- return path24.join(securityDataRoot(cwd), "raw", "state.json");
6027
+ return path25.join(securityDataRoot(cwd), "raw", "state.json");
6028
6028
  }
6029
6029
  async function readState(cwd) {
6030
6030
  const file = stateFile(cwd);
@@ -6039,7 +6039,7 @@ async function readState(cwd) {
6039
6039
  }
6040
6040
  async function writeState(cwd, state) {
6041
6041
  const file = stateFile(cwd);
6042
- await mkdir7(path24.dirname(file), { recursive: true });
6042
+ await mkdir7(path25.dirname(file), { recursive: true });
6043
6043
  await writeFile5(file, `${JSON.stringify(state, null, 2)}
6044
6044
  `, "utf8");
6045
6045
  }
@@ -6057,12 +6057,12 @@ var init_self_protect = __esm(() => {
6057
6057
 
6058
6058
  // src/lib/descriptor-read.ts
6059
6059
  import { constants, fstatSync, lstatSync as lstatSync2, statSync } from "fs";
6060
- import path25 from "path";
6060
+ import path26 from "path";
6061
6061
  import { dlopen, FFIType, ptr } from "bun:ffi";
6062
6062
  function readDescriptorChain(workspaceRoot, absolutePath, options = {}) {
6063
- const relativePath = path25.relative(workspaceRoot, absolutePath);
6064
- const components = relativePath.split(path25.sep);
6065
- if (!relativePath || path25.isAbsolute(relativePath) || components.some((component) => !component || component === "." || component === "..")) {
6063
+ const relativePath = path26.relative(workspaceRoot, absolutePath);
6064
+ const components = relativePath.split(path26.sep);
6065
+ if (!relativePath || path26.isAbsolute(relativePath) || components.some((component) => !component || component === "." || component === "..")) {
6066
6066
  throw new DescriptorReadError("invalid-path", "safe source path is not workspace-relative");
6067
6067
  }
6068
6068
  if (options.maxBytes !== undefined && (!Number.isSafeInteger(options.maxBytes) || options.maxBytes < 0)) {
@@ -6185,7 +6185,7 @@ var init_descriptor_read = __esm(() => {
6185
6185
 
6186
6186
  // src/lib/contained-read.ts
6187
6187
  import { lstat as lstat3, realpath as realpath2, stat as stat3 } from "fs/promises";
6188
- import path26 from "path";
6188
+ import path27 from "path";
6189
6189
  async function readContainedFile(ownerRoot, candidatePath, options = {}) {
6190
6190
  if (options.backend === "unsupported") {
6191
6191
  throw new ContainedReadError("CONTAINED_READ_UNAVAILABLE", "safe descriptor source reads are unavailable on this platform");
@@ -6234,8 +6234,8 @@ async function readContainedFile(ownerRoot, candidatePath, options = {}) {
6234
6234
  }
6235
6235
  }
6236
6236
  function isInside2(root, candidate) {
6237
- const relative = path26.relative(root, candidate);
6238
- return relative === "" || !path26.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path26.sep}`);
6237
+ const relative = path27.relative(root, candidate);
6238
+ return relative === "" || !path27.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path27.sep}`);
6239
6239
  }
6240
6240
  function mapDescriptorError(error) {
6241
6241
  if (!(error instanceof DescriptorReadError))
@@ -6260,16 +6260,16 @@ var init_contained_read = __esm(() => {
6260
6260
 
6261
6261
  // src/security/path-scan.ts
6262
6262
  import { readdir as readdir6, realpath as realpath3, stat as stat4 } from "fs/promises";
6263
- import path27 from "path";
6263
+ import path28 from "path";
6264
6264
  function isInside3(root, candidate) {
6265
- const relative = path27.relative(root, candidate);
6266
- return relative === "" || !path27.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path27.sep}`);
6265
+ const relative = path28.relative(root, candidate);
6266
+ return relative === "" || !path28.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path28.sep}`);
6267
6267
  }
6268
6268
  function identityFor(value) {
6269
6269
  return `${String(value.dev)}:${String(value.ino)}`;
6270
6270
  }
6271
6271
  function relativePath(root, candidate) {
6272
- const relative = path27.relative(root, candidate);
6272
+ const relative = path28.relative(root, candidate);
6273
6273
  return relative === "" ? "." : relative;
6274
6274
  }
6275
6275
  function safeReason(error) {
@@ -6298,7 +6298,7 @@ async function secretBearingFilesIn(dirAbsolute, remainingDepth) {
6298
6298
  }
6299
6299
  const matches = [];
6300
6300
  for (const entry of entries) {
6301
- const entryPath = path27.join(dirAbsolute, entry);
6301
+ const entryPath = path28.join(dirAbsolute, entry);
6302
6302
  let entryStat;
6303
6303
  try {
6304
6304
  entryStat = await stat4(entryPath);
@@ -6362,14 +6362,14 @@ async function scanContainedPath(input) {
6362
6362
  throw new Error("security scan target is outside the project root");
6363
6363
  }
6364
6364
  const exclusions = (input.exclusions ?? []).map((entry) => {
6365
- const absolute = path27.resolve(ownerRoot, entry);
6365
+ const absolute = path28.resolve(ownerRoot, entry);
6366
6366
  return isInside3(ownerRoot, absolute) ? absolute : null;
6367
6367
  }).filter((entry) => entry !== null);
6368
6368
  const scope = {
6369
6369
  path: relativePath(ownerRoot, targetReal),
6370
6370
  recursive: input.recursive ?? true,
6371
6371
  exclusions: (input.exclusions ?? []).map((entry) => {
6372
- const absolute = path27.resolve(ownerRoot, entry);
6372
+ const absolute = path28.resolve(ownerRoot, entry);
6373
6373
  return isInside3(ownerRoot, absolute) ? relativePath(ownerRoot, absolute) : "[external exclusion omitted]";
6374
6374
  }),
6375
6375
  limits
@@ -6390,15 +6390,15 @@ async function scanContainedPath(input) {
6390
6390
  if (!coverage.reasons.includes(reason))
6391
6391
  coverage.reasons.push(reason);
6392
6392
  };
6393
- const excluded = (candidate) => exclusions.some((entry) => candidate === entry || candidate.startsWith(`${entry}${path27.sep}`));
6393
+ const excluded = (candidate) => exclusions.some((entry) => candidate === entry || candidate.startsWith(`${entry}${path28.sep}`));
6394
6394
  const visit = async (candidate, depth) => {
6395
6395
  if (stoppedByLimit)
6396
6396
  return;
6397
6397
  const displayPath = relativePath(ownerRoot, candidate);
6398
6398
  if (respectIgnoreRules) {
6399
- const normalized = displayPath.split(path27.sep).join("/");
6399
+ const normalized = displayPath.split(path28.sep).join("/");
6400
6400
  if (isIgnoredPath(ignoredPaths, normalized)) {
6401
- const basename = path27.basename(displayPath);
6401
+ const basename = path28.basename(displayPath);
6402
6402
  const inHardcodedIgnore = ALWAYS_IGNORED_RELATIVE_DIRS.some((dir) => normalized === dir || normalized.startsWith(`${dir}/`));
6403
6403
  if (!inHardcodedIgnore && looksSecretBearingByName(basename)) {} else {
6404
6404
  if (!inHardcodedIgnore) {
@@ -6480,7 +6480,7 @@ async function scanContainedPath(input) {
6480
6480
  return;
6481
6481
  }
6482
6482
  for (const entry of entries) {
6483
- await visit(path27.join(canonical, entry), depth + 1);
6483
+ await visit(path28.join(canonical, entry), depth + 1);
6484
6484
  if (stoppedByLimit)
6485
6485
  break;
6486
6486
  }
@@ -6555,7 +6555,7 @@ var init_path_scan = __esm(() => {
6555
6555
 
6556
6556
  // src/security/read-source.ts
6557
6557
  import { realpath as realpath4, stat as stat5 } from "fs/promises";
6558
- import path28 from "path";
6558
+ import path29 from "path";
6559
6559
  async function sourceForFileRead(cwd, absolutePath) {
6560
6560
  const projectRoot = resolveProjectRoot(cwd);
6561
6561
  const contained = await resolveContainedPath(projectRoot, absolutePath);
@@ -6563,8 +6563,8 @@ async function sourceForFileRead(cwd, absolutePath) {
6563
6563
  return "untrusted-external";
6564
6564
  }
6565
6565
  const projectRootReal = await realpath4(projectRoot).catch(() => projectRoot);
6566
- const relativePath = path28.relative(projectRootReal, contained.path);
6567
- if (relativePath.length === 0 || path28.isAbsolute(relativePath)) {
6566
+ const relativePath = path29.relative(projectRootReal, contained.path);
6567
+ if (relativePath.length === 0 || path29.isAbsolute(relativePath)) {
6568
6568
  return "untrusted-external";
6569
6569
  }
6570
6570
  const fileStat = await stat5(contained.path).catch(() => null);
@@ -6931,9 +6931,9 @@ var SUBSYSTEM_INSTRUCTIONS = "instructions", SUBSYSTEM_ACP_PERMISSION = "acp-per
6931
6931
 
6932
6932
  // src/lib/symlink-safety.ts
6933
6933
  import { lstat as lstat4, realpath as realpath5 } from "fs/promises";
6934
- import path29 from "path";
6934
+ import path30 from "path";
6935
6935
  async function refuseEscapingSymlink(root, relativePath) {
6936
- const rootResolved = path29.resolve(root);
6936
+ const rootResolved = path30.resolve(root);
6937
6937
  let rootReal;
6938
6938
  try {
6939
6939
  rootReal = await realpath5(rootResolved);
@@ -6943,7 +6943,7 @@ async function refuseEscapingSymlink(root, relativePath) {
6943
6943
  const segments = relativePath.split("/").filter((s) => s.length > 0);
6944
6944
  let current = rootResolved;
6945
6945
  for (const segment of segments) {
6946
- current = path29.join(current, segment);
6946
+ current = path30.join(current, segment);
6947
6947
  let stats;
6948
6948
  try {
6949
6949
  stats = await lstat4(current);
@@ -6956,21 +6956,21 @@ async function refuseEscapingSymlink(root, relativePath) {
6956
6956
  try {
6957
6957
  real = await realpath5(current);
6958
6958
  } catch {
6959
- return `${relativePath}: refuses to write through a broken symlink at ${path29.relative(rootResolved, current) || "."}`;
6959
+ return `${relativePath}: refuses to write through a broken symlink at ${path30.relative(rootResolved, current) || "."}`;
6960
6960
  }
6961
- const rel = path29.relative(rootReal, real);
6962
- const escapes = rel === ".." || rel.startsWith(`..${path29.sep}`) || path29.isAbsolute(rel);
6961
+ const rel = path30.relative(rootReal, real);
6962
+ const escapes = rel === ".." || rel.startsWith(`..${path30.sep}`) || path30.isAbsolute(rel);
6963
6963
  if (escapes) {
6964
- return `${relativePath}: refuses to write through a symlink at ${path29.relative(rootResolved, current) || "."} that resolves outside the project root`;
6964
+ return `${relativePath}: refuses to write through a symlink at ${path30.relative(rootResolved, current) || "."} that resolves outside the project root`;
6965
6965
  }
6966
6966
  if (hasGitSegment(rel)) {
6967
- return `${relativePath}: refuses to write through a symlink at ${path29.relative(rootResolved, current) || "."} that resolves through a .git directory`;
6967
+ return `${relativePath}: refuses to write through a symlink at ${path30.relative(rootResolved, current) || "."} that resolves through a .git directory`;
6968
6968
  }
6969
6969
  }
6970
6970
  return;
6971
6971
  }
6972
6972
  function hasGitSegment(rel) {
6973
- return rel.split(path29.sep).some((segment) => segment.toLowerCase() === ".git");
6973
+ return rel.split(path30.sep).some((segment) => segment.toLowerCase() === ".git");
6974
6974
  }
6975
6975
  var SymlinkRefusedError;
6976
6976
  var init_symlink_safety = __esm(() => {
@@ -6982,12 +6982,12 @@ var init_symlink_safety = __esm(() => {
6982
6982
  import { chmod as chmod3, lstat as lstat5, mkdir as mkdir8, open, readdir as readdir7, realpath as realpath6, rename as rename4, rm as rm3, rmdir, stat as stat6 } from "fs/promises";
6983
6983
  import { constants as fsConstants } from "fs";
6984
6984
  import { randomBytes as randomBytes3 } from "crypto";
6985
- import path30 from "path";
6985
+ import path31 from "path";
6986
6986
  function splitRel(rel) {
6987
6987
  return rel.split("/").filter((s) => s.length > 0);
6988
6988
  }
6989
6989
  function assertSafeRel(rel) {
6990
- if (path30.isAbsolute(rel)) {
6990
+ if (path31.isAbsolute(rel)) {
6991
6991
  throw new ContainedWriteError("absolute-path", `${rel}: refuses an absolute path`);
6992
6992
  }
6993
6993
  const segments = splitRel(rel);
@@ -7006,10 +7006,10 @@ function assertSafeRel(rel) {
7006
7006
  return nonDotSegments;
7007
7007
  }
7008
7008
  async function assertNoCycleOrDangling(root, rel, segments) {
7009
- const rootResolved = path30.resolve(root);
7009
+ const rootResolved = path31.resolve(root);
7010
7010
  let current = rootResolved;
7011
7011
  for (const segment of segments) {
7012
- current = path30.join(current, segment);
7012
+ current = path31.join(current, segment);
7013
7013
  let stats;
7014
7014
  try {
7015
7015
  stats = await lstat5(current);
@@ -7022,7 +7022,7 @@ async function assertNoCycleOrDangling(root, rel, segments) {
7022
7022
  await realpath6(current);
7023
7023
  } catch (error) {
7024
7024
  const code = error.code;
7025
- const at = path30.relative(rootResolved, current) || ".";
7025
+ const at = path31.relative(rootResolved, current) || ".";
7026
7026
  if (code === "ELOOP") {
7027
7027
  throw new ContainedWriteError("symlink-cycle", `${rel}: refuses a symlink cycle at ${at}`);
7028
7028
  }
@@ -7037,13 +7037,13 @@ async function assertContained(root, rel, opts = {}) {
7037
7037
  if (refusal) {
7038
7038
  throw new ContainedWriteError("escaping-symlink", refusal);
7039
7039
  }
7040
- const rootResolved = path30.resolve(root);
7041
- const targetPath = path30.join(rootResolved, ...segments);
7040
+ const rootResolved = path31.resolve(root);
7041
+ const targetPath = path31.join(rootResolved, ...segments);
7042
7042
  const rootReal = await realpath6(rootResolved).catch(() => rootResolved);
7043
7043
  const targetReal = await realpath6(targetPath).catch(() => null);
7044
7044
  if (targetReal !== null) {
7045
- const relToRoot = path30.relative(rootReal, targetReal);
7046
- const escapes = relToRoot === ".." || relToRoot.startsWith(`..${path30.sep}`) || path30.isAbsolute(relToRoot);
7045
+ const relToRoot = path31.relative(rootReal, targetReal);
7046
+ const escapes = relToRoot === ".." || relToRoot.startsWith(`..${path31.sep}`) || path31.isAbsolute(relToRoot);
7047
7047
  if (escapes) {
7048
7048
  throw new ContainedWriteError("not-contained", `${rel}: resolves outside ${rootReal}`);
7049
7049
  }
@@ -7065,7 +7065,7 @@ async function assertContained(root, rel, opts = {}) {
7065
7065
  }
7066
7066
  }
7067
7067
  const resolvedPath = targetReal ?? targetPath;
7068
- return { targetPath, dir: path30.dirname(targetPath), resolvedPath, resolvedDir: path30.dirname(resolvedPath) };
7068
+ return { targetPath, dir: path31.dirname(targetPath), resolvedPath, resolvedDir: path31.dirname(resolvedPath) };
7069
7069
  }
7070
7070
  async function pathExistsLstat(p) {
7071
7071
  try {
@@ -7102,7 +7102,7 @@ async function writeContained(root, rel, data, opts = {}) {
7102
7102
  } catch {
7103
7103
  existingMode = undefined;
7104
7104
  }
7105
- const tmp = path30.join(resolvedDir, `.${path30.basename(resolvedPath)}.tmp-${randomBytes3(6).toString("hex")}`);
7105
+ const tmp = path31.join(resolvedDir, `.${path31.basename(resolvedPath)}.tmp-${randomBytes3(6).toString("hex")}`);
7106
7106
  try {
7107
7107
  const handle = await open(tmp, "wx", opts.mode);
7108
7108
  try {
@@ -7371,7 +7371,7 @@ var init_codecs = __esm(() => {
7371
7371
  });
7372
7372
 
7373
7373
  // src/integrations/surfaces.ts
7374
- import path31 from "path";
7374
+ import path32 from "path";
7375
7375
  function ctxHookCommand(id) {
7376
7376
  return `keryx ctx hook ${id}`;
7377
7377
  }
@@ -7416,7 +7416,7 @@ function nestedCtxSurface(opts) {
7416
7416
  confidence,
7417
7417
  sourceDocs,
7418
7418
  ...riskNotes !== undefined ? { riskNotes } : {},
7419
- settingsFile: (root) => path31.join(root, ...relativePath.split("/")),
7419
+ settingsFile: (root) => path32.join(root, ...relativePath.split("/")),
7420
7420
  relativePath,
7421
7421
  slots: [
7422
7422
  { key: container ?? "hooks", type: "object", access: "owns" },
@@ -7530,7 +7530,7 @@ function flatSecuritySurface(harnessId, on, relativePath) {
7530
7530
  "`securityHooks` matches no documented hook contract for this harness; it is keryx's own invention (tracked as OQ-3)."
7531
7531
  ],
7532
7532
  sourceDocs: ["src/security/agent-hooks/runtimes.ts"],
7533
- settingsFile: (root) => path31.join(root, ...relativePath.split("/")),
7533
+ settingsFile: (root) => path32.join(root, ...relativePath.split("/")),
7534
7534
  relativePath,
7535
7535
  slots: [
7536
7536
  { key: SECURITY_HOOKS_KEY, type: "array", access: "owns" },
@@ -7609,7 +7609,7 @@ var init_surfaces = __esm(() => {
7609
7609
  sentinel: CTX_HOOK_SENTINEL,
7610
7610
  confidence: "verified",
7611
7611
  sourceDocs: ["src/ctx/runtimes.ts"],
7612
- settingsFile: (root) => path31.join(root, ".cursor", "hooks.json"),
7612
+ settingsFile: (root) => path32.join(root, ".cursor", "hooks.json"),
7613
7613
  relativePath: ".cursor/hooks.json",
7614
7614
  slots: [
7615
7615
  { key: "hooks", type: "object", access: "owns" },
@@ -7636,7 +7636,7 @@ var init_surfaces = __esm(() => {
7636
7636
  sentinel: CTX_HOOK_SENTINEL,
7637
7637
  confidence: "verified",
7638
7638
  sourceDocs: ["src/ctx/runtimes.ts"],
7639
- settingsFile: (root) => path31.join(root, ".windsurf", "hooks.json"),
7639
+ settingsFile: (root) => path32.join(root, ".windsurf", "hooks.json"),
7640
7640
  relativePath: ".windsurf/hooks.json",
7641
7641
  slots: [
7642
7642
  { key: "hooks", type: "object", access: "owns" },
@@ -7660,7 +7660,7 @@ var init_surfaces = __esm(() => {
7660
7660
  confidence: "experimental",
7661
7661
  riskNotes: ["No first-party docs confirm this hook contract; verify on a live install."],
7662
7662
  sourceDocs: ["src/ctx/runtimes.ts"],
7663
- settingsFile: (root) => path31.join(root, ".agents", "hooks.json"),
7663
+ settingsFile: (root) => path32.join(root, ".agents", "hooks.json"),
7664
7664
  relativePath: ".agents/hooks.json",
7665
7665
  slots: [
7666
7666
  { key: ANTIGRAVITY_CONTAINER, type: "object", access: "owns" },
@@ -7713,7 +7713,7 @@ var init_surfaces = __esm(() => {
7713
7713
  confidence: "experimental",
7714
7714
  riskNotes: ["Bridged via a generated plugin file rather than a documented hook config."],
7715
7715
  sourceDocs: ["src/ctx/runtimes.ts"],
7716
- settingsFile: (root) => path31.join(root, ...OPENCODE_PLUGIN_RELATIVE_PATH.split("/")),
7716
+ settingsFile: (root) => path32.join(root, ...OPENCODE_PLUGIN_RELATIVE_PATH.split("/")),
7717
7717
  relativePath: OPENCODE_PLUGIN_RELATIVE_PATH,
7718
7718
  slots: [],
7719
7719
  label: OPENCODE_PLUGIN_RELATIVE_PATH,
@@ -7750,7 +7750,7 @@ var init_surfaces = __esm(() => {
7750
7750
  sentinel: ORIENT_SENTINEL,
7751
7751
  confidence: "verified",
7752
7752
  sourceDocs: ["src/ctx/orient-runtimes.ts"],
7753
- settingsFile: (root) => path31.join(root, ".claude", "settings.json"),
7753
+ settingsFile: (root) => path32.join(root, ".claude", "settings.json"),
7754
7754
  relativePath: ".claude/settings.json",
7755
7755
  slots: [
7756
7756
  { key: "hooks", type: "object", access: "owns" },
@@ -7771,7 +7771,7 @@ var init_surfaces = __esm(() => {
7771
7771
  sentinel: ORIENT_SENTINEL,
7772
7772
  confidence: "verified",
7773
7773
  sourceDocs: ["src/ctx/orient-runtimes.ts"],
7774
- settingsFile: (root) => path31.join(root, ".codex", "hooks.json"),
7774
+ settingsFile: (root) => path32.join(root, ".codex", "hooks.json"),
7775
7775
  relativePath: ".codex/hooks.json",
7776
7776
  slots: [
7777
7777
  { key: "hooks", type: "object", access: "owns" },
@@ -7792,7 +7792,7 @@ var init_surfaces = __esm(() => {
7792
7792
  sentinel: ORIENT_SENTINEL,
7793
7793
  confidence: "verified",
7794
7794
  sourceDocs: ["src/ctx/orient-runtimes.ts"],
7795
- settingsFile: (root) => path31.join(root, ".cursor", "hooks.json"),
7795
+ settingsFile: (root) => path32.join(root, ".cursor", "hooks.json"),
7796
7796
  relativePath: ".cursor/hooks.json",
7797
7797
  slots: [
7798
7798
  { key: "hooks", type: "object", access: "owns" },
@@ -7823,7 +7823,7 @@ var init_surfaces = __esm(() => {
7823
7823
  sentinel: AGENT_HOOKS_SENTINEL,
7824
7824
  confidence: "verified",
7825
7825
  sourceDocs: ["src/security/agent-hooks/runtimes.ts"],
7826
- settingsFile: (root) => path31.join(root, ".claude", "settings.json"),
7826
+ settingsFile: (root) => path32.join(root, ".claude", "settings.json"),
7827
7827
  relativePath: ".claude/settings.json",
7828
7828
  slots: [
7829
7829
  { key: "hooks", type: "object", access: "owns" },
@@ -7843,7 +7843,7 @@ var init_surfaces = __esm(() => {
7843
7843
  sentinel: AGENT_HOOKS_SENTINEL,
7844
7844
  confidence: "verified",
7845
7845
  sourceDocs: ["src/security/agent-hooks/runtimes.ts"],
7846
- settingsFile: (root) => path31.join(root, ".claude", "settings.json"),
7846
+ settingsFile: (root) => path32.join(root, ".claude", "settings.json"),
7847
7847
  relativePath: ".claude/settings.json",
7848
7848
  slots: [
7849
7849
  { key: "hooks", type: "object", access: "owns" },
@@ -7870,7 +7870,7 @@ var init_surfaces = __esm(() => {
7870
7870
 
7871
7871
  // src/integrations/markdown-block.ts
7872
7872
  import { readFile as readFile15 } from "fs/promises";
7873
- import path32 from "path";
7873
+ import path33 from "path";
7874
7874
  function dominantEol(content) {
7875
7875
  const crlf = (content.match(/\r\n/g) ?? []).length;
7876
7876
  const totalLf = (content.match(/\n/g) ?? []).length;
@@ -8012,7 +8012,7 @@ function appendBlock(content, block, eol) {
8012
8012
  return endsWithEol(content) ? `${content}${eol}${block}` : `${content}${eol}${eol}${block}`;
8013
8013
  }
8014
8014
  function fileFor(root, relativePath) {
8015
- return path32.join(root, ...relativePath.split("/"));
8015
+ return path33.join(root, ...relativePath.split("/"));
8016
8016
  }
8017
8017
  async function installMarkdownBlock(root, relativePath, frontMatter, spec = INSTRUCTIONS_BLOCK_SPEC) {
8018
8018
  const symlinkRefusal = await refuseEscapingSymlink(root, relativePath);
@@ -8124,7 +8124,7 @@ var init_markdown_block = __esm(() => {
8124
8124
  });
8125
8125
 
8126
8126
  // src/integrations/surfaces-w5b.ts
8127
- import path33 from "path";
8127
+ import path34 from "path";
8128
8128
  function kiroHookEntry() {
8129
8129
  return {
8130
8130
  name: KIRO_HOOK_ID,
@@ -8151,7 +8151,7 @@ function copilotHookEntry() {
8151
8151
  };
8152
8152
  }
8153
8153
  async function agentsMdHasKeryxBlock(root) {
8154
- const file = path33.join(root, "AGENTS.md");
8154
+ const file = path34.join(root, "AGENTS.md");
8155
8155
  if (!await pathExists(file))
8156
8156
  return false;
8157
8157
  const { readFile } = await import("fs/promises");
@@ -8209,7 +8209,7 @@ var init_surfaces_w5b = __esm(() => {
8209
8209
  confidence: "experimental",
8210
8210
  riskNotes: ["Whether Gemini CLI actually reads GEMINI.md end-to-end (beyond the documented context.fileName option) is not independently confirmed here."],
8211
8211
  sourceDocs: ["https://github.com/google-gemini/gemini-cli/blob/main/docs/cli/gemini-md.md"],
8212
- settingsFile: (root) => path33.join(root, "GEMINI.md"),
8212
+ settingsFile: (root) => path34.join(root, "GEMINI.md"),
8213
8213
  relativePath: "GEMINI.md",
8214
8214
  slots: [],
8215
8215
  customInstall: (root) => installMarkdownBlock(root, "GEMINI.md"),
@@ -8233,7 +8233,7 @@ var init_surfaces_w5b = __esm(() => {
8233
8233
  "Kiro's hook stdin field names and its shell tool's name are third-party-reported only, not confirmed by first-party docs \u2014 the matcher above is a best guess and may gate nothing on a real install; verify before relying on it."
8234
8234
  ],
8235
8235
  sourceDocs: KIRO_SOURCE_DOCS,
8236
- settingsFile: (root) => path33.join(root, ".kiro", "hooks", "keryx-ctx-guard.json"),
8236
+ settingsFile: (root) => path34.join(root, ".kiro", "hooks", "keryx-ctx-guard.json"),
8237
8237
  relativePath: ".kiro/hooks/keryx-ctx-guard.json",
8238
8238
  slots: [
8239
8239
  { key: "version", type: "string", access: "owns" },
@@ -8278,7 +8278,7 @@ var init_surfaces_w5b = __esm(() => {
8278
8278
  "Open Kiro issues report that steering file `inclusion` modes are not always honoured, even with `inclusion: always` set \u2014 verify on a live install."
8279
8279
  ],
8280
8280
  sourceDocs: ["https://kiro.dev/docs/steering/"],
8281
- settingsFile: (root) => path33.join(root, ".kiro", "steering", "keryx.md"),
8281
+ settingsFile: (root) => path34.join(root, ".kiro", "steering", "keryx.md"),
8282
8282
  relativePath: ".kiro/steering/keryx.md",
8283
8283
  slots: [],
8284
8284
  customInstall: (root) => installMarkdownBlock(root, ".kiro/steering/keryx.md", KIRO_STEERING_FRONT_MATTER),
@@ -8301,7 +8301,7 @@ var init_surfaces_w5b = __esm(() => {
8301
8301
  "The shell tool's name Copilot's hook payload carries is not documented; this guard parses any tool call whose payload carries `toolArgs.command`, whatever `toolName` is."
8302
8302
  ],
8303
8303
  sourceDocs: COPILOT_SOURCE_DOCS,
8304
- settingsFile: (root) => path33.join(root, ".github", "hooks", "keryx-ctx-guard.json"),
8304
+ settingsFile: (root) => path34.join(root, ".github", "hooks", "keryx-ctx-guard.json"),
8305
8305
  relativePath: ".github/hooks/keryx-ctx-guard.json",
8306
8306
  slots: [
8307
8307
  { key: "version", type: "number", access: "owns" },
@@ -8345,7 +8345,7 @@ var init_surfaces_w5b = __esm(() => {
8345
8345
  "https://docs.github.com/en/copilot/how-tos/configure-custom-instructions-in-your-ide/add-repository-instructions-in-your-ide",
8346
8346
  "https://github.blog/changelog/2025-08-28-copilot-coding-agent-now-supports-agents-md-custom-instructions/"
8347
8347
  ],
8348
- settingsFile: (root) => path33.join(root, ".github", "copilot-instructions.md"),
8348
+ settingsFile: (root) => path34.join(root, ".github", "copilot-instructions.md"),
8349
8349
  relativePath: ".github/copilot-instructions.md",
8350
8350
  slots: [],
8351
8351
  customInstall: (root) => installMarkdownBlock(root, ".github/copilot-instructions.md"),
@@ -8384,7 +8384,7 @@ var init_surfaces_w5b = __esm(() => {
8384
8384
  `Zed uses the first matching rules file among ${ZED_SHADOWING_RULES_FILES.join(", ")}, AGENT.md, AGENTS.md, CLAUDE.md, GEMINI.md, ... \u2014 an earlier file in that list shadows AGENTS.md even when AGENTS.md itself carries Keryx's block.`
8385
8385
  ],
8386
8386
  sourceDocs: ["https://github.com/zed-industries/zed/blob/main/docs/src/ai/rules.md"],
8387
- settingsFile: (root) => path33.join(root, "AGENTS.md"),
8387
+ settingsFile: (root) => path34.join(root, "AGENTS.md"),
8388
8388
  relativePath: "AGENTS.md",
8389
8389
  slots: [],
8390
8390
  probe: async (root) => await agentsMdHasKeryxBlock(root) ? [] : ["zed: AGENTS.md is missing or missing Keryx's block \u2014 run `keryx update`"]
@@ -8614,7 +8614,7 @@ function parseSkillFrontmatter(content) {
8614
8614
 
8615
8615
  // src/gdskills/catalog.ts
8616
8616
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
8617
- import path34 from "path";
8617
+ import path35 from "path";
8618
8618
  import { fileURLToPath } from "url";
8619
8619
  function skill(name, category, profiles, purpose, workflow) {
8620
8620
  let routing;
@@ -8637,10 +8637,10 @@ function renderedSkill(name, category, profiles, purpose, workflow, triggers, de
8637
8637
  return { name, category, description, purpose, workflow, triggers, profiles };
8638
8638
  }
8639
8639
  function bundledSkillMarkdownPath(category, name) {
8640
- const here = path34.dirname(fileURLToPath(import.meta.url));
8640
+ const here = path35.dirname(fileURLToPath(import.meta.url));
8641
8641
  return [
8642
- path34.join(here, "bundled", "skills", category, name, "SKILL.md"),
8643
- path34.join(here, "..", "src", "gdskills", "bundled", "skills", category, name, "SKILL.md")
8642
+ path35.join(here, "bundled", "skills", category, name, "SKILL.md"),
8643
+ path35.join(here, "..", "src", "gdskills", "bundled", "skills", category, name, "SKILL.md")
8644
8644
  ].find((candidate) => existsSync2(candidate));
8645
8645
  }
8646
8646
  function readBundledSkillRouting(category, name) {
@@ -9150,7 +9150,7 @@ var init_catalog = __esm(() => {
9150
9150
  "Sync only selected skills and report changed files."
9151
9151
  ], ["sync skills", "install runtime skills", "global skill sync"], "Use when already-exported runtime skills need pushing to configured local runtimes, and only when sync is explicitly enabled. NOT for: producing the runtime export itself (see skill-runtime-exporter).")
9152
9152
  ];
9153
- BUNDLED_TREE_MARKER = path34.join("src", "gdskills", "bundled");
9153
+ BUNDLED_TREE_MARKER = path35.join("src", "gdskills", "bundled");
9154
9154
  });
9155
9155
 
9156
9156
  // src/gdskills/resolve.ts
@@ -9284,12 +9284,12 @@ var init_skill_length_ceilings = __esm(() => {
9284
9284
 
9285
9285
  // src/gdskills/bundled-eval.ts
9286
9286
  import { existsSync as existsSync3, readFileSync as readFileSync3, readdirSync } from "fs";
9287
- import path35 from "path";
9287
+ import path36 from "path";
9288
9288
  function defaultBundledRoot() {
9289
- const directPath = path35.join(import.meta.dir, "bundled");
9289
+ const directPath = path36.join(import.meta.dir, "bundled");
9290
9290
  if (existsSync3(directPath))
9291
9291
  return directPath;
9292
- const packagedPath = path35.join(import.meta.dir, "..", "src", "gdskills", "bundled");
9292
+ const packagedPath = path36.join(import.meta.dir, "..", "src", "gdskills", "bundled");
9293
9293
  if (existsSync3(packagedPath))
9294
9294
  return packagedPath;
9295
9295
  return directPath;
@@ -9806,12 +9806,12 @@ var init_schema = __esm(() => {
9806
9806
 
9807
9807
  // src/agents/catalog.ts
9808
9808
  import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as readFileSync4 } from "fs";
9809
- import path36 from "path";
9809
+ import path37 from "path";
9810
9810
  function agentDefinitionFiles(dir) {
9811
9811
  if (!existsSync4(dir)) {
9812
9812
  return [];
9813
9813
  }
9814
- return readdirSync2(dir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".md")).map((entry) => path36.join(dir, entry.name)).sort();
9814
+ return readdirSync2(dir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".md")).map((entry) => path37.join(dir, entry.name)).sort();
9815
9815
  }
9816
9816
  function loadOne(filePath, kind) {
9817
9817
  let raw;
@@ -9843,7 +9843,7 @@ function loadOne(filePath, kind) {
9843
9843
  };
9844
9844
  }
9845
9845
  const definition = buildAgentDefinition(parsed.result.data, parsed.result.body);
9846
- const stem = path36.basename(filePath, ".md");
9846
+ const stem = path37.basename(filePath, ".md");
9847
9847
  if (stem !== definition.name) {
9848
9848
  return {
9849
9849
  error: {
@@ -9877,8 +9877,8 @@ function loadSource(dir, kind, byName, errors) {
9877
9877
  }
9878
9878
  }
9879
9879
  function loadAgentCatalog(projectRoot, options = {}) {
9880
- const bundledRoot = options.bundledRoot ?? path36.join(defaultBundledRoot(), "agents");
9881
- const projectDir = path36.join(projectRoot, ".metaproject", "agents");
9880
+ const bundledRoot = options.bundledRoot ?? path37.join(defaultBundledRoot(), "agents");
9881
+ const projectDir = path37.join(projectRoot, ".metaproject", "agents");
9882
9882
  const byName = new Map;
9883
9883
  const errors = [];
9884
9884
  loadSource(bundledRoot, "bundled", byName, errors);
@@ -10671,7 +10671,7 @@ var init_compile = __esm(() => {
10671
10671
 
10672
10672
  // src/agents/export.ts
10673
10673
  import { readFile as readFile16, readdir as readdir8, lstat as lstat6, realpath as realpath7 } from "fs/promises";
10674
- import path37 from "path";
10674
+ import path38 from "path";
10675
10675
  function matrixStateToExportLevel(state) {
10676
10676
  return state === "native" || state === "adapter" ? state : "instruction-only";
10677
10677
  }
@@ -10683,7 +10683,7 @@ function proseExportRelativePath(runtime, name) {
10683
10683
  return `${PROSE_EXPORT_ROOT}/${runtime}/${name}.md`;
10684
10684
  }
10685
10685
  async function readExistingFileContent(projectRoot, relativePath) {
10686
- const absolute = path37.join(projectRoot, ...relativePath.split("/"));
10686
+ const absolute = path38.join(projectRoot, ...relativePath.split("/"));
10687
10687
  try {
10688
10688
  return await readFile16(absolute, "utf8");
10689
10689
  } catch (error) {
@@ -10696,7 +10696,7 @@ async function checkExportPathSafety(projectRoot, relativePath) {
10696
10696
  const segments = relativePath.split("/");
10697
10697
  let current = projectRoot;
10698
10698
  for (const segment of segments) {
10699
- current = path37.join(current, segment);
10699
+ current = path38.join(current, segment);
10700
10700
  let stats;
10701
10701
  try {
10702
10702
  stats = await lstat6(current);
@@ -10706,12 +10706,12 @@ async function checkExportPathSafety(projectRoot, relativePath) {
10706
10706
  throw error;
10707
10707
  }
10708
10708
  if (stats.isSymbolicLink()) {
10709
- return `refusing to write ${relativePath} \u2014 ${path37.relative(projectRoot, current) || "."} is a symlink; this exporter never writes through a symlink`;
10709
+ return `refusing to write ${relativePath} \u2014 ${path38.relative(projectRoot, current) || "."} is a symlink; this exporter never writes through a symlink`;
10710
10710
  }
10711
10711
  }
10712
- let ancestor = path37.dirname(path37.join(projectRoot, ...segments));
10712
+ let ancestor = path38.dirname(path38.join(projectRoot, ...segments));
10713
10713
  for (let guard = 0;guard < segments.length + 1 && !await pathExists(ancestor); guard += 1) {
10714
- const parent = path37.dirname(ancestor);
10714
+ const parent = path38.dirname(ancestor);
10715
10715
  if (parent === ancestor)
10716
10716
  break;
10717
10717
  ancestor = parent;
@@ -10744,7 +10744,7 @@ function decideAction(existing, generated, format, expectedName) {
10744
10744
  return { action: "update" };
10745
10745
  }
10746
10746
  async function readClaudeSubagentAliasesConfig(projectRoot) {
10747
- const file = path37.join(projectRoot, CLAUDE_SUBAGENT_ALIASES_CONFIG_PATH);
10747
+ const file = path38.join(projectRoot, CLAUDE_SUBAGENT_ALIASES_CONFIG_PATH);
10748
10748
  if (!await pathExists(file)) {
10749
10749
  return { enabled: true };
10750
10750
  }
@@ -10886,7 +10886,7 @@ async function writeAgentExport(projectRoot, plan, opts = {}) {
10886
10886
  }
10887
10887
  async function scanManagedAgentExports(projectRoot, runtime) {
10888
10888
  const dirRelative = HOST_AGENTS_DIR[runtime];
10889
- const dirAbsolute = path37.join(projectRoot, ...dirRelative.split("/"));
10889
+ const dirAbsolute = path38.join(projectRoot, ...dirRelative.split("/"));
10890
10890
  let dirStats;
10891
10891
  try {
10892
10892
  dirStats = await lstat6(dirAbsolute);
@@ -10907,7 +10907,7 @@ async function scanManagedAgentExports(projectRoot, runtime) {
10907
10907
  if (!entry.isFile())
10908
10908
  continue;
10909
10909
  const relativePath = `${dirRelative}/${entry.name}`;
10910
- const absolute = path37.join(projectRoot, ...relativePath.split("/"));
10910
+ const absolute = path38.join(projectRoot, ...relativePath.split("/"));
10911
10911
  let entryStats;
10912
10912
  try {
10913
10913
  entryStats = await lstat6(absolute);
@@ -10922,7 +10922,7 @@ async function scanManagedAgentExports(projectRoot, runtime) {
10922
10922
  } catch {
10923
10923
  continue;
10924
10924
  }
10925
- const stem = entry.name.slice(0, entry.name.length - path37.extname(entry.name).length);
10925
+ const stem = entry.name.slice(0, entry.name.length - path38.extname(entry.name).length);
10926
10926
  const format = agentSentinelFormatOf(relativePath);
10927
10927
  if (!isStructurallyManaged(content, format, stem))
10928
10928
  continue;
@@ -11092,7 +11092,7 @@ var init_surfaces_agents = __esm(() => {
11092
11092
 
11093
11093
  // src/rules/export-render.ts
11094
11094
  import { readFile as readFile17, readdir as readdir9 } from "fs/promises";
11095
- import path38 from "path";
11095
+ import path39 from "path";
11096
11096
  function isUnsafeRulePath(relativePath) {
11097
11097
  return UNSAFE_RULE_PATH_PATTERN.test(relativePath) || relativePath.includes("<!--") || relativePath.includes("-->");
11098
11098
  }
@@ -11135,7 +11135,7 @@ function firstHeading(body) {
11135
11135
  return match ? match[1].trim() : undefined;
11136
11136
  }
11137
11137
  function titleFromFileName(relativePath) {
11138
- const base = path38.basename(relativePath).replace(/\.(mdc|md)$/i, "");
11138
+ const base = path39.basename(relativePath).replace(/\.(mdc|md)$/i, "");
11139
11139
  return base.split(/[-_]+/).filter((part) => part.length > 0).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
11140
11140
  }
11141
11141
  function parseRuleFile(fileName, content) {
@@ -11148,7 +11148,7 @@ function parseRuleFile(fileName, content) {
11148
11148
  return { title: neutralise(collapseSingleLine(title, 120)), description };
11149
11149
  }
11150
11150
  async function collectCanonicalRules(root) {
11151
- const rulesDir = path38.join(root, ".metaproject", "rules");
11151
+ const rulesDir = path39.join(root, ".metaproject", "rules");
11152
11152
  if (!await pathExists(rulesDir))
11153
11153
  return { rules: [], skipped: [] };
11154
11154
  const rules = [];
@@ -11162,14 +11162,14 @@ async function collectCanonicalRules(root) {
11162
11162
  }
11163
11163
  for (const dirent of dirents) {
11164
11164
  const childRelative = dirRelative ? `${dirRelative}/${dirent.name}` : dirent.name;
11165
- const childAbsolute = path38.join(dirAbsolute, dirent.name);
11165
+ const childAbsolute = path39.join(dirAbsolute, dirent.name);
11166
11166
  if (dirent.isDirectory()) {
11167
11167
  await walk(childAbsolute, childRelative);
11168
11168
  continue;
11169
11169
  }
11170
11170
  if (!dirent.isFile())
11171
11171
  continue;
11172
- const ext = path38.extname(dirent.name).toLowerCase();
11172
+ const ext = path39.extname(dirent.name).toLowerCase();
11173
11173
  if (!RULE_EXTENSIONS.has(ext))
11174
11174
  continue;
11175
11175
  if (dirent.name.toLowerCase() === README_BASENAME)
@@ -11220,7 +11220,7 @@ var init_export_render = __esm(() => {
11220
11220
  });
11221
11221
 
11222
11222
  // src/integrations/surfaces-rules.ts
11223
- import path39 from "path";
11223
+ import path40 from "path";
11224
11224
  async function rulesSpec(root) {
11225
11225
  const { rules, skipped } = await collectCanonicalRules(root);
11226
11226
  const body = renderRulesBlockBody(rules);
@@ -11265,7 +11265,7 @@ function rulesExportSurface(params) {
11265
11265
  ...riskNotes !== undefined ? { riskNotes } : {},
11266
11266
  sourceDocs,
11267
11267
  optIn: true,
11268
- settingsFile: (root) => path39.join(root, ...relativePath.split("/")),
11268
+ settingsFile: (root) => path40.join(root, ...relativePath.split("/")),
11269
11269
  relativePath,
11270
11270
  label: relativePath,
11271
11271
  slots: [],
@@ -11348,7 +11348,7 @@ var init_surfaces_rules = __esm(() => {
11348
11348
  });
11349
11349
 
11350
11350
  // src/integrations/surfaces-learning.ts
11351
- import path40 from "path";
11351
+ import path41 from "path";
11352
11352
  function learningObserverCommand() {
11353
11353
  return "keryx learn observe --hook claude";
11354
11354
  }
@@ -11403,7 +11403,7 @@ var init_surfaces_learning = __esm(() => {
11403
11403
  "docs/requirements/keryx-agent-platform-expansion/workstreams/W3-self-learning.md",
11404
11404
  "src/learning/observe.ts"
11405
11405
  ],
11406
- settingsFile: (root) => path40.join(root, ".claude", "settings.json"),
11406
+ settingsFile: (root) => path41.join(root, ".claude", "settings.json"),
11407
11407
  relativePath: ".claude/settings.json",
11408
11408
  slots: [
11409
11409
  { key: "hooks", type: "object", access: "owns" },
@@ -11752,13 +11752,13 @@ var init_registry = __esm(() => {
11752
11752
  var init_package = () => {};
11753
11753
 
11754
11754
  // src/lib/install-plan.ts
11755
- import path41 from "path";
11755
+ import path42 from "path";
11756
11756
  var INSTALL_JOURNAL_RELATIVE_PATH;
11757
11757
  var init_install_plan = __esm(() => {
11758
11758
  init_package();
11759
11759
  init_fs();
11760
11760
  init_contained_write();
11761
- INSTALL_JOURNAL_RELATIVE_PATH = path41.join("runtime", "install", "journal.json");
11761
+ INSTALL_JOURNAL_RELATIVE_PATH = path42.join("runtime", "install", "journal.json");
11762
11762
  });
11763
11763
 
11764
11764
  // src/integrations/install-state.ts
@@ -11813,11 +11813,11 @@ var init_integrations = __esm(() => {
11813
11813
  });
11814
11814
 
11815
11815
  // src/security/audit-harness/surfaces.ts
11816
- import path42 from "path";
11816
+ import path43 from "path";
11817
11817
  import { lstat as lstat7, readdir as readdir10, realpath as realpath8, stat as stat7 } from "fs/promises";
11818
11818
  async function resolvesInsideRoot(root, absolute) {
11819
11819
  try {
11820
- const rootReal = await realpath8(root).catch(() => path42.resolve(root));
11820
+ const rootReal = await realpath8(root).catch(() => path43.resolve(root));
11821
11821
  const real = await realpath8(absolute);
11822
11822
  return isPathInside(rootReal, real);
11823
11823
  } catch {
@@ -11827,7 +11827,7 @@ async function resolvesInsideRoot(root, absolute) {
11827
11827
  async function existingFiles(root, relativePaths) {
11828
11828
  const found = [];
11829
11829
  for (const relativePath of relativePaths) {
11830
- const absolute = path42.join(root, relativePath);
11830
+ const absolute = path43.join(root, relativePath);
11831
11831
  if (await pathExists(absolute)) {
11832
11832
  found.push(toPosix(relativePath));
11833
11833
  }
@@ -11850,7 +11850,7 @@ async function discoverHookSurfaceFiles(root) {
11850
11850
  return existingFiles(root, [...NON_JSON_HOOK_SURFACE_PATHS, ".metaproject/hooks.json"]);
11851
11851
  }
11852
11852
  async function listFilesByExtensions(root, dirRelative, extensions) {
11853
- const dirAbsolute = path42.join(root, dirRelative);
11853
+ const dirAbsolute = path43.join(root, dirRelative);
11854
11854
  if (!await pathExists(dirAbsolute)) {
11855
11855
  return { found: [], unreadable: [] };
11856
11856
  }
@@ -11863,15 +11863,15 @@ async function listFilesByExtensions(root, dirRelative, extensions) {
11863
11863
  const found = [];
11864
11864
  const unreadable = [];
11865
11865
  for (const entry of entries) {
11866
- if (!extensions.has(path42.extname(entry.name)))
11866
+ if (!extensions.has(path43.extname(entry.name)))
11867
11867
  continue;
11868
- const childRelative = path42.join(dirRelative, entry.name);
11868
+ const childRelative = path43.join(dirRelative, entry.name);
11869
11869
  if (entry.isFile()) {
11870
11870
  found.push(toPosix(childRelative));
11871
11871
  continue;
11872
11872
  }
11873
11873
  if (entry.isSymbolicLink()) {
11874
- const absolute = path42.join(root, childRelative);
11874
+ const absolute = path43.join(root, childRelative);
11875
11875
  if (await resolvesInsideRoot(root, absolute)) {
11876
11876
  found.push(toPosix(childRelative));
11877
11877
  } else {
@@ -11907,7 +11907,7 @@ async function walkScripts(root, dirRelative, depth, visited, acc) {
11907
11907
  acc.reasons.add(`skills: walk truncated at depth ${depth} (${toPosix(dirRelative)})`);
11908
11908
  return;
11909
11909
  }
11910
- const dirAbsolute = path42.join(root, dirRelative);
11910
+ const dirAbsolute = path43.join(root, dirRelative);
11911
11911
  if (!await pathExists(dirAbsolute)) {
11912
11912
  return;
11913
11913
  }
@@ -11934,17 +11934,17 @@ async function walkScripts(root, dirRelative, depth, visited, acc) {
11934
11934
  return;
11935
11935
  }
11936
11936
  for (const entry of entries) {
11937
- const childRelative = path42.join(dirRelative, entry.name);
11937
+ const childRelative = path43.join(dirRelative, entry.name);
11938
11938
  if (entry.isDirectory()) {
11939
11939
  await walkScripts(root, childRelative, depth + 1, visited, acc);
11940
11940
  continue;
11941
11941
  }
11942
- if (entry.isFile() && SCRIPT_EXTENSIONS.has(path42.extname(entry.name))) {
11942
+ if (entry.isFile() && SCRIPT_EXTENSIONS.has(path43.extname(entry.name))) {
11943
11943
  acc.found.push(toPosix(childRelative));
11944
11944
  continue;
11945
11945
  }
11946
11946
  if (entry.isSymbolicLink()) {
11947
- const absolute = path42.join(root, childRelative);
11947
+ const absolute = path43.join(root, childRelative);
11948
11948
  if (!await resolvesInsideRoot(root, absolute)) {
11949
11949
  acc.unreadable.push(toPosix(childRelative));
11950
11950
  continue;
@@ -11954,7 +11954,7 @@ async function walkScripts(root, dirRelative, depth, visited, acc) {
11954
11954
  });
11955
11955
  if (stats?.isDirectory()) {
11956
11956
  await walkScripts(root, childRelative, depth + 1, visited, acc);
11957
- } else if (stats?.isFile() && SCRIPT_EXTENSIONS.has(path42.extname(entry.name))) {
11957
+ } else if (stats?.isFile() && SCRIPT_EXTENSIONS.has(path43.extname(entry.name))) {
11958
11958
  acc.found.push(toPosix(childRelative));
11959
11959
  } else if (stats === undefined) {
11960
11960
  acc.unreadable.push(toPosix(childRelative));
@@ -13480,10 +13480,10 @@ var init_checks = __esm(() => {
13480
13480
  });
13481
13481
 
13482
13482
  // src/security/audit-harness/baseline.ts
13483
- import path43 from "path";
13483
+ import path44 from "path";
13484
13484
  import { readFile as readFile18 } from "fs/promises";
13485
13485
  function defaultBaselinePath(root) {
13486
- return path43.join(root, ".metaproject", "security-audit-baseline.json");
13486
+ return path44.join(root, ".metaproject", "security-audit-baseline.json");
13487
13487
  }
13488
13488
  async function readBaseline(baselinePath) {
13489
13489
  if (!await pathExists(baselinePath)) {
@@ -13582,7 +13582,7 @@ async function addBaselineEntry(root, entry, options = {}) {
13582
13582
  const now = options.now ? options.now() : new Date;
13583
13583
  backupPath = `${filePath}.bak-${now.toISOString().replace(/[:.]/g, "-")}`;
13584
13584
  const preResealBytes = await readFile18(filePath);
13585
- await writeContained(root, path43.relative(root, backupPath), preResealBytes);
13585
+ await writeContained(root, path44.relative(root, backupPath), preResealBytes);
13586
13586
  entries = loaded.state.entries;
13587
13587
  const rawIds = await readRawBaselineFindingIds(filePath);
13588
13588
  const keptIds = new Set(entries.map((e) => e.findingId));
@@ -13596,7 +13596,7 @@ async function addBaselineEntry(root, entry, options = {}) {
13596
13596
  const next = [...entries.filter((existing) => existing.findingId !== entry.findingId), entry];
13597
13597
  const checksum = computeObjectChecksum(next);
13598
13598
  const payload = { schemaVersion: 1, entries: next, checksum };
13599
- await writeContained(root, path43.relative(root, filePath), `${JSON.stringify(payload, null, 2)}
13599
+ await writeContained(root, path44.relative(root, filePath), `${JSON.stringify(payload, null, 2)}
13600
13600
  `);
13601
13601
  return { resealed, carriedOver, discarded, ...backupPath ? { backupPath } : {} };
13602
13602
  }
@@ -13687,7 +13687,7 @@ var init_types2 = __esm(() => {
13687
13687
  });
13688
13688
 
13689
13689
  // src/security/audit-harness/proposals.ts
13690
- import path44 from "path";
13690
+ import path45 from "path";
13691
13691
  import { readFile as readFile19, realpath as realpath9 } from "fs/promises";
13692
13692
  async function assertContained2(rootReal, absolute, label) {
13693
13693
  if (!isPathInside(rootReal, absolute)) {
@@ -13702,7 +13702,7 @@ async function assertContained2(rootReal, absolute, label) {
13702
13702
  }
13703
13703
  return;
13704
13704
  }
13705
- let dir = path44.dirname(absolute);
13705
+ let dir = path45.dirname(absolute);
13706
13706
  for (;; ) {
13707
13707
  const dirReal = await realpath9(dir).catch(() => {
13708
13708
  return;
@@ -13713,23 +13713,23 @@ async function assertContained2(rootReal, absolute, label) {
13713
13713
  }
13714
13714
  return;
13715
13715
  }
13716
- const parent = path44.dirname(dir);
13716
+ const parent = path45.dirname(dir);
13717
13717
  if (parent === dir)
13718
13718
  return;
13719
13719
  dir = parent;
13720
13720
  }
13721
13721
  }
13722
13722
  function dataRoot(root) {
13723
- return path44.join(root, ".metaproject", "data", "security", "audit-harness");
13723
+ return path45.join(root, ".metaproject", "data", "security", "audit-harness");
13724
13724
  }
13725
13725
  function lockPath2(root) {
13726
- return path44.join(dataRoot(root), "apply.lock");
13726
+ return path45.join(dataRoot(root), "apply.lock");
13727
13727
  }
13728
13728
  function changelogPath(root) {
13729
- return path44.join(dataRoot(root), "changelog.jsonl");
13729
+ return path45.join(dataRoot(root), "changelog.jsonl");
13730
13730
  }
13731
13731
  function appliedMarkerPath(root, proposalId) {
13732
- return path44.join(dataRoot(root), `${proposalId}.applied.json`);
13732
+ return path45.join(dataRoot(root), `${proposalId}.applied.json`);
13733
13733
  }
13734
13734
  function setPointer(target, pointer, mutate) {
13735
13735
  const segments = pointer.split("/").filter((s) => s.length > 0).map((s) => s.replace(/~1/g, "/").replace(/~0/g, "~"));
@@ -13751,7 +13751,7 @@ function setPointer(target, pointer, mutate) {
13751
13751
  return target;
13752
13752
  }
13753
13753
  async function applyJsonEdit(rootReal, edit) {
13754
- const absolute = path44.resolve(rootReal, edit.path);
13754
+ const absolute = path45.resolve(rootReal, edit.path);
13755
13755
  await assertContained2(rootReal, absolute, `target file "${edit.path}"`);
13756
13756
  const read = await readJsonObjectFile(absolute);
13757
13757
  if (read.state !== "object") {
@@ -13784,7 +13784,7 @@ async function applyJsonEdit(rootReal, edit) {
13784
13784
  } catch {
13785
13785
  throw new Error(`Cannot apply proposal: result is not valid JSON for ${edit.path}; refusing to write.`);
13786
13786
  }
13787
- await writeContained(rootReal, path44.relative(rootReal, absolute), serialized);
13787
+ await writeContained(rootReal, path45.relative(rootReal, absolute), serialized);
13788
13788
  }
13789
13789
  function countOccurrences(haystack, needle) {
13790
13790
  if (needle.length === 0)
@@ -13800,7 +13800,7 @@ function countOccurrences(haystack, needle) {
13800
13800
  }
13801
13801
  }
13802
13802
  async function applyTextEdit(rootReal, edit) {
13803
- const absolute = path44.resolve(rootReal, edit.path);
13803
+ const absolute = path45.resolve(rootReal, edit.path);
13804
13804
  await assertContained2(rootReal, absolute, `target file "${edit.path}"`);
13805
13805
  const content = await readFile19(absolute, "utf8");
13806
13806
  const occurrences = countOccurrences(content, edit.from);
@@ -13821,7 +13821,7 @@ async function applyTextEdit(rootReal, edit) {
13821
13821
  throw new Error(`Cannot apply proposal: result is not valid JSON for ${edit.path}; refusing to write.`);
13822
13822
  }
13823
13823
  }
13824
- await writeContained(rootReal, path44.relative(rootReal, absolute), next);
13824
+ await writeContained(rootReal, path45.relative(rootReal, absolute), next);
13825
13825
  }
13826
13826
  async function applyAuditProposal(root, proposalId, options = {}) {
13827
13827
  if (!PROPOSAL_ID_RE.test(proposalId)) {
@@ -13829,7 +13829,7 @@ async function applyAuditProposal(root, proposalId, options = {}) {
13829
13829
  }
13830
13830
  const rootReal = await realpath9(root).catch(() => {
13831
13831
  return;
13832
- }) ?? path44.resolve(root);
13832
+ }) ?? path45.resolve(root);
13833
13833
  return withFileLock(lockPath2(rootReal), async () => {
13834
13834
  const marker = appliedMarkerPath(rootReal, proposalId);
13835
13835
  await assertContained2(rootReal, marker, "applied-marker file");
@@ -13864,9 +13864,9 @@ async function applyAuditProposal(root, proposalId, options = {}) {
13864
13864
  };
13865
13865
  const changelog = changelogPath(rootReal);
13866
13866
  await assertContained2(rootReal, changelog, "changelog file");
13867
- await appendContained(rootReal, path44.relative(rootReal, changelog), `${JSON.stringify(result)}
13867
+ await appendContained(rootReal, path45.relative(rootReal, changelog), `${JSON.stringify(result)}
13868
13868
  `);
13869
- await writeContained(rootReal, path44.relative(rootReal, marker), `${JSON.stringify(result, null, 2)}
13869
+ await writeContained(rootReal, path45.relative(rootReal, marker), `${JSON.stringify(result, null, 2)}
13870
13870
  `);
13871
13871
  return result;
13872
13872
  });
@@ -13882,7 +13882,7 @@ var init_proposals = __esm(() => {
13882
13882
 
13883
13883
  // src/security/audit-harness/index.ts
13884
13884
  import { createHash as createHash7 } from "crypto";
13885
- import path45 from "path";
13885
+ import path46 from "path";
13886
13886
  import { readFile as readFile20 } from "fs/promises";
13887
13887
  function findingId(f) {
13888
13888
  const pointerOrLine = f.location?.pointer ?? (f.location?.line !== undefined ? `line:${f.location.line}` : "");
@@ -14057,7 +14057,7 @@ function asBundleFindings(findings, bundleCheck) {
14057
14057
  function isSafeBundleEntryPath(relativePath) {
14058
14058
  if (relativePath.length === 0)
14059
14059
  return false;
14060
- if (path45.isAbsolute(relativePath))
14060
+ if (path46.isAbsolute(relativePath))
14061
14061
  return false;
14062
14062
  if (relativePath.includes("\\"))
14063
14063
  return false;
@@ -14074,7 +14074,7 @@ async function scanImportedBundle(root, entries) {
14074
14074
  unreadable.push(entry.path);
14075
14075
  continue;
14076
14076
  }
14077
- const absolute = path45.join(root, entry.path);
14077
+ const absolute = path46.join(root, entry.path);
14078
14078
  if (!isPathInside(root, absolute)) {
14079
14079
  unreadable.push(entry.path);
14080
14080
  continue;
@@ -14183,7 +14183,7 @@ async function scanImportedBundle(root, entries) {
14183
14183
  return { raw, surface: surfaceResult("imported-bundles", scanned, unreadable), notes };
14184
14184
  }
14185
14185
  async function mcpBaselineTools(root) {
14186
- const file = path45.join(securityDataRoot(root), "mcp-baseline.json");
14186
+ const file = path46.join(securityDataRoot(root), "mcp-baseline.json");
14187
14187
  if (!await pathExists(file)) {
14188
14188
  return { tools: {}, state: "absent" };
14189
14189
  }
@@ -14202,7 +14202,7 @@ async function computeAuditInternal(root, options = {}) {
14202
14202
  const files = await discoverInstructions(root);
14203
14203
  const unreadable = [];
14204
14204
  for (const relativePath of files) {
14205
- const content = await safeReadText(path45.join(root, relativePath));
14205
+ const content = await safeReadText(path46.join(root, relativePath));
14206
14206
  if (content === undefined) {
14207
14207
  unreadable.push(relativePath);
14208
14208
  continue;
@@ -14222,7 +14222,7 @@ async function computeAuditInternal(root, options = {}) {
14222
14222
  if (relativePath.endsWith(".toml")) {
14223
14223
  continue;
14224
14224
  }
14225
- const read = await readJsonObjectFile(path45.join(root, relativePath));
14225
+ const read = await readJsonObjectFile(path46.join(root, relativePath));
14226
14226
  if (read.state !== "object") {
14227
14227
  unreadable.push(relativePath);
14228
14228
  continue;
@@ -14250,7 +14250,7 @@ async function computeAuditInternal(root, options = {}) {
14250
14250
  const { tools: baselineTools, state: baselineState } = await mcpBaselineTools(root);
14251
14251
  for (const relativePath of uniqueFiles) {
14252
14252
  if (relativePath.endsWith(".toml")) {
14253
- const content = await safeReadText(path45.join(root, relativePath));
14253
+ const content = await safeReadText(path46.join(root, relativePath));
14254
14254
  if (content === undefined) {
14255
14255
  unreadable.push(relativePath);
14256
14256
  continue;
@@ -14272,7 +14272,7 @@ async function computeAuditInternal(root, options = {}) {
14272
14272
  }
14273
14273
  let record = settingsJsonByPath.get(relativePath);
14274
14274
  if (record === undefined) {
14275
- const read = await readJsonObjectFile(path45.join(root, relativePath));
14275
+ const read = await readJsonObjectFile(path46.join(root, relativePath));
14276
14276
  record = read.state === "object" ? read.value : undefined;
14277
14277
  }
14278
14278
  if (!record) {
@@ -14334,7 +14334,7 @@ async function computeAuditInternal(root, options = {}) {
14334
14334
  }
14335
14335
  }
14336
14336
  for (const relativePath of nonJsonFiles) {
14337
- const content = await safeReadText(path45.join(root, relativePath));
14337
+ const content = await safeReadText(path46.join(root, relativePath));
14338
14338
  if (content === undefined) {
14339
14339
  unreadable.push(relativePath);
14340
14340
  continue;
@@ -14348,7 +14348,7 @@ async function computeAuditInternal(root, options = {}) {
14348
14348
  const { found: files, unreadable: discoveryUnreadable } = await discoverAgentDefinitions(root);
14349
14349
  const unreadable = [...discoveryUnreadable];
14350
14350
  for (const relativePath of files) {
14351
- const buffer = await safeReadBuffer(path45.join(root, relativePath));
14351
+ const buffer = await safeReadBuffer(path46.join(root, relativePath));
14352
14352
  if (buffer === undefined) {
14353
14353
  unreadable.push(relativePath);
14354
14354
  continue;
@@ -14365,7 +14365,7 @@ async function computeAuditInternal(root, options = {}) {
14365
14365
  const { found: files, unreadable: discoveryUnreadable, reasons: skillReasons } = await discoverSkillScripts(root);
14366
14366
  const unreadable = [...discoveryUnreadable];
14367
14367
  for (const relativePath of files) {
14368
- const content = await safeReadText(path45.join(root, relativePath));
14368
+ const content = await safeReadText(path46.join(root, relativePath));
14369
14369
  if (content === undefined) {
14370
14370
  unreadable.push(relativePath);
14371
14371
  continue;
@@ -14512,7 +14512,7 @@ __export(exports_service, {
14512
14512
  validateSerializedOutput: () => validateSerializedOutput,
14513
14513
  verifyConfigChecksum: () => verifyConfigChecksum
14514
14514
  });
14515
- import path46 from "path";
14515
+ import path47 from "path";
14516
14516
  import { readFile as readFile21 } from "fs/promises";
14517
14517
  import { randomBytes as randomBytes4 } from "crypto";
14518
14518
  function validateSerializedOutput(content, exemptExfil) {
@@ -14640,7 +14640,7 @@ function hasRecognizedGate(value) {
14640
14640
  return typeof gate === "string" && RECOGNIZED_GATES.has(gate);
14641
14641
  }
14642
14642
  async function readLatestReport(cwd) {
14643
- const file = path46.join(artifactsDir(cwd), "latest.json");
14643
+ const file = path47.join(artifactsDir(cwd), "latest.json");
14644
14644
  if (!await pathExists(file)) {
14645
14645
  return { kind: "absent" };
14646
14646
  }
@@ -14766,9 +14766,9 @@ var init_service2 = __esm(() => {
14766
14766
  });
14767
14767
 
14768
14768
  // src/gdgraph/config.ts
14769
- import path51 from "path";
14769
+ import path52 from "path";
14770
14770
  function gdgraphConfigPath(cwd) {
14771
- return path51.join(cwd, ".metaproject", "gdgraph.config.json");
14771
+ return path52.join(cwd, ".metaproject", "gdgraph.config.json");
14772
14772
  }
14773
14773
  function mergeGdgraphConfig(parsed) {
14774
14774
  const base = DEFAULT_GDGRAPH_CONFIG;
@@ -15373,7 +15373,7 @@ var init_extract = __esm(() => {
15373
15373
  });
15374
15374
 
15375
15375
  // src/gdgraph/treesitter/grammars.ts
15376
- import path52 from "path";
15376
+ import path53 from "path";
15377
15377
  function grammarAssetId(language) {
15378
15378
  return `tree-sitter-${language}`;
15379
15379
  }
@@ -15389,7 +15389,7 @@ function symbolLanguage(language) {
15389
15389
  async function resolveGrammar(cwd, language, grammarsPath) {
15390
15390
  const id = grammarAssetId(language);
15391
15391
  const lock = await loadAssetsLock(cwd);
15392
- const overrides = grammarsPath ? { [id]: { path: path52.join(grammarsPath, `${id}.wasm`) } } : undefined;
15392
+ const overrides = grammarsPath ? { [id]: { path: path53.join(grammarsPath, `${id}.wasm`) } } : undefined;
15393
15393
  const registry = registryFromLock(lock, overrides);
15394
15394
  const resolved = await resolveAsset(registry, id);
15395
15395
  if (!resolved) {
@@ -15419,7 +15419,7 @@ function toGrammarLanguages(languages) {
15419
15419
  return out;
15420
15420
  }
15421
15421
  function grammarForFile(file, available) {
15422
- const ext = path52.extname(file);
15422
+ const ext = path53.extname(file);
15423
15423
  const preference = ext === ".tsx" ? ["tsx", "typescript"] : ext === ".ts" ? ["typescript"] : ext === ".jsx" || ext === ".js" || ext === ".mjs" || ext === ".cjs" ? ["javascript"] : ext === ".java" ? ["java"] : ext === ".py" ? ["python"] : [];
15424
15424
  for (const language of preference) {
15425
15425
  if (available.includes(language)) {
@@ -15681,7 +15681,7 @@ var init_adapter = __esm(() => {
15681
15681
 
15682
15682
  // src/gdgraph/enrich.ts
15683
15683
  import { mkdir as mkdir12, writeFile as writeFile6 } from "fs/promises";
15684
- import path53 from "path";
15684
+ import path54 from "path";
15685
15685
  async function enrichBuildWithSymbols(cwd, files, resolve) {
15686
15686
  const config = await loadGdgraphConfig(cwd);
15687
15687
  const treesitterConfig = {
@@ -15697,12 +15697,12 @@ async function enrichBuildWithSymbols(cwd, files, resolve) {
15697
15697
  return { enriched: true, symbols: layer.symbols.length, calls: layer.calls.length };
15698
15698
  }
15699
15699
  async function writeSymbolLayer(cwd, layer) {
15700
- const storageDir = path53.join(cwd, ".metaproject", "data", "gdgraph", "storage");
15700
+ const storageDir = path54.join(cwd, ".metaproject", "data", "gdgraph", "storage");
15701
15701
  await mkdir12(storageDir, { recursive: true });
15702
- await writeFile6(path53.join(storageDir, "symbols.jsonl"), layer.symbols.map((symbol) => JSON.stringify(symbol)).join(`
15702
+ await writeFile6(path54.join(storageDir, "symbols.jsonl"), layer.symbols.map((symbol) => JSON.stringify(symbol)).join(`
15703
15703
  `) + `
15704
15704
  `, "utf8");
15705
- await writeFile6(path53.join(storageDir, "calls.jsonl"), layer.calls.map((call) => JSON.stringify(call)).join(`
15705
+ await writeFile6(path54.join(storageDir, "calls.jsonl"), layer.calls.map((call) => JSON.stringify(call)).join(`
15706
15706
  `) + `
15707
15707
  `, "utf8");
15708
15708
  }
@@ -15895,10 +15895,10 @@ var init_describes = () => {};
15895
15895
 
15896
15896
  // src/sync/provenance.ts
15897
15897
  import { mkdir as mkdir13, readFile as readFile25, writeFile as writeFile7 } from "fs/promises";
15898
- import path54 from "path";
15898
+ import path55 from "path";
15899
15899
  import { spawn } from "child_process";
15900
15900
  function provenancePath(cwd, module) {
15901
- return path54.join(cwd, ".metaproject", "data", module, ".provenance.json");
15901
+ return path55.join(cwd, ".metaproject", "data", module, ".provenance.json");
15902
15902
  }
15903
15903
  function gitCmdResult(cwd, args) {
15904
15904
  return new Promise((resolve) => {
@@ -15943,7 +15943,7 @@ async function recordProvenance(cwd, module, at) {
15943
15943
  if (!head)
15944
15944
  return;
15945
15945
  const file = provenancePath(cwd, module);
15946
- await mkdir13(path54.dirname(file), { recursive: true });
15946
+ await mkdir13(path55.dirname(file), { recursive: true });
15947
15947
  const provenance = { commit: head.commit, branch: head.branch, builtAt: at };
15948
15948
  await writeFile7(file, `${JSON.stringify(provenance, null, 2)}
15949
15949
  `, "utf8");
@@ -15968,7 +15968,7 @@ var init_provenance = __esm(() => {
15968
15968
  // src/gdgraph/staleness.ts
15969
15969
  import { spawn as spawn2 } from "child_process";
15970
15970
  import { stat as stat8 } from "fs/promises";
15971
- import path55 from "path";
15971
+ import path56 from "path";
15972
15972
  function gitStatusPorcelain(cwd) {
15973
15973
  return new Promise((resolve) => {
15974
15974
  try {
@@ -15991,10 +15991,10 @@ function gitStatusPorcelain(cwd) {
15991
15991
  });
15992
15992
  }
15993
15993
  function nodesJsonlPath(cwd) {
15994
- return path55.join(cwd, ".metaproject", "data", "gdgraph", "storage", "nodes.jsonl");
15994
+ return path56.join(cwd, ".metaproject", "data", "gdgraph", "storage", "nodes.jsonl");
15995
15995
  }
15996
15996
  function gdgraphConfigPath2(cwd) {
15997
- return path55.join(cwd, ".metaproject", "gdgraph.config.json");
15997
+ return path56.join(cwd, ".metaproject", "gdgraph.config.json");
15998
15998
  }
15999
15999
  function categorizeStatusEntries(entries, rootPrefix) {
16000
16000
  const metaprojectPrefix = `${rootPrefix}.metaproject/`;
@@ -16075,7 +16075,7 @@ async function checkGraphStaleness(cwd) {
16075
16075
  }
16076
16076
  } else {
16077
16077
  provenanceMissing = true;
16078
- const logsHeadStat = await stat8(path55.join(cwd, ".git", "logs", "HEAD")).catch(() => null);
16078
+ const logsHeadStat = await stat8(path56.join(cwd, ".git", "logs", "HEAD")).catch(() => null);
16079
16079
  if (logsHeadStat && logsHeadStat.mtimeMs > nodesStat.mtimeMs) {
16080
16080
  reasons.push("repo HEAD moved since the graph was built (no build provenance recorded; inferred from .git/logs/HEAD)");
16081
16081
  }
@@ -16104,7 +16104,7 @@ async function checkGraphStaleness(cwd) {
16104
16104
  if (projectRelative === null) {
16105
16105
  continue;
16106
16106
  }
16107
- const fileStat = await stat8(path55.join(cwd, projectRelative)).catch(() => null);
16107
+ const fileStat = await stat8(path56.join(cwd, projectRelative)).catch(() => null);
16108
16108
  if (fileStat && fileStat.mtimeMs > nodesStat.mtimeMs) {
16109
16109
  postBuildEdits.push(displayPath);
16110
16110
  }
@@ -16240,15 +16240,15 @@ var init_types3 = __esm(() => {
16240
16240
 
16241
16241
  // src/wiki/collect.ts
16242
16242
  import { readFile as readFile26, readdir as readdir11 } from "fs/promises";
16243
- import path56 from "path";
16243
+ import path57 from "path";
16244
16244
  function wikiRootPath(cwd) {
16245
- return path56.join(cwd, ".metaproject", "wiki");
16245
+ return path57.join(cwd, ".metaproject", "wiki");
16246
16246
  }
16247
16247
  async function collectPages(cwd) {
16248
16248
  const root = wikiRootPath(cwd);
16249
16249
  const pages = [];
16250
16250
  for (const { type, folder } of WIKI_PAGE_TYPES) {
16251
- const dir = path56.join(root, folder);
16251
+ const dir = path57.join(root, folder);
16252
16252
  let names;
16253
16253
  try {
16254
16254
  names = await readdir11(dir);
@@ -16263,7 +16263,7 @@ async function collectPages(cwd) {
16263
16263
  if (!entry.endsWith(".md")) {
16264
16264
  continue;
16265
16265
  }
16266
- const absolutePath = path56.join(dir, entry);
16266
+ const absolutePath = path57.join(dir, entry);
16267
16267
  let content;
16268
16268
  try {
16269
16269
  content = await readFile26(absolutePath, "utf8");
@@ -17073,7 +17073,7 @@ var init_section_index = __esm(() => {
17073
17073
  });
17074
17074
 
17075
17075
  // src/security/guard.ts
17076
- import path57 from "path";
17076
+ import path58 from "path";
17077
17077
  function prepareOutputForPersistence(guard, original) {
17078
17078
  if (!guard.allowed) {
17079
17079
  return { allowed: false, reason: guard.reason ?? "security gate blocked" };
@@ -17091,7 +17091,7 @@ function prepareOutputForPersistence(guard, original) {
17091
17091
  };
17092
17092
  }
17093
17093
  async function resolveManifestSecurityState(cwd) {
17094
- const manifestPath = path57.join(securityProjectRoot(cwd), ".metaproject", "metaproject.json");
17094
+ const manifestPath = path58.join(securityProjectRoot(cwd), ".metaproject", "metaproject.json");
17095
17095
  if (!await pathExists(manifestPath)) {
17096
17096
  return { enabled: false, manifestUnreadable: false };
17097
17097
  }
@@ -17298,9 +17298,9 @@ var MEMORY_EMBEDDING_ID = "memory.embedding", DEFAULT_EMBED_DIMS = 96;
17298
17298
  // src/memory/embedding/index.ts
17299
17299
  import { createHash as createHash10 } from "crypto";
17300
17300
  import { mkdir as mkdir14, readFile as readFile27, writeFile as writeFile8 } from "fs/promises";
17301
- import path58 from "path";
17301
+ import path59 from "path";
17302
17302
  function embeddingsDir(cwd) {
17303
- return path58.join(cwd, ".metaproject", "data", "memory", "embeddings");
17303
+ return path59.join(cwd, ".metaproject", "data", "memory", "embeddings");
17304
17304
  }
17305
17305
  function entryText(entry) {
17306
17306
  return `${entry.title}
@@ -17329,17 +17329,17 @@ async function buildEmbeddingIndex(cwd, entries, embedder, model, now) {
17329
17329
  };
17330
17330
  const dir = embeddingsDir(cwd);
17331
17331
  await mkdir14(dir, { recursive: true });
17332
- await writeFile8(path58.join(dir, "index.meta.json"), `${JSON.stringify(meta, null, 2)}
17332
+ await writeFile8(path59.join(dir, "index.meta.json"), `${JSON.stringify(meta, null, 2)}
17333
17333
  `, "utf8");
17334
- await writeFile8(path58.join(dir, "vectors.jsonl"), records.map((record) => JSON.stringify(record)).join(`
17334
+ await writeFile8(path59.join(dir, "vectors.jsonl"), records.map((record) => JSON.stringify(record)).join(`
17335
17335
  `) + (records.length > 0 ? `
17336
17336
  ` : ""), "utf8");
17337
17337
  return toIndex(meta, records);
17338
17338
  }
17339
17339
  async function loadEmbeddingIndex(cwd) {
17340
17340
  const dir = embeddingsDir(cwd);
17341
- const metaPath = path58.join(dir, "index.meta.json");
17342
- const vectorsPath = path58.join(dir, "vectors.jsonl");
17341
+ const metaPath = path59.join(dir, "index.meta.json");
17342
+ const vectorsPath = path59.join(dir, "vectors.jsonl");
17343
17343
  if (!await pathExists(metaPath) || !await pathExists(vectorsPath)) {
17344
17344
  return null;
17345
17345
  }
@@ -17420,10 +17420,10 @@ var init_embedding = __esm(() => {
17420
17420
  });
17421
17421
 
17422
17422
  // src/wiki/section-tombstone.ts
17423
- import path59 from "path";
17423
+ import path60 from "path";
17424
17424
  import { stat as stat9 } from "fs/promises";
17425
17425
  function sectionRegistryPath(cwd) {
17426
- return path59.join(cwd, ".metaproject", "wiki", ".sections.json");
17426
+ return path60.join(cwd, ".metaproject", "wiki", ".sections.json");
17427
17427
  }
17428
17428
  function emptySectionRegistry() {
17429
17429
  return { version: SECTION_REGISTRY_VERSION, entries: [], tombstones: [], lifted: [] };
@@ -17725,10 +17725,10 @@ var init_section_tombstone = __esm(() => {
17725
17725
 
17726
17726
  // src/memory/cross-layer.ts
17727
17727
  import { readFile as readFile28 } from "fs/promises";
17728
- import path60 from "path";
17728
+ import path61 from "path";
17729
17729
  function extractWikiReferences(entryRelativePath, entryAbsolutePath, content, wikiRoot) {
17730
17730
  const references = [];
17731
- const entryDir = path60.dirname(entryAbsolutePath);
17731
+ const entryDir = path61.dirname(entryAbsolutePath);
17732
17732
  const lines = content.split(`
17733
17733
  `);
17734
17734
  for (let index = 0;index < lines.length; index += 1) {
@@ -17743,16 +17743,16 @@ function extractWikiReferences(entryRelativePath, entryAbsolutePath, content, wi
17743
17743
  if (withoutAnchor.length === 0) {
17744
17744
  continue;
17745
17745
  }
17746
- const absolute = path60.resolve(entryDir, withoutAnchor);
17747
- const relativeToWiki = path60.relative(wikiRoot, absolute);
17748
- if (relativeToWiki.startsWith("..") || path60.isAbsolute(relativeToWiki)) {
17746
+ const absolute = path61.resolve(entryDir, withoutAnchor);
17747
+ const relativeToWiki = path61.relative(wikiRoot, absolute);
17748
+ if (relativeToWiki.startsWith("..") || path61.isAbsolute(relativeToWiki)) {
17749
17749
  continue;
17750
17750
  }
17751
17751
  references.push({
17752
17752
  entry: entryRelativePath,
17753
17753
  kind: "page-path",
17754
17754
  raw: href,
17755
- target: relativeToWiki.split(path60.sep).join("/"),
17755
+ target: relativeToWiki.split(path61.sep).join("/"),
17756
17756
  line
17757
17757
  });
17758
17758
  }
@@ -17772,7 +17772,7 @@ function isDangling(finding) {
17772
17772
  return finding.state !== "intact";
17773
17773
  }
17774
17774
  async function loadWikiKnowledgeView(cwd) {
17775
- const wikiRoot = path60.join(cwd, ".metaproject", "wiki");
17775
+ const wikiRoot = path61.join(cwd, ".metaproject", "wiki");
17776
17776
  const pages = await collectPages(cwd);
17777
17777
  const index = buildSectionIndex(await Promise.all(pages.map(async (page) => ({
17778
17778
  page,
@@ -17990,7 +17990,7 @@ function round2(value) {
17990
17990
  var init_dedup = () => {};
17991
17991
 
17992
17992
  // src/memory/check.ts
17993
- import path61 from "path";
17993
+ import path62 from "path";
17994
17994
  async function checkMemory(cwd, config) {
17995
17995
  const entries = await collectEntries(cwd);
17996
17996
  const issues = [];
@@ -18006,7 +18006,7 @@ async function checkMemory(cwd, config) {
18006
18006
  }
18007
18007
  for (const file of entry.scopes.files) {
18008
18008
  const clean = file.replace(/^`|`$/g, "");
18009
- if (!await pathExists(path61.resolve(cwd, clean))) {
18009
+ if (!await pathExists(path62.resolve(cwd, clean))) {
18010
18010
  issues.push({ path: entry.relativePath, kind: "link", message: `related file not found: ${clean}` });
18011
18011
  }
18012
18012
  }
@@ -18061,12 +18061,12 @@ var init_check = __esm(() => {
18061
18061
 
18062
18062
  // src/memory/write.ts
18063
18063
  import { mkdir as mkdir15, open as open2, readFile as readFile29, rename as rename5, rm as rm4, writeFile as writeFile9 } from "fs/promises";
18064
- import path62 from "path";
18064
+ import path63 from "path";
18065
18065
  async function resolveCanonicalEntryPath(cwd, relativePath) {
18066
- const root = path62.resolve(memoryRoot(cwd));
18067
- const absolutePath = path62.resolve(root, relativePath);
18068
- const normalized = toPosix2(path62.relative(root, absolutePath));
18069
- if (!normalized || normalized.startsWith("../") || path62.isAbsolute(normalized) || !normalized.endsWith(".md")) {
18066
+ const root = path63.resolve(memoryRoot(cwd));
18067
+ const absolutePath = path63.resolve(root, relativePath);
18068
+ const normalized = toPosix2(path63.relative(root, absolutePath));
18069
+ if (!normalized || normalized.startsWith("../") || path63.isAbsolute(normalized) || !normalized.endsWith(".md")) {
18070
18070
  return null;
18071
18071
  }
18072
18072
  return { absolutePath, relativePath: normalized };
@@ -18162,9 +18162,9 @@ function validateNextEntry(relativePath, content) {
18162
18162
  return null;
18163
18163
  }
18164
18164
  async function replaceAtomically(target, content) {
18165
- const dir = path62.dirname(target);
18165
+ const dir = path63.dirname(target);
18166
18166
  await mkdir15(dir, { recursive: true });
18167
- const tmp = path62.join(dir, `.${path62.basename(target)}.keryx-tmp-${process.pid}-${Math.random().toString(16).slice(2)}`);
18167
+ const tmp = path63.join(dir, `.${path63.basename(target)}.keryx-tmp-${process.pid}-${Math.random().toString(16).slice(2)}`);
18168
18168
  try {
18169
18169
  await writeFile9(tmp, content, "utf8");
18170
18170
  const file = await open2(tmp, "r");
@@ -18200,7 +18200,7 @@ function header(content, name) {
18200
18200
  return content.match(new RegExp(`^${name}:\\s*(.+)$`, "mi"))?.[1]?.trim() ?? null;
18201
18201
  }
18202
18202
  function toPosix2(value) {
18203
- return value.split(path62.sep).join("/");
18203
+ return value.split(path63.sep).join("/");
18204
18204
  }
18205
18205
  function message(cause) {
18206
18206
  return cause instanceof Error ? cause.message : String(cause);
@@ -18214,9 +18214,9 @@ var init_write = __esm(() => {
18214
18214
  // src/memory/ingest.ts
18215
18215
  import { existsSync as existsSync5 } from "fs";
18216
18216
  import { readFile as readFile30 } from "fs/promises";
18217
- import path63 from "path";
18217
+ import path64 from "path";
18218
18218
  async function ingestMemory(cwd, source, filePath, config, now) {
18219
- const absolute = path63.resolve(cwd, filePath);
18219
+ const absolute = path64.resolve(cwd, filePath);
18220
18220
  if (!await pathExists(absolute)) {
18221
18221
  throw new Error(`Ingest source not found: ${filePath}`);
18222
18222
  }
@@ -18233,8 +18233,8 @@ async function ingestMemory(cwd, source, filePath, config, now) {
18233
18233
  const securityWarnings = [];
18234
18234
  const securitySkipped = [];
18235
18235
  let skippedDuplicates = 0;
18236
- const dir = path63.join(memoryRoot(cwd), folder);
18237
- const link = path63.relative(cwd, absolute);
18236
+ const dir = path64.join(memoryRoot(cwd), folder);
18237
+ const link = path64.relative(cwd, absolute);
18238
18238
  const date = dateString(now);
18239
18239
  for (const text of candidates) {
18240
18240
  const title = toTitle(text);
@@ -18415,7 +18415,7 @@ function uniqueSlug(dir, title) {
18415
18415
  const base = slugify2(title) || "entry";
18416
18416
  let slug = base;
18417
18417
  let counter = 2;
18418
- while (existsSync5(path63.join(dir, `${slug}.md`))) {
18418
+ while (existsSync5(path64.join(dir, `${slug}.md`))) {
18419
18419
  slug = `${base}-${counter}`;
18420
18420
  counter += 1;
18421
18421
  }
@@ -18450,7 +18450,7 @@ var init_ingest = __esm(() => {
18450
18450
 
18451
18451
  // src/memory/supersede.ts
18452
18452
  import { readFile as readFile31 } from "fs/promises";
18453
- import path64 from "path";
18453
+ import path65 from "path";
18454
18454
  async function supersedeEntry(input, now) {
18455
18455
  const date = input.date ?? now.toISOString().slice(0, 10);
18456
18456
  const today = now.toISOString().slice(0, 10);
@@ -18510,12 +18510,12 @@ async function supersedeEntry(input, now) {
18510
18510
  async function resolveEntryPath(cwd, raw) {
18511
18511
  const root = memoryRoot(cwd);
18512
18512
  const candidates = [
18513
- path64.resolve(cwd, raw),
18514
- path64.resolve(root, raw),
18515
- path64.isAbsolute(raw) ? raw : path64.join(cwd, raw)
18513
+ path65.resolve(cwd, raw),
18514
+ path65.resolve(root, raw),
18515
+ path65.isAbsolute(raw) ? raw : path65.join(cwd, raw)
18516
18516
  ];
18517
18517
  for (const absolute of candidates) {
18518
- const confined = await resolveCanonicalEntryPath(cwd, path64.relative(root, absolute));
18518
+ const confined = await resolveCanonicalEntryPath(cwd, path65.relative(root, absolute));
18519
18519
  if (confined && await pathExists(confined.absolutePath)) {
18520
18520
  return { absolute: confined.absolutePath, relative: confined.relativePath };
18521
18521
  }
@@ -18711,9 +18711,9 @@ __export(exports_service3, {
18711
18711
  });
18712
18712
  import { createHash as createHash11 } from "crypto";
18713
18713
  import { mkdir as mkdir16, readFile as readFile32, writeFile as writeFile10 } from "fs/promises";
18714
- import path65 from "path";
18714
+ import path66 from "path";
18715
18715
  function dataRoot2(cwd) {
18716
- return path65.join(cwd, ".metaproject", "data", "memory");
18716
+ return path66.join(cwd, ".metaproject", "data", "memory");
18717
18717
  }
18718
18718
  function createMemoryService() {
18719
18719
  const reportStore = createMemoryReportStore();
@@ -18728,9 +18728,9 @@ function createMemoryService() {
18728
18728
  if (!/^[a-z0-9][a-z0-9-]*$/.test(slug)) {
18729
18729
  throw new Error(`Invalid slug: ${slug}. Use lowercase letters, digits, and hyphens.`);
18730
18730
  }
18731
- const dir = path65.join(memoryRoot(input.cwd), typeConfig.folder);
18732
- const filePath = path65.join(dir, `${slug}.md`);
18733
- const relativePath = path65.relative(input.cwd, filePath);
18731
+ const dir = path66.join(memoryRoot(input.cwd), typeConfig.folder);
18732
+ const filePath = path66.join(dir, `${slug}.md`);
18733
+ const relativePath = path66.relative(input.cwd, filePath);
18734
18734
  if (await pathExists(filePath) && !input.force) {
18735
18735
  throw new Error(`Entry already exists: ${relativePath}. Use --force to overwrite.`);
18736
18736
  }
@@ -18761,9 +18761,9 @@ function createMemoryService() {
18761
18761
  async index(input) {
18762
18762
  const entries = await collectEntries(input.cwd);
18763
18763
  const generatedAt = new Date().toISOString();
18764
- const indexDir = path65.join(dataRoot2(input.cwd), "index");
18764
+ const indexDir = path66.join(dataRoot2(input.cwd), "index");
18765
18765
  await mkdir16(indexDir, { recursive: true });
18766
- const indexPath = path65.join(indexDir, "index.json");
18766
+ const indexPath = path66.join(indexDir, "index.json");
18767
18767
  await writeFile10(indexPath, `${JSON.stringify({
18768
18768
  catalogVersion: 1,
18769
18769
  sourceFingerprint: createHash11("sha256").update(JSON.stringify(entries.map((e) => ({
@@ -18784,7 +18784,7 @@ function createMemoryService() {
18784
18784
  }, null, 2)}
18785
18785
  `, "utf8");
18786
18786
  const result = {
18787
- path: path65.relative(input.cwd, indexPath),
18787
+ path: path66.relative(input.cwd, indexPath),
18788
18788
  entryCount: entries.length,
18789
18789
  generatedAt
18790
18790
  };
@@ -18797,7 +18797,7 @@ function createMemoryService() {
18797
18797
  const built = await buildEmbeddingIndex(input.cwd, entries, embedder.embed, embedder.model, new Date);
18798
18798
  result.embeddings = {
18799
18799
  built: true,
18800
- path: path65.relative(input.cwd, embeddingsDir(input.cwd)),
18800
+ path: path66.relative(input.cwd, embeddingsDir(input.cwd)),
18801
18801
  vectorCount: built.meta.entryCount,
18802
18802
  model: built.meta.model
18803
18803
  };
@@ -19399,7 +19399,7 @@ var init_ask = __esm(() => {
19399
19399
  });
19400
19400
 
19401
19401
  // src/wiki/backlinks.ts
19402
- import path66 from "path";
19402
+ import path67 from "path";
19403
19403
  function extractCodePaths(content) {
19404
19404
  const out = [];
19405
19405
  let match;
@@ -19429,8 +19429,8 @@ function resolveLink(fromRepoPath, raw) {
19429
19429
  const clean = (raw.split("#")[0] ?? "").trim();
19430
19430
  if (!clean)
19431
19431
  return "";
19432
- const fromDir = path66.posix.dirname(fromRepoPath.split(path66.sep).join("/"));
19433
- return path66.posix.normalize(path66.posix.join(fromDir, clean));
19432
+ const fromDir = path67.posix.dirname(fromRepoPath.split(path67.sep).join("/"));
19433
+ return path67.posix.normalize(path67.posix.join(fromDir, clean));
19434
19434
  }
19435
19435
  function buildBacklinkIndex(pages) {
19436
19436
  const index = new Map;
@@ -19444,18 +19444,18 @@ function buildBacklinkIndex(pages) {
19444
19444
  }
19445
19445
  };
19446
19446
  for (const page of pages) {
19447
- const from = page.repoPath.split(path66.sep).join("/");
19447
+ const from = page.repoPath.split(path67.sep).join("/");
19448
19448
  for (const raw of extractLinks(page.content))
19449
19449
  add(resolveLink(from, raw), from);
19450
19450
  for (const raw of extractCodePaths(page.content))
19451
- add(path66.posix.normalize(raw), from);
19451
+ add(path67.posix.normalize(raw), from);
19452
19452
  }
19453
19453
  for (const list of index.values())
19454
19454
  list.sort();
19455
19455
  return index;
19456
19456
  }
19457
19457
  function backlinksFor(index, targetRepoPath) {
19458
- const key = path66.posix.normalize(targetRepoPath.split(path66.sep).join("/"));
19458
+ const key = path67.posix.normalize(targetRepoPath.split(path67.sep).join("/"));
19459
19459
  return index.get(key) ?? [];
19460
19460
  }
19461
19461
  var LINK, CODE_SPAN, FILE_LIKE;
@@ -19468,7 +19468,7 @@ var init_backlinks = __esm(() => {
19468
19468
  // src/ctx/assembly.ts
19469
19469
  import { createHash as createHash12 } from "crypto";
19470
19470
  import { mkdir as mkdir17, rename as rename6, writeFile as writeFile11 } from "fs/promises";
19471
- import path67 from "path";
19471
+ import path68 from "path";
19472
19472
  function assembleContext(input) {
19473
19473
  let items = 0;
19474
19474
  let tokens = 0;
@@ -19512,9 +19512,9 @@ async function recordNoContentContext(input) {
19512
19512
  return assembly;
19513
19513
  }
19514
19514
  async function recordContextAssembly(input) {
19515
- const directory = path67.join(input.workspaceRoot, ".metaproject", "context-operations", "traces");
19515
+ const directory = path68.join(input.workspaceRoot, ".metaproject", "context-operations", "traces");
19516
19516
  await mkdir17(directory, { recursive: true });
19517
- const target = path67.join(directory, path67.basename(input.assembly.traceRef));
19517
+ const target = path68.join(directory, path68.basename(input.assembly.traceRef));
19518
19518
  const temporary = `${target}.${process.pid}.tmp`;
19519
19519
  await writeFile11(temporary, `${JSON.stringify({ schemaVersion: "1.0", correlationId: input.correlationId, outcome: input.outcome, configurationRevision: input.assembly.configurationRevision, policy: { ref: input.assembly.policyRef, revision: input.assembly.policyRevision }, selected: input.assembly.selected, omittedOptional: input.assembly.omittedOptional, partial: input.assembly.partial })}
19520
19520
  `, { mode: 384 });
@@ -20365,15 +20365,15 @@ __export(exports_service4, {
20365
20365
  import { spawn as spawn3 } from "child_process";
20366
20366
  import { createHash as createHash14 } from "crypto";
20367
20367
  import { mkdir as mkdir18, readFile as readFile34, readdir as readdir12, rm as rm5, writeFile as writeFile12 } from "fs/promises";
20368
- import path68 from "path";
20368
+ import path69 from "path";
20369
20369
  function wikiRootPath2(cwd) {
20370
- return path68.join(cwd, ".metaproject", "wiki");
20370
+ return path69.join(cwd, ".metaproject", "wiki");
20371
20371
  }
20372
20372
  function dataRootPath(cwd) {
20373
- return path68.join(cwd, ".metaproject", "data", "gdwiki");
20373
+ return path69.join(cwd, ".metaproject", "data", "gdwiki");
20374
20374
  }
20375
20375
  function linkCheckReportPath(cwd) {
20376
- return path68.join(dataRootPath(cwd), "link-check", "latest.md");
20376
+ return path69.join(dataRootPath(cwd), "link-check", "latest.md");
20377
20377
  }
20378
20378
  async function wikiStatus(cwd) {
20379
20379
  const root = wikiRootPath2(cwd);
@@ -20381,7 +20381,7 @@ async function wikiStatus(cwd) {
20381
20381
  const pages = enabled ? await collectPages(cwd) : [];
20382
20382
  return {
20383
20383
  enabled,
20384
- wikiRoot: path68.relative(cwd, root),
20384
+ wikiRoot: path69.relative(cwd, root),
20385
20385
  totalPages: pages.length,
20386
20386
  countsByType: WIKI_PAGE_TYPES.map(({ type }) => ({
20387
20387
  type,
@@ -20412,9 +20412,9 @@ async function wikiCreatePage(input) {
20412
20412
  if (!/^[a-z0-9][a-z0-9-]*$/.test(input.slug)) {
20413
20413
  throw new Error(`Invalid slug: ${input.slug}. Use lowercase letters, digits, and hyphens.`);
20414
20414
  }
20415
- const dir = path68.join(wikiRootPath2(input.cwd), typeConfig.folder);
20416
- const filePath = path68.join(dir, `${input.slug}.md`);
20417
- const relativePath = path68.relative(input.cwd, filePath);
20415
+ const dir = path69.join(wikiRootPath2(input.cwd), typeConfig.folder);
20416
+ const filePath = path69.join(dir, `${input.slug}.md`);
20417
+ const relativePath = path69.relative(input.cwd, filePath);
20418
20418
  if (await pathExists(filePath) && !input.force) {
20419
20419
  throw new Error(`Page already exists: ${relativePath}. Use --force to overwrite.`);
20420
20420
  }
@@ -20425,7 +20425,7 @@ async function wikiCreatePage(input) {
20425
20425
  }
20426
20426
  async function wikiGenerateIndex(cwd) {
20427
20427
  const root = wikiRootPath2(cwd);
20428
- const indexPath = path68.join(root, "index.md");
20428
+ const indexPath = path69.join(root, "index.md");
20429
20429
  const pages = await collectPages(cwd);
20430
20430
  const generatedAt = new Date().toISOString();
20431
20431
  const managedBlock = `${WIKI_INDEX_BEGIN}
@@ -20443,7 +20443,7 @@ ${managedBlock}
20443
20443
  await mkdir18(root, { recursive: true });
20444
20444
  await writeFile12(indexPath, next, "utf8");
20445
20445
  return {
20446
- path: path68.relative(cwd, indexPath),
20446
+ path: path69.relative(cwd, indexPath),
20447
20447
  pageCount: pages.length,
20448
20448
  generatedAt
20449
20449
  };
@@ -20451,13 +20451,13 @@ ${managedBlock}
20451
20451
  async function wikiCheckLinks(cwd) {
20452
20452
  const root = wikiRootPath2(cwd);
20453
20453
  const allFiles = await pathExists(root) ? await walkMarkdown(root) : [];
20454
- const files = allFiles.filter((absolutePath) => !path68.relative(root, absolutePath).startsWith(`templates${path68.sep}`));
20454
+ const files = allFiles.filter((absolutePath) => !path69.relative(root, absolutePath).startsWith(`templates${path69.sep}`));
20455
20455
  const broken = [];
20456
20456
  let checkedLinks = 0;
20457
20457
  let skippedExternal = 0;
20458
20458
  for (const absolutePath of files) {
20459
20459
  const content = await readFile34(absolutePath, "utf8");
20460
- const pageRelative = path68.relative(cwd, absolutePath);
20460
+ const pageRelative = path69.relative(cwd, absolutePath);
20461
20461
  for (const target of extractLinkTargets(content)) {
20462
20462
  if (EXTERNAL_LINK.test(target)) {
20463
20463
  skippedExternal += 1;
@@ -20468,7 +20468,7 @@ async function wikiCheckLinks(cwd) {
20468
20468
  continue;
20469
20469
  }
20470
20470
  checkedLinks += 1;
20471
- const resolved = path68.resolve(path68.dirname(absolutePath), filePart);
20471
+ const resolved = path69.resolve(path69.dirname(absolutePath), filePart);
20472
20472
  if (!await pathExists(resolved)) {
20473
20473
  broken.push({
20474
20474
  page: pageRelative,
@@ -20480,7 +20480,7 @@ async function wikiCheckLinks(cwd) {
20480
20480
  }
20481
20481
  const generatedAt = new Date().toISOString();
20482
20482
  const reportPath = linkCheckReportPath(cwd);
20483
- await mkdir18(path68.dirname(reportPath), { recursive: true });
20483
+ await mkdir18(path69.dirname(reportPath), { recursive: true });
20484
20484
  await writeFile12(reportPath, renderLinkCheckReport({
20485
20485
  generatedAt,
20486
20486
  checkedPages: files.length,
@@ -20489,7 +20489,7 @@ async function wikiCheckLinks(cwd) {
20489
20489
  broken
20490
20490
  }), "utf8");
20491
20491
  return {
20492
- reportPath: path68.relative(cwd, reportPath),
20492
+ reportPath: path69.relative(cwd, reportPath),
20493
20493
  checkedPages: files.length,
20494
20494
  checkedLinks,
20495
20495
  skippedExternal,
@@ -20539,7 +20539,7 @@ async function wikiValidate(cwd) {
20539
20539
  }
20540
20540
  if (await isIndexStale(cwd, pages)) {
20541
20541
  issues.push({
20542
- page: path68.join(path68.relative(cwd, wikiRootPath2(cwd)), "index.md"),
20542
+ page: path69.join(path69.relative(cwd, wikiRootPath2(cwd)), "index.md"),
20543
20543
  kind: "index",
20544
20544
  message: "index out of date, run `keryx wiki index`"
20545
20545
  });
@@ -20576,7 +20576,7 @@ async function wikiCollect(input) {
20576
20576
  };
20577
20577
  }
20578
20578
  async function wikiPruneOrphans(cwd) {
20579
- const componentsDir = path68.join(wikiRootPath2(cwd), "components");
20579
+ const componentsDir = path69.join(wikiRootPath2(cwd), "components");
20580
20580
  if (!await pathExists(componentsDir)) {
20581
20581
  return { pruned: [], orphanedAccepted: [] };
20582
20582
  }
@@ -20593,20 +20593,20 @@ async function wikiPruneOrphans(cwd) {
20593
20593
  if (validSlugs.has(slug)) {
20594
20594
  continue;
20595
20595
  }
20596
- const filePath = path68.join(componentsDir, entry);
20596
+ const filePath = path69.join(componentsDir, entry);
20597
20597
  const current = await readFile34(filePath, "utf8");
20598
20598
  const isUnmodifiedDraft = /\nStatus:\s*draft\s*\n/.test(current) && current.includes("Generated by `keryx wiki collect`");
20599
20599
  if (isUnmodifiedDraft) {
20600
20600
  await rm5(filePath);
20601
- pruned.push(path68.relative(cwd, filePath));
20601
+ pruned.push(path69.relative(cwd, filePath));
20602
20602
  } else {
20603
- orphanedAccepted.push(path68.relative(cwd, filePath));
20603
+ orphanedAccepted.push(path69.relative(cwd, filePath));
20604
20604
  }
20605
20605
  }
20606
20606
  return { pruned, orphanedAccepted };
20607
20607
  }
20608
20608
  async function validModuleNames(cwd) {
20609
- const nodesPath = path68.join(cwd, ".metaproject", "data", "gdgraph", "storage", "nodes.jsonl");
20609
+ const nodesPath = path69.join(cwd, ".metaproject", "data", "gdgraph", "storage", "nodes.jsonl");
20610
20610
  if (!await pathExists(nodesPath)) {
20611
20611
  return;
20612
20612
  }
@@ -20676,9 +20676,9 @@ async function wikiEvidence(input) {
20676
20676
  });
20677
20677
  }
20678
20678
  function resolveEvidenceScope(cwd, override) {
20679
- const absolute = path68.resolve(cwd);
20679
+ const absolute = path69.resolve(cwd);
20680
20680
  return {
20681
- projectId: override?.projectId ?? (path68.basename(absolute) || "project"),
20681
+ projectId: override?.projectId ?? (path69.basename(absolute) || "project"),
20682
20682
  checkoutId: override?.checkoutId ?? `checkout:${createHash14("sha256").update(absolute).digest("hex").slice(0, 16)}`,
20683
20683
  ...override?.workspaceId ? { workspaceId: override.workspaceId } : {},
20684
20684
  ...override?.taskId ? { taskId: override.taskId } : {}
@@ -20693,7 +20693,7 @@ function isMachineAuthoredPage(pageType, relativePath, content) {
20693
20693
  if (source === null) {
20694
20694
  return false;
20695
20695
  }
20696
- const normalised = relativePath.split(path68.sep).join("/").replace(/^wiki\//, "");
20696
+ const normalised = relativePath.split(path69.sep).join("/").replace(/^wiki\//, "");
20697
20697
  return WIKI_PAGE_PRODUCERS.some((producer) => producer.source === source && producer.pageType === pageType && producer.path.test(normalised) && /^-[ \t]+Link:.*\bsha256\b/m.test(content));
20698
20698
  }
20699
20699
  function createGdWikiService() {
@@ -20709,8 +20709,8 @@ function createGdWikiService() {
20709
20709
  };
20710
20710
  }
20711
20711
  async function collectGraphWikiCandidates(cwd, generatedAt, limit, onlyModules) {
20712
- const nodesPath = path68.join(cwd, ".metaproject", "data", "gdgraph", "storage", "nodes.jsonl");
20713
- const edgesPath = path68.join(cwd, ".metaproject", "data", "gdgraph", "storage", "edges.jsonl");
20712
+ const nodesPath = path69.join(cwd, ".metaproject", "data", "gdgraph", "storage", "nodes.jsonl");
20713
+ const edgesPath = path69.join(cwd, ".metaproject", "data", "gdgraph", "storage", "edges.jsonl");
20714
20714
  if (!await pathExists(nodesPath) || !await pathExists(edgesPath)) {
20715
20715
  return [];
20716
20716
  }
@@ -20894,7 +20894,7 @@ function topCounts(bucket, limit) {
20894
20894
  return [...bucket.entries()].sort((a, b) => b[1] - a[1]).slice(0, limit);
20895
20895
  }
20896
20896
  async function readModuleReadme(cwd, moduleName) {
20897
- const readmePath = path68.join(cwd, ...moduleName.split("/"), "README.md");
20897
+ const readmePath = path69.join(cwd, ...moduleName.split("/"), "README.md");
20898
20898
  if (!await pathExists(readmePath)) {
20899
20899
  return null;
20900
20900
  }
@@ -20915,7 +20915,7 @@ async function extractModuleExports(cwd, files) {
20915
20915
  const declRe = /export\s+(?:async\s+)?(?:default\s+)?(?:const|let|var|function|class|type|interface|enum)\s+([A-Za-z_$][\w$]*)/g;
20916
20916
  const braceRe = /export\s*\{([^}]+)\}/g;
20917
20917
  for (const file of files.slice(0, 4)) {
20918
- const filePath = path68.join(cwd, ...file.split("/"));
20918
+ const filePath = path69.join(cwd, ...file.split("/"));
20919
20919
  if (!await pathExists(filePath)) {
20920
20920
  continue;
20921
20921
  }
@@ -20946,7 +20946,7 @@ async function extractModuleExports(cwd, files) {
20946
20946
  }
20947
20947
  async function extractModuleApi(cwd, files) {
20948
20948
  const names = await extractModuleExports(cwd, files);
20949
- const symbolsPath = path68.join(cwd, ".metaproject", "data", "gdgraph", "storage", "symbols.jsonl");
20949
+ const symbolsPath = path69.join(cwd, ".metaproject", "data", "gdgraph", "storage", "symbols.jsonl");
20950
20950
  if (names.length === 0 || !await pathExists(symbolsPath)) {
20951
20951
  return names.map((name) => "`" + name + "`");
20952
20952
  }
@@ -20972,7 +20972,7 @@ async function extractModuleApi(cwd, files) {
20972
20972
  });
20973
20973
  }
20974
20974
  async function collectHealthWikiCandidates(cwd, generatedAt) {
20975
- const healthPath = path68.join(cwd, ".metaproject", "data", "health", "artifacts", "latest.json");
20975
+ const healthPath = path69.join(cwd, ".metaproject", "data", "health", "artifacts", "latest.json");
20976
20976
  if (!await pathExists(healthPath)) {
20977
20977
  return [];
20978
20978
  }
@@ -21014,7 +21014,7 @@ async function collectHealthWikiCandidates(cwd, generatedAt) {
21014
21014
  }];
21015
21015
  }
21016
21016
  async function collectTestingWikiCandidates(cwd, generatedAt) {
21017
- const contextPath = path68.join(cwd, ".metaproject", "data", "testing", "context.md");
21017
+ const contextPath = path69.join(cwd, ".metaproject", "data", "testing", "context.md");
21018
21018
  if (!await pathExists(contextPath)) {
21019
21019
  return [];
21020
21020
  }
@@ -21045,8 +21045,8 @@ async function writeCollectedPage(cwd, candidate, force) {
21045
21045
  if (!folder) {
21046
21046
  throw new Error(`Unsupported collected wiki type: ${candidate.type}`);
21047
21047
  }
21048
- const filePath = path68.join(wikiRootPath2(cwd), folder, `${candidate.slug}.md`);
21049
- const relativePath = path68.relative(cwd, filePath);
21048
+ const filePath = path69.join(wikiRootPath2(cwd), folder, `${candidate.slug}.md`);
21049
+ const relativePath = path69.relative(cwd, filePath);
21050
21050
  const exists = await pathExists(filePath);
21051
21051
  if (exists && !force) {
21052
21052
  return { path: relativePath, type: candidate.type, source: candidate.source, action: "skipped" };
@@ -21074,7 +21074,7 @@ async function writeCollectedPage(cwd, candidate, force) {
21074
21074
  securityReason: output.reason
21075
21075
  };
21076
21076
  }
21077
- await mkdir18(path68.dirname(filePath), { recursive: true });
21077
+ await mkdir18(path69.dirname(filePath), { recursive: true });
21078
21078
  await writeFile12(filePath, output.content, "utf8");
21079
21079
  return {
21080
21080
  path: relativePath,
@@ -21086,7 +21086,7 @@ async function writeCollectedPage(cwd, candidate, force) {
21086
21086
  async function wikiPagesForFile(cwd, targetRepoPath) {
21087
21087
  const pages = await collectPages(cwd);
21088
21088
  const refs = await Promise.all(pages.map(async (page) => ({
21089
- repoPath: path68.relative(cwd, page.absolutePath).split(path68.sep).join("/"),
21089
+ repoPath: path69.relative(cwd, page.absolutePath).split(path69.sep).join("/"),
21090
21090
  content: await readFile34(page.absolutePath, "utf8")
21091
21091
  })));
21092
21092
  return backlinksFor(buildBacklinkIndex(refs), targetRepoPath);
@@ -21125,7 +21125,7 @@ function renderIndexBody(pages, generatedAt) {
21125
21125
  `).trimEnd();
21126
21126
  }
21127
21127
  async function isIndexStale(cwd, pages) {
21128
- const indexPath = path68.join(wikiRootPath2(cwd), "index.md");
21128
+ const indexPath = path69.join(wikiRootPath2(cwd), "index.md");
21129
21129
  if (!await pathExists(indexPath)) {
21130
21130
  return true;
21131
21131
  }
@@ -21143,7 +21143,7 @@ async function walkMarkdown(root) {
21143
21143
  const results = [];
21144
21144
  const entries = await readdir12(root, { withFileTypes: true });
21145
21145
  for (const entry of entries) {
21146
- const absolutePath = path68.join(root, entry.name);
21146
+ const absolutePath = path69.join(root, entry.name);
21147
21147
  if (entry.isDirectory()) {
21148
21148
  results.push(...await walkMarkdown(absolutePath));
21149
21149
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
@@ -21200,7 +21200,7 @@ ${JSON.stringify(state, null, 2)}
21200
21200
  `;
21201
21201
  }
21202
21202
  async function readIndexGeneratedAt(cwd) {
21203
- const indexPath = path68.join(wikiRootPath2(cwd), "index.md");
21203
+ const indexPath = path69.join(wikiRootPath2(cwd), "index.md");
21204
21204
  if (!await pathExists(indexPath)) {
21205
21205
  return null;
21206
21206
  }
@@ -21437,7 +21437,7 @@ async function validateStructure(cwd, pages, issues) {
21437
21437
  if (pattern.includes("*")) {
21438
21438
  continue;
21439
21439
  }
21440
- if (!await pathExists(path68.join(cwd, pattern))) {
21440
+ if (!await pathExists(path69.join(cwd, pattern))) {
21441
21441
  issues.push({
21442
21442
  page: page.relativePath,
21443
21443
  kind: "describes",
@@ -21508,9 +21508,9 @@ var init_service4 = __esm(() => {
21508
21508
  // src/gdgraph/wiki-layer.ts
21509
21509
  import { createHash as createHash15 } from "crypto";
21510
21510
  import { mkdir as mkdir19, stat as stat10, writeFile as writeFile13 } from "fs/promises";
21511
- import path69 from "path";
21511
+ import path70 from "path";
21512
21512
  function storageDir(projectRoot) {
21513
- return path69.join(projectRoot, ".metaproject", "data", "gdgraph", "storage");
21513
+ return path70.join(projectRoot, ".metaproject", "data", "gdgraph", "storage");
21514
21514
  }
21515
21515
  function wikiPageId(relativePath) {
21516
21516
  return `wiki:${relativePath}`;
@@ -21576,11 +21576,11 @@ async function enrichBuildWithWikiLayer(input) {
21576
21576
  const mtimes = new Map;
21577
21577
  for (const record of input.fileRecords) {
21578
21578
  try {
21579
- const info = await stat10(path69.join(input.projectRoot, record.path));
21579
+ const info = await stat10(path70.join(input.projectRoot, record.path));
21580
21580
  mtimes.set(record.path, info.mtimeMs);
21581
21581
  } catch {}
21582
21582
  }
21583
- await writeFile13(path69.join(dir, BUILD_MANIFEST_FILE), `${JSON.stringify({ version: 1, files: computeFingerprints(input.fileRecords, mtimes) }, null, 2)}
21583
+ await writeFile13(path70.join(dir, BUILD_MANIFEST_FILE), `${JSON.stringify({ version: 1, files: computeFingerprints(input.fileRecords, mtimes) }, null, 2)}
21584
21584
  `, "utf8");
21585
21585
  const validModules = input.validModules !== undefined ? input.validModules : await (input.loadValidModules ?? defaultLoadValidModules)(input.projectRoot);
21586
21586
  const wikiPages = await collectPages(input.projectRoot);
@@ -21605,8 +21605,8 @@ async function enrichBuildWithWikiLayer(input) {
21605
21605
  version: page.version
21606
21606
  }))
21607
21607
  });
21608
- await writeJsonl(path69.join(dir, WIKI_PAGES_FILE), layer.pages);
21609
- await writeJsonl(path69.join(dir, DESCRIBES_FILE), layer.describes);
21608
+ await writeJsonl(path70.join(dir, WIKI_PAGES_FILE), layer.pages);
21609
+ await writeJsonl(path70.join(dir, DESCRIBES_FILE), layer.describes);
21610
21610
  return layer;
21611
21611
  }
21612
21612
  async function defaultLoadValidModules(projectRoot) {
@@ -21629,6 +21629,9 @@ __export(exports_service2, {
21629
21629
  AC_CHECK_TOKEN_BUDGET: () => AC_CHECK_TOKEN_BUDGET,
21630
21630
  AC_KINDS: () => AC_KINDS,
21631
21631
  CONFIRMATION_CAVEAT: () => CONFIRMATION_CAVEAT,
21632
+ DEFAULT_OUTCOME_AUTHOR: () => DEFAULT_OUTCOME_AUTHOR,
21633
+ OUTCOME_AUTHORS: () => OUTCOME_AUTHORS,
21634
+ OUTCOME_AUTHOR_READINGS: () => OUTCOME_AUTHOR_READINGS,
21632
21635
  OUTCOME_HINT: () => OUTCOME_HINT,
21633
21636
  REVIEW_GATE_CONFIG_PATH: () => REVIEW_GATE_CONFIG_PATH,
21634
21637
  acCheckCacheKey: () => acCheckCacheKey,
@@ -21655,11 +21658,13 @@ __export(exports_service2, {
21655
21658
  isFrozen: () => isFrozen,
21656
21659
  notCheckableVerdict: () => notCheckableVerdict,
21657
21660
  parseAcceptanceCriteria: () => parseAcceptanceCriteria,
21661
+ parseOutcomeAuthor: () => parseOutcomeAuthor,
21658
21662
  proseOutsideFences: () => proseOutsideFences,
21659
21663
  readAcCheckCache: () => readAcCheckCache,
21660
21664
  readAcCheckEnabled: () => readAcCheckEnabled,
21661
21665
  readAcKindRecords: () => readAcKindRecords,
21662
21666
  readFlow: () => readFlow,
21667
+ readOutcomeAuthor: () => readOutcomeAuthor,
21663
21668
  renderAcCheckAdvisoryNotice: () => renderAcCheckAdvisoryNotice,
21664
21669
  renderAcCheckReport: () => renderAcCheckReport,
21665
21670
  renderAcKindDistribution: () => renderAcKindDistribution,
@@ -21671,11 +21676,13 @@ __export(exports_service2, {
21671
21676
  statusLabel: () => statusLabel,
21672
21677
  stripVerifyMarker: () => stripVerifyMarker,
21673
21678
  summarizeVerdicts: () => summarizeVerdicts,
21679
+ uncommittedFlowStateNote: () => uncommittedFlowStateNote,
21680
+ uncommittedFlowStateNotes: () => uncommittedFlowStateNotes,
21674
21681
  validateCriterionName: () => validateCriterionName,
21675
21682
  writeAcCheckCache: () => writeAcCheckCache
21676
21683
  });
21677
21684
  import { mkdir as mkdir11, readFile as readFile24 } from "fs/promises";
21678
- import path50 from "path";
21685
+ import path51 from "path";
21679
21686
 
21680
21687
  // src/flow/machine.ts
21681
21688
  var TRANSITIONS = {
@@ -23120,6 +23127,19 @@ async function reviewGate(input) {
23120
23127
  return { name: "review", status: verdict.status, detail: verdict.detail };
23121
23128
  }
23122
23129
 
23130
+ // src/flow/outcome-author.ts
23131
+ var OUTCOME_AUTHORS = ["agent", "human"];
23132
+ var OUTCOME_AUTHOR_READINGS = [...OUTCOME_AUTHORS, "unknown"];
23133
+ var DEFAULT_OUTCOME_AUTHOR = "agent";
23134
+ function readOutcomeAuthor(value) {
23135
+ return value === "agent" || value === "human" ? value : "unknown";
23136
+ }
23137
+ function parseOutcomeAuthor(raw, flag = "--outcome-author") {
23138
+ if (raw === "agent" || raw === "human")
23139
+ return raw;
23140
+ const shown = typeof raw === "string" ? `"${raw}"` : "nothing";
23141
+ throw new Error(`${flag} must be one of: ${OUTCOME_AUTHORS.join(", ")} (got ${shown}).`);
23142
+ }
23123
23143
  // src/flow/identity.ts
23124
23144
  function resolveSignerIdentity(input) {
23125
23145
  const stated = input.stated?.trim();
@@ -23406,6 +23426,11 @@ function flowStateSchema() {
23406
23426
  $ref: "#/definitions/identity",
23407
23427
  description: "The human accountable for this flow, or absent if one was never set. Never inferred: only ever written by an explicit `--owner` on `flow init` or `flow owner set`, so `basis` is always `stated`."
23408
23428
  },
23429
+ outcomeAuthor: {
23430
+ type: "string",
23431
+ enum: ["agent", "human"],
23432
+ description: "Who wrote the outcome criterion. Written by `flow init --outcome-author` (default `agent`; `human` only when the flag says so, never inferred) and changed only by `flow outcome author`, which journals the change. Absent on flows created before the field existed, and read as `unknown` (neither agent nor human). Gates nothing."
23433
+ },
23409
23434
  signatures: {
23410
23435
  type: "array",
23411
23436
  description: "Append-only signing record for `flow ac confirm` and a passing `flow complete`. Absent means never signed under this field's existence.",
@@ -23994,6 +24019,108 @@ async function readRequireConfirmationDefault(cwd) {
23994
24019
  return false;
23995
24020
  }
23996
24021
  }
24022
+ // src/flow/uncommitted-state.ts
24023
+ import path15 from "path";
24024
+ var UNCOMMITTED_LIST_CAP = 5;
24025
+ var READ_ONLY_GIT_FLAGS = ["--no-optional-locks"];
24026
+ var GIT_TIMEOUT_MS = 5000;
24027
+ var spawnGit = async (cwd, args) => {
24028
+ const proc = Bun.spawn(["git", ...args], {
24029
+ cwd,
24030
+ stdout: "pipe",
24031
+ stderr: "pipe",
24032
+ timeout: GIT_TIMEOUT_MS
24033
+ });
24034
+ const [out, code] = await Promise.all([new Response(proc.stdout).text(), proc.exited]);
24035
+ return { code: proc.signalCode === null ? code : -1, out };
24036
+ };
24037
+ var FLOW_PATH = /(?:^|\/)\.metaproject\/flows\/([^/]+)\/(.+)$/;
24038
+ function groupByFlowDir(listing, porcelain) {
24039
+ const groups = new Map;
24040
+ for (const line of listing.split(`
24041
+ `)) {
24042
+ let file = porcelain ? line.length < 4 ? "" : line.slice(3) : line;
24043
+ const renamed = porcelain ? file.indexOf(" -> ") : -1;
24044
+ if (renamed !== -1)
24045
+ file = file.slice(renamed + 4);
24046
+ file = file.replace(/^"|"$/g, "");
24047
+ const match = FLOW_PATH.exec(file);
24048
+ if (match === null)
24049
+ continue;
24050
+ const [, dir, inside] = match;
24051
+ if (dir === undefined || inside === undefined)
24052
+ continue;
24053
+ const list = groups.get(dir);
24054
+ if (list === undefined)
24055
+ groups.set(dir, [inside]);
24056
+ else
24057
+ list.push(inside);
24058
+ }
24059
+ return groups;
24060
+ }
24061
+ function noteFor(flowId, dir, listings) {
24062
+ if ((listings.tracked.get(dir) ?? []).length === 0)
24063
+ return null;
24064
+ const seen = new Set;
24065
+ for (const inside of listings.status.get(dir) ?? []) {
24066
+ const slash = inside.indexOf("/");
24067
+ seen.add(slash === -1 ? inside : `${inside.slice(0, slash)}/`);
24068
+ }
24069
+ const entries = [...seen];
24070
+ if (entries.length === 0)
24071
+ return null;
24072
+ const shown = entries.slice(0, UNCOMMITTED_LIST_CAP);
24073
+ const more = entries.length - shown.length;
24074
+ const list = `${shown.join(", ")}${more > 0 ? `, +${more} more` : ""}`;
24075
+ return `flow ${flowId} has uncommitted changes in .metaproject/flows/${dir}: ${list} \u2014 ` + "a common cause is the closing state `flow complete` writes after the merge; commit it (nothing gates on this)";
24076
+ }
24077
+ async function readGit(cwd, scope, git) {
24078
+ const tracked = await git(cwd, [...READ_ONLY_GIT_FLAGS, "ls-files", "--", scope]);
24079
+ if (tracked.code !== 0)
24080
+ return null;
24081
+ const empty = { tracked: new Map, status: new Map };
24082
+ if (tracked.out.trim().length === 0)
24083
+ return empty;
24084
+ const status = await git(cwd, [
24085
+ ...READ_ONLY_GIT_FLAGS,
24086
+ "-c",
24087
+ "core.quotepath=off",
24088
+ "status",
24089
+ "--porcelain",
24090
+ "--untracked-files=all",
24091
+ "--",
24092
+ scope
24093
+ ]);
24094
+ if (status.code !== 0)
24095
+ return null;
24096
+ return { tracked: groupByFlowDir(tracked.out, false), status: groupByFlowDir(status.out, true) };
24097
+ }
24098
+ async function uncommittedFlowStateNote(cwd, flowId, dir, git = spawnGit) {
24099
+ try {
24100
+ const read = await readGit(cwd, path15.join(flowsRoot(cwd), dir), git);
24101
+ return read === null ? null : noteFor(flowId, dir, read);
24102
+ } catch {
24103
+ return null;
24104
+ }
24105
+ }
24106
+ async function uncommittedFlowStateNotes(cwd, flows, git = spawnGit) {
24107
+ const notes = new Map;
24108
+ if (flows.length === 0)
24109
+ return notes;
24110
+ try {
24111
+ const read = await readGit(cwd, flowsRoot(cwd), git);
24112
+ if (read === null)
24113
+ return notes;
24114
+ for (const flow of flows) {
24115
+ const text = noteFor(flow.id, flow.dir, read);
24116
+ if (text !== null)
24117
+ notes.set(flow.dir, text);
24118
+ }
24119
+ } catch {
24120
+ return new Map;
24121
+ }
24122
+ return notes;
24123
+ }
23997
24124
  // src/flow/ac-kinds.ts
23998
24125
  var AC_KINDS = ["exec", "invariant", "judged", "none", "unclassified"];
23999
24126
  var AC_LINE = /^\s*[-*]\s*(AC\d+)\s*:\s?(.*)$/i;
@@ -24151,7 +24278,7 @@ function readAcKindRecords(value) {
24151
24278
  }
24152
24279
  // src/flow/description-intent.ts
24153
24280
  import { readFile as readFile10 } from "fs/promises";
24154
- import path15 from "path";
24281
+ import path16 from "path";
24155
24282
  var OUTCOME_HINT = 'State an outcome criterion: what you would look at afterwards to see this helped, as a bullet. Or write "- not measured \u2014 <reason>".';
24156
24283
  var PLACEHOLDERS = ["Describe the problem precisely", "What must be true when this flow is done"];
24157
24284
  var FLOW_STATEMENT_HEADINGS = [/^problem$/i, /^expected outcome$/i];
@@ -24238,7 +24365,7 @@ function initIntentNote(description) {
24238
24365
  }
24239
24366
  async function intentNoteForNewFlow(cwd, dir) {
24240
24367
  try {
24241
- return initIntentNote(await readFile10(path15.join(cwd, dir, "description.md"), "utf8"));
24368
+ return initIntentNote(await readFile10(path16.join(cwd, dir, "description.md"), "utf8"));
24242
24369
  } catch {
24243
24370
  return null;
24244
24371
  }
@@ -24246,7 +24373,7 @@ async function intentNoteForNewFlow(cwd, dir) {
24246
24373
  // src/flow/check-ac.ts
24247
24374
  import { createHash as createHash8 } from "crypto";
24248
24375
  import { chmod as chmod4, mkdir as mkdir9, readFile as readFile22 } from "fs/promises";
24249
- import path47 from "path";
24376
+ import path48 from "path";
24250
24377
 
24251
24378
  // src/review/cost.ts
24252
24379
  function estimateTokens(text) {
@@ -24434,7 +24561,7 @@ function factsOnlyVerdict(item) {
24434
24561
  }
24435
24562
  async function readAcCheckEnabled(cwd) {
24436
24563
  try {
24437
- const parsed = JSON.parse(await readFile22(path47.join(cwd, REVIEW_GATE_CONFIG_PATH), "utf8"));
24564
+ const parsed = JSON.parse(await readFile22(path48.join(cwd, REVIEW_GATE_CONFIG_PATH), "utf8"));
24438
24565
  if (typeof parsed !== "object" || parsed === null)
24439
24566
  return false;
24440
24567
  const review = parsed["review"];
@@ -24455,7 +24582,7 @@ function acCheckCacheKey(criteriaChecksum, diffText) {
24455
24582
  return `${criteriaChecksum}:${hashDiff(diffText)}`;
24456
24583
  }
24457
24584
  function acCheckCachePath(cwd, flowDir) {
24458
- return path47.join(cwd, ".metaproject", "data", "ac-check", `${flowDir}.json`);
24585
+ return path48.join(cwd, ".metaproject", "data", "ac-check", `${flowDir}.json`);
24459
24586
  }
24460
24587
  async function readAcCheckCache(cachePath) {
24461
24588
  if (!await pathExists(cachePath))
@@ -24467,7 +24594,7 @@ async function readAcCheckCache(cachePath) {
24467
24594
  }
24468
24595
  }
24469
24596
  async function writeAcCheckCache(cachePath, record) {
24470
- await mkdir9(path47.dirname(cachePath), { recursive: true });
24597
+ await mkdir9(path48.dirname(cachePath), { recursive: true });
24471
24598
  await writeFileAtomic(cachePath, `${JSON.stringify(record, null, 2)}
24472
24599
  `, { mode: 384 });
24473
24600
  if (process.platform !== "win32") {
@@ -24525,10 +24652,10 @@ function renderAcCheckAdvisoryNotice(verdicts) {
24525
24652
  }
24526
24653
  // src/flow/allocation.ts
24527
24654
  import { appendFile as appendFile3, mkdir as mkdir10, readFile as readFile23 } from "fs/promises";
24528
- import path49 from "path";
24655
+ import path50 from "path";
24529
24656
 
24530
24657
  // src/lib/clone-scope.ts
24531
- import path48 from "path";
24658
+ import path49 from "path";
24532
24659
  async function gitCommonDir(cwd) {
24533
24660
  try {
24534
24661
  const proc = Bun.spawn(["git", "rev-parse", "--git-common-dir"], {
@@ -24540,7 +24667,7 @@ async function gitCommonDir(cwd) {
24540
24667
  if (await proc.exited !== 0 || output.length === 0) {
24541
24668
  return null;
24542
24669
  }
24543
- return path48.isAbsolute(output) ? output : path48.resolve(cwd, output);
24670
+ return path49.isAbsolute(output) ? output : path49.resolve(cwd, output);
24544
24671
  } catch {
24545
24672
  return null;
24546
24673
  }
@@ -24565,23 +24692,23 @@ function projectKey(toplevel, cwd) {
24565
24692
  if (!toplevel) {
24566
24693
  return "root";
24567
24694
  }
24568
- const relative = path49.relative(toplevel, cwd);
24695
+ const relative = path50.relative(toplevel, cwd);
24569
24696
  return relative === "" ? "root" : slugify(relative);
24570
24697
  }
24571
24698
  async function resolveAllocationScope(cwd) {
24572
24699
  const commonDir = await gitCommonDir(cwd);
24573
24700
  if (!commonDir) {
24574
24701
  return {
24575
- lockPath: path49.join(flowsRoot(cwd), ".flow-init.lock"),
24702
+ lockPath: path50.join(flowsRoot(cwd), ".flow-init.lock"),
24576
24703
  ledgerPath: null,
24577
24704
  project: "root"
24578
24705
  };
24579
24706
  }
24580
24707
  const key = projectKey(await gitToplevel(cwd), cwd);
24581
- const dir = path49.join(commonDir, "keryx", "flow-ids");
24708
+ const dir = path50.join(commonDir, "keryx", "flow-ids");
24582
24709
  return {
24583
- lockPath: path49.join(dir, `${key}.lock`),
24584
- ledgerPath: path49.join(dir, `${key}.jsonl`),
24710
+ lockPath: path50.join(dir, `${key}.lock`),
24711
+ ledgerPath: path50.join(dir, `${key}.jsonl`),
24585
24712
  project: key
24586
24713
  };
24587
24714
  }
@@ -24614,7 +24741,7 @@ async function recordAllocation(scope, record) {
24614
24741
  if (!scope.ledgerPath) {
24615
24742
  return;
24616
24743
  }
24617
- await mkdir10(path49.dirname(scope.ledgerPath), { recursive: true });
24744
+ await mkdir10(path50.dirname(scope.ledgerPath), { recursive: true });
24618
24745
  await appendFile3(scope.ledgerPath, `${JSON.stringify(record)}
24619
24746
  `, "utf8");
24620
24747
  }
@@ -24786,6 +24913,7 @@ function createFlowService(deps) {
24786
24913
  if (input.owner !== undefined && !input.owner.trim()) {
24787
24914
  throw new Error(BLANK_OWNER_MESSAGE);
24788
24915
  }
24916
+ const outcomeAuthor = input.outcomeAuthor === undefined ? DEFAULT_OUTCOME_AUTHOR : parseOutcomeAuthor(input.outcomeAuthor);
24789
24917
  const trackerReady = deps.tracker ? await deps.tracker.detect() : false;
24790
24918
  const tracker = trackerReady ? deps.tracker : null;
24791
24919
  const issueRef = input.issue && deps.tracker ? deps.tracker.parseRef(input.issue) : null;
@@ -24808,7 +24936,7 @@ function createFlowService(deps) {
24808
24936
  const date = now().slice(0, 10);
24809
24937
  const slug = slugify(input.slug ?? title);
24810
24938
  const dir = `${id}-${date}-${slug}`;
24811
- const absolute = path50.join(flowsRoot(input.cwd), dir);
24939
+ const absolute = path51.join(flowsRoot(input.cwd), dir);
24812
24940
  if (await pathExists(absolute)) {
24813
24941
  throw new Error(`Flow directory already exists: ${dir}`);
24814
24942
  }
@@ -24837,19 +24965,20 @@ function createFlowService(deps) {
24837
24965
  pr: { url: null },
24838
24966
  ...input.baseBranch === undefined ? {} : { baseBranch: input.baseBranch },
24839
24967
  ...input.owner?.trim() ? { owner: ownerIdentity(input.owner.trim(), "`--owner` flag on `flow init`") } : {},
24968
+ outcomeAuthor,
24840
24969
  tasks: DEFAULT_TASKS.map((task) => ({ ...task, status: "todo" })),
24841
24970
  history: [{ at: createdAt, event: "created" }]
24842
24971
  };
24843
24972
  const sourceLabel = input.issue ?? "user description";
24844
- await writeFileAtomic(path50.join(absolute, "description.md"), renderDescription(title, sourceLabel));
24845
- await writeFileAtomic(path50.join(absolute, "context.md"), context.markdown);
24846
- await writeFileAtomic(path50.join(absolute, "plan.md"), renderPlan());
24847
- await writeFileAtomic(path50.join(absolute, "tasks.md"), renderTasksDoc());
24848
- await writeFileAtomic(path50.join(absolute, "acceptance-criteria.md"), renderAcceptanceCriteria());
24849
- await writeFileAtomic(path50.join(absolute, "journal.md"), renderJournal(createdAt));
24973
+ await writeFileAtomic(path51.join(absolute, "description.md"), renderDescription(title, sourceLabel));
24974
+ await writeFileAtomic(path51.join(absolute, "context.md"), context.markdown);
24975
+ await writeFileAtomic(path51.join(absolute, "plan.md"), renderPlan());
24976
+ await writeFileAtomic(path51.join(absolute, "tasks.md"), renderTasksDoc());
24977
+ await writeFileAtomic(path51.join(absolute, "acceptance-criteria.md"), renderAcceptanceCriteria());
24978
+ await writeFileAtomic(path51.join(absolute, "journal.md"), renderJournal(createdAt));
24850
24979
  await writeFlow(input.cwd, dir, flow);
24851
24980
  await recordAllocation(scope, { id, dir, at: createdAt, project: scope.project });
24852
- return { flow, dir: path50.relative(input.cwd, absolute), contextNotes: context.notes };
24981
+ return { flow, dir: path51.relative(input.cwd, absolute), contextNotes: context.notes };
24853
24982
  });
24854
24983
  },
24855
24984
  async list({ cwd }) {
@@ -24894,6 +25023,25 @@ function createFlowService(deps) {
24894
25023
  return save(cwd, dir, flow, previous === null ? "owner-set" : "owner-changed", detail);
24895
25024
  });
24896
25025
  },
25026
+ async outcomeAuthorSet({ cwd, id, author, reason }) {
25027
+ const next = parseOutcomeAuthor(author, "outcome author");
25028
+ if (!reason?.trim()) {
25029
+ throw new Error('flow outcome author requires --reason "<why>"');
25030
+ }
25031
+ validateSingleLineReason(reason);
25032
+ let previous = "unknown";
25033
+ let changed = false;
25034
+ const flow = await mutate(cwd, id, async ({ dir, flow: current }) => {
25035
+ previous = readOutcomeAuthor(current.outcomeAuthor);
25036
+ if (previous === next) {
25037
+ return current;
25038
+ }
25039
+ changed = true;
25040
+ current.outcomeAuthor = next;
25041
+ return save(cwd, dir, current, "outcome-author-set", `${previous} -> ${next} (${reason.trim()})`);
25042
+ });
25043
+ return { flow, previous, changed };
25044
+ },
24897
25045
  async freeze({ cwd, id }) {
24898
25046
  return mutate(cwd, id, async ({ dir, flow }) => {
24899
25047
  assertTransition(flow.status, "ready");
@@ -25433,7 +25581,7 @@ function createFlowService(deps) {
25433
25581
  issues.push({ flow: dir, kind: "schema", message: `unknown schemaVersion ${flow.schemaVersion}` });
25434
25582
  }
25435
25583
  try {
25436
- const raw = JSON.parse(await Bun.file(path50.join(flowsRoot(cwd), dir, "flow.json")).text());
25584
+ const raw = JSON.parse(await Bun.file(path51.join(flowsRoot(cwd), dir, "flow.json")).text());
25437
25585
  const validation = validateAgainstSchemaObject(flowStateSchema(), raw);
25438
25586
  if (!validation.valid) {
25439
25587
  issues.push({
@@ -25444,7 +25592,7 @@ function createFlowService(deps) {
25444
25592
  }
25445
25593
  } catch {}
25446
25594
  for (const file of ["description.md", "context.md", "plan.md", "tasks.md", "acceptance-criteria.md", "journal.md"]) {
25447
- if (!await pathExists(path50.join(flowsRoot(cwd), dir, file))) {
25595
+ if (!await pathExists(path51.join(flowsRoot(cwd), dir, file))) {
25448
25596
  issues.push({ flow: dir, kind: "structure", message: `missing ${file}` });
25449
25597
  }
25450
25598
  }
@@ -25483,7 +25631,7 @@ function createFlowService(deps) {
25483
25631
  };
25484
25632
  }
25485
25633
  async function appendIdMap(cwd, entry) {
25486
- const file = path50.join(flowsRoot(cwd), "id-map.json");
25634
+ const file = path51.join(flowsRoot(cwd), "id-map.json");
25487
25635
  let entries = [];
25488
25636
  if (await pathExists(file)) {
25489
25637
  const raw = await readFile24(file, "utf8");
@@ -25494,7 +25642,7 @@ async function appendIdMap(cwd, entry) {
25494
25642
  }
25495
25643
  entries = parsed;
25496
25644
  } catch (error) {
25497
- throw new Error(`Cannot read ${path50.relative(cwd, file)}: ${error instanceof Error ? error.message : String(error)}`);
25645
+ throw new Error(`Cannot read ${path51.relative(cwd, file)}: ${error instanceof Error ? error.message : String(error)}`);
25498
25646
  }
25499
25647
  }
25500
25648
  entries.push(entry);
@@ -25747,7 +25895,7 @@ __export(exports_service5, {
25747
25895
  // src/gdgraph/build.ts
25748
25896
  import { mkdir as mkdir20, readdir as readdir13, readFile as readFile35, writeFile as writeFile14 } from "fs/promises";
25749
25897
  import { existsSync as existsSync6 } from "fs";
25750
- import path70 from "path";
25898
+ import path71 from "path";
25751
25899
 
25752
25900
  // src/gdgraph/types.ts
25753
25901
  var UNKNOWN_IMPORT_KIND = "unknown-static";
@@ -25812,7 +25960,7 @@ async function buildGraph(projectRoot) {
25812
25960
  const assetNodes = new Map;
25813
25961
  const fileRecords = [];
25814
25962
  for (const file of files) {
25815
- const absolutePath = path70.join(projectRoot, file);
25963
+ const absolutePath = path71.join(projectRoot, file);
25816
25964
  const content = await readFile35(absolutePath, "utf8");
25817
25965
  fileRecords.push({ path: file, content });
25818
25966
  const language = getLanguage(file);
@@ -25865,24 +26013,24 @@ async function collectSourceFiles(projectRoot) {
25865
26013
  const result = [];
25866
26014
  const skippedDirectories = [];
25867
26015
  async function walk(relativeDir) {
25868
- const absoluteDir = path70.join(projectRoot, relativeDir);
26016
+ const absoluteDir = path71.join(projectRoot, relativeDir);
25869
26017
  const entries = await readdir13(absoluteDir, { withFileTypes: true });
25870
26018
  for (const entry of entries) {
25871
26019
  if (entry.isDirectory()) {
25872
26020
  if (IGNORE_DIRS.has(entry.name)) {
25873
- skippedDirectories.push(normalizePath2(path70.posix.join(relativeDir, entry.name)).replace(/^\.\//, ""));
26021
+ skippedDirectories.push(normalizePath2(path71.posix.join(relativeDir, entry.name)).replace(/^\.\//, ""));
25874
26022
  continue;
25875
26023
  }
25876
- await walk(normalizePath2(path70.posix.join(relativeDir, entry.name)));
26024
+ await walk(normalizePath2(path71.posix.join(relativeDir, entry.name)));
25877
26025
  continue;
25878
26026
  }
25879
26027
  if (!entry.isFile()) {
25880
26028
  continue;
25881
26029
  }
25882
- if (!SOURCE_EXTENSIONS.includes(path70.extname(entry.name))) {
26030
+ if (!SOURCE_EXTENSIONS.includes(path71.extname(entry.name))) {
25883
26031
  continue;
25884
26032
  }
25885
- result.push(normalizePath2(path70.posix.join(relativeDir, entry.name)).replace(/^\.\//, ""));
26033
+ result.push(normalizePath2(path71.posix.join(relativeDir, entry.name)).replace(/^\.\//, ""));
25886
26034
  }
25887
26035
  }
25888
26036
  await walk(".");
@@ -25964,8 +26112,8 @@ function resolveImport(projectRoot, fromFile, specifier, fileSet, resolver) {
25964
26112
  }
25965
26113
  function resolveAssetImport(projectRoot, fromFile, specifier, resolver) {
25966
26114
  for (const candidate of importCandidateBases(projectRoot, fromFile, specifier, resolver)) {
25967
- const extension = path70.posix.extname(candidate);
25968
- if (ASSET_EXTENSIONS.includes(extension) && existsSync6(path70.join(projectRoot, candidate))) {
26115
+ const extension = path71.posix.extname(candidate);
26116
+ if (ASSET_EXTENSIONS.includes(extension) && existsSync6(path71.join(projectRoot, candidate))) {
25969
26117
  return candidate;
25970
26118
  }
25971
26119
  }
@@ -25974,17 +26122,17 @@ function resolveAssetImport(projectRoot, fromFile, specifier, resolver) {
25974
26122
  function importCandidateBases(projectRoot, fromFile, specifier, resolver) {
25975
26123
  const normalizedSpecifier = stripImportSuffix(specifier);
25976
26124
  if (normalizedSpecifier.startsWith(".") && getLanguage(fromFile) !== "python") {
25977
- const fromDir = path70.posix.dirname(fromFile);
25978
- return [normalizePath2(path70.posix.normalize(path70.posix.join(fromDir, normalizedSpecifier)))];
26125
+ const fromDir = path71.posix.dirname(fromFile);
26126
+ return [normalizePath2(path71.posix.normalize(path71.posix.join(fromDir, normalizedSpecifier)))];
25979
26127
  }
25980
- return resolver.candidateBases(normalizedSpecifier, fromFile).map((candidate) => normalizePath2(path70.relative(projectRoot, path70.join(projectRoot, candidate))));
26128
+ return resolver.candidateBases(normalizedSpecifier, fromFile).map((candidate) => normalizePath2(path71.relative(projectRoot, path71.join(projectRoot, candidate))));
25981
26129
  }
25982
26130
  function resolveSourceCandidate(base, fileSet) {
25983
26131
  const candidates = [
25984
26132
  base,
25985
26133
  ...SOURCE_RESOLUTION_EXTENSIONS.map((extension) => `${base}${extension}`),
25986
- ...SOURCE_RESOLUTION_EXTENSIONS.map((extension) => path70.posix.join(base, `index${extension}`)),
25987
- path70.posix.join(base, "__init__.py")
26134
+ ...SOURCE_RESOLUTION_EXTENSIONS.map((extension) => path71.posix.join(base, `index${extension}`)),
26135
+ path71.posix.join(base, "__init__.py")
25988
26136
  ];
25989
26137
  return candidates.find((candidate) => fileSet.has(candidate)) ?? null;
25990
26138
  }
@@ -26014,7 +26162,7 @@ async function loadJavaResolver(projectRoot) {
26014
26162
  return createJavaResolver(roots);
26015
26163
  }
26016
26164
  async function discoverJavaSourceRoots(projectRoot) {
26017
- const pomPath = path70.join(projectRoot, "pom.xml");
26165
+ const pomPath = path71.join(projectRoot, "pom.xml");
26018
26166
  if (existsSync6(pomPath)) {
26019
26167
  try {
26020
26168
  const roots = parseMavenSourceRoots(await readFile35(pomPath, "utf8"));
@@ -26024,7 +26172,7 @@ async function discoverJavaSourceRoots(projectRoot) {
26024
26172
  } catch {}
26025
26173
  }
26026
26174
  for (const gradleName of ["build.gradle", "build.gradle.kts"]) {
26027
- const gradlePath = path70.join(projectRoot, gradleName);
26175
+ const gradlePath = path71.join(projectRoot, gradleName);
26028
26176
  if (existsSync6(gradlePath)) {
26029
26177
  try {
26030
26178
  const roots = parseGradleSourceRoots(await readFile35(gradlePath, "utf8"));
@@ -26046,12 +26194,12 @@ function createJavaResolver(sourceRoots) {
26046
26194
  return [];
26047
26195
  }
26048
26196
  const relative = specifier.split(".").join("/");
26049
- return sourceRoots.map((root) => normalizePath2(path70.posix.join(root, relative)));
26197
+ return sourceRoots.map((root) => normalizePath2(path71.posix.join(root, relative)));
26050
26198
  }
26051
26199
  };
26052
26200
  }
26053
26201
  function loadPythonResolver(projectRoot) {
26054
- const hasSrc = existsSync6(path70.join(projectRoot, "src"));
26202
+ const hasSrc = existsSync6(path71.join(projectRoot, "src"));
26055
26203
  return createPythonResolver(hasSrc);
26056
26204
  }
26057
26205
  function createPythonResolver(hasSrc) {
@@ -26064,16 +26212,16 @@ function createPythonResolver(hasSrc) {
26064
26212
  if (specifier.startsWith(".")) {
26065
26213
  const dots = /^\.+/.exec(specifier)?.[0].length ?? 0;
26066
26214
  const rest = specifier.slice(dots);
26067
- let baseDir = path70.posix.dirname(fromFile);
26215
+ let baseDir = path71.posix.dirname(fromFile);
26068
26216
  for (let level = 1;level < dots; level += 1) {
26069
- baseDir = path70.posix.dirname(baseDir);
26217
+ baseDir = path71.posix.dirname(baseDir);
26070
26218
  }
26071
26219
  const suffix = rest ? rest.split(".").join("/") : "";
26072
- const base = suffix ? path70.posix.join(baseDir, suffix) : baseDir;
26220
+ const base = suffix ? path71.posix.join(baseDir, suffix) : baseDir;
26073
26221
  return [normalizePath2(base)];
26074
26222
  }
26075
26223
  const relative = specifier.split(".").join("/");
26076
- return roots.map((root) => normalizePath2(root ? path70.posix.join(root, relative) : relative));
26224
+ return roots.map((root) => normalizePath2(root ? path71.posix.join(root, relative) : relative));
26077
26225
  }
26078
26226
  };
26079
26227
  }
@@ -26082,8 +26230,8 @@ function parseMavenSourceRoots(pomXml) {
26082
26230
  for (const match of pomXml.matchAll(/<module>\s*([^<]+?)\s*<\/module>/g)) {
26083
26231
  const moduleDir = match[1]?.trim();
26084
26232
  if (moduleDir && !moduleDir.includes("${")) {
26085
- roots.add(normalizePath2(path70.posix.join(moduleDir, "src/main/java")));
26086
- roots.add(normalizePath2(path70.posix.join(moduleDir, "src/test/java")));
26233
+ roots.add(normalizePath2(path71.posix.join(moduleDir, "src/main/java")));
26234
+ roots.add(normalizePath2(path71.posix.join(moduleDir, "src/test/java")));
26087
26235
  }
26088
26236
  }
26089
26237
  for (const tag of ["sourceDirectory", "testSourceDirectory"]) {
@@ -26116,7 +26264,7 @@ function parseGradleSourceRoots(buildGradle) {
26116
26264
  var TSCONFIG_EXTENDS_MAX_DEPTH = 10;
26117
26265
  async function loadTsconfigResolver(projectRoot) {
26118
26266
  const empty = createTsconfigResolver(null, []);
26119
- const tsconfigPath = path70.join(projectRoot, "tsconfig.json");
26267
+ const tsconfigPath = path71.join(projectRoot, "tsconfig.json");
26120
26268
  if (!existsSync6(tsconfigPath)) {
26121
26269
  return empty;
26122
26270
  }
@@ -26129,7 +26277,7 @@ async function loadTsconfigResolver(projectRoot) {
26129
26277
  return createTsconfigResolver(resolved.baseUrl, paths);
26130
26278
  }
26131
26279
  function toProjectRelativeDir(projectRoot, absoluteDir) {
26132
- const relative = normalizePath2(path70.relative(projectRoot, absoluteDir)).replace(/^\.\//, "");
26280
+ const relative = normalizePath2(path71.relative(projectRoot, absoluteDir)).replace(/^\.\//, "");
26133
26281
  return relative === "." ? "" : relative;
26134
26282
  }
26135
26283
  async function readTsconfigJson(configPath) {
@@ -26144,11 +26292,11 @@ function resolveTsconfigExtendsPath(configDir, extendsSpecifier) {
26144
26292
  if (!extendsSpecifier.startsWith(".") && !extendsSpecifier.startsWith("/")) {
26145
26293
  return null;
26146
26294
  }
26147
- const resolved = path70.resolve(configDir, extendsSpecifier);
26295
+ const resolved = path71.resolve(configDir, extendsSpecifier);
26148
26296
  return resolved.endsWith(".json") ? resolved : `${resolved}.json`;
26149
26297
  }
26150
26298
  async function resolveTsconfigOptions(configPath, visited, depth, projectRoot) {
26151
- const resolvedPath = path70.resolve(configPath);
26299
+ const resolvedPath = path71.resolve(configPath);
26152
26300
  if (depth > TSCONFIG_EXTENDS_MAX_DEPTH || visited.has(resolvedPath)) {
26153
26301
  return null;
26154
26302
  }
@@ -26159,15 +26307,15 @@ async function resolveTsconfigOptions(configPath, visited, depth, projectRoot) {
26159
26307
  }
26160
26308
  let inherited = null;
26161
26309
  if (typeof parsed.extends === "string") {
26162
- const basePath = resolveTsconfigExtendsPath(path70.dirname(resolvedPath), parsed.extends);
26310
+ const basePath = resolveTsconfigExtendsPath(path71.dirname(resolvedPath), parsed.extends);
26163
26311
  if (basePath) {
26164
26312
  inherited = await resolveTsconfigOptions(basePath, visited, depth + 1, projectRoot);
26165
26313
  }
26166
26314
  }
26167
- const configDir = path70.dirname(resolvedPath);
26315
+ const configDir = path71.dirname(resolvedPath);
26168
26316
  const declaringDir = toProjectRelativeDir(projectRoot, configDir);
26169
26317
  const options = parsed.compilerOptions ?? {};
26170
- const ownBaseUrl = typeof options.baseUrl === "string" ? toProjectRelativeDir(projectRoot, path70.resolve(configDir, options.baseUrl)) : null;
26318
+ const ownBaseUrl = typeof options.baseUrl === "string" ? toProjectRelativeDir(projectRoot, path71.resolve(configDir, options.baseUrl)) : null;
26171
26319
  const baseUrl = ownBaseUrl ?? inherited?.baseUrl ?? null;
26172
26320
  const ownPaths = isRecord2(options.paths) ? Object.entries(options.paths).filter((entry) => Array.isArray(entry[1])).map(([pattern, targets]) => ({
26173
26321
  pattern,
@@ -26196,7 +26344,7 @@ function createTsconfigResolver(baseUrl, mappings) {
26196
26344
  }
26197
26345
  }
26198
26346
  if (baseUrl !== null) {
26199
- candidates.push(normalizePath2(path70.posix.join(baseUrl, normalizedSpecifier)));
26347
+ candidates.push(normalizePath2(path71.posix.join(baseUrl, normalizedSpecifier)));
26200
26348
  }
26201
26349
  return [...new Set(candidates.map((candidate) => candidate.replace(/^\.\//, "")))];
26202
26350
  }
@@ -26216,7 +26364,7 @@ function matchPathPattern(pattern, specifier) {
26216
26364
  }
26217
26365
  function applyPathTarget(base, target, wildcard) {
26218
26366
  const replaced = target.includes("*") ? target.replace("*", wildcard) : target;
26219
- return normalizePath2(path70.posix.normalize(path70.posix.join(base, replaced)));
26367
+ return normalizePath2(path71.posix.normalize(path71.posix.join(base, replaced)));
26220
26368
  }
26221
26369
  function stripJsonComments(source) {
26222
26370
  let out = "";
@@ -26269,21 +26417,21 @@ function isRecord2(value) {
26269
26417
  return typeof value === "object" && value !== null && !Array.isArray(value);
26270
26418
  }
26271
26419
  async function writeGraph(projectRoot, graph) {
26272
- const storageDir = path70.join(projectRoot, ".metaproject", "data", "gdgraph", "storage");
26273
- const artifactsDir = path70.join(projectRoot, ".metaproject", "data", "gdgraph", "artifacts");
26420
+ const storageDir = path71.join(projectRoot, ".metaproject", "data", "gdgraph", "storage");
26421
+ const artifactsDir = path71.join(projectRoot, ".metaproject", "data", "gdgraph", "artifacts");
26274
26422
  await mkdir20(storageDir, { recursive: true });
26275
26423
  await mkdir20(artifactsDir, { recursive: true });
26276
- await writeFile14(path70.join(storageDir, "nodes.jsonl"), graph.nodes.map((node) => JSON.stringify(node)).join(`
26424
+ await writeFile14(path71.join(storageDir, "nodes.jsonl"), graph.nodes.map((node) => JSON.stringify(node)).join(`
26277
26425
  `) + `
26278
26426
  `, "utf8");
26279
- await writeFile14(path70.join(storageDir, "edges.jsonl"), graph.edges.map((edge) => JSON.stringify(edge)).join(`
26427
+ await writeFile14(path71.join(storageDir, "edges.jsonl"), graph.edges.map((edge) => JSON.stringify(edge)).join(`
26280
26428
  `) + `
26281
26429
  `, "utf8");
26282
- await writeFile14(path70.join(artifactsDir, "module-map.json"), JSON.stringify(buildModuleMap(graph), null, 2) + `
26430
+ await writeFile14(path71.join(artifactsDir, "module-map.json"), JSON.stringify(buildModuleMap(graph), null, 2) + `
26283
26431
  `, "utf8");
26284
26432
  }
26285
26433
  async function writeSummary(projectRoot, graph, collection) {
26286
- const artifactsDir = path70.join(projectRoot, ".metaproject", "data", "gdgraph", "artifacts");
26434
+ const artifactsDir = path71.join(projectRoot, ".metaproject", "data", "gdgraph", "artifacts");
26287
26435
  await mkdir20(artifactsDir, { recursive: true });
26288
26436
  const unresolved = graph.edges.filter((edge) => edge.kind === "unresolved");
26289
26437
  const imports = graph.edges.filter((edge) => edge.kind === "imports");
@@ -26298,7 +26446,7 @@ async function writeSummary(projectRoot, graph, collection) {
26298
26446
  `);
26299
26447
  const skippedList = collection.skippedDirectories.length > 0 ? collection.skippedDirectories.slice(0, 30).map((dir) => `- \`${dir}\``).join(`
26300
26448
  `) : "- none";
26301
- const summaryPath = path70.join(artifactsDir, "summary.md");
26449
+ const summaryPath = path71.join(artifactsDir, "summary.md");
26302
26450
  const content = `# gdgraph Summary
26303
26451
 
26304
26452
  ## Stats
@@ -26379,7 +26527,7 @@ function groupBy(items, getKey) {
26379
26527
  }
26380
26528
  function unresolvedType(specifier) {
26381
26529
  const stripped = stripImportSuffix(specifier);
26382
- const extension = path70.posix.extname(stripped);
26530
+ const extension = path71.posix.extname(stripped);
26383
26531
  if (extension) {
26384
26532
  return extension;
26385
26533
  }
@@ -26389,13 +26537,13 @@ function unresolvedType(specifier) {
26389
26537
  return "package";
26390
26538
  }
26391
26539
  function normalizePath2(value) {
26392
- return value.split(path70.sep).join("/");
26540
+ return value.split(path71.sep).join("/");
26393
26541
  }
26394
26542
 
26395
26543
  // src/gdgraph/target.ts
26396
- import path71 from "path";
26544
+ import path72 from "path";
26397
26545
  function normalizeTarget(target) {
26398
- return target.replace(/^\.\//, "").split(path71.sep).join("/");
26546
+ return target.replace(/^\.\//, "").split(path72.sep).join("/");
26399
26547
  }
26400
26548
  function resolveGraphTarget(graph, target) {
26401
26549
  const normalized = normalizeTarget(target);
@@ -26488,15 +26636,15 @@ init_config3();
26488
26636
 
26489
26637
  // src/gdgraph/query.ts
26490
26638
  import { readFile as readFile36 } from "fs/promises";
26491
- import path72 from "path";
26639
+ import path73 from "path";
26492
26640
  async function loadGraph(projectRoot) {
26493
- const storageDir = path72.join(projectRoot, ".metaproject", "data", "gdgraph", "storage");
26494
- const nodes = await readJsonl(path72.join(storageDir, "nodes.jsonl"));
26495
- const edges = await readJsonl(path72.join(storageDir, "edges.jsonl"));
26496
- const symbols = await readJsonl(path72.join(storageDir, "symbols.jsonl"));
26497
- const calls = await readJsonl(path72.join(storageDir, "calls.jsonl"));
26498
- const wikiPages = await readJsonl(path72.join(storageDir, "wiki-pages.jsonl"));
26499
- const describes = await readJsonl(path72.join(storageDir, "describes.jsonl"));
26641
+ const storageDir = path73.join(projectRoot, ".metaproject", "data", "gdgraph", "storage");
26642
+ const nodes = await readJsonl(path73.join(storageDir, "nodes.jsonl"));
26643
+ const edges = await readJsonl(path73.join(storageDir, "edges.jsonl"));
26644
+ const symbols = await readJsonl(path73.join(storageDir, "symbols.jsonl"));
26645
+ const calls = await readJsonl(path73.join(storageDir, "calls.jsonl"));
26646
+ const wikiPages = await readJsonl(path73.join(storageDir, "wiki-pages.jsonl"));
26647
+ const describes = await readJsonl(path73.join(storageDir, "describes.jsonl"));
26500
26648
  const graph = { nodes, edges };
26501
26649
  if (symbols.length > 0) {
26502
26650
  graph.symbols = symbols;
@@ -26556,7 +26704,7 @@ async function bunfigPreloadRoots(projectRoot) {
26556
26704
  const roots = new Set;
26557
26705
  let text;
26558
26706
  try {
26559
- text = await readFile36(path72.join(projectRoot, "bunfig.toml"), "utf8");
26707
+ text = await readFile36(path73.join(projectRoot, "bunfig.toml"), "utf8");
26560
26708
  } catch {
26561
26709
  return roots;
26562
26710
  }
@@ -26570,8 +26718,8 @@ async function bunfigPreloadRoots(projectRoot) {
26570
26718
  if (raw.length === 0) {
26571
26719
  continue;
26572
26720
  }
26573
- const absolute = path72.resolve(projectRoot, raw);
26574
- const relative = path72.relative(projectRoot, absolute).split(path72.sep).join("/");
26721
+ const absolute = path73.resolve(projectRoot, raw);
26722
+ const relative = path73.relative(projectRoot, absolute).split(path73.sep).join("/");
26575
26723
  roots.add(relative);
26576
26724
  }
26577
26725
  }
@@ -26644,7 +26792,7 @@ function canonicalCycle(cycle) {
26644
26792
 
26645
26793
  // src/gdgraph/repomap.ts
26646
26794
  import { mkdir as mkdir21, writeFile as writeFile15 } from "fs/promises";
26647
- import path73 from "path";
26795
+ import path74 from "path";
26648
26796
 
26649
26797
  // src/gdgraph/pagerank.ts
26650
26798
  function personalizedPageRank(nodes, edges, options) {
@@ -26755,7 +26903,7 @@ function overflowContent(required, missing, budget) {
26755
26903
  `);
26756
26904
  }
26757
26905
  function repomapArtifactPath(cwd) {
26758
- return path73.join(cwd, ".metaproject", "data", "gdgraph", "artifacts", "repomap.md");
26906
+ return path74.join(cwd, ".metaproject", "data", "gdgraph", "artifacts", "repomap.md");
26759
26907
  }
26760
26908
  function buildRankEdges(graph, config) {
26761
26909
  const edges = [];
@@ -26900,7 +27048,7 @@ function computeRepomap(graph, config, options = {}) {
26900
27048
  async function writeRepomap(cwd, graph, config, options = {}) {
26901
27049
  const result = computeRepomap(graph, config, options);
26902
27050
  const artifactPath = repomapArtifactPath(cwd);
26903
- await mkdir21(path73.dirname(artifactPath), { recursive: true });
27051
+ await mkdir21(path74.dirname(artifactPath), { recursive: true });
26904
27052
  await writeFile15(artifactPath, result.content, "utf8");
26905
27053
  return { ...result, path: artifactPath };
26906
27054
  }
@@ -26983,12 +27131,12 @@ init_section_tombstone();
26983
27131
  // src/forgetting/journal.ts
26984
27132
  init_fs();
26985
27133
  import { appendFile as appendFile4, mkdir as mkdir22, readFile as readFile37, stat as stat11 } from "fs/promises";
26986
- import path74 from "path";
27134
+ import path75 from "path";
26987
27135
  function forgettingDataDir(cwd) {
26988
- return path74.join(cwd, ".metaproject", "data", "forgetting");
27136
+ return path75.join(cwd, ".metaproject", "data", "forgetting");
26989
27137
  }
26990
27138
  function deletionJournalPath(cwd) {
26991
- return path74.join(forgettingDataDir(cwd), "journal.jsonl");
27139
+ return path75.join(forgettingDataDir(cwd), "journal.jsonl");
26992
27140
  }
26993
27141
  async function readDeletionJournal(cwd) {
26994
27142
  const file = deletionJournalPath(cwd);
@@ -27407,12 +27555,12 @@ __export(exports_service7, {
27407
27555
  gateExitCode: () => gateExitCode,
27408
27556
  readWikiFreshnessMetric: () => readWikiFreshnessMetric
27409
27557
  });
27410
- import path94 from "path";
27558
+ import path95 from "path";
27411
27559
 
27412
27560
  // src/health/config.ts
27413
27561
  init_fs();
27414
27562
  init_json();
27415
- import path75 from "path";
27563
+ import path76 from "path";
27416
27564
  var DEFAULT_HEALTH_CONFIG = {
27417
27565
  schemaVersion: 2,
27418
27566
  ignore: {
@@ -27468,7 +27616,7 @@ var DEFAULT_HEALTH_CONFIG = {
27468
27616
  }
27469
27617
  };
27470
27618
  function configPath2(cwd) {
27471
- return path75.join(cwd, ".metaproject", "health.config.json");
27619
+ return path76.join(cwd, ".metaproject", "health.config.json");
27472
27620
  }
27473
27621
  var STRICTEST_GATE = {
27474
27622
  failOnPriorities: ["P0", "P1", "P2", "P3"],
@@ -27519,7 +27667,7 @@ async function loadHealthConfig(cwd) {
27519
27667
  // src/health/run.ts
27520
27668
  init_fs();
27521
27669
  import { mkdir as mkdir26, writeFile as writeFile19 } from "fs/promises";
27522
- import path93 from "path";
27670
+ import path94 from "path";
27523
27671
 
27524
27672
  // src/metrics/provenance.ts
27525
27673
  async function collectGitProvenance(cwd) {
@@ -27619,12 +27767,12 @@ function computeGate2(input) {
27619
27767
  }
27620
27768
 
27621
27769
  // src/health/scopes.ts
27622
- import path78 from "path";
27770
+ import path79 from "path";
27623
27771
 
27624
27772
  // src/health/util.ts
27625
27773
  init_fs();
27626
27774
  import { mkdir as mkdir23, readFile as readFile38, readdir as readdir14, writeFile as writeFile16 } from "fs/promises";
27627
- import path76 from "path";
27775
+ import path77 from "path";
27628
27776
  var IGNORED_DIRS = new Set([
27629
27777
  "node_modules",
27630
27778
  ".git",
@@ -27668,14 +27816,14 @@ async function toolVersion(command, cwd) {
27668
27816
  }
27669
27817
  }
27670
27818
  function dataRoot3(cwd) {
27671
- return path76.join(cwd, ".metaproject", "data", "health");
27819
+ return path77.join(cwd, ".metaproject", "data", "health");
27672
27820
  }
27673
27821
  async function writeRaw(cwd, source, content, stamp) {
27674
- const dir = path76.join(dataRoot3(cwd), "raw", source);
27822
+ const dir = path77.join(dataRoot3(cwd), "raw", source);
27675
27823
  await mkdir23(dir, { recursive: true });
27676
- const file = path76.join(dir, `${stamp}.log`);
27824
+ const file = path77.join(dir, `${stamp}.log`);
27677
27825
  await writeFile16(file, content, "utf8");
27678
- return path76.relative(cwd, file);
27826
+ return path77.relative(cwd, file);
27679
27827
  }
27680
27828
  async function listSourceFiles(cwd, ignorePaths = []) {
27681
27829
  const { files } = await listSourceFilesWithReasons(cwd, ignorePaths);
@@ -27695,7 +27843,7 @@ async function walk2(root, dir, out, incompleteReasons) {
27695
27843
  try {
27696
27844
  entries = await readdir14(dir, { withFileTypes: true });
27697
27845
  } catch (error) {
27698
- incompleteReasons.push(`${path76.relative(root, dir) || "."}: ${error instanceof Error ? error.message : String(error)}`);
27846
+ incompleteReasons.push(`${path77.relative(root, dir) || "."}: ${error instanceof Error ? error.message : String(error)}`);
27699
27847
  return;
27700
27848
  }
27701
27849
  for (const entry of entries) {
@@ -27703,14 +27851,14 @@ async function walk2(root, dir, out, incompleteReasons) {
27703
27851
  if (entry.isDirectory() && !IGNORED_DIRS.has(entry.name)) {}
27704
27852
  continue;
27705
27853
  }
27706
- const abs = path76.join(dir, entry.name);
27854
+ const abs = path77.join(dir, entry.name);
27707
27855
  if (entry.isDirectory()) {
27708
27856
  if (IGNORED_DIRS.has(entry.name)) {
27709
27857
  continue;
27710
27858
  }
27711
27859
  await walk2(root, abs, out, incompleteReasons);
27712
- } else if (entry.isFile() && SOURCE_EXT.has(path76.extname(entry.name))) {
27713
- out.push(path76.relative(root, abs));
27860
+ } else if (entry.isFile() && SOURCE_EXT.has(path77.extname(entry.name))) {
27861
+ out.push(path77.relative(root, abs));
27714
27862
  }
27715
27863
  }
27716
27864
  }
@@ -27725,7 +27873,7 @@ function moduleOfFile(file) {
27725
27873
  return null;
27726
27874
  }
27727
27875
  function isSourceFile(file) {
27728
- return SOURCE_EXT.has(path76.extname(file));
27876
+ return SOURCE_EXT.has(path77.extname(file));
27729
27877
  }
27730
27878
  function matchesAnyPattern(file, patterns) {
27731
27879
  const normalized = file.replace(/\\/g, "/").replace(/^\.\//, "");
@@ -27825,7 +27973,7 @@ function rankHotspots(files, churn, sourceAnalysis) {
27825
27973
  // src/health/source-analysis.ts
27826
27974
  init_fs();
27827
27975
  import { readFile as readFile39 } from "fs/promises";
27828
- import path77 from "path";
27976
+ import path78 from "path";
27829
27977
 
27830
27978
  // src/health/metrics/complexity.ts
27831
27979
  var CONTROL_KEYWORDS = new Set([
@@ -28059,7 +28207,7 @@ async function analyzeSourceFiles(cwd, sourceFiles) {
28059
28207
  return new Map(entries.filter((entry) => entry !== null));
28060
28208
  }
28061
28209
  async function analyzeSourceFile(cwd, file) {
28062
- const abs = path77.join(cwd, file);
28210
+ const abs = path78.join(cwd, file);
28063
28211
  if (!await pathExists(abs)) {
28064
28212
  return null;
28065
28213
  }
@@ -28132,14 +28280,14 @@ async function computeMetrics(input) {
28132
28280
  }
28133
28281
  const components = new Map;
28134
28282
  for (const file of sourceFiles) {
28135
- const dir = path78.posix.dirname(file);
28283
+ const dir = path79.posix.dirname(file);
28136
28284
  if (dir === "." || dir === moduleOfFile(file)) {
28137
28285
  continue;
28138
28286
  }
28139
28287
  components.set(dir, [...components.get(dir) ?? [], file]);
28140
28288
  }
28141
28289
  for (const [name, files] of [...components.entries()].sort()) {
28142
- const compFindings = findings.filter((f) => f.file && path78.posix.dirname(f.file) === name);
28290
+ const compFindings = findings.filter((f) => f.file && path79.posix.dirname(f.file) === name);
28143
28291
  scopes.push(build("component", `component:${name}`, name, files, compFindings, averageCoverage(files, coverage)));
28144
28292
  }
28145
28293
  const findingFiles = findings.map((f) => f.file).filter((f) => Boolean(f));
@@ -28184,9 +28332,9 @@ function tally2(values) {
28184
28332
  // src/health/baseline.ts
28185
28333
  init_fs();
28186
28334
  import { mkdir as mkdir24, readFile as readFile40, writeFile as writeFile17 } from "fs/promises";
28187
- import path79 from "path";
28335
+ import path80 from "path";
28188
28336
  function baselinePath(cwd) {
28189
- return path79.join(cwd, ".metaproject", "health", "baselines", "scores.json");
28337
+ return path80.join(cwd, ".metaproject", "health", "baselines", "scores.json");
28190
28338
  }
28191
28339
  async function loadBaseline(cwd) {
28192
28340
  const file = baselinePath(cwd);
@@ -28218,7 +28366,7 @@ async function writeBaseline(cwd, metrics, generatedAt, selector) {
28218
28366
  scopes[key] = value;
28219
28367
  }
28220
28368
  const file = baselinePath(cwd);
28221
- await mkdir24(path79.dirname(file), { recursive: true });
28369
+ await mkdir24(path80.dirname(file), { recursive: true });
28222
28370
  await writeFile17(file, `${JSON.stringify({ generatedAt, scopes }, null, 2)}
28223
28371
  `, "utf8");
28224
28372
  return updated;
@@ -28272,10 +28420,10 @@ async function getChurn(cwd, windowDays) {
28272
28420
 
28273
28421
  // src/health/metrics/wiki-freshness.ts
28274
28422
  import { readFile as readFile41, stat as stat12 } from "fs/promises";
28275
- import path80 from "path";
28423
+ import path81 from "path";
28276
28424
  var DEFAULT_STALE_EVIDENCE_DAYS = 7;
28277
28425
  function freshnessReportPath(cwd) {
28278
- return path80.join(cwd, ".metaproject", "data", "wiki", "freshness", "latest.json");
28426
+ return path81.join(cwd, ".metaproject", "data", "wiki", "freshness", "latest.json");
28279
28427
  }
28280
28428
  async function readWikiFreshnessMetric(cwd, options = {}) {
28281
28429
  const file = freshnessReportPath(cwd);
@@ -28296,7 +28444,7 @@ async function readWikiFreshnessMetric(cwd, options = {}) {
28296
28444
  } catch {
28297
28445
  return {
28298
28446
  status: "unreadable-report",
28299
- reason: `${path80.relative(cwd, file)} is not valid JSON; re-run \`keryx wiki freshness\`.`
28447
+ reason: `${path81.relative(cwd, file)} is not valid JSON; re-run \`keryx wiki freshness\`.`
28300
28448
  };
28301
28449
  }
28302
28450
  const report = parsed;
@@ -28306,7 +28454,7 @@ async function readWikiFreshnessMetric(cwd, options = {}) {
28306
28454
  if (pagesTotal === null || pagesFresh === null) {
28307
28455
  return {
28308
28456
  status: "unreadable-report",
28309
- reason: `${path80.relative(cwd, file)} is missing its totals; re-run \`keryx wiki freshness\`.`
28457
+ reason: `${path81.relative(cwd, file)} is missing its totals; re-run \`keryx wiki freshness\`.`
28310
28458
  };
28311
28459
  }
28312
28460
  const pagesUndecidable = numberOr2(totals.pagesUndecidable) ?? 0;
@@ -28360,12 +28508,12 @@ function renderWikiFreshnessLine(metric) {
28360
28508
  }
28361
28509
 
28362
28510
  // src/health/sources/helpers.ts
28363
- import path81 from "path";
28511
+ import path82 from "path";
28364
28512
  import { existsSync as existsSync7 } from "fs";
28365
28513
  class NoImportError extends Error {
28366
28514
  }
28367
28515
  function resolveBin(cwd, name) {
28368
- const local = path81.join(cwd, "node_modules", ".bin", name);
28516
+ const local = path82.join(cwd, "node_modules", ".bin", name);
28369
28517
  if (existsSync7(local)) {
28370
28518
  return local;
28371
28519
  }
@@ -28446,13 +28594,13 @@ async function getComplexityFindings(cwd, sourceFiles, config, sourceAnalysis) {
28446
28594
 
28447
28595
  // src/health/metrics/coverage.ts
28448
28596
  import { existsSync as existsSync8 } from "fs";
28449
- import path82 from "path";
28597
+ import path83 from "path";
28450
28598
  var SUMMARY_PATHS = [
28451
28599
  "coverage/coverage-summary.json",
28452
28600
  "coverage/coverage-final.json"
28453
28601
  ];
28454
28602
  async function getCoverage(cwd) {
28455
- const summary = SUMMARY_PATHS.map((rel) => path82.join(cwd, rel)).find((abs) => existsSync8(abs));
28603
+ const summary = SUMMARY_PATHS.map((rel) => path83.join(cwd, rel)).find((abs) => existsSync8(abs));
28456
28604
  if (!summary) {
28457
28605
  return { status: "missing", total: null, byFile: new Map };
28458
28606
  }
@@ -28473,7 +28621,7 @@ async function getCoverage(cwd) {
28473
28621
  total = pct;
28474
28622
  continue;
28475
28623
  }
28476
- const relative = path82.isAbsolute(key) ? path82.relative(cwd, key) : key;
28624
+ const relative = path83.isAbsolute(key) ? path83.relative(cwd, key) : key;
28477
28625
  byFile.set(relative.replace(/\\/g, "/"), pct);
28478
28626
  }
28479
28627
  return { status: "available", total, byFile };
@@ -28606,10 +28754,10 @@ function renderWikiFreshness(metric) {
28606
28754
  // src/health/skills.ts
28607
28755
  init_fs();
28608
28756
  import { readFile as readFile42 } from "fs/promises";
28609
- import path83 from "path";
28757
+ import path84 from "path";
28610
28758
  var EMPTY = { skills: [], skillForFile: () => null };
28611
28759
  async function loadSkillOwnership(cwd) {
28612
- const manifestPath = path83.join(cwd, ".metaproject", "metaproject.json");
28760
+ const manifestPath = path84.join(cwd, ".metaproject", "metaproject.json");
28613
28761
  if (!await pathExists(manifestPath)) {
28614
28762
  return EMPTY;
28615
28763
  }
@@ -28647,7 +28795,7 @@ function normalize(value) {
28647
28795
 
28648
28796
  // src/health/sources/eslint.ts
28649
28797
  import { existsSync as existsSync9 } from "fs";
28650
- import path84 from "path";
28798
+ import path85 from "path";
28651
28799
  var CONFIG_FILES = [
28652
28800
  ".eslintrc",
28653
28801
  ".eslintrc.js",
@@ -28661,7 +28809,7 @@ var CONFIG_FILES = [
28661
28809
  "eslint.config.ts"
28662
28810
  ];
28663
28811
  function hasConfig(cwd) {
28664
- return CONFIG_FILES.some((file) => existsSync9(path84.join(cwd, file)));
28812
+ return CONFIG_FILES.some((file) => existsSync9(path85.join(cwd, file)));
28665
28813
  }
28666
28814
  var eslintAdapter = {
28667
28815
  id: "eslint",
@@ -28686,7 +28834,7 @@ var eslintAdapter = {
28686
28834
  };
28687
28835
  },
28688
28836
  async import(ctx) {
28689
- const report = path84.join(ctx.cwd, "eslint-report.json");
28837
+ const report = path85.join(ctx.cwd, "eslint-report.json");
28690
28838
  if (!existsSync9(report)) {
28691
28839
  throw new NoImportError("no eslint-report.json");
28692
28840
  }
@@ -28713,7 +28861,7 @@ var eslintAdapter = {
28713
28861
  }
28714
28862
  const findings = [];
28715
28863
  for (const file of data) {
28716
- const relative = path84.isAbsolute(file.filePath) ? path84.relative(ctx.cwd, file.filePath) : file.filePath;
28864
+ const relative = path85.isAbsolute(file.filePath) ? path85.relative(ctx.cwd, file.filePath) : file.filePath;
28717
28865
  for (const message of file.messages ?? []) {
28718
28866
  const isError = message.severity === 2;
28719
28867
  findings.push(makeFinding({
@@ -28745,9 +28893,9 @@ var eslintAdapter = {
28745
28893
 
28746
28894
  // src/health/sources/typescript.ts
28747
28895
  import { existsSync as existsSync10 } from "fs";
28748
- import path85 from "path";
28896
+ import path86 from "path";
28749
28897
  function hasTsconfig(cwd) {
28750
- return existsSync10(path85.join(cwd, "tsconfig.json"));
28898
+ return existsSync10(path86.join(cwd, "tsconfig.json"));
28751
28899
  }
28752
28900
  var typescriptAdapter = {
28753
28901
  id: "typescript",
@@ -28823,7 +28971,7 @@ __export(exports_service6, {
28823
28971
  });
28824
28972
  import { existsSync as existsSync11 } from "fs";
28825
28973
  import { readFile as readFile45, readdir as readdir15 } from "fs/promises";
28826
- import path90 from "path";
28974
+ import path91 from "path";
28827
28975
 
28828
28976
  // src/lib/git-env.ts
28829
28977
  var GIT_DISCOVERY_OVERRIDE_VARS = [
@@ -28848,7 +28996,7 @@ function withoutGitDiscoveryOverrides(env) {
28848
28996
  init_fs();
28849
28997
  init_guard();
28850
28998
  import { readFile as readFile43 } from "fs/promises";
28851
- import path86 from "path";
28999
+ import path87 from "path";
28852
29000
 
28853
29001
  // src/metrics/record.ts
28854
29002
  var RELIABILITIES = new Set(["exact", "estimated", "unknown"]);
@@ -28863,7 +29011,7 @@ var RETRY_TYPES = new Set([
28863
29011
 
28864
29012
  // src/metrics/lifecycle.ts
28865
29013
  async function readArtifactPointer(root, expected) {
28866
- const pointerFile = path86.join(root, "latest.json");
29014
+ const pointerFile = path87.join(root, "latest.json");
28867
29015
  if (!await pathExists(pointerFile))
28868
29016
  return { status: "missing", pointer: null };
28869
29017
  let pointer;
@@ -28872,7 +29020,7 @@ async function readArtifactPointer(root, expected) {
28872
29020
  } catch {
28873
29021
  return { status: "stale", pointer: null, reason: "latest pointer is invalid JSON" };
28874
29022
  }
28875
- const recordFile = pointer.record ? path86.join(root, pointer.record) : null;
29023
+ const recordFile = pointer.record ? path87.join(root, pointer.record) : null;
28876
29024
  if (!recordFile || !isPathInside(root, recordFile) || !await pathExists(recordFile)) {
28877
29025
  return { status: "stale", pointer, reason: "pointer record is missing" };
28878
29026
  }
@@ -28888,9 +29036,9 @@ init_guard();
28888
29036
  // src/testing/capability.ts
28889
29037
  init_fs();
28890
29038
  init_json();
28891
- import path87 from "path";
29039
+ import path88 from "path";
28892
29040
  async function isTestingCapabilityEnabled(cwd, capability) {
28893
- const manifestPath = path87.join(cwd, ".metaproject", "metaproject.json");
29041
+ const manifestPath = path88.join(cwd, ".metaproject", "metaproject.json");
28894
29042
  if (!await pathExists(manifestPath)) {
28895
29043
  return false;
28896
29044
  }
@@ -28916,10 +29064,10 @@ async function isTestingCapabilityEnabled(cwd, capability) {
28916
29064
  init_fs();
28917
29065
  init_guard();
28918
29066
  import { readFile as readFile44, mkdir as mkdir25, writeFile as writeFile18 } from "fs/promises";
28919
- import path88 from "path";
29067
+ import path89 from "path";
28920
29068
  var COVERAGE_MAP_SCHEMA_VERSION = 1;
28921
29069
  function coverageMapPath(cwd, cfg) {
28922
- return path88.isAbsolute(cfg.coverageMap.artifact) ? cfg.coverageMap.artifact : path88.join(cwd, cfg.coverageMap.artifact);
29070
+ return path89.isAbsolute(cfg.coverageMap.artifact) ? cfg.coverageMap.artifact : path89.join(cwd, cfg.coverageMap.artifact);
28923
29071
  }
28924
29072
  async function loadCoverageMap(cwd, cfg) {
28925
29073
  const file = coverageMapPath(cwd, cfg);
@@ -28993,20 +29141,20 @@ function normalizePath4(file) {
28993
29141
  }
28994
29142
 
28995
29143
  // src/testing/selection.ts
28996
- import path89 from "path";
29144
+ import path90 from "path";
28997
29145
  var TEST_FILE_RE = /(^|\/)(__tests__\/.*|.*\.(test|spec)\.[cm]?[tj]sx?$|e2e\/.*\.[cm]?[tj]sx?$|tests\/.*\.[cm]?[tj]sx?$)/;
28998
29146
  function normalizePath5(file) {
28999
29147
  return file.replace(/\\/g, "/").replace(/^\.\//, "");
29000
29148
  }
29001
29149
  function relatedByNamingAndDirectory(target, testFiles) {
29002
29150
  const normalized = normalizePath5(target);
29003
- const ext = path89.extname(normalized);
29151
+ const ext = path90.extname(normalized);
29004
29152
  const withoutExt = ext ? normalized.slice(0, -ext.length) : normalized;
29005
- const base = path89.basename(withoutExt);
29006
- const dir = path89.dirname(normalized);
29153
+ const base = path90.basename(withoutExt);
29154
+ const dir = path90.dirname(normalized);
29007
29155
  return testFiles.filter((file) => {
29008
- const fileDir = path89.dirname(file);
29009
- const fileBase = path89.basename(file);
29156
+ const fileDir = path90.dirname(file);
29157
+ const fileBase = path90.basename(file);
29010
29158
  return file.startsWith(`${withoutExt}.`) || file.includes(`${withoutExt}.`) || fileDir === dir && fileBase.startsWith(`${base}.`) || fileDir.startsWith(dir) && fileBase.includes(base);
29011
29159
  }).sort();
29012
29160
  }
@@ -29136,7 +29284,7 @@ var DEFAULT_TESTING_CONFIG = {
29136
29284
  }
29137
29285
  };
29138
29286
  function testingDataRoot(cwd) {
29139
- return path90.join(cwd, ".metaproject", "data", "testing");
29287
+ return path91.join(cwd, ".metaproject", "data", "testing");
29140
29288
  }
29141
29289
  async function computeTestingContext(cwd) {
29142
29290
  const { files, incompleteReasons } = await listProjectFiles(cwd);
@@ -29311,7 +29459,7 @@ async function runTesting(input) {
29311
29459
  return runResult;
29312
29460
  }
29313
29461
  async function loadTestingContext(cwd) {
29314
- const file = path90.join(testingDataRoot(cwd), "context.json");
29462
+ const file = path91.join(testingDataRoot(cwd), "context.json");
29315
29463
  if (!await pathExists(file)) {
29316
29464
  return null;
29317
29465
  }
@@ -29322,18 +29470,18 @@ async function loadTestingContext(cwd) {
29322
29470
  }
29323
29471
  }
29324
29472
  async function loadTestingReport(cwd) {
29325
- const file = path90.join(testingDataRoot(cwd), "artifacts", "latest.json");
29473
+ const file = path91.join(testingDataRoot(cwd), "artifacts", "latest.json");
29326
29474
  if (!await pathExists(file)) {
29327
29475
  return null;
29328
29476
  }
29329
29477
  try {
29330
29478
  const latest = JSON.parse(await readFile45(file, "utf8"));
29331
29479
  if (typeof latest.record === "string") {
29332
- const pointer = await readArtifactPointer(path90.join(testingDataRoot(cwd), "artifacts"), await collectGitProvenance(cwd));
29480
+ const pointer = await readArtifactPointer(path91.join(testingDataRoot(cwd), "artifacts"), await collectGitProvenance(cwd));
29333
29481
  if (pointer.status !== "fresh")
29334
29482
  return null;
29335
- const recordFile = path90.join(testingDataRoot(cwd), "artifacts", latest.record);
29336
- if (!isPathInside(path90.join(testingDataRoot(cwd), "artifacts"), recordFile))
29483
+ const recordFile = path91.join(testingDataRoot(cwd), "artifacts", latest.record);
29484
+ if (!isPathInside(path91.join(testingDataRoot(cwd), "artifacts"), recordFile))
29337
29485
  return null;
29338
29486
  if (!await pathExists(recordFile))
29339
29487
  return null;
@@ -29380,28 +29528,28 @@ async function ensureContext(cwd) {
29380
29528
  }
29381
29529
  async function writeContext(cwd, context) {
29382
29530
  const root = testingDataRoot(cwd);
29383
- const rel = (p) => path90.relative(cwd, p);
29531
+ const rel = (p) => path91.relative(cwd, p);
29384
29532
  await mkdirContained(cwd, rel(root));
29385
- await writeContained(cwd, rel(path90.join(root, "context.json")), `${JSON.stringify(context, null, 2)}
29533
+ await writeContained(cwd, rel(path91.join(root, "context.json")), `${JSON.stringify(context, null, 2)}
29386
29534
  `);
29387
- await writeContained(cwd, rel(path90.join(root, "context.md")), renderContextMarkdown(context));
29388
- await writeContained(cwd, rel(path90.join(root, "recommendations.md")), renderRecommendationsMarkdown(context));
29535
+ await writeContained(cwd, rel(path91.join(root, "context.md")), renderContextMarkdown(context));
29536
+ await writeContained(cwd, rel(path91.join(root, "recommendations.md")), renderRecommendationsMarkdown(context));
29389
29537
  }
29390
29538
  async function writeReport(cwd, report) {
29391
29539
  const root = testingDataRoot(cwd);
29392
- const artifacts = path90.join(root, "artifacts");
29393
- const history = path90.join(root, "history");
29394
- const rel = (p) => path90.relative(cwd, p);
29540
+ const artifacts = path91.join(root, "artifacts");
29541
+ const history = path91.join(root, "history");
29542
+ const rel = (p) => path91.relative(cwd, p);
29395
29543
  await mkdirContained(cwd, rel(artifacts));
29396
29544
  await mkdirContained(cwd, rel(history));
29397
29545
  const stamp = report.generatedAt.replace(/[:.]/g, "-");
29398
- const json = path90.join(artifacts, "latest.json");
29399
- const markdown = path90.join(artifacts, "latest.md");
29546
+ const json = path91.join(artifacts, "latest.json");
29547
+ const markdown = path91.join(artifacts, "latest.md");
29400
29548
  const serialized = `${JSON.stringify(report, null, 2)}
29401
29549
  `;
29402
29550
  if (report.runId) {
29403
- const runJson = path90.join(artifacts, "runs", `${report.runId}.json`);
29404
- const runMarkdown = path90.join(artifacts, "runs", `${report.runId}.md`);
29551
+ const runJson = path91.join(artifacts, "runs", `${report.runId}.json`);
29552
+ const runMarkdown = path91.join(artifacts, "runs", `${report.runId}.md`);
29405
29553
  if (await pathExists(runJson))
29406
29554
  throw new Error(`immutable testing run already exists: ${report.runId}`);
29407
29555
  await writeContained(cwd, rel(runJson), serialized);
@@ -29412,26 +29560,26 @@ async function writeReport(cwd, report) {
29412
29560
  branch: report.provenance?.branch ?? null,
29413
29561
  worktree: report.provenance?.worktree ?? null,
29414
29562
  generated_at: report.generatedAt,
29415
- record: path90.posix.join("runs", `${report.runId}.json`)
29563
+ record: path91.posix.join("runs", `${report.runId}.json`)
29416
29564
  }, null, 2)}
29417
29565
  `);
29418
29566
  } else {
29419
29567
  await writeContained(cwd, rel(json), serialized);
29420
29568
  }
29421
29569
  await writeContained(cwd, rel(markdown), renderReportMarkdown3(report));
29422
- await writeContained(cwd, rel(path90.join(history, `${stamp}.json`)), serialized);
29570
+ await writeContained(cwd, rel(path91.join(history, `${stamp}.json`)), serialized);
29423
29571
  return {
29424
- markdownPath: path90.relative(cwd, markdown),
29425
- jsonPath: path90.relative(cwd, json)
29572
+ markdownPath: path91.relative(cwd, markdown),
29573
+ jsonPath: path91.relative(cwd, json)
29426
29574
  };
29427
29575
  }
29428
29576
  async function writeRawLog(cwd, raw) {
29429
- const logs = path90.join(testingDataRoot(cwd), "logs");
29430
- const rel = (p) => path90.relative(cwd, p);
29577
+ const logs = path91.join(testingDataRoot(cwd), "logs");
29578
+ const rel = (p) => path91.relative(cwd, p);
29431
29579
  await mkdirContained(cwd, rel(logs));
29432
- const latest = path90.join(logs, "latest.raw.log");
29580
+ const latest = path91.join(logs, "latest.raw.log");
29433
29581
  await writeContained(cwd, rel(latest), raw);
29434
- return path90.relative(cwd, latest);
29582
+ return path91.relative(cwd, latest);
29435
29583
  }
29436
29584
  async function listProjectFiles(cwd) {
29437
29585
  const out = [];
@@ -29444,11 +29592,11 @@ async function walk3(root, dir, out, incompleteReasons) {
29444
29592
  try {
29445
29593
  entries = await readdir15(dir, { withFileTypes: true });
29446
29594
  } catch (error) {
29447
- incompleteReasons.push(`${normalizePath6(path90.relative(root, dir)) || "."}: ${error instanceof Error ? error.message : String(error)}`);
29595
+ incompleteReasons.push(`${normalizePath6(path91.relative(root, dir)) || "."}: ${error instanceof Error ? error.message : String(error)}`);
29448
29596
  return;
29449
29597
  }
29450
29598
  for (const entry of entries) {
29451
- const abs = path90.join(dir, entry.name);
29599
+ const abs = path91.join(dir, entry.name);
29452
29600
  if (entry.isDirectory()) {
29453
29601
  if (IGNORED_DIRS2.has(entry.name) || entry.name.startsWith(".tmp-")) {
29454
29602
  continue;
@@ -29457,12 +29605,12 @@ async function walk3(root, dir, out, incompleteReasons) {
29457
29605
  continue;
29458
29606
  }
29459
29607
  if (entry.isFile()) {
29460
- out.push(normalizePath6(path90.relative(root, abs)));
29608
+ out.push(normalizePath6(path91.relative(root, abs)));
29461
29609
  }
29462
29610
  }
29463
29611
  }
29464
29612
  async function readPackageJson(cwd) {
29465
- const file = path90.join(cwd, "package.json");
29613
+ const file = path91.join(cwd, "package.json");
29466
29614
  if (!await pathExists(file)) {
29467
29615
  return null;
29468
29616
  }
@@ -29473,7 +29621,7 @@ async function readPackageJson(cwd) {
29473
29621
  }
29474
29622
  }
29475
29623
  async function loadTestingConfig(cwd) {
29476
- const file = path90.join(cwd, ".metaproject", "testing.config.json");
29624
+ const file = path91.join(cwd, ".metaproject", "testing.config.json");
29477
29625
  if (!await pathExists(file)) {
29478
29626
  return DEFAULT_TESTING_CONFIG;
29479
29627
  }
@@ -29538,7 +29686,7 @@ function detectFrameworks(input) {
29538
29686
  async function extractConventions(cwd, files) {
29539
29687
  const conventions = new Set;
29540
29688
  for (const file of files.slice(0, 40)) {
29541
- const abs = path90.join(cwd, file);
29689
+ const abs = path91.join(cwd, file);
29542
29690
  if (!await pathExists(abs)) {
29543
29691
  continue;
29544
29692
  }
@@ -29668,7 +29816,7 @@ async function findTestsByImportedTargets(cwd, targets, testFiles) {
29668
29816
  const targetKeys = new Set(targets.map((target) => modulePathKey(normalizePath6(target))));
29669
29817
  const selected = new Set;
29670
29818
  for (const testFile of testFiles) {
29671
- const absoluteTest = path90.join(cwd, testFile);
29819
+ const absoluteTest = path91.join(cwd, testFile);
29672
29820
  if (!await pathExists(absoluteTest)) {
29673
29821
  continue;
29674
29822
  }
@@ -29702,10 +29850,10 @@ function resolveImportPath(cwd, testFile, importPath) {
29702
29850
  if (!importPath.startsWith(".")) {
29703
29851
  return null;
29704
29852
  }
29705
- const importerDir = path90.dirname(testFile);
29706
- const absoluteResolved = path90.resolve(path90.join(cwd, importerDir), importPath);
29707
- const relative = path90.relative(cwd, absoluteResolved);
29708
- if (relative.startsWith(`..${path90.sep}`) || relative === "..") {
29853
+ const importerDir = path91.dirname(testFile);
29854
+ const absoluteResolved = path91.resolve(path91.join(cwd, importerDir), importPath);
29855
+ const relative = path91.relative(cwd, absoluteResolved);
29856
+ if (relative.startsWith(`..${path91.sep}`) || relative === "..") {
29709
29857
  return null;
29710
29858
  }
29711
29859
  const relativeNormalized = normalizePath6(relative);
@@ -29757,13 +29905,13 @@ function resolveTestCommand(cwd, context, input) {
29757
29905
  }
29758
29906
  var BUN_LOCKFILES = ["bun.lock", "bun.lockb"];
29759
29907
  function detectPackageManager(cwd) {
29760
- if (resolveBunBin() && BUN_LOCKFILES.some((name) => pathExistsSync(path90.join(cwd, name)))) {
29908
+ if (resolveBunBin() && BUN_LOCKFILES.some((name) => pathExistsSync(path91.join(cwd, name)))) {
29761
29909
  return "bun";
29762
29910
  }
29763
- if (Bun.which("pnpm") && pathExistsSync(path90.join(cwd, "pnpm-lock.yaml"))) {
29911
+ if (Bun.which("pnpm") && pathExistsSync(path91.join(cwd, "pnpm-lock.yaml"))) {
29764
29912
  return "pnpm";
29765
29913
  }
29766
- if (Bun.which("yarn") && pathExistsSync(path90.join(cwd, "yarn.lock"))) {
29914
+ if (Bun.which("yarn") && pathExistsSync(path91.join(cwd, "yarn.lock"))) {
29767
29915
  return "yarn";
29768
29916
  }
29769
29917
  return "npm";
@@ -30103,7 +30251,7 @@ async function compatibleReportForHealth(ctx) {
30103
30251
 
30104
30252
  // src/health/sources/dependency-audit.ts
30105
30253
  import { existsSync as existsSync12 } from "fs";
30106
- import path91 from "path";
30254
+ import path92 from "path";
30107
30255
  function auditSeverityToPriority(severity) {
30108
30256
  if (severity === "critical" || severity === "high")
30109
30257
  return "P0";
@@ -30222,7 +30370,7 @@ var LOCKFILE_COMMANDS = [
30222
30370
  ];
30223
30371
  function auditCommand(cwd) {
30224
30372
  for (const entry of LOCKFILE_COMMANDS) {
30225
- if (!entry.lockfiles.some((name) => existsSync12(path91.join(cwd, name))))
30373
+ if (!entry.lockfiles.some((name) => existsSync12(path92.join(cwd, name))))
30226
30374
  continue;
30227
30375
  const bin = resolveBin(cwd, entry.bin);
30228
30376
  if (bin)
@@ -30281,13 +30429,13 @@ var dependencyAuditAdapter = {
30281
30429
 
30282
30430
  // src/health/sources/sonarqube.ts
30283
30431
  import { existsSync as existsSync13 } from "fs";
30284
- import path92 from "path";
30432
+ import path93 from "path";
30285
30433
  var REPORT_FILES = ["sonar-issues.json", ".metaproject/data/health/sonar-issues.json"];
30286
30434
  function reportPath(cwd) {
30287
30435
  const fromEnv = process.env.SONAR_ISSUES_FILE;
30288
30436
  const candidates = fromEnv ? [fromEnv, ...REPORT_FILES] : REPORT_FILES;
30289
30437
  for (const rel of candidates) {
30290
- const abs = path92.isAbsolute(rel) ? rel : path92.join(cwd, rel);
30438
+ const abs = path93.isAbsolute(rel) ? rel : path93.join(cwd, rel);
30291
30439
  if (existsSync13(abs)) {
30292
30440
  return abs;
30293
30441
  }
@@ -30371,7 +30519,7 @@ var sonarqubeAdapter = {
30371
30519
  function relativizeComponent(component, cwd) {
30372
30520
  const colon = component.indexOf(":");
30373
30521
  const value = colon >= 0 ? component.slice(colon + 1) : component;
30374
- return path92.isAbsolute(value) ? path92.relative(cwd, value) : value;
30522
+ return path93.isAbsolute(value) ? path93.relative(cwd, value) : value;
30375
30523
  }
30376
30524
 
30377
30525
  // src/health/sources/index.ts
@@ -30708,19 +30856,19 @@ function filteredInfo(source, cfg) {
30708
30856
  };
30709
30857
  }
30710
30858
  async function writeOutputs(cwd, report, config, stamp) {
30711
- const artifacts = path93.join(dataRoot3(cwd), "artifacts");
30712
- const history = path93.join(dataRoot3(cwd), "history");
30859
+ const artifacts = path94.join(dataRoot3(cwd), "artifacts");
30860
+ const history = path94.join(dataRoot3(cwd), "history");
30713
30861
  await mkdir26(artifacts, { recursive: true });
30714
30862
  await mkdir26(history, { recursive: true });
30715
- const markdown = path93.join(artifacts, "latest.md");
30716
- const json = path93.join(artifacts, "latest.json");
30717
- const historyJson = path93.join(history, `${stamp}.json`);
30863
+ const markdown = path94.join(artifacts, "latest.md");
30864
+ const json = path94.join(artifacts, "latest.json");
30865
+ const historyJson = path94.join(history, `${stamp}.json`);
30718
30866
  const serialized = `${JSON.stringify(report, null, 2)}
30719
30867
  `;
30720
30868
  await writeFile19(markdown, renderReportMarkdown2(report, config), "utf8");
30721
30869
  if (report.runId) {
30722
- const runJson = path93.join(artifacts, "runs", `${report.runId}.json`);
30723
- const runMarkdown = path93.join(artifacts, "runs", `${report.runId}.md`);
30870
+ const runJson = path94.join(artifacts, "runs", `${report.runId}.json`);
30871
+ const runMarkdown = path94.join(artifacts, "runs", `${report.runId}.md`);
30724
30872
  if (await pathExists(runJson))
30725
30873
  throw new Error(`immutable health run already exists: ${report.runId}`);
30726
30874
  await writeFileAtomic(runJson, serialized);
@@ -30731,7 +30879,7 @@ async function writeOutputs(cwd, report, config, stamp) {
30731
30879
  branch: report.provenance?.branch ?? null,
30732
30880
  worktree: report.provenance?.worktree ?? null,
30733
30881
  generated_at: report.generatedAt,
30734
- record: path93.posix.join("runs", `${report.runId}.json`)
30882
+ record: path94.posix.join("runs", `${report.runId}.json`)
30735
30883
  }, null, 2)}
30736
30884
  `);
30737
30885
  } else {
@@ -30739,8 +30887,8 @@ async function writeOutputs(cwd, report, config, stamp) {
30739
30887
  }
30740
30888
  await writeFile19(historyJson, serialized, "utf8");
30741
30889
  return {
30742
- markdownPath: path93.relative(cwd, markdown),
30743
- jsonPath: path93.relative(cwd, json)
30890
+ markdownPath: path94.relative(cwd, markdown),
30891
+ jsonPath: path94.relative(cwd, json)
30744
30892
  };
30745
30893
  }
30746
30894
  async function resolveChanged(cwd, selector) {
@@ -30793,7 +30941,7 @@ function hasGateShape(value) {
30793
30941
  return Array.isArray(report.metrics) && Array.isArray(report.sources) && Array.isArray(report.findings);
30794
30942
  }
30795
30943
  async function readLatest(cwd) {
30796
- const file = path94.join(dataRoot3(cwd), "artifacts", "latest.json");
30944
+ const file = path95.join(dataRoot3(cwd), "artifacts", "latest.json");
30797
30945
  if (!await pathExists(file)) {
30798
30946
  return null;
30799
30947
  }
@@ -30804,11 +30952,11 @@ async function readLatest(cwd) {
30804
30952
  const latest = read.value;
30805
30953
  const record = latest.record;
30806
30954
  if (typeof record === "string") {
30807
- const pointer = await readArtifactPointer(path94.join(dataRoot3(cwd), "artifacts"), await collectGitProvenance(cwd));
30955
+ const pointer = await readArtifactPointer(path95.join(dataRoot3(cwd), "artifacts"), await collectGitProvenance(cwd));
30808
30956
  if (pointer.status !== "fresh")
30809
30957
  return null;
30810
- const recordFile = path94.join(dataRoot3(cwd), "artifacts", record);
30811
- if (!isPathInside(path94.join(dataRoot3(cwd), "artifacts"), recordFile))
30958
+ const recordFile = path95.join(dataRoot3(cwd), "artifacts", record);
30959
+ if (!isPathInside(path95.join(dataRoot3(cwd), "artifacts"), recordFile))
30812
30960
  return null;
30813
30961
  if (!await pathExists(recordFile))
30814
30962
  return null;
@@ -30881,7 +31029,7 @@ function createCodeHealthService() {
30881
31029
  return {
30882
31030
  run: (input) => runHealth(input),
30883
31031
  async status(input) {
30884
- const enabled = await pathExists(path94.join(input.cwd, ".metaproject", "health.config.json"));
31032
+ const enabled = await pathExists(path95.join(input.cwd, ".metaproject", "health.config.json"));
30885
31033
  const latest = await readLatest(input.cwd);
30886
31034
  const project = latest?.metrics.find((m) => m.key === "project") ?? null;
30887
31035
  const decliningScopes = latest ? latest.metrics.filter((m) => m.regression_score > 0).length : 0;
@@ -31039,10 +31187,10 @@ function renderEvidenceBlock(evidences, siblings) {
31039
31187
  init_fs();
31040
31188
  init_contained_write();
31041
31189
  init_json();
31042
- import path95 from "path";
31190
+ import path96 from "path";
31043
31191
  import { createHash as createHash16 } from "crypto";
31044
31192
  function impactEvidenceDataRoot(root) {
31045
- return path95.join(root, ".metaproject", "data", "security", "impact-evidence");
31193
+ return path96.join(root, ".metaproject", "data", "security", "impact-evidence");
31046
31194
  }
31047
31195
  function sanitizeSessionId(sessionId) {
31048
31196
  const cleaned = sessionId.replace(/[^A-Za-z0-9._-]/g, "_");
@@ -31054,7 +31202,7 @@ function sessionStateFilename(sessionId) {
31054
31202
  return `${sanitized}-${suffix}.json`;
31055
31203
  }
31056
31204
  function sessionStatePath(root, sessionId) {
31057
- return path95.join(impactEvidenceDataRoot(root), "sessions", sessionStateFilename(sessionId));
31205
+ return path96.join(impactEvidenceDataRoot(root), "sessions", sessionStateFilename(sessionId));
31058
31206
  }
31059
31207
  async function loadSessionState(root, sessionId) {
31060
31208
  const file = sessionStatePath(root, sessionId);
@@ -31073,11 +31221,11 @@ async function loadSessionState(root, sessionId) {
31073
31221
  }
31074
31222
  async function saveSessionState(root, sessionId, state) {
31075
31223
  const file = sessionStatePath(root, sessionId);
31076
- await writeContained(root, path95.relative(root, file), `${JSON.stringify(state, null, 2)}
31224
+ await writeContained(root, path96.relative(root, file), `${JSON.stringify(state, null, 2)}
31077
31225
  `);
31078
31226
  }
31079
31227
  function logPath(root) {
31080
- return path95.join(impactEvidenceDataRoot(root), "log.jsonl");
31228
+ return path96.join(impactEvidenceDataRoot(root), "log.jsonl");
31081
31229
  }
31082
31230
  async function appendLogRecord(root, record) {
31083
31231
  const full = {
@@ -31088,7 +31236,7 @@ async function appendLogRecord(root, record) {
31088
31236
  ...record.detail !== undefined ? { detail: record.detail } : {}
31089
31237
  };
31090
31238
  const file = logPath(root);
31091
- await appendContained(root, path95.relative(root, file), `${JSON.stringify(full)}
31239
+ await appendContained(root, path96.relative(root, file), `${JSON.stringify(full)}
31092
31240
  `);
31093
31241
  return full;
31094
31242
  }
@@ -31115,7 +31263,7 @@ init_command_risk();
31115
31263
  init_shell_syntax();
31116
31264
  init_fs();
31117
31265
  init_service2();
31118
- import path96 from "path";
31266
+ import path97 from "path";
31119
31267
  import { createHash as createHash17 } from "crypto";
31120
31268
  import { realpathSync as realpathSync2 } from "fs";
31121
31269
  function impactEvidenceHookClass(strict) {
@@ -31131,29 +31279,29 @@ function realpathNearestExisting(p) {
31131
31279
  for (;; ) {
31132
31280
  try {
31133
31281
  const real = realpathSync2(current);
31134
- return tail.length > 0 ? path96.join(real, ...tail) : real;
31282
+ return tail.length > 0 ? path97.join(real, ...tail) : real;
31135
31283
  } catch {
31136
- const parent = path96.dirname(current);
31284
+ const parent = path97.dirname(current);
31137
31285
  if (parent === current) {
31138
- return tail.length > 0 ? path96.join(current, ...tail) : current;
31286
+ return tail.length > 0 ? path97.join(current, ...tail) : current;
31139
31287
  }
31140
- tail.unshift(path96.basename(current));
31288
+ tail.unshift(path97.basename(current));
31141
31289
  current = parent;
31142
31290
  }
31143
31291
  }
31144
31292
  }
31145
31293
  function normalizeRequestFiles(root, files) {
31146
- const rootReal = realpathNearestExisting(path96.resolve(root));
31294
+ const rootReal = realpathNearestExisting(path97.resolve(root));
31147
31295
  const normalized = [];
31148
31296
  const rejected = [];
31149
31297
  for (const file of files) {
31150
- const lexicalAbsolute = path96.isAbsolute(file) ? path96.resolve(file) : path96.resolve(rootReal, toPosix(file).replace(/^\.\//, ""));
31298
+ const lexicalAbsolute = path97.isAbsolute(file) ? path97.resolve(file) : path97.resolve(rootReal, toPosix(file).replace(/^\.\//, ""));
31151
31299
  const effective = realpathNearestExisting(lexicalAbsolute);
31152
31300
  if (!isPathInside(rootReal, effective)) {
31153
31301
  rejected.push(file);
31154
31302
  continue;
31155
31303
  }
31156
- normalized.push(toPosix(path96.relative(rootReal, effective)));
31304
+ normalized.push(toPosix(path97.relative(rootReal, effective)));
31157
31305
  }
31158
31306
  return { files: [...new Set(normalized)], rejected };
31159
31307
  }
@@ -31439,7 +31587,7 @@ __export(exports_service8, {
31439
31587
  createJobService: () => createJobService
31440
31588
  });
31441
31589
  import { copyFile, mkdir as mkdir28 } from "fs/promises";
31442
- import path99 from "path";
31590
+ import path100 from "path";
31443
31591
 
31444
31592
  // src/job/types.ts
31445
31593
  var JOB_INTENTS = ["implement", "analyze", "review", "custom"];
@@ -31578,12 +31726,12 @@ function defaultPlan(intent) {
31578
31726
  // src/job/store.ts
31579
31727
  init_validator();
31580
31728
  import { appendFile as appendFile5, mkdir as mkdir27, readFile as readFile47, readdir as readdir16 } from "fs/promises";
31581
- import path98 from "path";
31729
+ import path99 from "path";
31582
31730
 
31583
31731
  // src/gdskills/contracts.ts
31584
31732
  import { readFile as readFile46 } from "fs/promises";
31585
31733
  import { existsSync as existsSync14 } from "fs";
31586
- import path97 from "path";
31734
+ import path98 from "path";
31587
31735
  import { fileURLToPath as fileURLToPath2 } from "url";
31588
31736
  var CONTRACTS = [
31589
31737
  {
@@ -31706,10 +31854,10 @@ async function loadSchema(name) {
31706
31854
  return JSON.parse(raw);
31707
31855
  }
31708
31856
  function contractPath(contract) {
31709
- const here = path97.dirname(fileURLToPath2(import.meta.url));
31857
+ const here = path98.dirname(fileURLToPath2(import.meta.url));
31710
31858
  if (contract.sourcePath) {
31711
- for (const root of [path97.join(here, "..", ".."), path97.join(here, ".."), here]) {
31712
- const candidate = path97.resolve(root, contract.sourcePath);
31859
+ for (const root of [path98.join(here, "..", ".."), path98.join(here, ".."), here]) {
31860
+ const candidate = path98.resolve(root, contract.sourcePath);
31713
31861
  if (existsSync14(candidate)) {
31714
31862
  return candidate;
31715
31863
  }
@@ -31719,7 +31867,7 @@ function contractPath(contract) {
31719
31867
  if (existsSync14(directPath)) {
31720
31868
  return directPath;
31721
31869
  }
31722
- const packagedSourcePath = path97.join(here, "..", "src", "gdskills", "contracts", contract.fileName);
31870
+ const packagedSourcePath = path98.join(here, "..", "src", "gdskills", "contracts", contract.fileName);
31723
31871
  if (existsSync14(packagedSourcePath)) {
31724
31872
  return packagedSourcePath;
31725
31873
  }
@@ -31733,13 +31881,13 @@ var SCHEMA_ROOTS = [
31733
31881
  // src/job/store.ts
31734
31882
  init_fs();
31735
31883
  function jobsRoot(cwd) {
31736
- return path98.join(cwd, ".metaproject", "jobs");
31884
+ return path99.join(cwd, ".metaproject", "jobs");
31737
31885
  }
31738
31886
  function jobDir(cwd, name) {
31739
- return path98.join(jobsRoot(cwd), name);
31887
+ return path99.join(jobsRoot(cwd), name);
31740
31888
  }
31741
31889
  function jobStatePath(cwd, name) {
31742
- return path98.join(jobDir(cwd, name), "state.json");
31890
+ return path99.join(jobDir(cwd, name), "state.json");
31743
31891
  }
31744
31892
  var JOB_NAME_PATTERN = /^[a-z0-9-]+$/;
31745
31893
  function assertJobName(name) {
@@ -31776,12 +31924,12 @@ async function writeJob(cwd, name, state) {
31776
31924
  `));
31777
31925
  }
31778
31926
  const file = jobStatePath(cwd, name);
31779
- await mkdir27(path98.dirname(file), { recursive: true });
31927
+ await mkdir27(path99.dirname(file), { recursive: true });
31780
31928
  await writeFileAtomic(file, `${JSON.stringify(state, null, 2)}
31781
31929
  `);
31782
31930
  }
31783
31931
  async function appendJournal2(cwd, name, at, line) {
31784
- await appendFile5(path98.join(jobDir(cwd, name), "journal.md"), `- ${at} - ${line}
31932
+ await appendFile5(path99.join(jobDir(cwd, name), "journal.md"), `- ${at} - ${line}
31785
31933
  `, "utf8");
31786
31934
  }
31787
31935
  function renderJournal2(name, at) {
@@ -31802,7 +31950,7 @@ function assertDocumentType(raw) {
31802
31950
  return raw;
31803
31951
  }
31804
31952
  function documentFileName(type, sourcePath) {
31805
- const extension = path98.extname(sourcePath) || ".md";
31953
+ const extension = path99.extname(sourcePath) || ".md";
31806
31954
  return `${type}${extension}`;
31807
31955
  }
31808
31956
 
@@ -31810,7 +31958,7 @@ function documentFileName(type, sourcePath) {
31810
31958
  function createJobService(deps) {
31811
31959
  const now = () => deps.now().toISOString();
31812
31960
  function lockPath(cwd, name) {
31813
- return path99.join(jobsRoot(cwd), `.job-lock-${name}`);
31961
+ return path100.join(jobsRoot(cwd), `.job-lock-${name}`);
31814
31962
  }
31815
31963
  async function mutate(cwd, name, run) {
31816
31964
  assertJobName(name);
@@ -31859,20 +32007,20 @@ function createJobService(deps) {
31859
32007
  },
31860
32008
  plan: { steps: defaultPlan(intent) },
31861
32009
  documentation: {
31862
- job_path: path99.join(".metaproject", "jobs", name),
32010
+ job_path: path100.join(".metaproject", "jobs", name),
31863
32011
  documents_created: []
31864
32012
  },
31865
32013
  metrics: { steps: [] },
31866
- jobs_root: path99.join(".metaproject", "jobs"),
32014
+ jobs_root: path100.join(".metaproject", "jobs"),
31867
32015
  updated_at: createdAt
31868
32016
  };
31869
32017
  const first = firstOpenStep(state.plan.steps);
31870
32018
  if (first) {
31871
32019
  state.plan.current_step = first.id;
31872
32020
  }
31873
- await writeFileAtomic(path99.join(absolute, "journal.md"), renderJournal2(name, createdAt));
32021
+ await writeFileAtomic(path100.join(absolute, "journal.md"), renderJournal2(name, createdAt));
31874
32022
  await writeJob(input.cwd, name, state);
31875
- return { state, dir: path99.relative(input.cwd, absolute) };
32023
+ return { state, dir: path100.relative(input.cwd, absolute) };
31876
32024
  },
31877
32025
  async status({ cwd, name }) {
31878
32026
  assertJobName(name);
@@ -31884,7 +32032,7 @@ function createJobService(deps) {
31884
32032
  }
31885
32033
  return {
31886
32034
  state,
31887
- dir: path99.join(".metaproject", "jobs", name),
32035
+ dir: path100.join(".metaproject", "jobs", name),
31888
32036
  stepsDone: state.plan.steps.filter((step) => isTerminalStep(step.status)).length,
31889
32037
  stepsTotal: state.plan.steps.length,
31890
32038
  nextStep: firstOpenStep(state.plan.steps),
@@ -31941,23 +32089,23 @@ function createJobService(deps) {
31941
32089
  if (!input.file) {
31942
32090
  throw new Error("Missing --file. Usage: keryx job document <name> --type <type> --file <path>");
31943
32091
  }
31944
- const source = path99.isAbsolute(input.file) ? input.file : path99.join(input.cwd, input.file);
32092
+ const source = path100.isAbsolute(input.file) ? input.file : path100.join(input.cwd, input.file);
31945
32093
  if (!await pathExists(source)) {
31946
32094
  throw new Error(`--file not found: ${input.file}. Write the document first, then record it.`);
31947
32095
  }
31948
32096
  let recorded;
31949
32097
  await mutate(input.cwd, input.name, async (state) => {
31950
32098
  const fileName = documentFileName(type, source);
31951
- const target = path99.join(jobDir(input.cwd, state.job_name), fileName);
32099
+ const target = path100.join(jobDir(input.cwd, state.job_name), fileName);
31952
32100
  await copyFile(source, target);
31953
32101
  state.documentation ??= {};
31954
- state.documentation.job_path ??= path99.join(".metaproject", "jobs", state.job_name);
32102
+ state.documentation.job_path ??= path100.join(".metaproject", "jobs", state.job_name);
31955
32103
  const created = state.documentation.documents_created ?? [];
31956
32104
  state.documentation.documents_created = created.includes(fileName) ? created : [...created, fileName];
31957
32105
  recorded = {
31958
32106
  state,
31959
32107
  document: fileName,
31960
- path: path99.join(".metaproject", "jobs", state.job_name, fileName)
32108
+ path: path100.join(".metaproject", "jobs", state.job_name, fileName)
31961
32109
  };
31962
32110
  return { state, event: "document", detail: `${type} -> ${fileName}` };
31963
32111
  });
@@ -31992,7 +32140,7 @@ function createJobService(deps) {
31992
32140
  name: state.job_name,
31993
32141
  phase: state.phase,
31994
32142
  intent: state.intent,
31995
- dir: path99.join(".metaproject", "jobs", name),
32143
+ dir: path100.join(".metaproject", "jobs", name),
31996
32144
  stepsDone: state.plan.steps.filter((step) => isTerminalStep(step.status)).length,
31997
32145
  stepsTotal: state.plan.steps.length,
31998
32146
  nextStep: firstOpenStep(state.plan.steps)?.id ?? null
@@ -32097,12 +32245,12 @@ function normalizeWorkspaceReference(raw) {
32097
32245
  // src/sac/fwk-service.ts
32098
32246
  init_assembly();
32099
32247
  import { appendFile as appendFile6, mkdir as mkdir30, open as open3, readFile as readFile50, rename as rename7, rm as rm6, stat as stat13, writeFile as writeFile20 } from "fs/promises";
32100
- import path103 from "path";
32248
+ import path104 from "path";
32101
32249
 
32102
32250
  // src/sac/index.ts
32103
32251
  import { access as access3, readFile as readFile48, realpath as realpath10 } from "fs/promises";
32104
32252
  import { createHash as createHash18 } from "crypto";
32105
- import path100 from "path";
32253
+ import path101 from "path";
32106
32254
  import { fileURLToPath as fileURLToPath3 } from "url";
32107
32255
  var idPattern = /^[a-z][a-z0-9-]{2,63}$/;
32108
32256
  var subjectPattern = /^(?:user|team|service|agent):[a-z0-9][a-z0-9._-]{0,127}$/;
@@ -32120,21 +32268,21 @@ var normativeSchemaFiles = {
32120
32268
  "review-decision": "review-decision.schema.json"
32121
32269
  };
32122
32270
  var normativeSchemas = new Map;
32123
- var NORMATIVE_SCHEMA_DIR = path100.join("docs", "requirements", "shared-agent-context", "schemas");
32271
+ var NORMATIVE_SCHEMA_DIR = path101.join("docs", "requirements", "shared-agent-context", "schemas");
32124
32272
  async function resolveSacNormativeSchemaPath(fileName, searchFrom = [fileURLToPath3(new URL(".", import.meta.url)), process.cwd()]) {
32125
32273
  const seen = new Set;
32126
32274
  for (const start of searchFrom) {
32127
- let dir = path100.resolve(start);
32275
+ let dir = path101.resolve(start);
32128
32276
  for (let i = 0;i < 10; i++) {
32129
32277
  if (seen.has(dir))
32130
32278
  break;
32131
32279
  seen.add(dir);
32132
- const candidate = path100.join(dir, NORMATIVE_SCHEMA_DIR, fileName);
32280
+ const candidate = path101.join(dir, NORMATIVE_SCHEMA_DIR, fileName);
32133
32281
  try {
32134
32282
  await access3(candidate);
32135
32283
  return candidate;
32136
32284
  } catch {}
32137
- const parent = path100.dirname(dir);
32285
+ const parent = path101.dirname(dir);
32138
32286
  if (parent === dir)
32139
32287
  break;
32140
32288
  dir = parent;
@@ -32803,12 +32951,12 @@ class SacReferenceError extends Error {
32803
32951
  code = "unsafe_workspace_reference";
32804
32952
  }
32805
32953
  async function resolveWorkspaceReference(input) {
32806
- if (!workspacePathPattern.test(input.uri) || path100.isAbsolute(input.uri) || /^[a-z][a-z0-9+.-]*:/i.test(input.uri) || input.uri.includes("\\"))
32954
+ if (!workspacePathPattern.test(input.uri) || path101.isAbsolute(input.uri) || /^[a-z][a-z0-9+.-]*:/i.test(input.uri) || input.uri.includes("\\"))
32807
32955
  throw new SacReferenceError("unsafe workspace reference");
32808
- const lexicalRoot = path100.resolve(input.workspaceRoot);
32956
+ const lexicalRoot = path101.resolve(input.workspaceRoot);
32809
32957
  const root = await realpath10(lexicalRoot);
32810
- const candidate = path100.resolve(lexicalRoot, input.uri.slice(2));
32811
- if (candidate !== lexicalRoot && !candidate.startsWith(`${lexicalRoot}${path100.sep}`))
32958
+ const candidate = path101.resolve(lexicalRoot, input.uri.slice(2));
32959
+ if (candidate !== lexicalRoot && !candidate.startsWith(`${lexicalRoot}${path101.sep}`))
32812
32960
  throw new SacReferenceError("workspace reference escapes root");
32813
32961
  let resolved;
32814
32962
  try {
@@ -32816,7 +32964,7 @@ async function resolveWorkspaceReference(input) {
32816
32964
  } catch {
32817
32965
  throw new SacReferenceError("workspace reference is not resolvable");
32818
32966
  }
32819
- if (resolved !== root && !resolved.startsWith(`${root}${path100.sep}`))
32967
+ if (resolved !== root && !resolved.startsWith(`${root}${path101.sep}`))
32820
32968
  throw new SacReferenceError("workspace reference escapes root after realpath");
32821
32969
  return candidate;
32822
32970
  }
@@ -32872,16 +33020,16 @@ async function evaluateStrictSacGuard(input) {
32872
33020
  init_fs();
32873
33021
  import { mkdir as mkdir29, readdir as readdir17, readFile as readFile49 } from "fs/promises";
32874
33022
  import { createHash as createHash19, randomUUID as randomUUID3 } from "crypto";
32875
- import path102 from "path";
33023
+ import path103 from "path";
32876
33024
 
32877
33025
  // src/sac/secure-resource-read.ts
32878
33026
  init_contained_read();
32879
33027
  init_descriptor_read();
32880
- import path101 from "path";
33028
+ import path102 from "path";
32881
33029
  function readWorkspaceFileNoFollow(workspaceRoot, absolutePath) {
32882
- const relativePath = path101.relative(workspaceRoot, absolutePath);
32883
- const components = relativePath.split(path101.sep);
32884
- if (!relativePath || path101.isAbsolute(relativePath) || components.some((component) => !component || component === "." || component === "..")) {
33030
+ const relativePath = path102.relative(workspaceRoot, absolutePath);
33031
+ const components = relativePath.split(path102.sep);
33032
+ if (!relativePath || path102.isAbsolute(relativePath) || components.some((component) => !component || component === "." || component === "..")) {
32885
33033
  throw new Error("safe source path is not workspace-relative");
32886
33034
  }
32887
33035
  return readDescriptorChain(workspaceRoot, absolutePath, {
@@ -32908,8 +33056,8 @@ class WorkspaceService {
32908
33056
  now;
32909
33057
  constructor(options) {
32910
33058
  this.options = options;
32911
- this.root = path102.resolve(options.workspaceRoot);
32912
- this.storageRoot = path102.resolve(options.storageRoot ?? path102.join(this.root, ".metaproject", "workspaces"));
33059
+ this.root = path103.resolve(options.workspaceRoot);
33060
+ this.storageRoot = path103.resolve(options.storageRoot ?? path103.join(this.root, ".metaproject", "workspaces"));
32913
33061
  this.now = options.now ?? (() => new Date);
32914
33062
  }
32915
33063
  async create(input) {
@@ -33234,13 +33382,13 @@ class WorkspaceService {
33234
33382
  return parsed;
33235
33383
  }
33236
33384
  workspaceDir(id) {
33237
- return path102.join(this.storageRoot, id);
33385
+ return path103.join(this.storageRoot, id);
33238
33386
  }
33239
33387
  manifestPath(id) {
33240
- return path102.join(this.workspaceDir(id), "workspace.json");
33388
+ return path103.join(this.workspaceDir(id), "workspace.json");
33241
33389
  }
33242
33390
  lockPath(id) {
33243
- return path102.join(this.storageRoot, `.${id}.lock`);
33391
+ return path103.join(this.storageRoot, `.${id}.lock`);
33244
33392
  }
33245
33393
  timestamp() {
33246
33394
  return this.now().toISOString();
@@ -34029,7 +34177,7 @@ function hasReportIntegrity(report) {
34029
34177
  return reportHashPattern.test(reportDigest) && sha2564(body) === reportDigest;
34030
34178
  }
34031
34179
  async function resolvePolicySelection(workspaceRoot, canonicalFallback) {
34032
- const configPath = path103.join(workspaceRoot, ...policyExperimentConfigPath);
34180
+ const configPath = path104.join(workspaceRoot, ...policyExperimentConfigPath);
34033
34181
  let configJson;
34034
34182
  try {
34035
34183
  const raw = await readFile50(configPath, "utf8").catch((error) => {
@@ -34227,9 +34375,9 @@ class FwkReadService {
34227
34375
  const recordedAt = nowIso(now);
34228
34376
  const id = `receipt-${randomUUID4().replace(/-/g, "").slice(0, 16)}`;
34229
34377
  const base = { schemaVersion: "1.0", id, workspaceId, actor, action, decision, recordedAt, cost: { tokens: 0, toolCalls: 1, elapsedMs: 0 }, contextAssembly: { traceRef: assembly.traceRef, configurationRevision: assembly.configurationRevision, selected: assembly.selected.map((id) => `./ids/${id}`), omittedOptional: assembly.omittedOptional.map((id) => `./ids/${id}`) }, policy: { ref: assembly.policyRef, revision: assembly.policyRevision }, ...action === "resource" ? { resourceRef: `./ids/${resourceId ?? "unknown"}` } : {} };
34230
- const ledger = path103.join(this.options.canonical.workspaceRoot, ".metaproject", "context-operations", "access-receipts.jsonl");
34231
- const checkpointPath = path103.join(path103.dirname(ledger), "access-receipts.checkpoint.json");
34232
- await mkdir30(path103.dirname(ledger), { recursive: true, mode: 448 });
34378
+ const ledger = path104.join(this.options.canonical.workspaceRoot, ".metaproject", "context-operations", "access-receipts.jsonl");
34379
+ const checkpointPath = path104.join(path104.dirname(ledger), "access-receipts.checkpoint.json");
34380
+ await mkdir30(path104.dirname(ledger), { recursive: true, mode: 448 });
34233
34381
  return withFileLock(`${ledger}.lock`, async () => {
34234
34382
  const state = await resolveLedgerState(ledger, checkpointPath, this.options.verifyReceiptLedger ?? verifyAccessReceiptLedger);
34235
34383
  const receipt = sealAccessReceipt(base, state.headHash);
@@ -34333,7 +34481,7 @@ function normalizeFwkResult(result) {
34333
34481
  init_fs();
34334
34482
  import { createHash as createHash29, randomUUID as randomUUID7 } from "crypto";
34335
34483
  import { appendFile as appendFile7, mkdir as mkdir34, readdir as readdir19, readFile as readFile59 } from "fs/promises";
34336
- import path113 from "path";
34484
+ import path114 from "path";
34337
34485
 
34338
34486
  // src/sac/trusted-wrap-up.ts
34339
34487
  import { createHash as createHash23, randomUUID as randomUUID5 } from "crypto";
@@ -34405,7 +34553,7 @@ function bindingHash(owner, intent) {
34405
34553
  // src/sac/session-wrap-up.ts
34406
34554
  import { createHash as createHash25 } from "crypto";
34407
34555
  import { mkdir as mkdir32, writeFile as writeFile21 } from "fs/promises";
34408
- import path107 from "path";
34556
+ import path108 from "path";
34409
34557
 
34410
34558
  // src/session/store.ts
34411
34559
  import {
@@ -34416,7 +34564,7 @@ import {
34416
34564
  renameSync as renameSync2,
34417
34565
  writeFileSync as writeFileSync2
34418
34566
  } from "fs";
34419
- import path106 from "path";
34567
+ import path107 from "path";
34420
34568
 
34421
34569
  // src/lib/config-dir.ts
34422
34570
  import {
@@ -34461,7 +34609,7 @@ function readTranscriptFile(file) {
34461
34609
  // src/session/paths.ts
34462
34610
  import { existsSync as existsSync15 } from "fs";
34463
34611
  import { homedir } from "os";
34464
- import path104 from "path";
34612
+ import path105 from "path";
34465
34613
  function keryxDataDir(override) {
34466
34614
  if (override !== undefined && override.length > 0) {
34467
34615
  return override;
@@ -34473,22 +34621,22 @@ function keryxDataDir(override) {
34473
34621
  const home = homedir();
34474
34622
  if (process.platform === "win32") {
34475
34623
  const appData = process.env.APPDATA;
34476
- const base = appData !== undefined && appData.length > 0 ? appData : path104.join(home, "AppData", "Roaming");
34477
- return path104.join(base, "keryx");
34624
+ const base = appData !== undefined && appData.length > 0 ? appData : path105.join(home, "AppData", "Roaming");
34625
+ return path105.join(base, "keryx");
34478
34626
  }
34479
34627
  const xdg = process.env.XDG_DATA_HOME;
34480
- const base = xdg !== undefined && xdg.length > 0 ? xdg : path104.join(home, ".local", "share");
34481
- return path104.join(base, "keryx");
34628
+ const base = xdg !== undefined && xdg.length > 0 ? xdg : path105.join(home, ".local", "share");
34629
+ return path105.join(base, "keryx");
34482
34630
  }
34483
34631
  function resolveProjectRoot2(cwd) {
34484
- const abs = path104.resolve(cwd);
34632
+ const abs = path105.resolve(cwd);
34485
34633
  let dir = abs;
34486
34634
  for (;; ) {
34487
- const gitPath = path104.join(dir, ".git");
34635
+ const gitPath = path105.join(dir, ".git");
34488
34636
  if (existsSync15(gitPath)) {
34489
34637
  return dir;
34490
34638
  }
34491
- const parent = path104.dirname(dir);
34639
+ const parent = path105.dirname(dir);
34492
34640
  if (parent === dir) {
34493
34641
  break;
34494
34642
  }
@@ -34497,12 +34645,12 @@ function resolveProjectRoot2(cwd) {
34497
34645
  return abs;
34498
34646
  }
34499
34647
  function projectKeyFromPath(projectPath) {
34500
- const abs = path104.resolve(projectPath);
34648
+ const abs = path105.resolve(projectPath);
34501
34649
  const encoded = encodeURIComponent(abs);
34502
34650
  if (encoded.length <= 200) {
34503
34651
  return encoded;
34504
34652
  }
34505
- const base = path104.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 40);
34653
+ const base = path105.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 40);
34506
34654
  let h = 0;
34507
34655
  for (let i = 0;i < abs.length; i++) {
34508
34656
  h = Math.imul(31, h) + abs.charCodeAt(i) | 0;
@@ -34512,17 +34660,17 @@ function projectKeyFromPath(projectPath) {
34512
34660
  }
34513
34661
  function projectSessionsDir(projectPath, dataDir) {
34514
34662
  const key = projectKeyFromPath(resolveProjectRoot2(projectPath));
34515
- return path104.join(keryxDataDir(dataDir), "sessions", key);
34663
+ return path105.join(keryxDataDir(dataDir), "sessions", key);
34516
34664
  }
34517
34665
  function sessionDir(projectPath, sessionId, dataDir) {
34518
- return path104.join(projectSessionsDir(projectPath, dataDir), sessionId);
34666
+ return path105.join(projectSessionsDir(projectPath, dataDir), sessionId);
34519
34667
  }
34520
34668
 
34521
34669
  // src/session/slate.ts
34522
34670
  init_fs();
34523
34671
  init_assembly();
34524
34672
  import { mkdir as mkdir31, readFile as readFile51, rm as rm7 } from "fs/promises";
34525
- import path105 from "path";
34673
+ import path106 from "path";
34526
34674
  init_redact();
34527
34675
  var SLATE_SEED_KINDS = [
34528
34676
  "decision",
@@ -34537,7 +34685,7 @@ function isSlateSeedKind(value) {
34537
34685
  }
34538
34686
  var SEED_TEXT_MAX_LENGTH = 4000;
34539
34687
  function slatePath(dir) {
34540
- return path105.join(dir, "slate.json");
34688
+ return path106.join(dir, "slate.json");
34541
34689
  }
34542
34690
  function slateLockPath(dir) {
34543
34691
  return `${slatePath(dir)}.lock`;
@@ -34740,11 +34888,11 @@ function listSessions(cwd, dataDir) {
34740
34888
  if (name.startsWith(".")) {
34741
34889
  continue;
34742
34890
  }
34743
- const summary = readSummaryFile(path106.join(root, name, "summary.json"));
34891
+ const summary = readSummaryFile(path107.join(root, name, "summary.json"));
34744
34892
  if (summary === undefined) {
34745
34893
  continue;
34746
34894
  }
34747
- if (path106.resolve(summary.projectPath) !== path106.resolve(projectPath)) {
34895
+ if (path107.resolve(summary.projectPath) !== path107.resolve(projectPath)) {
34748
34896
  continue;
34749
34897
  }
34750
34898
  out.push(summary);
@@ -34777,15 +34925,15 @@ async function readSessionSlate(cwd, sessionId, dataDir) {
34777
34925
  }
34778
34926
  function loadContext(cwd, sessionId, dataDir) {
34779
34927
  const dir = sessionDir(resolveProjectRoot2(cwd), sessionId, dataDir);
34780
- const contextPath = path106.join(dir, "context.jsonl");
34928
+ const contextPath = path107.join(dir, "context.jsonl");
34781
34929
  if (existsSync16(contextPath)) {
34782
34930
  return readJsonl2(contextPath);
34783
34931
  }
34784
- return readJsonl2(path106.join(dir, "transcript.jsonl"));
34932
+ return readJsonl2(path107.join(dir, "transcript.jsonl"));
34785
34933
  }
34786
34934
  function loadArchive(cwd, sessionId, dataDir, onDegraded) {
34787
34935
  const dir = sessionDir(resolveProjectRoot2(cwd), sessionId, dataDir);
34788
- const archivePath = path106.join(dir, "archive.jsonl");
34936
+ const archivePath = path107.join(dir, "archive.jsonl");
34789
34937
  if (existsSync16(archivePath)) {
34790
34938
  try {
34791
34939
  const archive = readJsonl2(archivePath);
@@ -34969,7 +35117,7 @@ function sessionEvidenceRef(workspaceId, sessionId) {
34969
35117
  }
34970
35118
  async function resolveSessionWrapUp(input) {
34971
35119
  const now = input.now ?? (() => new Date);
34972
- const sessionId = path107.posix.basename(input.sourceRef, ".md");
35120
+ const sessionId = path108.posix.basename(input.sourceRef, ".md");
34973
35121
  const summary = findSession(input.cwd, sessionId);
34974
35122
  if (summary === undefined || input.sourceRef !== sessionEvidenceRef(input.workspaceId, summary.id)) {
34975
35123
  throw new SessionWrapUpError("session_not_found", `no session matching "${input.sourceRef}" in this project \u2014 use \`keryx sessions list\``);
@@ -34986,7 +35134,7 @@ async function resolveSessionWrapUp(input) {
34986
35134
  throw new SessionWrapUpError("session_unreadable", `session "${summary.id}" could not be read: ${cause.message}`);
34987
35135
  }
34988
35136
  const relPath = sessionEvidenceRef(input.workspaceId, summary.id).slice(2);
34989
- const evidenceDir = path107.dirname(relPath);
35137
+ const evidenceDir = path108.dirname(relPath);
34990
35138
  const slate = await readSessionSlate(input.cwd, summary.id);
34991
35139
  const diff = await gitDiff(input.cwd);
34992
35140
  const diffBody = diff.kind === "measured" ? diff.text : unmeasurableDiffBody(diff.detail);
@@ -35008,23 +35156,23 @@ async function resolveSessionWrapUp(input) {
35008
35156
  ""
35009
35157
  ].join(`
35010
35158
  `);
35011
- const wrapUpRelPath = path107.join(evidenceDir, `${summary.id}.wrap-up.md`);
35012
- const diffRelPath = path107.join(evidenceDir, `${summary.id}.diff.txt`);
35013
- const noticeRelPath = path107.join(evidenceDir, `${summary.id}.redaction.md`);
35159
+ const wrapUpRelPath = path108.join(evidenceDir, `${summary.id}.wrap-up.md`);
35160
+ const diffRelPath = path108.join(evidenceDir, `${summary.id}.diff.txt`);
35161
+ const noticeRelPath = path108.join(evidenceDir, `${summary.id}.redaction.md`);
35014
35162
  const floor = await applyEvidenceRedactionFloor(input.cwd, [
35015
- { name: path107.basename(relPath), content: markdown, path: relPath, source: "generated" },
35016
- { name: path107.basename(wrapUpRelPath), content: wrapUpMarkdown, path: wrapUpRelPath, source: "generated" },
35017
- { name: path107.basename(diffRelPath), content: diffBody, path: diffRelPath, source: "tool-output" }
35163
+ { name: path108.basename(relPath), content: markdown, path: relPath, source: "generated" },
35164
+ { name: path108.basename(wrapUpRelPath), content: wrapUpMarkdown, path: wrapUpRelPath, source: "generated" },
35165
+ { name: path108.basename(diffRelPath), content: diffBody, path: diffRelPath, source: "tool-output" }
35018
35166
  ]);
35019
35167
  if (!floor.ok)
35020
35168
  throw new SessionWrapUpError("security_denied", floor.reason);
35021
35169
  const [safeSession, safeWrapUp, safeDiff] = floor.bodies;
35022
- await mkdir32(path107.join(input.cwd, evidenceDir), { recursive: true });
35023
- await writeFile21(path107.join(input.cwd, relPath), safeSession.content, "utf8");
35024
- await writeFile21(path107.join(input.cwd, wrapUpRelPath), safeWrapUp.content, "utf8");
35025
- await writeFile21(path107.join(input.cwd, diffRelPath), safeDiff.content, "utf8");
35170
+ await mkdir32(path108.join(input.cwd, evidenceDir), { recursive: true });
35171
+ await writeFile21(path108.join(input.cwd, relPath), safeSession.content, "utf8");
35172
+ await writeFile21(path108.join(input.cwd, wrapUpRelPath), safeWrapUp.content, "utf8");
35173
+ await writeFile21(path108.join(input.cwd, diffRelPath), safeDiff.content, "utf8");
35026
35174
  if (floor.notice !== undefined)
35027
- await writeFile21(path107.join(input.cwd, noticeRelPath), floor.notice, "utf8");
35175
+ await writeFile21(path108.join(input.cwd, noticeRelPath), floor.notice, "utf8");
35028
35176
  const observedAt = now().toISOString();
35029
35177
  const evidence = [
35030
35178
  { kind: "wrap-up", uri: `./${wrapUpRelPath}`, revision: createHash25("sha256").update(safeWrapUp.content).digest("hex"), observedAt },
@@ -35047,13 +35195,13 @@ async function resolveSessionWrapUp(input) {
35047
35195
  init_fs();
35048
35196
  import { createHash as createHash26, randomBytes as randomBytes5 } from "crypto";
35049
35197
  import { readFile as readFile52 } from "fs/promises";
35050
- import path108 from "path";
35198
+ import path109 from "path";
35051
35199
  var CONFIRM_TOKEN_TTL_MS = 2 * 60000;
35052
35200
  function confirmTokenPath2(cwd, workspaceId, proposalId) {
35053
- return path108.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.confirm-token.json`);
35201
+ return path109.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.confirm-token.json`);
35054
35202
  }
35055
35203
  function confirmReceiptPath(cwd, workspaceId, proposalId, idempotencyKey) {
35056
- return path108.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${sha2565(idempotencyKey)}.confirm-receipt.json`);
35204
+ return path109.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${sha2565(idempotencyKey)}.confirm-receipt.json`);
35057
35205
  }
35058
35206
  function sha2565(text) {
35059
35207
  return createHash26("sha256").update(text).digest("hex");
@@ -35094,21 +35242,21 @@ init_store();
35094
35242
  init_config();
35095
35243
  import { readFile as readFile54, readdir as readdir18 } from "fs/promises";
35096
35244
  import { randomUUID as randomUUID6 } from "crypto";
35097
- import path110 from "path";
35245
+ import path111 from "path";
35098
35246
 
35099
35247
  // src/sac/proposal-evidence.ts
35100
35248
  init_fs();
35101
35249
  import { createHash as createHash27 } from "crypto";
35102
35250
  import { readFile as readFile53, rm as rm8 } from "fs/promises";
35103
- import path109 from "path";
35251
+ import path110 from "path";
35104
35252
  function proposalPath(cwd, workspaceId, proposalId) {
35105
- return path109.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.json`);
35253
+ return path110.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.json`);
35106
35254
  }
35107
35255
  function ownerReceiptPath(cwd, owner, workspaceId, idempotencyKey) {
35108
- return path109.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-receipts`, `${idempotencyKey}.json`);
35256
+ return path110.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-receipts`, `${idempotencyKey}.json`);
35109
35257
  }
35110
35258
  function proposalNotePath(cwd, workspaceId, proposalId) {
35111
- return path109.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.note.txt`);
35259
+ return path110.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.note.txt`);
35112
35260
  }
35113
35261
  async function readVerifiedProposalEvidence(cwd, workspaceId, proposalId) {
35114
35262
  let proposal;
@@ -35122,7 +35270,7 @@ async function readVerifiedProposalEvidence(cwd, workspaceId, proposalId) {
35122
35270
  return { ok: false, code: "no_evidence_to_write" };
35123
35271
  let content;
35124
35272
  try {
35125
- content = await readFile53(path109.join(cwd, evidence.uri), "utf8");
35273
+ content = await readFile53(path110.join(cwd, evidence.uri), "utf8");
35126
35274
  } catch {
35127
35275
  return { ok: false, code: "evidence_file_unreadable" };
35128
35276
  }
@@ -35152,22 +35300,22 @@ function targetRelPath(targetRef) {
35152
35300
  return targetRef.replace(/^\.\//, "");
35153
35301
  }
35154
35302
  function targetAbsolutePath(cwd, targetRef) {
35155
- return path109.join(cwd, ".metaproject", targetRelPath(targetRef));
35303
+ return path110.join(cwd, ".metaproject", targetRelPath(targetRef));
35156
35304
  }
35157
35305
  function targetKey(targetRef) {
35158
35306
  return digestOf2(targetRelPath(targetRef)).slice(0, 32);
35159
35307
  }
35160
35308
  function ownerTargetVersionPath(cwd, owner, workspaceId, targetRef) {
35161
- return path109.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-target-versions`, `${targetKey(targetRef)}.json`);
35309
+ return path110.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-target-versions`, `${targetKey(targetRef)}.json`);
35162
35310
  }
35163
35311
  function ownerTargetLockPath(cwd, owner, targetRef) {
35164
- return path109.join(cwd, ".metaproject", "data", "sac", "target-locks", owner, `${targetKey(targetRef)}.lock`);
35312
+ return path110.join(cwd, ".metaproject", "data", "sac", "target-locks", owner, `${targetKey(targetRef)}.lock`);
35165
35313
  }
35166
35314
  function ownerStagingDir(cwd, owner, workspaceId, idempotencyKey) {
35167
- return path109.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-staging`, digestOf2(idempotencyKey).slice(0, 32));
35315
+ return path110.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-staging`, digestOf2(idempotencyKey).slice(0, 32));
35168
35316
  }
35169
35317
  function ownerConflictDir(cwd, owner, workspaceId, idempotencyKey) {
35170
- return path109.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-conflicts`, digestOf2(idempotencyKey).slice(0, 32));
35318
+ return path110.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-conflicts`, digestOf2(idempotencyKey).slice(0, 32));
35171
35319
  }
35172
35320
  async function readJson2(file) {
35173
35321
  try {
@@ -35238,7 +35386,7 @@ async function applyGuardedTargetWrite(input) {
35238
35386
  staged: input.staged,
35239
35387
  stagedAt: receipt.completedAt
35240
35388
  };
35241
- await writeFileAtomic(path109.join(ownerStagingDir(cwd, owner, intent.workspaceId, intent.idempotencyKey), "plan.json"), `${JSON.stringify(staged, null, 2)}
35389
+ await writeFileAtomic(path110.join(ownerStagingDir(cwd, owner, intent.workspaceId, intent.idempotencyKey), "plan.json"), `${JSON.stringify(staged, null, 2)}
35242
35390
  `);
35243
35391
  const applied = await input.apply(input.staged);
35244
35392
  if (!applied.ok) {
@@ -35264,15 +35412,15 @@ async function recoverStagedOwnerWrite(input) {
35264
35412
  });
35265
35413
  }
35266
35414
  async function readStagedOwnerWrite(cwd, owner, workspaceId, idempotencyKey) {
35267
- return readJson2(path109.join(ownerStagingDir(cwd, owner, workspaceId, idempotencyKey), "plan.json"));
35415
+ return readJson2(path110.join(ownerStagingDir(cwd, owner, workspaceId, idempotencyKey), "plan.json"));
35268
35416
  }
35269
35417
  async function recordConflict(input) {
35270
35418
  const base = { targetRef: input.targetRef, expectedVersion: input.expectedVersion, currentVersion: input.currentVersion };
35271
35419
  if (input.proposedContent === undefined)
35272
35420
  return base;
35273
35421
  const dir = ownerConflictDir(input.cwd, input.owner, input.intent.workspaceId, input.intent.idempotencyKey);
35274
- await writeFileAtomic(path109.join(dir, "proposed"), input.proposedContent);
35275
- const diffRef = `./workspaces/${input.intent.workspaceId}/${input.owner}-write-conflicts/${path109.basename(dir)}/proposed`;
35422
+ await writeFileAtomic(path110.join(dir, "proposed"), input.proposedContent);
35423
+ const diffRef = `./workspaces/${input.intent.workspaceId}/${input.owner}-write-conflicts/${path110.basename(dir)}/proposed`;
35276
35424
  return { ...base, diffRef };
35277
35425
  }
35278
35426
 
@@ -35322,7 +35470,7 @@ async function resolveWorkspaceModule(cwd, workspaceId) {
35322
35470
  }
35323
35471
  }
35324
35472
  async function collectWikiDecisionEntries(cwd) {
35325
- const dir = path110.join(cwd, ".metaproject", "wiki", "decisions");
35473
+ const dir = path111.join(cwd, ".metaproject", "wiki", "decisions");
35326
35474
  let files;
35327
35475
  try {
35328
35476
  files = (await readdir18(dir)).filter((name) => name.endsWith(".md"));
@@ -35331,12 +35479,12 @@ async function collectWikiDecisionEntries(cwd) {
35331
35479
  }
35332
35480
  const entries = [];
35333
35481
  for (const file of files) {
35334
- const absolutePath = path110.join(dir, file);
35482
+ const absolutePath = path111.join(dir, file);
35335
35483
  try {
35336
35484
  const content = await readFile54(absolutePath, "utf8");
35337
35485
  entries.push({
35338
35486
  absolutePath,
35339
- relativePath: path110.posix.join("decisions", file),
35487
+ relativePath: path111.posix.join("decisions", file),
35340
35488
  type: extractHeaderField(content, "Type") ?? "decision",
35341
35489
  title: extractTitle(content),
35342
35490
  version: extractHeaderField(content, "Version") ?? null,
@@ -35558,7 +35706,7 @@ function createRealMemoryOwnerWriter(cwd, opts) {
35558
35706
  init_fs();
35559
35707
  init_guard();
35560
35708
  import { readFile as readFile56 } from "fs/promises";
35561
- import path111 from "path";
35709
+ import path112 from "path";
35562
35710
  function renderWrapUpDecisionPage(input) {
35563
35711
  const note = input.note?.trim();
35564
35712
  return `# ${input.title}
@@ -35599,14 +35747,14 @@ export is the source of truth for what actually happened.
35599
35747
  `;
35600
35748
  }
35601
35749
  function wikiPageRelativePath(proposalId) {
35602
- return path111.posix.join("decisions", `sac-${proposalId}.md`);
35750
+ return path112.posix.join("decisions", `sac-${proposalId}.md`);
35603
35751
  }
35604
35752
  function createRealWikiOwnerWriter(cwd, opts) {
35605
35753
  const now = opts?.now ?? (() => new Date);
35606
35754
  const applyStaged = async (staged) => {
35607
35755
  const relativePath = staged.relativePath;
35608
35756
  const content = staged.content;
35609
- await writeFileAtomic(path111.join(cwd, ".metaproject", "wiki", relativePath), content);
35757
+ await writeFileAtomic(path112.join(cwd, ".metaproject", "wiki", relativePath), content);
35610
35758
  return { ok: true };
35611
35759
  };
35612
35760
  return {
@@ -35675,10 +35823,10 @@ init_guard();
35675
35823
  import { createHash as createHash28 } from "crypto";
35676
35824
  import { homedir as homedir2 } from "os";
35677
35825
  import { mkdir as mkdir33, readFile as readFile57, stat as stat14 } from "fs/promises";
35678
- import path112 from "path";
35826
+ import path113 from "path";
35679
35827
  var VERSION = "0.1.0";
35680
35828
  async function createProjectSkill(projectRoot, options) {
35681
- const metaprojectRoot = path112.join(projectRoot, ".metaproject");
35829
+ const metaprojectRoot = path113.join(projectRoot, ".metaproject");
35682
35830
  if (!await pathExists(metaprojectRoot)) {
35683
35831
  throw new Error("Metaproject is not initialized. Run: keryx init");
35684
35832
  }
@@ -35688,8 +35836,8 @@ async function createProjectSkill(projectRoot, options) {
35688
35836
  const moduleName = slugify5(options.module ?? inferModule(options.target));
35689
35837
  const skillName = slugify5(options.name ?? inferSkillName(options.target));
35690
35838
  const format = options.format ?? "auto";
35691
- const packageRoot = path112.join(metaprojectRoot, "project-skills", moduleName, skillName);
35692
- const relativeSkillPath = toPosix(path112.relative(projectRoot, packageRoot));
35839
+ const packageRoot = path113.join(metaprojectRoot, "project-skills", moduleName, skillName);
35840
+ const relativeSkillPath = toPosix(path113.relative(projectRoot, packageRoot));
35693
35841
  const origin = options.origin ? options.originContent !== undefined ? {
35694
35842
  ref: options.origin.trim(),
35695
35843
  hash: hashOriginContent(options.originContent),
@@ -35699,7 +35847,7 @@ async function createProjectSkill(projectRoot, options) {
35699
35847
  const warnings = collectWarnings(evidence, format);
35700
35848
  const files = filesForPackage(packageRoot, format);
35701
35849
  if (!options.dryRun) {
35702
- await withFileLock(path112.join(metaprojectRoot, "data", "gdskills", "project-skills.lock"), async () => {
35850
+ await withFileLock(path113.join(metaprojectRoot, "data", "gdskills", "project-skills.lock"), async () => {
35703
35851
  await writeProjectSkillPackage({
35704
35852
  projectRoot,
35705
35853
  packageRoot,
@@ -35728,7 +35876,7 @@ async function createProjectSkill(projectRoot, options) {
35728
35876
  name: skillName,
35729
35877
  target: options.target,
35730
35878
  skillPath: relativeSkillPath,
35731
- files: files.map((filePath) => toPosix(path112.relative(projectRoot, filePath))),
35879
+ files: files.map((filePath) => toPosix(path113.relative(projectRoot, filePath))),
35732
35880
  warnings,
35733
35881
  dryRun: options.dryRun === true
35734
35882
  };
@@ -35737,9 +35885,9 @@ var MAX_SKILL_TARGET_LENGTH = 80;
35737
35885
  function resolveOriginPath(ref, projectRoot) {
35738
35886
  const trimmed = ref.trim();
35739
35887
  if (trimmed === "~" || trimmed.startsWith("~/")) {
35740
- return path112.join(homedir2(), trimmed.slice(1));
35888
+ return path113.join(homedir2(), trimmed.slice(1));
35741
35889
  }
35742
- return path112.resolve(projectRoot, trimmed);
35890
+ return path113.resolve(projectRoot, trimmed);
35743
35891
  }
35744
35892
  function hashOriginContent(content) {
35745
35893
  return `sha256:${createHash28("sha256").update(content).digest("hex")}`;
@@ -35777,32 +35925,32 @@ async function writeProjectSkillPackage({
35777
35925
  }) {
35778
35926
  const packageFormat = format === "single" ? "single" : "package";
35779
35927
  const skillContent = renderProjectSkill({ moduleName, skillName, target, note, origin, evidence, packageFormat });
35780
- const relativeSkillMdPath = toPosix(path112.join(path112.relative(projectRoot, packageRoot), "SKILL.md"));
35928
+ const relativeSkillMdPath = toPosix(path113.join(path113.relative(projectRoot, packageRoot), "SKILL.md"));
35781
35929
  const guard = await guardOutput({ cwd: projectRoot, content: skillContent, target: "skill", source: "generated", path: relativeSkillMdPath });
35782
35930
  const output = prepareOutputForPersistence(guard, skillContent);
35783
35931
  if (!output.allowed) {
35784
35932
  throw new Error(`Project skill blocked by the security gate: ${output.reason}`);
35785
35933
  }
35786
35934
  await mkdir33(packageRoot, { recursive: true });
35787
- const skillPath = path112.join(packageRoot, "SKILL.md");
35935
+ const skillPath = path113.join(packageRoot, "SKILL.md");
35788
35936
  await writeFileAtomic(skillPath, output.content);
35789
- const changelogPath = path112.join(packageRoot, "skill-changelog.md");
35937
+ const changelogPath = path113.join(packageRoot, "skill-changelog.md");
35790
35938
  if (!await pathExists(changelogPath)) {
35791
35939
  await writeFileAtomic(changelogPath, renderSkillChangelog({ moduleName, skillName, target }));
35792
35940
  }
35793
35941
  if (packageFormat === "package") {
35794
- await mkdir33(path112.join(packageRoot, "references"), { recursive: true });
35795
- await mkdir33(path112.join(packageRoot, "templates"), { recursive: true });
35796
- await writeFileAtomic(path112.join(packageRoot, "references", "context.md"), renderReferenceContext({ moduleName, skillName, target, evidence }));
35797
- await writeFileAtomic(path112.join(packageRoot, "templates", "README.md"), renderTemplatesReadme({ moduleName, skillName }));
35798
- await writeFileAtomic(path112.join(packageRoot, "verification.md"), renderVerification({ moduleName, skillName, evidence }));
35942
+ await mkdir33(path113.join(packageRoot, "references"), { recursive: true });
35943
+ await mkdir33(path113.join(packageRoot, "templates"), { recursive: true });
35944
+ await writeFileAtomic(path113.join(packageRoot, "references", "context.md"), renderReferenceContext({ moduleName, skillName, target, evidence }));
35945
+ await writeFileAtomic(path113.join(packageRoot, "templates", "README.md"), renderTemplatesReadme({ moduleName, skillName }));
35946
+ await writeFileAtomic(path113.join(packageRoot, "verification.md"), renderVerification({ moduleName, skillName, evidence }));
35799
35947
  }
35800
35948
  }
35801
35949
  async function collectEvidence(projectRoot, target) {
35802
- const absoluteTarget = path112.resolve(projectRoot, target);
35950
+ const absoluteTarget = path113.resolve(projectRoot, target);
35803
35951
  const targetExists = await pathExists(absoluteTarget);
35804
35952
  const targetKind = await classifyTarget(absoluteTarget, targetExists);
35805
- const maybeRelativeTarget = targetExists ? toPosix(path112.relative(projectRoot, absoluteTarget)) : undefined;
35953
+ const maybeRelativeTarget = targetExists ? toPosix(path113.relative(projectRoot, absoluteTarget)) : undefined;
35806
35954
  const graphArtifacts = await existingRelativePaths(projectRoot, [
35807
35955
  ".metaproject/data/gdgraph/artifacts/summary.md",
35808
35956
  ".metaproject/data/gdgraph/artifacts/module-map.json"
@@ -35832,7 +35980,7 @@ async function classifyTarget(absoluteTarget, targetExists) {
35832
35980
  async function existingRelativePaths(projectRoot, candidates) {
35833
35981
  const existing = [];
35834
35982
  for (const candidate of candidates) {
35835
- if (await pathExists(path112.join(projectRoot, candidate))) {
35983
+ if (await pathExists(path113.join(projectRoot, candidate))) {
35836
35984
  existing.push(candidate);
35837
35985
  }
35838
35986
  }
@@ -35859,17 +36007,17 @@ function collectWarnings(evidence, format) {
35859
36007
  }
35860
36008
  function filesForPackage(packageRoot, format) {
35861
36009
  const base = [
35862
- path112.join(packageRoot, "SKILL.md"),
35863
- path112.join(packageRoot, "skill-changelog.md")
36010
+ path113.join(packageRoot, "SKILL.md"),
36011
+ path113.join(packageRoot, "skill-changelog.md")
35864
36012
  ];
35865
36013
  if (format === "single") {
35866
36014
  return base;
35867
36015
  }
35868
36016
  return [
35869
36017
  ...base,
35870
- path112.join(packageRoot, "verification.md"),
35871
- path112.join(packageRoot, "references", "context.md"),
35872
- path112.join(packageRoot, "templates", "README.md")
36018
+ path113.join(packageRoot, "verification.md"),
36019
+ path113.join(packageRoot, "references", "context.md"),
36020
+ path113.join(packageRoot, "templates", "README.md")
35873
36021
  ];
35874
36022
  }
35875
36023
  function renderProjectSkill({
@@ -36097,7 +36245,7 @@ keryx skills verify ${moduleName}/${skillName}
36097
36245
  `;
36098
36246
  }
36099
36247
  async function updateManifest(projectRoot, entry) {
36100
- const manifestPath = path112.join(projectRoot, ".metaproject", "metaproject.json");
36248
+ const manifestPath = path113.join(projectRoot, ".metaproject", "metaproject.json");
36101
36249
  const manifest = await readJsonFileOr(manifestPath, {});
36102
36250
  manifest.modules ??= {};
36103
36251
  manifest.modules.gdskills ??= {};
@@ -36111,8 +36259,8 @@ async function updateManifest(projectRoot, entry) {
36111
36259
  `);
36112
36260
  }
36113
36261
  async function updateSkillsCatalog(projectRoot) {
36114
- const manifestPath = path112.join(projectRoot, ".metaproject", "metaproject.json");
36115
- const catalogPath = path112.join(projectRoot, ".metaproject", "skills", "catalog.md");
36262
+ const manifestPath = path113.join(projectRoot, ".metaproject", "metaproject.json");
36263
+ const catalogPath = path113.join(projectRoot, ".metaproject", "skills", "catalog.md");
36116
36264
  const manifest = await readJsonFileOr(manifestPath, {});
36117
36265
  const registry = manifest.modules?.gdskills?.projectSkillRegistry ?? [];
36118
36266
  const rows = registry.length > 0 ? registry.map((entry) => `| ${entry.module} | ${entry.name} | \`${entry.target}\` | ${entry.path}/SKILL.md |`).join(`
@@ -36152,7 +36300,7 @@ function inferModule(target) {
36152
36300
  }
36153
36301
  function inferSkillName(target) {
36154
36302
  const normalized = target.trim().replace(/[#:]+/g, "/");
36155
- const base = path112.basename(normalized).replace(/\.[^.]+$/, "");
36303
+ const base = path113.basename(normalized).replace(/\.[^.]+$/, "");
36156
36304
  return base || "entity";
36157
36305
  }
36158
36306
  function slugify5(value) {
@@ -36255,7 +36403,7 @@ class ProposalLifecycleService {
36255
36403
  now;
36256
36404
  constructor(options) {
36257
36405
  this.options = options;
36258
- this.root = path113.resolve(options.workspaceRoot);
36406
+ this.root = path114.resolve(options.workspaceRoot);
36259
36407
  this.now = options.now ?? (() => new Date);
36260
36408
  }
36261
36409
  async create(input) {
@@ -36274,7 +36422,7 @@ class ProposalLifecycleService {
36274
36422
  if (manifest.status === "archived")
36275
36423
  throw new ProposalLifecycleError("guard_denied", "workspace is archived");
36276
36424
  const file = this.proposalPath(workspaceId, proposal.id);
36277
- await mkdir34(path113.dirname(file), { recursive: true, mode: 448 });
36425
+ await mkdir34(path114.dirname(file), { recursive: true, mode: 448 });
36278
36426
  return withFileLock(`${file}.lock`, async () => {
36279
36427
  const consume = this.options.wrapUpAuthority.consume(input.wrapUp, { actor, workspaceId });
36280
36428
  if (consume !== "ok")
@@ -36302,7 +36450,7 @@ class ProposalLifecycleService {
36302
36450
  return this.options.workspaces.withAuthorizedActor({ actorContext: actor, workspaceId: input.workspaceId, action: "review", execute: async (manifest) => {
36303
36451
  const proposal = await this.loadProposal(input.workspaceId, input.proposalId);
36304
36452
  const ledger = this.ledgerPath(input.workspaceId);
36305
- await mkdir34(path113.dirname(ledger), { recursive: true, mode: 448 });
36453
+ await mkdir34(path114.dirname(ledger), { recursive: true, mode: 448 });
36306
36454
  return withFileLock(`${ledger}.lock`, async () => {
36307
36455
  const records = (await this.records(ledger)).filter((record) => record.proposalId === proposal.id);
36308
36456
  const events = records.filter((record) => record.recordType === "proposal-transition");
@@ -36344,7 +36492,7 @@ class ProposalLifecycleService {
36344
36492
  } });
36345
36493
  }
36346
36494
  async listProposedProposals(workspaceId) {
36347
- const proposalsDir = path113.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals");
36495
+ const proposalsDir = path114.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals");
36348
36496
  let entries;
36349
36497
  try {
36350
36498
  entries = (await readdir19(proposalsDir)).filter((name) => name.endsWith(".json"));
@@ -36356,7 +36504,7 @@ class ProposalLifecycleService {
36356
36504
  const proposals = [];
36357
36505
  for (const entry of entries) {
36358
36506
  try {
36359
- const parsed = JSON.parse(await readFile59(path113.join(proposalsDir, entry), "utf8"));
36507
+ const parsed = JSON.parse(await readFile59(path114.join(proposalsDir, entry), "utf8"));
36360
36508
  if (parsed.recordType === "proposal-created")
36361
36509
  proposals.push(parsed);
36362
36510
  } catch {}
@@ -36622,31 +36770,31 @@ class ProposalLifecycleService {
36622
36770
  }
36623
36771
  }
36624
36772
  proposalPath(workspaceId, proposalId) {
36625
- return path113.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.json`);
36773
+ return path114.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.json`);
36626
36774
  }
36627
36775
  decisionRef(proposalId, key) {
36628
36776
  return `./proposals/${proposalId}.${hash(key)}.decision.json`;
36629
36777
  }
36630
36778
  decisionPath(workspaceId, proposalId, key) {
36631
- return path113.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.decision.json`);
36779
+ return path114.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.decision.json`);
36632
36780
  }
36633
36781
  approvalRef(proposalId, key) {
36634
36782
  return `./proposals/${proposalId}.${hash(key)}.approval.json`;
36635
36783
  }
36636
36784
  approvalPath(workspaceId, proposalId, key) {
36637
- return path113.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.approval.json`);
36785
+ return path114.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.approval.json`);
36638
36786
  }
36639
36787
  writeResultPath(workspaceId, proposalId, key) {
36640
- return path113.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.write-result.json`);
36788
+ return path114.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.write-result.json`);
36641
36789
  }
36642
36790
  intentRef(proposalId, key) {
36643
36791
  return `./proposals/${proposalId}.${hash(key)}.write-intent.json`;
36644
36792
  }
36645
36793
  intentPath(workspaceId, proposalId, key) {
36646
- return path113.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.write-intent.json`);
36794
+ return path114.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.write-intent.json`);
36647
36795
  }
36648
36796
  attemptPath(workspaceId, proposalId, key) {
36649
- return path113.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.owner-write-attempt.json`);
36797
+ return path114.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.owner-write-attempt.json`);
36650
36798
  }
36651
36799
  async loadWriteResult(workspaceId, proposalId, key) {
36652
36800
  try {
@@ -36673,7 +36821,7 @@ class ProposalLifecycleService {
36673
36821
  }
36674
36822
  }
36675
36823
  ledgerPath(workspaceId) {
36676
- return path113.join(this.root, ".metaproject", "workspaces", workspaceId, "activity.jsonl");
36824
+ return path114.join(this.root, ".metaproject", "workspaces", workspaceId, "activity.jsonl");
36677
36825
  }
36678
36826
  timestamp() {
36679
36827
  return this.now().toISOString();
@@ -36756,7 +36904,7 @@ function normalizeProposalLifecycleResult(value) {
36756
36904
  // src/sac/collaboration-service.ts
36757
36905
  import { appendFile as appendFile8, mkdir as mkdir35, readFile as readFile60 } from "fs/promises";
36758
36906
  import { randomUUID as randomUUID8 } from "crypto";
36759
- import path114 from "path";
36907
+ import path115 from "path";
36760
36908
  class CollaborationServiceError extends Error {
36761
36909
  code;
36762
36910
  constructor(code, message) {
@@ -36771,7 +36919,7 @@ class CollaborationService {
36771
36919
  this.input = input;
36772
36920
  }
36773
36921
  file(id) {
36774
- return path114.join(this.input.workspaceRoot, ".metaproject", "workspaces", id, "activity.jsonl");
36922
+ return path115.join(this.input.workspaceRoot, ".metaproject", "workspaces", id, "activity.jsonl");
36775
36923
  }
36776
36924
  async overview(input) {
36777
36925
  const manifest = await this.input.workspaces.show(input);
@@ -36808,7 +36956,7 @@ class CollaborationService {
36808
36956
  occurredAt: (this.input.now ?? (() => new Date))().toISOString(),
36809
36957
  ...suppliedHandoff ? { handoff: { ...suppliedHandoff, from: actor.subject } } : {}
36810
36958
  });
36811
- await mkdir35(path114.dirname(this.file(manifest.id)), { recursive: true, mode: 448 });
36959
+ await mkdir35(path115.dirname(this.file(manifest.id)), { recursive: true, mode: 448 });
36812
36960
  await appendFile8(this.file(manifest.id), `${JSON.stringify(activity)}
36813
36961
  `, { mode: 384 });
36814
36962
  return normalizeCollaborationResult(activity);
@@ -36858,13 +37006,13 @@ function normalizeCollaborationResult(value) {
36858
37006
  // src/session/external-slate.ts
36859
37007
  init_fs();
36860
37008
  import { mkdir as mkdir37, readdir as readdir20, readFile as readFile61 } from "fs/promises";
36861
- import path116 from "path";
37009
+ import path117 from "path";
36862
37010
 
36863
37011
  // src/sac/machine-wrap-up.ts
36864
37012
  init_fs();
36865
37013
  import { createHash as createHash30, randomUUID as randomUUID10 } from "crypto";
36866
37014
  import { mkdir as mkdir36 } from "fs/promises";
36867
- import path115 from "path";
37015
+ import path116 from "path";
36868
37016
 
36869
37017
  // src/sac/workspace-resolve.ts
36870
37018
  init_redact();
@@ -37005,11 +37153,11 @@ async function resolveMachineWrapUp(input) {
37005
37153
  `;
37006
37154
  const seedsJson = `${JSON.stringify(seedsForKind.map((seed) => ({ text: seed.text, source: describeSource(seed.source) })), null, 2)}
37007
37155
  `;
37008
- const evidenceRelBase = path115.posix.join(".metaproject", "workspaces", input.workspaceId, "machine-evidence");
37156
+ const evidenceRelBase = path116.posix.join(".metaproject", "workspaces", input.workspaceId, "machine-evidence");
37009
37157
  const floor = await applyEvidenceRedactionFloor(input.cwd, [
37010
- { name: `${input.kind}.diff.txt`, content: diffBody, path: path115.posix.join(evidenceRelBase, `${input.kind}.diff.txt`), source: "tool-output" },
37011
- { name: `${input.kind}.flow.json`, content: flowSnapshotJson, path: path115.posix.join(evidenceRelBase, `${input.kind}.flow.json`), source: "generated" },
37012
- { name: `${input.kind}.seeds.json`, content: seedsJson, path: path115.posix.join(evidenceRelBase, `${input.kind}.seeds.json`), source: "generated" }
37158
+ { name: `${input.kind}.diff.txt`, content: diffBody, path: path116.posix.join(evidenceRelBase, `${input.kind}.diff.txt`), source: "tool-output" },
37159
+ { name: `${input.kind}.flow.json`, content: flowSnapshotJson, path: path116.posix.join(evidenceRelBase, `${input.kind}.flow.json`), source: "generated" },
37160
+ { name: `${input.kind}.seeds.json`, content: seedsJson, path: path116.posix.join(evidenceRelBase, `${input.kind}.seeds.json`), source: "generated" }
37013
37161
  ]);
37014
37162
  if (!floor.ok)
37015
37163
  return { ok: false, code: "security_denied", detail: floor.reason };
@@ -37063,14 +37211,14 @@ ${safeSeeds.content}`;
37063
37211
  }
37064
37212
  summary = result.text.trim().length > 0 ? result.text.trim() : mechanicalSummary(summaryDiff, course);
37065
37213
  }
37066
- const evidenceDir = path115.join(input.cwd, ".metaproject", "workspaces", input.workspaceId, "machine-evidence");
37214
+ const evidenceDir = path116.join(input.cwd, ".metaproject", "workspaces", input.workspaceId, "machine-evidence");
37067
37215
  await mkdir36(evidenceDir, { recursive: true });
37068
37216
  const diffFile = `${input.kind}.${shortHash}.diff.txt`;
37069
37217
  const flowFile = `${input.kind}.${shortHash}.flow.json`;
37070
37218
  const seedsFile = `${input.kind}.${shortHash}.seeds.json`;
37071
- await writeFileAtomic(path115.join(evidenceDir, diffFile), safeDiff.content);
37072
- await writeFileAtomic(path115.join(evidenceDir, flowFile), safeFlow.content);
37073
- await writeFileAtomic(path115.join(evidenceDir, seedsFile), safeSeeds.content);
37219
+ await writeFileAtomic(path116.join(evidenceDir, diffFile), safeDiff.content);
37220
+ await writeFileAtomic(path116.join(evidenceDir, flowFile), safeFlow.content);
37221
+ await writeFileAtomic(path116.join(evidenceDir, seedsFile), safeSeeds.content);
37074
37222
  const observedAt = now().toISOString();
37075
37223
  const relBase = `./.metaproject/workspaces/${input.workspaceId}/machine-evidence`;
37076
37224
  const evidence = [
@@ -37080,7 +37228,7 @@ ${safeSeeds.content}`;
37080
37228
  ];
37081
37229
  if (floor.notice !== undefined) {
37082
37230
  const noticeFile = `${input.kind}.${shortHash}.redaction.md`;
37083
- await writeFileAtomic(path115.join(evidenceDir, noticeFile), floor.notice);
37231
+ await writeFileAtomic(path116.join(evidenceDir, noticeFile), floor.notice);
37084
37232
  evidence.push({ kind: REDACTION_NOTICE_KIND, uri: `${relBase}/${noticeFile}`, revision: sha2566(floor.notice), observedAt });
37085
37233
  }
37086
37234
  return {
@@ -37099,18 +37247,18 @@ async function writeFlooredArchiveArtifact(params) {
37099
37247
  {
37100
37248
  name: params.filename,
37101
37249
  content: params.content,
37102
- path: path115.posix.join("slate-archive", params.filename),
37250
+ path: path116.posix.join("slate-archive", params.filename),
37103
37251
  source: "generated"
37104
37252
  }
37105
37253
  ]);
37106
37254
  if (!floor.ok)
37107
37255
  return { ok: false, code: "security_denied", detail: floor.reason };
37108
37256
  const body = floor.bodies[0];
37109
- const archiveDir = path115.join(params.dir, "slate-archive");
37257
+ const archiveDir = path116.join(params.dir, "slate-archive");
37110
37258
  await mkdir36(archiveDir, { recursive: true });
37111
- await writeFileAtomic(path115.join(archiveDir, params.filename), body.content);
37259
+ await writeFileAtomic(path116.join(archiveDir, params.filename), body.content);
37112
37260
  if (floor.notice !== undefined) {
37113
- await writeFileAtomic(path115.join(archiveDir, `${params.filename}${ARCHIVE_REDACTION_NOTICE_SUFFIX}`), floor.notice);
37261
+ await writeFileAtomic(path116.join(archiveDir, `${params.filename}${ARCHIVE_REDACTION_NOTICE_SUFFIX}`), floor.notice);
37114
37262
  }
37115
37263
  return { ok: true, altered: body.altered };
37116
37264
  }
@@ -37146,9 +37294,9 @@ async function writeWrapUpOutcomeArtifact(cwd, dir, trigger, now, groups) {
37146
37294
  return;
37147
37295
  const refusalIso = now().toISOString();
37148
37296
  const refusalFilename = `${refusalIso.replace(/[:.]/g, "-")}-wrap-up-outcome.json`;
37149
- const archiveDir = path115.join(dir, "slate-archive");
37297
+ const archiveDir = path116.join(dir, "slate-archive");
37150
37298
  await mkdir36(archiveDir, { recursive: true });
37151
- await writeFileAtomic(path115.join(archiveDir, refusalFilename), `${JSON.stringify({
37299
+ await writeFileAtomic(path116.join(archiveDir, refusalFilename), `${JSON.stringify({
37152
37300
  recordType: "wrap-up-outcome",
37153
37301
  trigger,
37154
37302
  generatedAt: refusalIso,
@@ -37284,7 +37432,7 @@ async function runWrapUp(input) {
37284
37432
 
37285
37433
  // src/session/external-slate.ts
37286
37434
  function externalSlatesDir(cwd) {
37287
- return path116.join(cwd, ".keryx", "external-slates");
37435
+ return path117.join(cwd, ".keryx", "external-slates");
37288
37436
  }
37289
37437
  var EXTERNAL_SESSION_ID_PATTERN = /^[A-Za-z0-9_-]{1,128}$/;
37290
37438
  function assertValidExternalSessionId(externalSessionId) {
@@ -37294,14 +37442,14 @@ function assertValidExternalSessionId(externalSessionId) {
37294
37442
  }
37295
37443
  function externalSlatePath(cwd, externalSessionId) {
37296
37444
  assertValidExternalSessionId(externalSessionId);
37297
- return path116.join(externalSlatesDir(cwd), `${externalSessionId}.json`);
37445
+ return path117.join(externalSlatesDir(cwd), `${externalSessionId}.json`);
37298
37446
  }
37299
37447
  function externalSlateLockPath(cwd, externalSessionId) {
37300
37448
  return `${externalSlatePath(cwd, externalSessionId)}.lock`;
37301
37449
  }
37302
37450
  function externalSlateEvidenceDir(cwd, externalSessionId) {
37303
37451
  assertValidExternalSessionId(externalSessionId);
37304
- return path116.join(externalSlatesDir(cwd), externalSessionId);
37452
+ return path117.join(externalSlatesDir(cwd), externalSessionId);
37305
37453
  }
37306
37454
  async function readExternalSlate(cwd, externalSessionId) {
37307
37455
  try {
@@ -37407,12 +37555,12 @@ __export(exports_service10, {
37407
37555
  runDoctor: () => runDoctor,
37408
37556
  runValidate: () => runValidate
37409
37557
  });
37410
- import path119 from "path";
37558
+ import path120 from "path";
37411
37559
  import { readFile as readFile64 } from "fs/promises";
37412
37560
 
37413
37561
  // src/standard/validate.ts
37414
37562
  init_fs();
37415
- import path118 from "path";
37563
+ import path119 from "path";
37416
37564
  import { readFile as readFile63 } from "fs/promises";
37417
37565
 
37418
37566
  // src/standard/schemas.ts
@@ -37541,7 +37689,7 @@ var SCHEMA_REGISTRY2 = {
37541
37689
 
37542
37690
  // src/standard/profiles.ts
37543
37691
  init_fs();
37544
- import path117 from "path";
37692
+ import path118 from "path";
37545
37693
  import { readFile as readFile62 } from "fs/promises";
37546
37694
  var AGENT_MODULES = ["gdgraph", "gdctx", "gdskills", "gdwiki", "memory"];
37547
37695
  var CI_MODULES = ["health", "testing"];
@@ -37553,7 +37701,7 @@ function enabledModuleKeys(manifest) {
37553
37701
  }
37554
37702
  async function rootEntrypointLinksIndex(cwd) {
37555
37703
  for (const name of ROOT_ENTRYPOINTS) {
37556
- const filePath = path117.join(cwd, name);
37704
+ const filePath = path118.join(cwd, name);
37557
37705
  if (!await pathExists(filePath)) {
37558
37706
  continue;
37559
37707
  }
@@ -37565,16 +37713,16 @@ async function rootEntrypointLinksIndex(cwd) {
37565
37713
  return false;
37566
37714
  }
37567
37715
  async function minimalSatisfied(cwd) {
37568
- const metaprojectRoot = path117.join(cwd, ".metaproject");
37716
+ const metaprojectRoot = path118.join(cwd, ".metaproject");
37569
37717
  const requiredFiles = ["index.md", "README.md", "metaproject.json"];
37570
37718
  const requiredDirs = ["modules", "rules", "skills", "data"];
37571
37719
  for (const file of requiredFiles) {
37572
- if (!await pathExists(path117.join(metaprojectRoot, file))) {
37720
+ if (!await pathExists(path118.join(metaprojectRoot, file))) {
37573
37721
  return false;
37574
37722
  }
37575
37723
  }
37576
37724
  for (const dir of requiredDirs) {
37577
- if (!await pathExists(path117.join(metaprojectRoot, dir))) {
37725
+ if (!await pathExists(path118.join(metaprojectRoot, dir))) {
37578
37726
  return false;
37579
37727
  }
37580
37728
  }
@@ -37587,7 +37735,7 @@ async function ciSatisfied(cwd, manifest) {
37587
37735
  return false;
37588
37736
  }
37589
37737
  for (const key of ciModules) {
37590
- if (await pathExists(path117.join(cwd, ".metaproject", "data", key, "artifacts"))) {
37738
+ if (await pathExists(path118.join(cwd, ".metaproject", "data", key, "artifacts"))) {
37591
37739
  return true;
37592
37740
  }
37593
37741
  }
@@ -37600,7 +37748,7 @@ async function evaluateProfiles(cwd, manifest) {
37600
37748
  satisfied.push("minimal");
37601
37749
  }
37602
37750
  const hasAgentModule = AGENT_MODULES.some((key) => new Set(enabledModuleKeys(manifest)).has(key));
37603
- const agent = minimal && hasAgentModule && await rootEntrypointLinksIndex(cwd) && await pathExists(path117.join(cwd, ".metaproject", "rules"));
37751
+ const agent = minimal && hasAgentModule && await rootEntrypointLinksIndex(cwd) && await pathExists(path118.join(cwd, ".metaproject", "rules"));
37604
37752
  if (agent) {
37605
37753
  satisfied.push("agent");
37606
37754
  }
@@ -37770,20 +37918,20 @@ var MANIFEST_TOP_LEVEL_SCHEMA = {
37770
37918
  async function validateWorkspace2(cwd) {
37771
37919
  const errors = [];
37772
37920
  const warnings = [];
37773
- const metaprojectRoot = path118.join(cwd, ".metaproject");
37921
+ const metaprojectRoot = path119.join(cwd, ".metaproject");
37774
37922
  const requiredFiles = ["index.md", "README.md", "metaproject.json"];
37775
37923
  for (const file of requiredFiles) {
37776
- if (!await pathExists(path118.join(metaprojectRoot, file))) {
37924
+ if (!await pathExists(path119.join(metaprojectRoot, file))) {
37777
37925
  errors.push(issue("missing-required-file", `Required file .metaproject/${file} is missing`, `Run \`keryx init\` to scaffold .metaproject/${file}.`));
37778
37926
  }
37779
37927
  }
37780
37928
  const requiredDirs = ["modules", "rules", "skills", "data"];
37781
37929
  for (const dir of requiredDirs) {
37782
- if (!await pathExists(path118.join(metaprojectRoot, dir))) {
37930
+ if (!await pathExists(path119.join(metaprojectRoot, dir))) {
37783
37931
  errors.push(issue("missing-required-dir", `Required directory .metaproject/${dir}/ is missing`, `Run \`keryx init\` to create .metaproject/${dir}/.`));
37784
37932
  }
37785
37933
  }
37786
- const manifestPath = path118.join(metaprojectRoot, "metaproject.json");
37934
+ const manifestPath = path119.join(metaprojectRoot, "metaproject.json");
37787
37935
  if (!await pathExists(manifestPath)) {
37788
37936
  return { ok: errors.length === 0, errors, warnings };
37789
37937
  }
@@ -37815,7 +37963,7 @@ async function validateWorkspace2(cwd) {
37815
37963
  if (typeof value !== "string") {
37816
37964
  continue;
37817
37965
  }
37818
- if (!await pathExists(path118.join(cwd, value))) {
37966
+ if (!await pathExists(path119.join(cwd, value))) {
37819
37967
  errors.push(issue("missing-declared-path", `Declared path paths.${key} -> ${value} does not exist`, `Create ${value} or remove paths.${key} from metaproject.json.`));
37820
37968
  }
37821
37969
  }
@@ -37825,7 +37973,7 @@ async function validateWorkspace2(cwd) {
37825
37973
  continue;
37826
37974
  }
37827
37975
  if (typeof entry.manifest === "string") {
37828
- if (!await pathExists(path118.join(cwd, entry.manifest))) {
37976
+ if (!await pathExists(path119.join(cwd, entry.manifest))) {
37829
37977
  errors.push(issue("missing-module-manifest", `Enabled module "${key}" manifest ${entry.manifest} is missing`, `Create ${entry.manifest} or run \`keryx update\` to regenerate module manifests.`));
37830
37978
  }
37831
37979
  }
@@ -37834,14 +37982,14 @@ async function validateWorkspace2(cwd) {
37834
37982
  if (typeof value !== "string") {
37835
37983
  continue;
37836
37984
  }
37837
- if (!await pathExists(path118.join(cwd, value))) {
37985
+ if (!await pathExists(path119.join(cwd, value))) {
37838
37986
  const sink = field === "data" ? warnings : errors;
37839
37987
  sink.push(issue("missing-module-path", `Module "${key}" declares ${String(field)} ${value}, which does not exist`, field === "data" ? `Run the module (e.g. \`keryx ${key} ...\`) to generate ${value}, or update modules.${key}.data in metaproject.json.` : `Create ${value} or update modules.${key}.${String(field)} in metaproject.json.`));
37840
37988
  }
37841
37989
  }
37842
37990
  }
37843
37991
  for (const name of ROOT_ENTRYPOINTS2) {
37844
- const filePath = path118.join(cwd, name);
37992
+ const filePath = path119.join(cwd, name);
37845
37993
  if (!await pathExists(filePath)) {
37846
37994
  continue;
37847
37995
  }
@@ -38685,7 +38833,7 @@ async function runDoctor(cwd) {
38685
38833
  return validateWorkspace2(cwd);
38686
38834
  }
38687
38835
  async function readManifest(cwd) {
38688
- const manifestPath = path119.join(cwd, ".metaproject", "metaproject.json");
38836
+ const manifestPath = path120.join(cwd, ".metaproject", "metaproject.json");
38689
38837
  if (!await pathExists(manifestPath)) {
38690
38838
  throw new Error("Metaproject is not initialized (missing .metaproject/metaproject.json). Run `keryx init` first.");
38691
38839
  }