@mrciphersmith/keryx 0.3.31 → 0.3.32

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 (3) hide show
  1. package/dist/cli.js +1789 -1651
  2. package/dist/core.js +806 -702
  3. 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) {
@@ -21671,11 +21671,13 @@ __export(exports_service2, {
21671
21671
  statusLabel: () => statusLabel,
21672
21672
  stripVerifyMarker: () => stripVerifyMarker,
21673
21673
  summarizeVerdicts: () => summarizeVerdicts,
21674
+ uncommittedFlowStateNote: () => uncommittedFlowStateNote,
21675
+ uncommittedFlowStateNotes: () => uncommittedFlowStateNotes,
21674
21676
  validateCriterionName: () => validateCriterionName,
21675
21677
  writeAcCheckCache: () => writeAcCheckCache
21676
21678
  });
21677
21679
  import { mkdir as mkdir11, readFile as readFile24 } from "fs/promises";
21678
- import path50 from "path";
21680
+ import path51 from "path";
21679
21681
 
21680
21682
  // src/flow/machine.ts
21681
21683
  var TRANSITIONS = {
@@ -23994,6 +23996,108 @@ async function readRequireConfirmationDefault(cwd) {
23994
23996
  return false;
23995
23997
  }
23996
23998
  }
23999
+ // src/flow/uncommitted-state.ts
24000
+ import path15 from "path";
24001
+ var UNCOMMITTED_LIST_CAP = 5;
24002
+ var READ_ONLY_GIT_FLAGS = ["--no-optional-locks"];
24003
+ var GIT_TIMEOUT_MS = 5000;
24004
+ var spawnGit = async (cwd, args) => {
24005
+ const proc = Bun.spawn(["git", ...args], {
24006
+ cwd,
24007
+ stdout: "pipe",
24008
+ stderr: "pipe",
24009
+ timeout: GIT_TIMEOUT_MS
24010
+ });
24011
+ const [out, code] = await Promise.all([new Response(proc.stdout).text(), proc.exited]);
24012
+ return { code: proc.signalCode === null ? code : -1, out };
24013
+ };
24014
+ var FLOW_PATH = /(?:^|\/)\.metaproject\/flows\/([^/]+)\/(.+)$/;
24015
+ function groupByFlowDir(listing, porcelain) {
24016
+ const groups = new Map;
24017
+ for (const line of listing.split(`
24018
+ `)) {
24019
+ let file = porcelain ? line.length < 4 ? "" : line.slice(3) : line;
24020
+ const renamed = porcelain ? file.indexOf(" -> ") : -1;
24021
+ if (renamed !== -1)
24022
+ file = file.slice(renamed + 4);
24023
+ file = file.replace(/^"|"$/g, "");
24024
+ const match = FLOW_PATH.exec(file);
24025
+ if (match === null)
24026
+ continue;
24027
+ const [, dir, inside] = match;
24028
+ if (dir === undefined || inside === undefined)
24029
+ continue;
24030
+ const list = groups.get(dir);
24031
+ if (list === undefined)
24032
+ groups.set(dir, [inside]);
24033
+ else
24034
+ list.push(inside);
24035
+ }
24036
+ return groups;
24037
+ }
24038
+ function noteFor(flowId, dir, listings) {
24039
+ if ((listings.tracked.get(dir) ?? []).length === 0)
24040
+ return null;
24041
+ const seen = new Set;
24042
+ for (const inside of listings.status.get(dir) ?? []) {
24043
+ const slash = inside.indexOf("/");
24044
+ seen.add(slash === -1 ? inside : `${inside.slice(0, slash)}/`);
24045
+ }
24046
+ const entries = [...seen];
24047
+ if (entries.length === 0)
24048
+ return null;
24049
+ const shown = entries.slice(0, UNCOMMITTED_LIST_CAP);
24050
+ const more = entries.length - shown.length;
24051
+ const list = `${shown.join(", ")}${more > 0 ? `, +${more} more` : ""}`;
24052
+ 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)";
24053
+ }
24054
+ async function readGit(cwd, scope, git) {
24055
+ const tracked = await git(cwd, [...READ_ONLY_GIT_FLAGS, "ls-files", "--", scope]);
24056
+ if (tracked.code !== 0)
24057
+ return null;
24058
+ const empty = { tracked: new Map, status: new Map };
24059
+ if (tracked.out.trim().length === 0)
24060
+ return empty;
24061
+ const status = await git(cwd, [
24062
+ ...READ_ONLY_GIT_FLAGS,
24063
+ "-c",
24064
+ "core.quotepath=off",
24065
+ "status",
24066
+ "--porcelain",
24067
+ "--untracked-files=all",
24068
+ "--",
24069
+ scope
24070
+ ]);
24071
+ if (status.code !== 0)
24072
+ return null;
24073
+ return { tracked: groupByFlowDir(tracked.out, false), status: groupByFlowDir(status.out, true) };
24074
+ }
24075
+ async function uncommittedFlowStateNote(cwd, flowId, dir, git = spawnGit) {
24076
+ try {
24077
+ const read = await readGit(cwd, path15.join(flowsRoot(cwd), dir), git);
24078
+ return read === null ? null : noteFor(flowId, dir, read);
24079
+ } catch {
24080
+ return null;
24081
+ }
24082
+ }
24083
+ async function uncommittedFlowStateNotes(cwd, flows, git = spawnGit) {
24084
+ const notes = new Map;
24085
+ if (flows.length === 0)
24086
+ return notes;
24087
+ try {
24088
+ const read = await readGit(cwd, flowsRoot(cwd), git);
24089
+ if (read === null)
24090
+ return notes;
24091
+ for (const flow of flows) {
24092
+ const text = noteFor(flow.id, flow.dir, read);
24093
+ if (text !== null)
24094
+ notes.set(flow.dir, text);
24095
+ }
24096
+ } catch {
24097
+ return new Map;
24098
+ }
24099
+ return notes;
24100
+ }
23997
24101
  // src/flow/ac-kinds.ts
23998
24102
  var AC_KINDS = ["exec", "invariant", "judged", "none", "unclassified"];
23999
24103
  var AC_LINE = /^\s*[-*]\s*(AC\d+)\s*:\s?(.*)$/i;
@@ -24151,7 +24255,7 @@ function readAcKindRecords(value) {
24151
24255
  }
24152
24256
  // src/flow/description-intent.ts
24153
24257
  import { readFile as readFile10 } from "fs/promises";
24154
- import path15 from "path";
24258
+ import path16 from "path";
24155
24259
  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
24260
  var PLACEHOLDERS = ["Describe the problem precisely", "What must be true when this flow is done"];
24157
24261
  var FLOW_STATEMENT_HEADINGS = [/^problem$/i, /^expected outcome$/i];
@@ -24238,7 +24342,7 @@ function initIntentNote(description) {
24238
24342
  }
24239
24343
  async function intentNoteForNewFlow(cwd, dir) {
24240
24344
  try {
24241
- return initIntentNote(await readFile10(path15.join(cwd, dir, "description.md"), "utf8"));
24345
+ return initIntentNote(await readFile10(path16.join(cwd, dir, "description.md"), "utf8"));
24242
24346
  } catch {
24243
24347
  return null;
24244
24348
  }
@@ -24246,7 +24350,7 @@ async function intentNoteForNewFlow(cwd, dir) {
24246
24350
  // src/flow/check-ac.ts
24247
24351
  import { createHash as createHash8 } from "crypto";
24248
24352
  import { chmod as chmod4, mkdir as mkdir9, readFile as readFile22 } from "fs/promises";
24249
- import path47 from "path";
24353
+ import path48 from "path";
24250
24354
 
24251
24355
  // src/review/cost.ts
24252
24356
  function estimateTokens(text) {
@@ -24434,7 +24538,7 @@ function factsOnlyVerdict(item) {
24434
24538
  }
24435
24539
  async function readAcCheckEnabled(cwd) {
24436
24540
  try {
24437
- const parsed = JSON.parse(await readFile22(path47.join(cwd, REVIEW_GATE_CONFIG_PATH), "utf8"));
24541
+ const parsed = JSON.parse(await readFile22(path48.join(cwd, REVIEW_GATE_CONFIG_PATH), "utf8"));
24438
24542
  if (typeof parsed !== "object" || parsed === null)
24439
24543
  return false;
24440
24544
  const review = parsed["review"];
@@ -24455,7 +24559,7 @@ function acCheckCacheKey(criteriaChecksum, diffText) {
24455
24559
  return `${criteriaChecksum}:${hashDiff(diffText)}`;
24456
24560
  }
24457
24561
  function acCheckCachePath(cwd, flowDir) {
24458
- return path47.join(cwd, ".metaproject", "data", "ac-check", `${flowDir}.json`);
24562
+ return path48.join(cwd, ".metaproject", "data", "ac-check", `${flowDir}.json`);
24459
24563
  }
24460
24564
  async function readAcCheckCache(cachePath) {
24461
24565
  if (!await pathExists(cachePath))
@@ -24467,7 +24571,7 @@ async function readAcCheckCache(cachePath) {
24467
24571
  }
24468
24572
  }
24469
24573
  async function writeAcCheckCache(cachePath, record) {
24470
- await mkdir9(path47.dirname(cachePath), { recursive: true });
24574
+ await mkdir9(path48.dirname(cachePath), { recursive: true });
24471
24575
  await writeFileAtomic(cachePath, `${JSON.stringify(record, null, 2)}
24472
24576
  `, { mode: 384 });
24473
24577
  if (process.platform !== "win32") {
@@ -24525,10 +24629,10 @@ function renderAcCheckAdvisoryNotice(verdicts) {
24525
24629
  }
24526
24630
  // src/flow/allocation.ts
24527
24631
  import { appendFile as appendFile3, mkdir as mkdir10, readFile as readFile23 } from "fs/promises";
24528
- import path49 from "path";
24632
+ import path50 from "path";
24529
24633
 
24530
24634
  // src/lib/clone-scope.ts
24531
- import path48 from "path";
24635
+ import path49 from "path";
24532
24636
  async function gitCommonDir(cwd) {
24533
24637
  try {
24534
24638
  const proc = Bun.spawn(["git", "rev-parse", "--git-common-dir"], {
@@ -24540,7 +24644,7 @@ async function gitCommonDir(cwd) {
24540
24644
  if (await proc.exited !== 0 || output.length === 0) {
24541
24645
  return null;
24542
24646
  }
24543
- return path48.isAbsolute(output) ? output : path48.resolve(cwd, output);
24647
+ return path49.isAbsolute(output) ? output : path49.resolve(cwd, output);
24544
24648
  } catch {
24545
24649
  return null;
24546
24650
  }
@@ -24565,23 +24669,23 @@ function projectKey(toplevel, cwd) {
24565
24669
  if (!toplevel) {
24566
24670
  return "root";
24567
24671
  }
24568
- const relative = path49.relative(toplevel, cwd);
24672
+ const relative = path50.relative(toplevel, cwd);
24569
24673
  return relative === "" ? "root" : slugify(relative);
24570
24674
  }
24571
24675
  async function resolveAllocationScope(cwd) {
24572
24676
  const commonDir = await gitCommonDir(cwd);
24573
24677
  if (!commonDir) {
24574
24678
  return {
24575
- lockPath: path49.join(flowsRoot(cwd), ".flow-init.lock"),
24679
+ lockPath: path50.join(flowsRoot(cwd), ".flow-init.lock"),
24576
24680
  ledgerPath: null,
24577
24681
  project: "root"
24578
24682
  };
24579
24683
  }
24580
24684
  const key = projectKey(await gitToplevel(cwd), cwd);
24581
- const dir = path49.join(commonDir, "keryx", "flow-ids");
24685
+ const dir = path50.join(commonDir, "keryx", "flow-ids");
24582
24686
  return {
24583
- lockPath: path49.join(dir, `${key}.lock`),
24584
- ledgerPath: path49.join(dir, `${key}.jsonl`),
24687
+ lockPath: path50.join(dir, `${key}.lock`),
24688
+ ledgerPath: path50.join(dir, `${key}.jsonl`),
24585
24689
  project: key
24586
24690
  };
24587
24691
  }
@@ -24614,7 +24718,7 @@ async function recordAllocation(scope, record) {
24614
24718
  if (!scope.ledgerPath) {
24615
24719
  return;
24616
24720
  }
24617
- await mkdir10(path49.dirname(scope.ledgerPath), { recursive: true });
24721
+ await mkdir10(path50.dirname(scope.ledgerPath), { recursive: true });
24618
24722
  await appendFile3(scope.ledgerPath, `${JSON.stringify(record)}
24619
24723
  `, "utf8");
24620
24724
  }
@@ -24808,7 +24912,7 @@ function createFlowService(deps) {
24808
24912
  const date = now().slice(0, 10);
24809
24913
  const slug = slugify(input.slug ?? title);
24810
24914
  const dir = `${id}-${date}-${slug}`;
24811
- const absolute = path50.join(flowsRoot(input.cwd), dir);
24915
+ const absolute = path51.join(flowsRoot(input.cwd), dir);
24812
24916
  if (await pathExists(absolute)) {
24813
24917
  throw new Error(`Flow directory already exists: ${dir}`);
24814
24918
  }
@@ -24841,15 +24945,15 @@ function createFlowService(deps) {
24841
24945
  history: [{ at: createdAt, event: "created" }]
24842
24946
  };
24843
24947
  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));
24948
+ await writeFileAtomic(path51.join(absolute, "description.md"), renderDescription(title, sourceLabel));
24949
+ await writeFileAtomic(path51.join(absolute, "context.md"), context.markdown);
24950
+ await writeFileAtomic(path51.join(absolute, "plan.md"), renderPlan());
24951
+ await writeFileAtomic(path51.join(absolute, "tasks.md"), renderTasksDoc());
24952
+ await writeFileAtomic(path51.join(absolute, "acceptance-criteria.md"), renderAcceptanceCriteria());
24953
+ await writeFileAtomic(path51.join(absolute, "journal.md"), renderJournal(createdAt));
24850
24954
  await writeFlow(input.cwd, dir, flow);
24851
24955
  await recordAllocation(scope, { id, dir, at: createdAt, project: scope.project });
24852
- return { flow, dir: path50.relative(input.cwd, absolute), contextNotes: context.notes };
24956
+ return { flow, dir: path51.relative(input.cwd, absolute), contextNotes: context.notes };
24853
24957
  });
24854
24958
  },
24855
24959
  async list({ cwd }) {
@@ -25433,7 +25537,7 @@ function createFlowService(deps) {
25433
25537
  issues.push({ flow: dir, kind: "schema", message: `unknown schemaVersion ${flow.schemaVersion}` });
25434
25538
  }
25435
25539
  try {
25436
- const raw = JSON.parse(await Bun.file(path50.join(flowsRoot(cwd), dir, "flow.json")).text());
25540
+ const raw = JSON.parse(await Bun.file(path51.join(flowsRoot(cwd), dir, "flow.json")).text());
25437
25541
  const validation = validateAgainstSchemaObject(flowStateSchema(), raw);
25438
25542
  if (!validation.valid) {
25439
25543
  issues.push({
@@ -25444,7 +25548,7 @@ function createFlowService(deps) {
25444
25548
  }
25445
25549
  } catch {}
25446
25550
  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))) {
25551
+ if (!await pathExists(path51.join(flowsRoot(cwd), dir, file))) {
25448
25552
  issues.push({ flow: dir, kind: "structure", message: `missing ${file}` });
25449
25553
  }
25450
25554
  }
@@ -25483,7 +25587,7 @@ function createFlowService(deps) {
25483
25587
  };
25484
25588
  }
25485
25589
  async function appendIdMap(cwd, entry) {
25486
- const file = path50.join(flowsRoot(cwd), "id-map.json");
25590
+ const file = path51.join(flowsRoot(cwd), "id-map.json");
25487
25591
  let entries = [];
25488
25592
  if (await pathExists(file)) {
25489
25593
  const raw = await readFile24(file, "utf8");
@@ -25494,7 +25598,7 @@ async function appendIdMap(cwd, entry) {
25494
25598
  }
25495
25599
  entries = parsed;
25496
25600
  } catch (error) {
25497
- throw new Error(`Cannot read ${path50.relative(cwd, file)}: ${error instanceof Error ? error.message : String(error)}`);
25601
+ throw new Error(`Cannot read ${path51.relative(cwd, file)}: ${error instanceof Error ? error.message : String(error)}`);
25498
25602
  }
25499
25603
  }
25500
25604
  entries.push(entry);
@@ -25747,7 +25851,7 @@ __export(exports_service5, {
25747
25851
  // src/gdgraph/build.ts
25748
25852
  import { mkdir as mkdir20, readdir as readdir13, readFile as readFile35, writeFile as writeFile14 } from "fs/promises";
25749
25853
  import { existsSync as existsSync6 } from "fs";
25750
- import path70 from "path";
25854
+ import path71 from "path";
25751
25855
 
25752
25856
  // src/gdgraph/types.ts
25753
25857
  var UNKNOWN_IMPORT_KIND = "unknown-static";
@@ -25812,7 +25916,7 @@ async function buildGraph(projectRoot) {
25812
25916
  const assetNodes = new Map;
25813
25917
  const fileRecords = [];
25814
25918
  for (const file of files) {
25815
- const absolutePath = path70.join(projectRoot, file);
25919
+ const absolutePath = path71.join(projectRoot, file);
25816
25920
  const content = await readFile35(absolutePath, "utf8");
25817
25921
  fileRecords.push({ path: file, content });
25818
25922
  const language = getLanguage(file);
@@ -25865,24 +25969,24 @@ async function collectSourceFiles(projectRoot) {
25865
25969
  const result = [];
25866
25970
  const skippedDirectories = [];
25867
25971
  async function walk(relativeDir) {
25868
- const absoluteDir = path70.join(projectRoot, relativeDir);
25972
+ const absoluteDir = path71.join(projectRoot, relativeDir);
25869
25973
  const entries = await readdir13(absoluteDir, { withFileTypes: true });
25870
25974
  for (const entry of entries) {
25871
25975
  if (entry.isDirectory()) {
25872
25976
  if (IGNORE_DIRS.has(entry.name)) {
25873
- skippedDirectories.push(normalizePath2(path70.posix.join(relativeDir, entry.name)).replace(/^\.\//, ""));
25977
+ skippedDirectories.push(normalizePath2(path71.posix.join(relativeDir, entry.name)).replace(/^\.\//, ""));
25874
25978
  continue;
25875
25979
  }
25876
- await walk(normalizePath2(path70.posix.join(relativeDir, entry.name)));
25980
+ await walk(normalizePath2(path71.posix.join(relativeDir, entry.name)));
25877
25981
  continue;
25878
25982
  }
25879
25983
  if (!entry.isFile()) {
25880
25984
  continue;
25881
25985
  }
25882
- if (!SOURCE_EXTENSIONS.includes(path70.extname(entry.name))) {
25986
+ if (!SOURCE_EXTENSIONS.includes(path71.extname(entry.name))) {
25883
25987
  continue;
25884
25988
  }
25885
- result.push(normalizePath2(path70.posix.join(relativeDir, entry.name)).replace(/^\.\//, ""));
25989
+ result.push(normalizePath2(path71.posix.join(relativeDir, entry.name)).replace(/^\.\//, ""));
25886
25990
  }
25887
25991
  }
25888
25992
  await walk(".");
@@ -25964,8 +26068,8 @@ function resolveImport(projectRoot, fromFile, specifier, fileSet, resolver) {
25964
26068
  }
25965
26069
  function resolveAssetImport(projectRoot, fromFile, specifier, resolver) {
25966
26070
  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))) {
26071
+ const extension = path71.posix.extname(candidate);
26072
+ if (ASSET_EXTENSIONS.includes(extension) && existsSync6(path71.join(projectRoot, candidate))) {
25969
26073
  return candidate;
25970
26074
  }
25971
26075
  }
@@ -25974,17 +26078,17 @@ function resolveAssetImport(projectRoot, fromFile, specifier, resolver) {
25974
26078
  function importCandidateBases(projectRoot, fromFile, specifier, resolver) {
25975
26079
  const normalizedSpecifier = stripImportSuffix(specifier);
25976
26080
  if (normalizedSpecifier.startsWith(".") && getLanguage(fromFile) !== "python") {
25977
- const fromDir = path70.posix.dirname(fromFile);
25978
- return [normalizePath2(path70.posix.normalize(path70.posix.join(fromDir, normalizedSpecifier)))];
26081
+ const fromDir = path71.posix.dirname(fromFile);
26082
+ return [normalizePath2(path71.posix.normalize(path71.posix.join(fromDir, normalizedSpecifier)))];
25979
26083
  }
25980
- return resolver.candidateBases(normalizedSpecifier, fromFile).map((candidate) => normalizePath2(path70.relative(projectRoot, path70.join(projectRoot, candidate))));
26084
+ return resolver.candidateBases(normalizedSpecifier, fromFile).map((candidate) => normalizePath2(path71.relative(projectRoot, path71.join(projectRoot, candidate))));
25981
26085
  }
25982
26086
  function resolveSourceCandidate(base, fileSet) {
25983
26087
  const candidates = [
25984
26088
  base,
25985
26089
  ...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")
26090
+ ...SOURCE_RESOLUTION_EXTENSIONS.map((extension) => path71.posix.join(base, `index${extension}`)),
26091
+ path71.posix.join(base, "__init__.py")
25988
26092
  ];
25989
26093
  return candidates.find((candidate) => fileSet.has(candidate)) ?? null;
25990
26094
  }
@@ -26014,7 +26118,7 @@ async function loadJavaResolver(projectRoot) {
26014
26118
  return createJavaResolver(roots);
26015
26119
  }
26016
26120
  async function discoverJavaSourceRoots(projectRoot) {
26017
- const pomPath = path70.join(projectRoot, "pom.xml");
26121
+ const pomPath = path71.join(projectRoot, "pom.xml");
26018
26122
  if (existsSync6(pomPath)) {
26019
26123
  try {
26020
26124
  const roots = parseMavenSourceRoots(await readFile35(pomPath, "utf8"));
@@ -26024,7 +26128,7 @@ async function discoverJavaSourceRoots(projectRoot) {
26024
26128
  } catch {}
26025
26129
  }
26026
26130
  for (const gradleName of ["build.gradle", "build.gradle.kts"]) {
26027
- const gradlePath = path70.join(projectRoot, gradleName);
26131
+ const gradlePath = path71.join(projectRoot, gradleName);
26028
26132
  if (existsSync6(gradlePath)) {
26029
26133
  try {
26030
26134
  const roots = parseGradleSourceRoots(await readFile35(gradlePath, "utf8"));
@@ -26046,12 +26150,12 @@ function createJavaResolver(sourceRoots) {
26046
26150
  return [];
26047
26151
  }
26048
26152
  const relative = specifier.split(".").join("/");
26049
- return sourceRoots.map((root) => normalizePath2(path70.posix.join(root, relative)));
26153
+ return sourceRoots.map((root) => normalizePath2(path71.posix.join(root, relative)));
26050
26154
  }
26051
26155
  };
26052
26156
  }
26053
26157
  function loadPythonResolver(projectRoot) {
26054
- const hasSrc = existsSync6(path70.join(projectRoot, "src"));
26158
+ const hasSrc = existsSync6(path71.join(projectRoot, "src"));
26055
26159
  return createPythonResolver(hasSrc);
26056
26160
  }
26057
26161
  function createPythonResolver(hasSrc) {
@@ -26064,16 +26168,16 @@ function createPythonResolver(hasSrc) {
26064
26168
  if (specifier.startsWith(".")) {
26065
26169
  const dots = /^\.+/.exec(specifier)?.[0].length ?? 0;
26066
26170
  const rest = specifier.slice(dots);
26067
- let baseDir = path70.posix.dirname(fromFile);
26171
+ let baseDir = path71.posix.dirname(fromFile);
26068
26172
  for (let level = 1;level < dots; level += 1) {
26069
- baseDir = path70.posix.dirname(baseDir);
26173
+ baseDir = path71.posix.dirname(baseDir);
26070
26174
  }
26071
26175
  const suffix = rest ? rest.split(".").join("/") : "";
26072
- const base = suffix ? path70.posix.join(baseDir, suffix) : baseDir;
26176
+ const base = suffix ? path71.posix.join(baseDir, suffix) : baseDir;
26073
26177
  return [normalizePath2(base)];
26074
26178
  }
26075
26179
  const relative = specifier.split(".").join("/");
26076
- return roots.map((root) => normalizePath2(root ? path70.posix.join(root, relative) : relative));
26180
+ return roots.map((root) => normalizePath2(root ? path71.posix.join(root, relative) : relative));
26077
26181
  }
26078
26182
  };
26079
26183
  }
@@ -26082,8 +26186,8 @@ function parseMavenSourceRoots(pomXml) {
26082
26186
  for (const match of pomXml.matchAll(/<module>\s*([^<]+?)\s*<\/module>/g)) {
26083
26187
  const moduleDir = match[1]?.trim();
26084
26188
  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")));
26189
+ roots.add(normalizePath2(path71.posix.join(moduleDir, "src/main/java")));
26190
+ roots.add(normalizePath2(path71.posix.join(moduleDir, "src/test/java")));
26087
26191
  }
26088
26192
  }
26089
26193
  for (const tag of ["sourceDirectory", "testSourceDirectory"]) {
@@ -26116,7 +26220,7 @@ function parseGradleSourceRoots(buildGradle) {
26116
26220
  var TSCONFIG_EXTENDS_MAX_DEPTH = 10;
26117
26221
  async function loadTsconfigResolver(projectRoot) {
26118
26222
  const empty = createTsconfigResolver(null, []);
26119
- const tsconfigPath = path70.join(projectRoot, "tsconfig.json");
26223
+ const tsconfigPath = path71.join(projectRoot, "tsconfig.json");
26120
26224
  if (!existsSync6(tsconfigPath)) {
26121
26225
  return empty;
26122
26226
  }
@@ -26129,7 +26233,7 @@ async function loadTsconfigResolver(projectRoot) {
26129
26233
  return createTsconfigResolver(resolved.baseUrl, paths);
26130
26234
  }
26131
26235
  function toProjectRelativeDir(projectRoot, absoluteDir) {
26132
- const relative = normalizePath2(path70.relative(projectRoot, absoluteDir)).replace(/^\.\//, "");
26236
+ const relative = normalizePath2(path71.relative(projectRoot, absoluteDir)).replace(/^\.\//, "");
26133
26237
  return relative === "." ? "" : relative;
26134
26238
  }
26135
26239
  async function readTsconfigJson(configPath) {
@@ -26144,11 +26248,11 @@ function resolveTsconfigExtendsPath(configDir, extendsSpecifier) {
26144
26248
  if (!extendsSpecifier.startsWith(".") && !extendsSpecifier.startsWith("/")) {
26145
26249
  return null;
26146
26250
  }
26147
- const resolved = path70.resolve(configDir, extendsSpecifier);
26251
+ const resolved = path71.resolve(configDir, extendsSpecifier);
26148
26252
  return resolved.endsWith(".json") ? resolved : `${resolved}.json`;
26149
26253
  }
26150
26254
  async function resolveTsconfigOptions(configPath, visited, depth, projectRoot) {
26151
- const resolvedPath = path70.resolve(configPath);
26255
+ const resolvedPath = path71.resolve(configPath);
26152
26256
  if (depth > TSCONFIG_EXTENDS_MAX_DEPTH || visited.has(resolvedPath)) {
26153
26257
  return null;
26154
26258
  }
@@ -26159,15 +26263,15 @@ async function resolveTsconfigOptions(configPath, visited, depth, projectRoot) {
26159
26263
  }
26160
26264
  let inherited = null;
26161
26265
  if (typeof parsed.extends === "string") {
26162
- const basePath = resolveTsconfigExtendsPath(path70.dirname(resolvedPath), parsed.extends);
26266
+ const basePath = resolveTsconfigExtendsPath(path71.dirname(resolvedPath), parsed.extends);
26163
26267
  if (basePath) {
26164
26268
  inherited = await resolveTsconfigOptions(basePath, visited, depth + 1, projectRoot);
26165
26269
  }
26166
26270
  }
26167
- const configDir = path70.dirname(resolvedPath);
26271
+ const configDir = path71.dirname(resolvedPath);
26168
26272
  const declaringDir = toProjectRelativeDir(projectRoot, configDir);
26169
26273
  const options = parsed.compilerOptions ?? {};
26170
- const ownBaseUrl = typeof options.baseUrl === "string" ? toProjectRelativeDir(projectRoot, path70.resolve(configDir, options.baseUrl)) : null;
26274
+ const ownBaseUrl = typeof options.baseUrl === "string" ? toProjectRelativeDir(projectRoot, path71.resolve(configDir, options.baseUrl)) : null;
26171
26275
  const baseUrl = ownBaseUrl ?? inherited?.baseUrl ?? null;
26172
26276
  const ownPaths = isRecord2(options.paths) ? Object.entries(options.paths).filter((entry) => Array.isArray(entry[1])).map(([pattern, targets]) => ({
26173
26277
  pattern,
@@ -26196,7 +26300,7 @@ function createTsconfigResolver(baseUrl, mappings) {
26196
26300
  }
26197
26301
  }
26198
26302
  if (baseUrl !== null) {
26199
- candidates.push(normalizePath2(path70.posix.join(baseUrl, normalizedSpecifier)));
26303
+ candidates.push(normalizePath2(path71.posix.join(baseUrl, normalizedSpecifier)));
26200
26304
  }
26201
26305
  return [...new Set(candidates.map((candidate) => candidate.replace(/^\.\//, "")))];
26202
26306
  }
@@ -26216,7 +26320,7 @@ function matchPathPattern(pattern, specifier) {
26216
26320
  }
26217
26321
  function applyPathTarget(base, target, wildcard) {
26218
26322
  const replaced = target.includes("*") ? target.replace("*", wildcard) : target;
26219
- return normalizePath2(path70.posix.normalize(path70.posix.join(base, replaced)));
26323
+ return normalizePath2(path71.posix.normalize(path71.posix.join(base, replaced)));
26220
26324
  }
26221
26325
  function stripJsonComments(source) {
26222
26326
  let out = "";
@@ -26269,21 +26373,21 @@ function isRecord2(value) {
26269
26373
  return typeof value === "object" && value !== null && !Array.isArray(value);
26270
26374
  }
26271
26375
  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");
26376
+ const storageDir = path71.join(projectRoot, ".metaproject", "data", "gdgraph", "storage");
26377
+ const artifactsDir = path71.join(projectRoot, ".metaproject", "data", "gdgraph", "artifacts");
26274
26378
  await mkdir20(storageDir, { recursive: true });
26275
26379
  await mkdir20(artifactsDir, { recursive: true });
26276
- await writeFile14(path70.join(storageDir, "nodes.jsonl"), graph.nodes.map((node) => JSON.stringify(node)).join(`
26380
+ await writeFile14(path71.join(storageDir, "nodes.jsonl"), graph.nodes.map((node) => JSON.stringify(node)).join(`
26277
26381
  `) + `
26278
26382
  `, "utf8");
26279
- await writeFile14(path70.join(storageDir, "edges.jsonl"), graph.edges.map((edge) => JSON.stringify(edge)).join(`
26383
+ await writeFile14(path71.join(storageDir, "edges.jsonl"), graph.edges.map((edge) => JSON.stringify(edge)).join(`
26280
26384
  `) + `
26281
26385
  `, "utf8");
26282
- await writeFile14(path70.join(artifactsDir, "module-map.json"), JSON.stringify(buildModuleMap(graph), null, 2) + `
26386
+ await writeFile14(path71.join(artifactsDir, "module-map.json"), JSON.stringify(buildModuleMap(graph), null, 2) + `
26283
26387
  `, "utf8");
26284
26388
  }
26285
26389
  async function writeSummary(projectRoot, graph, collection) {
26286
- const artifactsDir = path70.join(projectRoot, ".metaproject", "data", "gdgraph", "artifacts");
26390
+ const artifactsDir = path71.join(projectRoot, ".metaproject", "data", "gdgraph", "artifacts");
26287
26391
  await mkdir20(artifactsDir, { recursive: true });
26288
26392
  const unresolved = graph.edges.filter((edge) => edge.kind === "unresolved");
26289
26393
  const imports = graph.edges.filter((edge) => edge.kind === "imports");
@@ -26298,7 +26402,7 @@ async function writeSummary(projectRoot, graph, collection) {
26298
26402
  `);
26299
26403
  const skippedList = collection.skippedDirectories.length > 0 ? collection.skippedDirectories.slice(0, 30).map((dir) => `- \`${dir}\``).join(`
26300
26404
  `) : "- none";
26301
- const summaryPath = path70.join(artifactsDir, "summary.md");
26405
+ const summaryPath = path71.join(artifactsDir, "summary.md");
26302
26406
  const content = `# gdgraph Summary
26303
26407
 
26304
26408
  ## Stats
@@ -26379,7 +26483,7 @@ function groupBy(items, getKey) {
26379
26483
  }
26380
26484
  function unresolvedType(specifier) {
26381
26485
  const stripped = stripImportSuffix(specifier);
26382
- const extension = path70.posix.extname(stripped);
26486
+ const extension = path71.posix.extname(stripped);
26383
26487
  if (extension) {
26384
26488
  return extension;
26385
26489
  }
@@ -26389,13 +26493,13 @@ function unresolvedType(specifier) {
26389
26493
  return "package";
26390
26494
  }
26391
26495
  function normalizePath2(value) {
26392
- return value.split(path70.sep).join("/");
26496
+ return value.split(path71.sep).join("/");
26393
26497
  }
26394
26498
 
26395
26499
  // src/gdgraph/target.ts
26396
- import path71 from "path";
26500
+ import path72 from "path";
26397
26501
  function normalizeTarget(target) {
26398
- return target.replace(/^\.\//, "").split(path71.sep).join("/");
26502
+ return target.replace(/^\.\//, "").split(path72.sep).join("/");
26399
26503
  }
26400
26504
  function resolveGraphTarget(graph, target) {
26401
26505
  const normalized = normalizeTarget(target);
@@ -26488,15 +26592,15 @@ init_config3();
26488
26592
 
26489
26593
  // src/gdgraph/query.ts
26490
26594
  import { readFile as readFile36 } from "fs/promises";
26491
- import path72 from "path";
26595
+ import path73 from "path";
26492
26596
  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"));
26597
+ const storageDir = path73.join(projectRoot, ".metaproject", "data", "gdgraph", "storage");
26598
+ const nodes = await readJsonl(path73.join(storageDir, "nodes.jsonl"));
26599
+ const edges = await readJsonl(path73.join(storageDir, "edges.jsonl"));
26600
+ const symbols = await readJsonl(path73.join(storageDir, "symbols.jsonl"));
26601
+ const calls = await readJsonl(path73.join(storageDir, "calls.jsonl"));
26602
+ const wikiPages = await readJsonl(path73.join(storageDir, "wiki-pages.jsonl"));
26603
+ const describes = await readJsonl(path73.join(storageDir, "describes.jsonl"));
26500
26604
  const graph = { nodes, edges };
26501
26605
  if (symbols.length > 0) {
26502
26606
  graph.symbols = symbols;
@@ -26556,7 +26660,7 @@ async function bunfigPreloadRoots(projectRoot) {
26556
26660
  const roots = new Set;
26557
26661
  let text;
26558
26662
  try {
26559
- text = await readFile36(path72.join(projectRoot, "bunfig.toml"), "utf8");
26663
+ text = await readFile36(path73.join(projectRoot, "bunfig.toml"), "utf8");
26560
26664
  } catch {
26561
26665
  return roots;
26562
26666
  }
@@ -26570,8 +26674,8 @@ async function bunfigPreloadRoots(projectRoot) {
26570
26674
  if (raw.length === 0) {
26571
26675
  continue;
26572
26676
  }
26573
- const absolute = path72.resolve(projectRoot, raw);
26574
- const relative = path72.relative(projectRoot, absolute).split(path72.sep).join("/");
26677
+ const absolute = path73.resolve(projectRoot, raw);
26678
+ const relative = path73.relative(projectRoot, absolute).split(path73.sep).join("/");
26575
26679
  roots.add(relative);
26576
26680
  }
26577
26681
  }
@@ -26644,7 +26748,7 @@ function canonicalCycle(cycle) {
26644
26748
 
26645
26749
  // src/gdgraph/repomap.ts
26646
26750
  import { mkdir as mkdir21, writeFile as writeFile15 } from "fs/promises";
26647
- import path73 from "path";
26751
+ import path74 from "path";
26648
26752
 
26649
26753
  // src/gdgraph/pagerank.ts
26650
26754
  function personalizedPageRank(nodes, edges, options) {
@@ -26755,7 +26859,7 @@ function overflowContent(required, missing, budget) {
26755
26859
  `);
26756
26860
  }
26757
26861
  function repomapArtifactPath(cwd) {
26758
- return path73.join(cwd, ".metaproject", "data", "gdgraph", "artifacts", "repomap.md");
26862
+ return path74.join(cwd, ".metaproject", "data", "gdgraph", "artifacts", "repomap.md");
26759
26863
  }
26760
26864
  function buildRankEdges(graph, config) {
26761
26865
  const edges = [];
@@ -26900,7 +27004,7 @@ function computeRepomap(graph, config, options = {}) {
26900
27004
  async function writeRepomap(cwd, graph, config, options = {}) {
26901
27005
  const result = computeRepomap(graph, config, options);
26902
27006
  const artifactPath = repomapArtifactPath(cwd);
26903
- await mkdir21(path73.dirname(artifactPath), { recursive: true });
27007
+ await mkdir21(path74.dirname(artifactPath), { recursive: true });
26904
27008
  await writeFile15(artifactPath, result.content, "utf8");
26905
27009
  return { ...result, path: artifactPath };
26906
27010
  }
@@ -26983,12 +27087,12 @@ init_section_tombstone();
26983
27087
  // src/forgetting/journal.ts
26984
27088
  init_fs();
26985
27089
  import { appendFile as appendFile4, mkdir as mkdir22, readFile as readFile37, stat as stat11 } from "fs/promises";
26986
- import path74 from "path";
27090
+ import path75 from "path";
26987
27091
  function forgettingDataDir(cwd) {
26988
- return path74.join(cwd, ".metaproject", "data", "forgetting");
27092
+ return path75.join(cwd, ".metaproject", "data", "forgetting");
26989
27093
  }
26990
27094
  function deletionJournalPath(cwd) {
26991
- return path74.join(forgettingDataDir(cwd), "journal.jsonl");
27095
+ return path75.join(forgettingDataDir(cwd), "journal.jsonl");
26992
27096
  }
26993
27097
  async function readDeletionJournal(cwd) {
26994
27098
  const file = deletionJournalPath(cwd);
@@ -27407,12 +27511,12 @@ __export(exports_service7, {
27407
27511
  gateExitCode: () => gateExitCode,
27408
27512
  readWikiFreshnessMetric: () => readWikiFreshnessMetric
27409
27513
  });
27410
- import path94 from "path";
27514
+ import path95 from "path";
27411
27515
 
27412
27516
  // src/health/config.ts
27413
27517
  init_fs();
27414
27518
  init_json();
27415
- import path75 from "path";
27519
+ import path76 from "path";
27416
27520
  var DEFAULT_HEALTH_CONFIG = {
27417
27521
  schemaVersion: 2,
27418
27522
  ignore: {
@@ -27468,7 +27572,7 @@ var DEFAULT_HEALTH_CONFIG = {
27468
27572
  }
27469
27573
  };
27470
27574
  function configPath2(cwd) {
27471
- return path75.join(cwd, ".metaproject", "health.config.json");
27575
+ return path76.join(cwd, ".metaproject", "health.config.json");
27472
27576
  }
27473
27577
  var STRICTEST_GATE = {
27474
27578
  failOnPriorities: ["P0", "P1", "P2", "P3"],
@@ -27519,7 +27623,7 @@ async function loadHealthConfig(cwd) {
27519
27623
  // src/health/run.ts
27520
27624
  init_fs();
27521
27625
  import { mkdir as mkdir26, writeFile as writeFile19 } from "fs/promises";
27522
- import path93 from "path";
27626
+ import path94 from "path";
27523
27627
 
27524
27628
  // src/metrics/provenance.ts
27525
27629
  async function collectGitProvenance(cwd) {
@@ -27619,12 +27723,12 @@ function computeGate2(input) {
27619
27723
  }
27620
27724
 
27621
27725
  // src/health/scopes.ts
27622
- import path78 from "path";
27726
+ import path79 from "path";
27623
27727
 
27624
27728
  // src/health/util.ts
27625
27729
  init_fs();
27626
27730
  import { mkdir as mkdir23, readFile as readFile38, readdir as readdir14, writeFile as writeFile16 } from "fs/promises";
27627
- import path76 from "path";
27731
+ import path77 from "path";
27628
27732
  var IGNORED_DIRS = new Set([
27629
27733
  "node_modules",
27630
27734
  ".git",
@@ -27668,14 +27772,14 @@ async function toolVersion(command, cwd) {
27668
27772
  }
27669
27773
  }
27670
27774
  function dataRoot3(cwd) {
27671
- return path76.join(cwd, ".metaproject", "data", "health");
27775
+ return path77.join(cwd, ".metaproject", "data", "health");
27672
27776
  }
27673
27777
  async function writeRaw(cwd, source, content, stamp) {
27674
- const dir = path76.join(dataRoot3(cwd), "raw", source);
27778
+ const dir = path77.join(dataRoot3(cwd), "raw", source);
27675
27779
  await mkdir23(dir, { recursive: true });
27676
- const file = path76.join(dir, `${stamp}.log`);
27780
+ const file = path77.join(dir, `${stamp}.log`);
27677
27781
  await writeFile16(file, content, "utf8");
27678
- return path76.relative(cwd, file);
27782
+ return path77.relative(cwd, file);
27679
27783
  }
27680
27784
  async function listSourceFiles(cwd, ignorePaths = []) {
27681
27785
  const { files } = await listSourceFilesWithReasons(cwd, ignorePaths);
@@ -27695,7 +27799,7 @@ async function walk2(root, dir, out, incompleteReasons) {
27695
27799
  try {
27696
27800
  entries = await readdir14(dir, { withFileTypes: true });
27697
27801
  } catch (error) {
27698
- incompleteReasons.push(`${path76.relative(root, dir) || "."}: ${error instanceof Error ? error.message : String(error)}`);
27802
+ incompleteReasons.push(`${path77.relative(root, dir) || "."}: ${error instanceof Error ? error.message : String(error)}`);
27699
27803
  return;
27700
27804
  }
27701
27805
  for (const entry of entries) {
@@ -27703,14 +27807,14 @@ async function walk2(root, dir, out, incompleteReasons) {
27703
27807
  if (entry.isDirectory() && !IGNORED_DIRS.has(entry.name)) {}
27704
27808
  continue;
27705
27809
  }
27706
- const abs = path76.join(dir, entry.name);
27810
+ const abs = path77.join(dir, entry.name);
27707
27811
  if (entry.isDirectory()) {
27708
27812
  if (IGNORED_DIRS.has(entry.name)) {
27709
27813
  continue;
27710
27814
  }
27711
27815
  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));
27816
+ } else if (entry.isFile() && SOURCE_EXT.has(path77.extname(entry.name))) {
27817
+ out.push(path77.relative(root, abs));
27714
27818
  }
27715
27819
  }
27716
27820
  }
@@ -27725,7 +27829,7 @@ function moduleOfFile(file) {
27725
27829
  return null;
27726
27830
  }
27727
27831
  function isSourceFile(file) {
27728
- return SOURCE_EXT.has(path76.extname(file));
27832
+ return SOURCE_EXT.has(path77.extname(file));
27729
27833
  }
27730
27834
  function matchesAnyPattern(file, patterns) {
27731
27835
  const normalized = file.replace(/\\/g, "/").replace(/^\.\//, "");
@@ -27825,7 +27929,7 @@ function rankHotspots(files, churn, sourceAnalysis) {
27825
27929
  // src/health/source-analysis.ts
27826
27930
  init_fs();
27827
27931
  import { readFile as readFile39 } from "fs/promises";
27828
- import path77 from "path";
27932
+ import path78 from "path";
27829
27933
 
27830
27934
  // src/health/metrics/complexity.ts
27831
27935
  var CONTROL_KEYWORDS = new Set([
@@ -28059,7 +28163,7 @@ async function analyzeSourceFiles(cwd, sourceFiles) {
28059
28163
  return new Map(entries.filter((entry) => entry !== null));
28060
28164
  }
28061
28165
  async function analyzeSourceFile(cwd, file) {
28062
- const abs = path77.join(cwd, file);
28166
+ const abs = path78.join(cwd, file);
28063
28167
  if (!await pathExists(abs)) {
28064
28168
  return null;
28065
28169
  }
@@ -28132,14 +28236,14 @@ async function computeMetrics(input) {
28132
28236
  }
28133
28237
  const components = new Map;
28134
28238
  for (const file of sourceFiles) {
28135
- const dir = path78.posix.dirname(file);
28239
+ const dir = path79.posix.dirname(file);
28136
28240
  if (dir === "." || dir === moduleOfFile(file)) {
28137
28241
  continue;
28138
28242
  }
28139
28243
  components.set(dir, [...components.get(dir) ?? [], file]);
28140
28244
  }
28141
28245
  for (const [name, files] of [...components.entries()].sort()) {
28142
- const compFindings = findings.filter((f) => f.file && path78.posix.dirname(f.file) === name);
28246
+ const compFindings = findings.filter((f) => f.file && path79.posix.dirname(f.file) === name);
28143
28247
  scopes.push(build("component", `component:${name}`, name, files, compFindings, averageCoverage(files, coverage)));
28144
28248
  }
28145
28249
  const findingFiles = findings.map((f) => f.file).filter((f) => Boolean(f));
@@ -28184,9 +28288,9 @@ function tally2(values) {
28184
28288
  // src/health/baseline.ts
28185
28289
  init_fs();
28186
28290
  import { mkdir as mkdir24, readFile as readFile40, writeFile as writeFile17 } from "fs/promises";
28187
- import path79 from "path";
28291
+ import path80 from "path";
28188
28292
  function baselinePath(cwd) {
28189
- return path79.join(cwd, ".metaproject", "health", "baselines", "scores.json");
28293
+ return path80.join(cwd, ".metaproject", "health", "baselines", "scores.json");
28190
28294
  }
28191
28295
  async function loadBaseline(cwd) {
28192
28296
  const file = baselinePath(cwd);
@@ -28218,7 +28322,7 @@ async function writeBaseline(cwd, metrics, generatedAt, selector) {
28218
28322
  scopes[key] = value;
28219
28323
  }
28220
28324
  const file = baselinePath(cwd);
28221
- await mkdir24(path79.dirname(file), { recursive: true });
28325
+ await mkdir24(path80.dirname(file), { recursive: true });
28222
28326
  await writeFile17(file, `${JSON.stringify({ generatedAt, scopes }, null, 2)}
28223
28327
  `, "utf8");
28224
28328
  return updated;
@@ -28272,10 +28376,10 @@ async function getChurn(cwd, windowDays) {
28272
28376
 
28273
28377
  // src/health/metrics/wiki-freshness.ts
28274
28378
  import { readFile as readFile41, stat as stat12 } from "fs/promises";
28275
- import path80 from "path";
28379
+ import path81 from "path";
28276
28380
  var DEFAULT_STALE_EVIDENCE_DAYS = 7;
28277
28381
  function freshnessReportPath(cwd) {
28278
- return path80.join(cwd, ".metaproject", "data", "wiki", "freshness", "latest.json");
28382
+ return path81.join(cwd, ".metaproject", "data", "wiki", "freshness", "latest.json");
28279
28383
  }
28280
28384
  async function readWikiFreshnessMetric(cwd, options = {}) {
28281
28385
  const file = freshnessReportPath(cwd);
@@ -28296,7 +28400,7 @@ async function readWikiFreshnessMetric(cwd, options = {}) {
28296
28400
  } catch {
28297
28401
  return {
28298
28402
  status: "unreadable-report",
28299
- reason: `${path80.relative(cwd, file)} is not valid JSON; re-run \`keryx wiki freshness\`.`
28403
+ reason: `${path81.relative(cwd, file)} is not valid JSON; re-run \`keryx wiki freshness\`.`
28300
28404
  };
28301
28405
  }
28302
28406
  const report = parsed;
@@ -28306,7 +28410,7 @@ async function readWikiFreshnessMetric(cwd, options = {}) {
28306
28410
  if (pagesTotal === null || pagesFresh === null) {
28307
28411
  return {
28308
28412
  status: "unreadable-report",
28309
- reason: `${path80.relative(cwd, file)} is missing its totals; re-run \`keryx wiki freshness\`.`
28413
+ reason: `${path81.relative(cwd, file)} is missing its totals; re-run \`keryx wiki freshness\`.`
28310
28414
  };
28311
28415
  }
28312
28416
  const pagesUndecidable = numberOr2(totals.pagesUndecidable) ?? 0;
@@ -28360,12 +28464,12 @@ function renderWikiFreshnessLine(metric) {
28360
28464
  }
28361
28465
 
28362
28466
  // src/health/sources/helpers.ts
28363
- import path81 from "path";
28467
+ import path82 from "path";
28364
28468
  import { existsSync as existsSync7 } from "fs";
28365
28469
  class NoImportError extends Error {
28366
28470
  }
28367
28471
  function resolveBin(cwd, name) {
28368
- const local = path81.join(cwd, "node_modules", ".bin", name);
28472
+ const local = path82.join(cwd, "node_modules", ".bin", name);
28369
28473
  if (existsSync7(local)) {
28370
28474
  return local;
28371
28475
  }
@@ -28446,13 +28550,13 @@ async function getComplexityFindings(cwd, sourceFiles, config, sourceAnalysis) {
28446
28550
 
28447
28551
  // src/health/metrics/coverage.ts
28448
28552
  import { existsSync as existsSync8 } from "fs";
28449
- import path82 from "path";
28553
+ import path83 from "path";
28450
28554
  var SUMMARY_PATHS = [
28451
28555
  "coverage/coverage-summary.json",
28452
28556
  "coverage/coverage-final.json"
28453
28557
  ];
28454
28558
  async function getCoverage(cwd) {
28455
- const summary = SUMMARY_PATHS.map((rel) => path82.join(cwd, rel)).find((abs) => existsSync8(abs));
28559
+ const summary = SUMMARY_PATHS.map((rel) => path83.join(cwd, rel)).find((abs) => existsSync8(abs));
28456
28560
  if (!summary) {
28457
28561
  return { status: "missing", total: null, byFile: new Map };
28458
28562
  }
@@ -28473,7 +28577,7 @@ async function getCoverage(cwd) {
28473
28577
  total = pct;
28474
28578
  continue;
28475
28579
  }
28476
- const relative = path82.isAbsolute(key) ? path82.relative(cwd, key) : key;
28580
+ const relative = path83.isAbsolute(key) ? path83.relative(cwd, key) : key;
28477
28581
  byFile.set(relative.replace(/\\/g, "/"), pct);
28478
28582
  }
28479
28583
  return { status: "available", total, byFile };
@@ -28606,10 +28710,10 @@ function renderWikiFreshness(metric) {
28606
28710
  // src/health/skills.ts
28607
28711
  init_fs();
28608
28712
  import { readFile as readFile42 } from "fs/promises";
28609
- import path83 from "path";
28713
+ import path84 from "path";
28610
28714
  var EMPTY = { skills: [], skillForFile: () => null };
28611
28715
  async function loadSkillOwnership(cwd) {
28612
- const manifestPath = path83.join(cwd, ".metaproject", "metaproject.json");
28716
+ const manifestPath = path84.join(cwd, ".metaproject", "metaproject.json");
28613
28717
  if (!await pathExists(manifestPath)) {
28614
28718
  return EMPTY;
28615
28719
  }
@@ -28647,7 +28751,7 @@ function normalize(value) {
28647
28751
 
28648
28752
  // src/health/sources/eslint.ts
28649
28753
  import { existsSync as existsSync9 } from "fs";
28650
- import path84 from "path";
28754
+ import path85 from "path";
28651
28755
  var CONFIG_FILES = [
28652
28756
  ".eslintrc",
28653
28757
  ".eslintrc.js",
@@ -28661,7 +28765,7 @@ var CONFIG_FILES = [
28661
28765
  "eslint.config.ts"
28662
28766
  ];
28663
28767
  function hasConfig(cwd) {
28664
- return CONFIG_FILES.some((file) => existsSync9(path84.join(cwd, file)));
28768
+ return CONFIG_FILES.some((file) => existsSync9(path85.join(cwd, file)));
28665
28769
  }
28666
28770
  var eslintAdapter = {
28667
28771
  id: "eslint",
@@ -28686,7 +28790,7 @@ var eslintAdapter = {
28686
28790
  };
28687
28791
  },
28688
28792
  async import(ctx) {
28689
- const report = path84.join(ctx.cwd, "eslint-report.json");
28793
+ const report = path85.join(ctx.cwd, "eslint-report.json");
28690
28794
  if (!existsSync9(report)) {
28691
28795
  throw new NoImportError("no eslint-report.json");
28692
28796
  }
@@ -28713,7 +28817,7 @@ var eslintAdapter = {
28713
28817
  }
28714
28818
  const findings = [];
28715
28819
  for (const file of data) {
28716
- const relative = path84.isAbsolute(file.filePath) ? path84.relative(ctx.cwd, file.filePath) : file.filePath;
28820
+ const relative = path85.isAbsolute(file.filePath) ? path85.relative(ctx.cwd, file.filePath) : file.filePath;
28717
28821
  for (const message of file.messages ?? []) {
28718
28822
  const isError = message.severity === 2;
28719
28823
  findings.push(makeFinding({
@@ -28745,9 +28849,9 @@ var eslintAdapter = {
28745
28849
 
28746
28850
  // src/health/sources/typescript.ts
28747
28851
  import { existsSync as existsSync10 } from "fs";
28748
- import path85 from "path";
28852
+ import path86 from "path";
28749
28853
  function hasTsconfig(cwd) {
28750
- return existsSync10(path85.join(cwd, "tsconfig.json"));
28854
+ return existsSync10(path86.join(cwd, "tsconfig.json"));
28751
28855
  }
28752
28856
  var typescriptAdapter = {
28753
28857
  id: "typescript",
@@ -28823,7 +28927,7 @@ __export(exports_service6, {
28823
28927
  });
28824
28928
  import { existsSync as existsSync11 } from "fs";
28825
28929
  import { readFile as readFile45, readdir as readdir15 } from "fs/promises";
28826
- import path90 from "path";
28930
+ import path91 from "path";
28827
28931
 
28828
28932
  // src/lib/git-env.ts
28829
28933
  var GIT_DISCOVERY_OVERRIDE_VARS = [
@@ -28848,7 +28952,7 @@ function withoutGitDiscoveryOverrides(env) {
28848
28952
  init_fs();
28849
28953
  init_guard();
28850
28954
  import { readFile as readFile43 } from "fs/promises";
28851
- import path86 from "path";
28955
+ import path87 from "path";
28852
28956
 
28853
28957
  // src/metrics/record.ts
28854
28958
  var RELIABILITIES = new Set(["exact", "estimated", "unknown"]);
@@ -28863,7 +28967,7 @@ var RETRY_TYPES = new Set([
28863
28967
 
28864
28968
  // src/metrics/lifecycle.ts
28865
28969
  async function readArtifactPointer(root, expected) {
28866
- const pointerFile = path86.join(root, "latest.json");
28970
+ const pointerFile = path87.join(root, "latest.json");
28867
28971
  if (!await pathExists(pointerFile))
28868
28972
  return { status: "missing", pointer: null };
28869
28973
  let pointer;
@@ -28872,7 +28976,7 @@ async function readArtifactPointer(root, expected) {
28872
28976
  } catch {
28873
28977
  return { status: "stale", pointer: null, reason: "latest pointer is invalid JSON" };
28874
28978
  }
28875
- const recordFile = pointer.record ? path86.join(root, pointer.record) : null;
28979
+ const recordFile = pointer.record ? path87.join(root, pointer.record) : null;
28876
28980
  if (!recordFile || !isPathInside(root, recordFile) || !await pathExists(recordFile)) {
28877
28981
  return { status: "stale", pointer, reason: "pointer record is missing" };
28878
28982
  }
@@ -28888,9 +28992,9 @@ init_guard();
28888
28992
  // src/testing/capability.ts
28889
28993
  init_fs();
28890
28994
  init_json();
28891
- import path87 from "path";
28995
+ import path88 from "path";
28892
28996
  async function isTestingCapabilityEnabled(cwd, capability) {
28893
- const manifestPath = path87.join(cwd, ".metaproject", "metaproject.json");
28997
+ const manifestPath = path88.join(cwd, ".metaproject", "metaproject.json");
28894
28998
  if (!await pathExists(manifestPath)) {
28895
28999
  return false;
28896
29000
  }
@@ -28916,10 +29020,10 @@ async function isTestingCapabilityEnabled(cwd, capability) {
28916
29020
  init_fs();
28917
29021
  init_guard();
28918
29022
  import { readFile as readFile44, mkdir as mkdir25, writeFile as writeFile18 } from "fs/promises";
28919
- import path88 from "path";
29023
+ import path89 from "path";
28920
29024
  var COVERAGE_MAP_SCHEMA_VERSION = 1;
28921
29025
  function coverageMapPath(cwd, cfg) {
28922
- return path88.isAbsolute(cfg.coverageMap.artifact) ? cfg.coverageMap.artifact : path88.join(cwd, cfg.coverageMap.artifact);
29026
+ return path89.isAbsolute(cfg.coverageMap.artifact) ? cfg.coverageMap.artifact : path89.join(cwd, cfg.coverageMap.artifact);
28923
29027
  }
28924
29028
  async function loadCoverageMap(cwd, cfg) {
28925
29029
  const file = coverageMapPath(cwd, cfg);
@@ -28993,20 +29097,20 @@ function normalizePath4(file) {
28993
29097
  }
28994
29098
 
28995
29099
  // src/testing/selection.ts
28996
- import path89 from "path";
29100
+ import path90 from "path";
28997
29101
  var TEST_FILE_RE = /(^|\/)(__tests__\/.*|.*\.(test|spec)\.[cm]?[tj]sx?$|e2e\/.*\.[cm]?[tj]sx?$|tests\/.*\.[cm]?[tj]sx?$)/;
28998
29102
  function normalizePath5(file) {
28999
29103
  return file.replace(/\\/g, "/").replace(/^\.\//, "");
29000
29104
  }
29001
29105
  function relatedByNamingAndDirectory(target, testFiles) {
29002
29106
  const normalized = normalizePath5(target);
29003
- const ext = path89.extname(normalized);
29107
+ const ext = path90.extname(normalized);
29004
29108
  const withoutExt = ext ? normalized.slice(0, -ext.length) : normalized;
29005
- const base = path89.basename(withoutExt);
29006
- const dir = path89.dirname(normalized);
29109
+ const base = path90.basename(withoutExt);
29110
+ const dir = path90.dirname(normalized);
29007
29111
  return testFiles.filter((file) => {
29008
- const fileDir = path89.dirname(file);
29009
- const fileBase = path89.basename(file);
29112
+ const fileDir = path90.dirname(file);
29113
+ const fileBase = path90.basename(file);
29010
29114
  return file.startsWith(`${withoutExt}.`) || file.includes(`${withoutExt}.`) || fileDir === dir && fileBase.startsWith(`${base}.`) || fileDir.startsWith(dir) && fileBase.includes(base);
29011
29115
  }).sort();
29012
29116
  }
@@ -29136,7 +29240,7 @@ var DEFAULT_TESTING_CONFIG = {
29136
29240
  }
29137
29241
  };
29138
29242
  function testingDataRoot(cwd) {
29139
- return path90.join(cwd, ".metaproject", "data", "testing");
29243
+ return path91.join(cwd, ".metaproject", "data", "testing");
29140
29244
  }
29141
29245
  async function computeTestingContext(cwd) {
29142
29246
  const { files, incompleteReasons } = await listProjectFiles(cwd);
@@ -29311,7 +29415,7 @@ async function runTesting(input) {
29311
29415
  return runResult;
29312
29416
  }
29313
29417
  async function loadTestingContext(cwd) {
29314
- const file = path90.join(testingDataRoot(cwd), "context.json");
29418
+ const file = path91.join(testingDataRoot(cwd), "context.json");
29315
29419
  if (!await pathExists(file)) {
29316
29420
  return null;
29317
29421
  }
@@ -29322,18 +29426,18 @@ async function loadTestingContext(cwd) {
29322
29426
  }
29323
29427
  }
29324
29428
  async function loadTestingReport(cwd) {
29325
- const file = path90.join(testingDataRoot(cwd), "artifacts", "latest.json");
29429
+ const file = path91.join(testingDataRoot(cwd), "artifacts", "latest.json");
29326
29430
  if (!await pathExists(file)) {
29327
29431
  return null;
29328
29432
  }
29329
29433
  try {
29330
29434
  const latest = JSON.parse(await readFile45(file, "utf8"));
29331
29435
  if (typeof latest.record === "string") {
29332
- const pointer = await readArtifactPointer(path90.join(testingDataRoot(cwd), "artifacts"), await collectGitProvenance(cwd));
29436
+ const pointer = await readArtifactPointer(path91.join(testingDataRoot(cwd), "artifacts"), await collectGitProvenance(cwd));
29333
29437
  if (pointer.status !== "fresh")
29334
29438
  return null;
29335
- const recordFile = path90.join(testingDataRoot(cwd), "artifacts", latest.record);
29336
- if (!isPathInside(path90.join(testingDataRoot(cwd), "artifacts"), recordFile))
29439
+ const recordFile = path91.join(testingDataRoot(cwd), "artifacts", latest.record);
29440
+ if (!isPathInside(path91.join(testingDataRoot(cwd), "artifacts"), recordFile))
29337
29441
  return null;
29338
29442
  if (!await pathExists(recordFile))
29339
29443
  return null;
@@ -29380,28 +29484,28 @@ async function ensureContext(cwd) {
29380
29484
  }
29381
29485
  async function writeContext(cwd, context) {
29382
29486
  const root = testingDataRoot(cwd);
29383
- const rel = (p) => path90.relative(cwd, p);
29487
+ const rel = (p) => path91.relative(cwd, p);
29384
29488
  await mkdirContained(cwd, rel(root));
29385
- await writeContained(cwd, rel(path90.join(root, "context.json")), `${JSON.stringify(context, null, 2)}
29489
+ await writeContained(cwd, rel(path91.join(root, "context.json")), `${JSON.stringify(context, null, 2)}
29386
29490
  `);
29387
- await writeContained(cwd, rel(path90.join(root, "context.md")), renderContextMarkdown(context));
29388
- await writeContained(cwd, rel(path90.join(root, "recommendations.md")), renderRecommendationsMarkdown(context));
29491
+ await writeContained(cwd, rel(path91.join(root, "context.md")), renderContextMarkdown(context));
29492
+ await writeContained(cwd, rel(path91.join(root, "recommendations.md")), renderRecommendationsMarkdown(context));
29389
29493
  }
29390
29494
  async function writeReport(cwd, report) {
29391
29495
  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);
29496
+ const artifacts = path91.join(root, "artifacts");
29497
+ const history = path91.join(root, "history");
29498
+ const rel = (p) => path91.relative(cwd, p);
29395
29499
  await mkdirContained(cwd, rel(artifacts));
29396
29500
  await mkdirContained(cwd, rel(history));
29397
29501
  const stamp = report.generatedAt.replace(/[:.]/g, "-");
29398
- const json = path90.join(artifacts, "latest.json");
29399
- const markdown = path90.join(artifacts, "latest.md");
29502
+ const json = path91.join(artifacts, "latest.json");
29503
+ const markdown = path91.join(artifacts, "latest.md");
29400
29504
  const serialized = `${JSON.stringify(report, null, 2)}
29401
29505
  `;
29402
29506
  if (report.runId) {
29403
- const runJson = path90.join(artifacts, "runs", `${report.runId}.json`);
29404
- const runMarkdown = path90.join(artifacts, "runs", `${report.runId}.md`);
29507
+ const runJson = path91.join(artifacts, "runs", `${report.runId}.json`);
29508
+ const runMarkdown = path91.join(artifacts, "runs", `${report.runId}.md`);
29405
29509
  if (await pathExists(runJson))
29406
29510
  throw new Error(`immutable testing run already exists: ${report.runId}`);
29407
29511
  await writeContained(cwd, rel(runJson), serialized);
@@ -29412,26 +29516,26 @@ async function writeReport(cwd, report) {
29412
29516
  branch: report.provenance?.branch ?? null,
29413
29517
  worktree: report.provenance?.worktree ?? null,
29414
29518
  generated_at: report.generatedAt,
29415
- record: path90.posix.join("runs", `${report.runId}.json`)
29519
+ record: path91.posix.join("runs", `${report.runId}.json`)
29416
29520
  }, null, 2)}
29417
29521
  `);
29418
29522
  } else {
29419
29523
  await writeContained(cwd, rel(json), serialized);
29420
29524
  }
29421
29525
  await writeContained(cwd, rel(markdown), renderReportMarkdown3(report));
29422
- await writeContained(cwd, rel(path90.join(history, `${stamp}.json`)), serialized);
29526
+ await writeContained(cwd, rel(path91.join(history, `${stamp}.json`)), serialized);
29423
29527
  return {
29424
- markdownPath: path90.relative(cwd, markdown),
29425
- jsonPath: path90.relative(cwd, json)
29528
+ markdownPath: path91.relative(cwd, markdown),
29529
+ jsonPath: path91.relative(cwd, json)
29426
29530
  };
29427
29531
  }
29428
29532
  async function writeRawLog(cwd, raw) {
29429
- const logs = path90.join(testingDataRoot(cwd), "logs");
29430
- const rel = (p) => path90.relative(cwd, p);
29533
+ const logs = path91.join(testingDataRoot(cwd), "logs");
29534
+ const rel = (p) => path91.relative(cwd, p);
29431
29535
  await mkdirContained(cwd, rel(logs));
29432
- const latest = path90.join(logs, "latest.raw.log");
29536
+ const latest = path91.join(logs, "latest.raw.log");
29433
29537
  await writeContained(cwd, rel(latest), raw);
29434
- return path90.relative(cwd, latest);
29538
+ return path91.relative(cwd, latest);
29435
29539
  }
29436
29540
  async function listProjectFiles(cwd) {
29437
29541
  const out = [];
@@ -29444,11 +29548,11 @@ async function walk3(root, dir, out, incompleteReasons) {
29444
29548
  try {
29445
29549
  entries = await readdir15(dir, { withFileTypes: true });
29446
29550
  } catch (error) {
29447
- incompleteReasons.push(`${normalizePath6(path90.relative(root, dir)) || "."}: ${error instanceof Error ? error.message : String(error)}`);
29551
+ incompleteReasons.push(`${normalizePath6(path91.relative(root, dir)) || "."}: ${error instanceof Error ? error.message : String(error)}`);
29448
29552
  return;
29449
29553
  }
29450
29554
  for (const entry of entries) {
29451
- const abs = path90.join(dir, entry.name);
29555
+ const abs = path91.join(dir, entry.name);
29452
29556
  if (entry.isDirectory()) {
29453
29557
  if (IGNORED_DIRS2.has(entry.name) || entry.name.startsWith(".tmp-")) {
29454
29558
  continue;
@@ -29457,12 +29561,12 @@ async function walk3(root, dir, out, incompleteReasons) {
29457
29561
  continue;
29458
29562
  }
29459
29563
  if (entry.isFile()) {
29460
- out.push(normalizePath6(path90.relative(root, abs)));
29564
+ out.push(normalizePath6(path91.relative(root, abs)));
29461
29565
  }
29462
29566
  }
29463
29567
  }
29464
29568
  async function readPackageJson(cwd) {
29465
- const file = path90.join(cwd, "package.json");
29569
+ const file = path91.join(cwd, "package.json");
29466
29570
  if (!await pathExists(file)) {
29467
29571
  return null;
29468
29572
  }
@@ -29473,7 +29577,7 @@ async function readPackageJson(cwd) {
29473
29577
  }
29474
29578
  }
29475
29579
  async function loadTestingConfig(cwd) {
29476
- const file = path90.join(cwd, ".metaproject", "testing.config.json");
29580
+ const file = path91.join(cwd, ".metaproject", "testing.config.json");
29477
29581
  if (!await pathExists(file)) {
29478
29582
  return DEFAULT_TESTING_CONFIG;
29479
29583
  }
@@ -29538,7 +29642,7 @@ function detectFrameworks(input) {
29538
29642
  async function extractConventions(cwd, files) {
29539
29643
  const conventions = new Set;
29540
29644
  for (const file of files.slice(0, 40)) {
29541
- const abs = path90.join(cwd, file);
29645
+ const abs = path91.join(cwd, file);
29542
29646
  if (!await pathExists(abs)) {
29543
29647
  continue;
29544
29648
  }
@@ -29668,7 +29772,7 @@ async function findTestsByImportedTargets(cwd, targets, testFiles) {
29668
29772
  const targetKeys = new Set(targets.map((target) => modulePathKey(normalizePath6(target))));
29669
29773
  const selected = new Set;
29670
29774
  for (const testFile of testFiles) {
29671
- const absoluteTest = path90.join(cwd, testFile);
29775
+ const absoluteTest = path91.join(cwd, testFile);
29672
29776
  if (!await pathExists(absoluteTest)) {
29673
29777
  continue;
29674
29778
  }
@@ -29702,10 +29806,10 @@ function resolveImportPath(cwd, testFile, importPath) {
29702
29806
  if (!importPath.startsWith(".")) {
29703
29807
  return null;
29704
29808
  }
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 === "..") {
29809
+ const importerDir = path91.dirname(testFile);
29810
+ const absoluteResolved = path91.resolve(path91.join(cwd, importerDir), importPath);
29811
+ const relative = path91.relative(cwd, absoluteResolved);
29812
+ if (relative.startsWith(`..${path91.sep}`) || relative === "..") {
29709
29813
  return null;
29710
29814
  }
29711
29815
  const relativeNormalized = normalizePath6(relative);
@@ -29757,13 +29861,13 @@ function resolveTestCommand(cwd, context, input) {
29757
29861
  }
29758
29862
  var BUN_LOCKFILES = ["bun.lock", "bun.lockb"];
29759
29863
  function detectPackageManager(cwd) {
29760
- if (resolveBunBin() && BUN_LOCKFILES.some((name) => pathExistsSync(path90.join(cwd, name)))) {
29864
+ if (resolveBunBin() && BUN_LOCKFILES.some((name) => pathExistsSync(path91.join(cwd, name)))) {
29761
29865
  return "bun";
29762
29866
  }
29763
- if (Bun.which("pnpm") && pathExistsSync(path90.join(cwd, "pnpm-lock.yaml"))) {
29867
+ if (Bun.which("pnpm") && pathExistsSync(path91.join(cwd, "pnpm-lock.yaml"))) {
29764
29868
  return "pnpm";
29765
29869
  }
29766
- if (Bun.which("yarn") && pathExistsSync(path90.join(cwd, "yarn.lock"))) {
29870
+ if (Bun.which("yarn") && pathExistsSync(path91.join(cwd, "yarn.lock"))) {
29767
29871
  return "yarn";
29768
29872
  }
29769
29873
  return "npm";
@@ -30103,7 +30207,7 @@ async function compatibleReportForHealth(ctx) {
30103
30207
 
30104
30208
  // src/health/sources/dependency-audit.ts
30105
30209
  import { existsSync as existsSync12 } from "fs";
30106
- import path91 from "path";
30210
+ import path92 from "path";
30107
30211
  function auditSeverityToPriority(severity) {
30108
30212
  if (severity === "critical" || severity === "high")
30109
30213
  return "P0";
@@ -30222,7 +30326,7 @@ var LOCKFILE_COMMANDS = [
30222
30326
  ];
30223
30327
  function auditCommand(cwd) {
30224
30328
  for (const entry of LOCKFILE_COMMANDS) {
30225
- if (!entry.lockfiles.some((name) => existsSync12(path91.join(cwd, name))))
30329
+ if (!entry.lockfiles.some((name) => existsSync12(path92.join(cwd, name))))
30226
30330
  continue;
30227
30331
  const bin = resolveBin(cwd, entry.bin);
30228
30332
  if (bin)
@@ -30281,13 +30385,13 @@ var dependencyAuditAdapter = {
30281
30385
 
30282
30386
  // src/health/sources/sonarqube.ts
30283
30387
  import { existsSync as existsSync13 } from "fs";
30284
- import path92 from "path";
30388
+ import path93 from "path";
30285
30389
  var REPORT_FILES = ["sonar-issues.json", ".metaproject/data/health/sonar-issues.json"];
30286
30390
  function reportPath(cwd) {
30287
30391
  const fromEnv = process.env.SONAR_ISSUES_FILE;
30288
30392
  const candidates = fromEnv ? [fromEnv, ...REPORT_FILES] : REPORT_FILES;
30289
30393
  for (const rel of candidates) {
30290
- const abs = path92.isAbsolute(rel) ? rel : path92.join(cwd, rel);
30394
+ const abs = path93.isAbsolute(rel) ? rel : path93.join(cwd, rel);
30291
30395
  if (existsSync13(abs)) {
30292
30396
  return abs;
30293
30397
  }
@@ -30371,7 +30475,7 @@ var sonarqubeAdapter = {
30371
30475
  function relativizeComponent(component, cwd) {
30372
30476
  const colon = component.indexOf(":");
30373
30477
  const value = colon >= 0 ? component.slice(colon + 1) : component;
30374
- return path92.isAbsolute(value) ? path92.relative(cwd, value) : value;
30478
+ return path93.isAbsolute(value) ? path93.relative(cwd, value) : value;
30375
30479
  }
30376
30480
 
30377
30481
  // src/health/sources/index.ts
@@ -30708,19 +30812,19 @@ function filteredInfo(source, cfg) {
30708
30812
  };
30709
30813
  }
30710
30814
  async function writeOutputs(cwd, report, config, stamp) {
30711
- const artifacts = path93.join(dataRoot3(cwd), "artifacts");
30712
- const history = path93.join(dataRoot3(cwd), "history");
30815
+ const artifacts = path94.join(dataRoot3(cwd), "artifacts");
30816
+ const history = path94.join(dataRoot3(cwd), "history");
30713
30817
  await mkdir26(artifacts, { recursive: true });
30714
30818
  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`);
30819
+ const markdown = path94.join(artifacts, "latest.md");
30820
+ const json = path94.join(artifacts, "latest.json");
30821
+ const historyJson = path94.join(history, `${stamp}.json`);
30718
30822
  const serialized = `${JSON.stringify(report, null, 2)}
30719
30823
  `;
30720
30824
  await writeFile19(markdown, renderReportMarkdown2(report, config), "utf8");
30721
30825
  if (report.runId) {
30722
- const runJson = path93.join(artifacts, "runs", `${report.runId}.json`);
30723
- const runMarkdown = path93.join(artifacts, "runs", `${report.runId}.md`);
30826
+ const runJson = path94.join(artifacts, "runs", `${report.runId}.json`);
30827
+ const runMarkdown = path94.join(artifacts, "runs", `${report.runId}.md`);
30724
30828
  if (await pathExists(runJson))
30725
30829
  throw new Error(`immutable health run already exists: ${report.runId}`);
30726
30830
  await writeFileAtomic(runJson, serialized);
@@ -30731,7 +30835,7 @@ async function writeOutputs(cwd, report, config, stamp) {
30731
30835
  branch: report.provenance?.branch ?? null,
30732
30836
  worktree: report.provenance?.worktree ?? null,
30733
30837
  generated_at: report.generatedAt,
30734
- record: path93.posix.join("runs", `${report.runId}.json`)
30838
+ record: path94.posix.join("runs", `${report.runId}.json`)
30735
30839
  }, null, 2)}
30736
30840
  `);
30737
30841
  } else {
@@ -30739,8 +30843,8 @@ async function writeOutputs(cwd, report, config, stamp) {
30739
30843
  }
30740
30844
  await writeFile19(historyJson, serialized, "utf8");
30741
30845
  return {
30742
- markdownPath: path93.relative(cwd, markdown),
30743
- jsonPath: path93.relative(cwd, json)
30846
+ markdownPath: path94.relative(cwd, markdown),
30847
+ jsonPath: path94.relative(cwd, json)
30744
30848
  };
30745
30849
  }
30746
30850
  async function resolveChanged(cwd, selector) {
@@ -30793,7 +30897,7 @@ function hasGateShape(value) {
30793
30897
  return Array.isArray(report.metrics) && Array.isArray(report.sources) && Array.isArray(report.findings);
30794
30898
  }
30795
30899
  async function readLatest(cwd) {
30796
- const file = path94.join(dataRoot3(cwd), "artifacts", "latest.json");
30900
+ const file = path95.join(dataRoot3(cwd), "artifacts", "latest.json");
30797
30901
  if (!await pathExists(file)) {
30798
30902
  return null;
30799
30903
  }
@@ -30804,11 +30908,11 @@ async function readLatest(cwd) {
30804
30908
  const latest = read.value;
30805
30909
  const record = latest.record;
30806
30910
  if (typeof record === "string") {
30807
- const pointer = await readArtifactPointer(path94.join(dataRoot3(cwd), "artifacts"), await collectGitProvenance(cwd));
30911
+ const pointer = await readArtifactPointer(path95.join(dataRoot3(cwd), "artifacts"), await collectGitProvenance(cwd));
30808
30912
  if (pointer.status !== "fresh")
30809
30913
  return null;
30810
- const recordFile = path94.join(dataRoot3(cwd), "artifacts", record);
30811
- if (!isPathInside(path94.join(dataRoot3(cwd), "artifacts"), recordFile))
30914
+ const recordFile = path95.join(dataRoot3(cwd), "artifacts", record);
30915
+ if (!isPathInside(path95.join(dataRoot3(cwd), "artifacts"), recordFile))
30812
30916
  return null;
30813
30917
  if (!await pathExists(recordFile))
30814
30918
  return null;
@@ -30881,7 +30985,7 @@ function createCodeHealthService() {
30881
30985
  return {
30882
30986
  run: (input) => runHealth(input),
30883
30987
  async status(input) {
30884
- const enabled = await pathExists(path94.join(input.cwd, ".metaproject", "health.config.json"));
30988
+ const enabled = await pathExists(path95.join(input.cwd, ".metaproject", "health.config.json"));
30885
30989
  const latest = await readLatest(input.cwd);
30886
30990
  const project = latest?.metrics.find((m) => m.key === "project") ?? null;
30887
30991
  const decliningScopes = latest ? latest.metrics.filter((m) => m.regression_score > 0).length : 0;
@@ -31039,10 +31143,10 @@ function renderEvidenceBlock(evidences, siblings) {
31039
31143
  init_fs();
31040
31144
  init_contained_write();
31041
31145
  init_json();
31042
- import path95 from "path";
31146
+ import path96 from "path";
31043
31147
  import { createHash as createHash16 } from "crypto";
31044
31148
  function impactEvidenceDataRoot(root) {
31045
- return path95.join(root, ".metaproject", "data", "security", "impact-evidence");
31149
+ return path96.join(root, ".metaproject", "data", "security", "impact-evidence");
31046
31150
  }
31047
31151
  function sanitizeSessionId(sessionId) {
31048
31152
  const cleaned = sessionId.replace(/[^A-Za-z0-9._-]/g, "_");
@@ -31054,7 +31158,7 @@ function sessionStateFilename(sessionId) {
31054
31158
  return `${sanitized}-${suffix}.json`;
31055
31159
  }
31056
31160
  function sessionStatePath(root, sessionId) {
31057
- return path95.join(impactEvidenceDataRoot(root), "sessions", sessionStateFilename(sessionId));
31161
+ return path96.join(impactEvidenceDataRoot(root), "sessions", sessionStateFilename(sessionId));
31058
31162
  }
31059
31163
  async function loadSessionState(root, sessionId) {
31060
31164
  const file = sessionStatePath(root, sessionId);
@@ -31073,11 +31177,11 @@ async function loadSessionState(root, sessionId) {
31073
31177
  }
31074
31178
  async function saveSessionState(root, sessionId, state) {
31075
31179
  const file = sessionStatePath(root, sessionId);
31076
- await writeContained(root, path95.relative(root, file), `${JSON.stringify(state, null, 2)}
31180
+ await writeContained(root, path96.relative(root, file), `${JSON.stringify(state, null, 2)}
31077
31181
  `);
31078
31182
  }
31079
31183
  function logPath(root) {
31080
- return path95.join(impactEvidenceDataRoot(root), "log.jsonl");
31184
+ return path96.join(impactEvidenceDataRoot(root), "log.jsonl");
31081
31185
  }
31082
31186
  async function appendLogRecord(root, record) {
31083
31187
  const full = {
@@ -31088,7 +31192,7 @@ async function appendLogRecord(root, record) {
31088
31192
  ...record.detail !== undefined ? { detail: record.detail } : {}
31089
31193
  };
31090
31194
  const file = logPath(root);
31091
- await appendContained(root, path95.relative(root, file), `${JSON.stringify(full)}
31195
+ await appendContained(root, path96.relative(root, file), `${JSON.stringify(full)}
31092
31196
  `);
31093
31197
  return full;
31094
31198
  }
@@ -31115,7 +31219,7 @@ init_command_risk();
31115
31219
  init_shell_syntax();
31116
31220
  init_fs();
31117
31221
  init_service2();
31118
- import path96 from "path";
31222
+ import path97 from "path";
31119
31223
  import { createHash as createHash17 } from "crypto";
31120
31224
  import { realpathSync as realpathSync2 } from "fs";
31121
31225
  function impactEvidenceHookClass(strict) {
@@ -31131,29 +31235,29 @@ function realpathNearestExisting(p) {
31131
31235
  for (;; ) {
31132
31236
  try {
31133
31237
  const real = realpathSync2(current);
31134
- return tail.length > 0 ? path96.join(real, ...tail) : real;
31238
+ return tail.length > 0 ? path97.join(real, ...tail) : real;
31135
31239
  } catch {
31136
- const parent = path96.dirname(current);
31240
+ const parent = path97.dirname(current);
31137
31241
  if (parent === current) {
31138
- return tail.length > 0 ? path96.join(current, ...tail) : current;
31242
+ return tail.length > 0 ? path97.join(current, ...tail) : current;
31139
31243
  }
31140
- tail.unshift(path96.basename(current));
31244
+ tail.unshift(path97.basename(current));
31141
31245
  current = parent;
31142
31246
  }
31143
31247
  }
31144
31248
  }
31145
31249
  function normalizeRequestFiles(root, files) {
31146
- const rootReal = realpathNearestExisting(path96.resolve(root));
31250
+ const rootReal = realpathNearestExisting(path97.resolve(root));
31147
31251
  const normalized = [];
31148
31252
  const rejected = [];
31149
31253
  for (const file of files) {
31150
- const lexicalAbsolute = path96.isAbsolute(file) ? path96.resolve(file) : path96.resolve(rootReal, toPosix(file).replace(/^\.\//, ""));
31254
+ const lexicalAbsolute = path97.isAbsolute(file) ? path97.resolve(file) : path97.resolve(rootReal, toPosix(file).replace(/^\.\//, ""));
31151
31255
  const effective = realpathNearestExisting(lexicalAbsolute);
31152
31256
  if (!isPathInside(rootReal, effective)) {
31153
31257
  rejected.push(file);
31154
31258
  continue;
31155
31259
  }
31156
- normalized.push(toPosix(path96.relative(rootReal, effective)));
31260
+ normalized.push(toPosix(path97.relative(rootReal, effective)));
31157
31261
  }
31158
31262
  return { files: [...new Set(normalized)], rejected };
31159
31263
  }
@@ -31439,7 +31543,7 @@ __export(exports_service8, {
31439
31543
  createJobService: () => createJobService
31440
31544
  });
31441
31545
  import { copyFile, mkdir as mkdir28 } from "fs/promises";
31442
- import path99 from "path";
31546
+ import path100 from "path";
31443
31547
 
31444
31548
  // src/job/types.ts
31445
31549
  var JOB_INTENTS = ["implement", "analyze", "review", "custom"];
@@ -31578,12 +31682,12 @@ function defaultPlan(intent) {
31578
31682
  // src/job/store.ts
31579
31683
  init_validator();
31580
31684
  import { appendFile as appendFile5, mkdir as mkdir27, readFile as readFile47, readdir as readdir16 } from "fs/promises";
31581
- import path98 from "path";
31685
+ import path99 from "path";
31582
31686
 
31583
31687
  // src/gdskills/contracts.ts
31584
31688
  import { readFile as readFile46 } from "fs/promises";
31585
31689
  import { existsSync as existsSync14 } from "fs";
31586
- import path97 from "path";
31690
+ import path98 from "path";
31587
31691
  import { fileURLToPath as fileURLToPath2 } from "url";
31588
31692
  var CONTRACTS = [
31589
31693
  {
@@ -31706,10 +31810,10 @@ async function loadSchema(name) {
31706
31810
  return JSON.parse(raw);
31707
31811
  }
31708
31812
  function contractPath(contract) {
31709
- const here = path97.dirname(fileURLToPath2(import.meta.url));
31813
+ const here = path98.dirname(fileURLToPath2(import.meta.url));
31710
31814
  if (contract.sourcePath) {
31711
- for (const root of [path97.join(here, "..", ".."), path97.join(here, ".."), here]) {
31712
- const candidate = path97.resolve(root, contract.sourcePath);
31815
+ for (const root of [path98.join(here, "..", ".."), path98.join(here, ".."), here]) {
31816
+ const candidate = path98.resolve(root, contract.sourcePath);
31713
31817
  if (existsSync14(candidate)) {
31714
31818
  return candidate;
31715
31819
  }
@@ -31719,7 +31823,7 @@ function contractPath(contract) {
31719
31823
  if (existsSync14(directPath)) {
31720
31824
  return directPath;
31721
31825
  }
31722
- const packagedSourcePath = path97.join(here, "..", "src", "gdskills", "contracts", contract.fileName);
31826
+ const packagedSourcePath = path98.join(here, "..", "src", "gdskills", "contracts", contract.fileName);
31723
31827
  if (existsSync14(packagedSourcePath)) {
31724
31828
  return packagedSourcePath;
31725
31829
  }
@@ -31733,13 +31837,13 @@ var SCHEMA_ROOTS = [
31733
31837
  // src/job/store.ts
31734
31838
  init_fs();
31735
31839
  function jobsRoot(cwd) {
31736
- return path98.join(cwd, ".metaproject", "jobs");
31840
+ return path99.join(cwd, ".metaproject", "jobs");
31737
31841
  }
31738
31842
  function jobDir(cwd, name) {
31739
- return path98.join(jobsRoot(cwd), name);
31843
+ return path99.join(jobsRoot(cwd), name);
31740
31844
  }
31741
31845
  function jobStatePath(cwd, name) {
31742
- return path98.join(jobDir(cwd, name), "state.json");
31846
+ return path99.join(jobDir(cwd, name), "state.json");
31743
31847
  }
31744
31848
  var JOB_NAME_PATTERN = /^[a-z0-9-]+$/;
31745
31849
  function assertJobName(name) {
@@ -31776,12 +31880,12 @@ async function writeJob(cwd, name, state) {
31776
31880
  `));
31777
31881
  }
31778
31882
  const file = jobStatePath(cwd, name);
31779
- await mkdir27(path98.dirname(file), { recursive: true });
31883
+ await mkdir27(path99.dirname(file), { recursive: true });
31780
31884
  await writeFileAtomic(file, `${JSON.stringify(state, null, 2)}
31781
31885
  `);
31782
31886
  }
31783
31887
  async function appendJournal2(cwd, name, at, line) {
31784
- await appendFile5(path98.join(jobDir(cwd, name), "journal.md"), `- ${at} - ${line}
31888
+ await appendFile5(path99.join(jobDir(cwd, name), "journal.md"), `- ${at} - ${line}
31785
31889
  `, "utf8");
31786
31890
  }
31787
31891
  function renderJournal2(name, at) {
@@ -31802,7 +31906,7 @@ function assertDocumentType(raw) {
31802
31906
  return raw;
31803
31907
  }
31804
31908
  function documentFileName(type, sourcePath) {
31805
- const extension = path98.extname(sourcePath) || ".md";
31909
+ const extension = path99.extname(sourcePath) || ".md";
31806
31910
  return `${type}${extension}`;
31807
31911
  }
31808
31912
 
@@ -31810,7 +31914,7 @@ function documentFileName(type, sourcePath) {
31810
31914
  function createJobService(deps) {
31811
31915
  const now = () => deps.now().toISOString();
31812
31916
  function lockPath(cwd, name) {
31813
- return path99.join(jobsRoot(cwd), `.job-lock-${name}`);
31917
+ return path100.join(jobsRoot(cwd), `.job-lock-${name}`);
31814
31918
  }
31815
31919
  async function mutate(cwd, name, run) {
31816
31920
  assertJobName(name);
@@ -31859,20 +31963,20 @@ function createJobService(deps) {
31859
31963
  },
31860
31964
  plan: { steps: defaultPlan(intent) },
31861
31965
  documentation: {
31862
- job_path: path99.join(".metaproject", "jobs", name),
31966
+ job_path: path100.join(".metaproject", "jobs", name),
31863
31967
  documents_created: []
31864
31968
  },
31865
31969
  metrics: { steps: [] },
31866
- jobs_root: path99.join(".metaproject", "jobs"),
31970
+ jobs_root: path100.join(".metaproject", "jobs"),
31867
31971
  updated_at: createdAt
31868
31972
  };
31869
31973
  const first = firstOpenStep(state.plan.steps);
31870
31974
  if (first) {
31871
31975
  state.plan.current_step = first.id;
31872
31976
  }
31873
- await writeFileAtomic(path99.join(absolute, "journal.md"), renderJournal2(name, createdAt));
31977
+ await writeFileAtomic(path100.join(absolute, "journal.md"), renderJournal2(name, createdAt));
31874
31978
  await writeJob(input.cwd, name, state);
31875
- return { state, dir: path99.relative(input.cwd, absolute) };
31979
+ return { state, dir: path100.relative(input.cwd, absolute) };
31876
31980
  },
31877
31981
  async status({ cwd, name }) {
31878
31982
  assertJobName(name);
@@ -31884,7 +31988,7 @@ function createJobService(deps) {
31884
31988
  }
31885
31989
  return {
31886
31990
  state,
31887
- dir: path99.join(".metaproject", "jobs", name),
31991
+ dir: path100.join(".metaproject", "jobs", name),
31888
31992
  stepsDone: state.plan.steps.filter((step) => isTerminalStep(step.status)).length,
31889
31993
  stepsTotal: state.plan.steps.length,
31890
31994
  nextStep: firstOpenStep(state.plan.steps),
@@ -31941,23 +32045,23 @@ function createJobService(deps) {
31941
32045
  if (!input.file) {
31942
32046
  throw new Error("Missing --file. Usage: keryx job document <name> --type <type> --file <path>");
31943
32047
  }
31944
- const source = path99.isAbsolute(input.file) ? input.file : path99.join(input.cwd, input.file);
32048
+ const source = path100.isAbsolute(input.file) ? input.file : path100.join(input.cwd, input.file);
31945
32049
  if (!await pathExists(source)) {
31946
32050
  throw new Error(`--file not found: ${input.file}. Write the document first, then record it.`);
31947
32051
  }
31948
32052
  let recorded;
31949
32053
  await mutate(input.cwd, input.name, async (state) => {
31950
32054
  const fileName = documentFileName(type, source);
31951
- const target = path99.join(jobDir(input.cwd, state.job_name), fileName);
32055
+ const target = path100.join(jobDir(input.cwd, state.job_name), fileName);
31952
32056
  await copyFile(source, target);
31953
32057
  state.documentation ??= {};
31954
- state.documentation.job_path ??= path99.join(".metaproject", "jobs", state.job_name);
32058
+ state.documentation.job_path ??= path100.join(".metaproject", "jobs", state.job_name);
31955
32059
  const created = state.documentation.documents_created ?? [];
31956
32060
  state.documentation.documents_created = created.includes(fileName) ? created : [...created, fileName];
31957
32061
  recorded = {
31958
32062
  state,
31959
32063
  document: fileName,
31960
- path: path99.join(".metaproject", "jobs", state.job_name, fileName)
32064
+ path: path100.join(".metaproject", "jobs", state.job_name, fileName)
31961
32065
  };
31962
32066
  return { state, event: "document", detail: `${type} -> ${fileName}` };
31963
32067
  });
@@ -31992,7 +32096,7 @@ function createJobService(deps) {
31992
32096
  name: state.job_name,
31993
32097
  phase: state.phase,
31994
32098
  intent: state.intent,
31995
- dir: path99.join(".metaproject", "jobs", name),
32099
+ dir: path100.join(".metaproject", "jobs", name),
31996
32100
  stepsDone: state.plan.steps.filter((step) => isTerminalStep(step.status)).length,
31997
32101
  stepsTotal: state.plan.steps.length,
31998
32102
  nextStep: firstOpenStep(state.plan.steps)?.id ?? null
@@ -32097,12 +32201,12 @@ function normalizeWorkspaceReference(raw) {
32097
32201
  // src/sac/fwk-service.ts
32098
32202
  init_assembly();
32099
32203
  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";
32204
+ import path104 from "path";
32101
32205
 
32102
32206
  // src/sac/index.ts
32103
32207
  import { access as access3, readFile as readFile48, realpath as realpath10 } from "fs/promises";
32104
32208
  import { createHash as createHash18 } from "crypto";
32105
- import path100 from "path";
32209
+ import path101 from "path";
32106
32210
  import { fileURLToPath as fileURLToPath3 } from "url";
32107
32211
  var idPattern = /^[a-z][a-z0-9-]{2,63}$/;
32108
32212
  var subjectPattern = /^(?:user|team|service|agent):[a-z0-9][a-z0-9._-]{0,127}$/;
@@ -32120,21 +32224,21 @@ var normativeSchemaFiles = {
32120
32224
  "review-decision": "review-decision.schema.json"
32121
32225
  };
32122
32226
  var normativeSchemas = new Map;
32123
- var NORMATIVE_SCHEMA_DIR = path100.join("docs", "requirements", "shared-agent-context", "schemas");
32227
+ var NORMATIVE_SCHEMA_DIR = path101.join("docs", "requirements", "shared-agent-context", "schemas");
32124
32228
  async function resolveSacNormativeSchemaPath(fileName, searchFrom = [fileURLToPath3(new URL(".", import.meta.url)), process.cwd()]) {
32125
32229
  const seen = new Set;
32126
32230
  for (const start of searchFrom) {
32127
- let dir = path100.resolve(start);
32231
+ let dir = path101.resolve(start);
32128
32232
  for (let i = 0;i < 10; i++) {
32129
32233
  if (seen.has(dir))
32130
32234
  break;
32131
32235
  seen.add(dir);
32132
- const candidate = path100.join(dir, NORMATIVE_SCHEMA_DIR, fileName);
32236
+ const candidate = path101.join(dir, NORMATIVE_SCHEMA_DIR, fileName);
32133
32237
  try {
32134
32238
  await access3(candidate);
32135
32239
  return candidate;
32136
32240
  } catch {}
32137
- const parent = path100.dirname(dir);
32241
+ const parent = path101.dirname(dir);
32138
32242
  if (parent === dir)
32139
32243
  break;
32140
32244
  dir = parent;
@@ -32803,12 +32907,12 @@ class SacReferenceError extends Error {
32803
32907
  code = "unsafe_workspace_reference";
32804
32908
  }
32805
32909
  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("\\"))
32910
+ if (!workspacePathPattern.test(input.uri) || path101.isAbsolute(input.uri) || /^[a-z][a-z0-9+.-]*:/i.test(input.uri) || input.uri.includes("\\"))
32807
32911
  throw new SacReferenceError("unsafe workspace reference");
32808
- const lexicalRoot = path100.resolve(input.workspaceRoot);
32912
+ const lexicalRoot = path101.resolve(input.workspaceRoot);
32809
32913
  const root = await realpath10(lexicalRoot);
32810
- const candidate = path100.resolve(lexicalRoot, input.uri.slice(2));
32811
- if (candidate !== lexicalRoot && !candidate.startsWith(`${lexicalRoot}${path100.sep}`))
32914
+ const candidate = path101.resolve(lexicalRoot, input.uri.slice(2));
32915
+ if (candidate !== lexicalRoot && !candidate.startsWith(`${lexicalRoot}${path101.sep}`))
32812
32916
  throw new SacReferenceError("workspace reference escapes root");
32813
32917
  let resolved;
32814
32918
  try {
@@ -32816,7 +32920,7 @@ async function resolveWorkspaceReference(input) {
32816
32920
  } catch {
32817
32921
  throw new SacReferenceError("workspace reference is not resolvable");
32818
32922
  }
32819
- if (resolved !== root && !resolved.startsWith(`${root}${path100.sep}`))
32923
+ if (resolved !== root && !resolved.startsWith(`${root}${path101.sep}`))
32820
32924
  throw new SacReferenceError("workspace reference escapes root after realpath");
32821
32925
  return candidate;
32822
32926
  }
@@ -32872,16 +32976,16 @@ async function evaluateStrictSacGuard(input) {
32872
32976
  init_fs();
32873
32977
  import { mkdir as mkdir29, readdir as readdir17, readFile as readFile49 } from "fs/promises";
32874
32978
  import { createHash as createHash19, randomUUID as randomUUID3 } from "crypto";
32875
- import path102 from "path";
32979
+ import path103 from "path";
32876
32980
 
32877
32981
  // src/sac/secure-resource-read.ts
32878
32982
  init_contained_read();
32879
32983
  init_descriptor_read();
32880
- import path101 from "path";
32984
+ import path102 from "path";
32881
32985
  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 === "..")) {
32986
+ const relativePath = path102.relative(workspaceRoot, absolutePath);
32987
+ const components = relativePath.split(path102.sep);
32988
+ if (!relativePath || path102.isAbsolute(relativePath) || components.some((component) => !component || component === "." || component === "..")) {
32885
32989
  throw new Error("safe source path is not workspace-relative");
32886
32990
  }
32887
32991
  return readDescriptorChain(workspaceRoot, absolutePath, {
@@ -32908,8 +33012,8 @@ class WorkspaceService {
32908
33012
  now;
32909
33013
  constructor(options) {
32910
33014
  this.options = options;
32911
- this.root = path102.resolve(options.workspaceRoot);
32912
- this.storageRoot = path102.resolve(options.storageRoot ?? path102.join(this.root, ".metaproject", "workspaces"));
33015
+ this.root = path103.resolve(options.workspaceRoot);
33016
+ this.storageRoot = path103.resolve(options.storageRoot ?? path103.join(this.root, ".metaproject", "workspaces"));
32913
33017
  this.now = options.now ?? (() => new Date);
32914
33018
  }
32915
33019
  async create(input) {
@@ -33234,13 +33338,13 @@ class WorkspaceService {
33234
33338
  return parsed;
33235
33339
  }
33236
33340
  workspaceDir(id) {
33237
- return path102.join(this.storageRoot, id);
33341
+ return path103.join(this.storageRoot, id);
33238
33342
  }
33239
33343
  manifestPath(id) {
33240
- return path102.join(this.workspaceDir(id), "workspace.json");
33344
+ return path103.join(this.workspaceDir(id), "workspace.json");
33241
33345
  }
33242
33346
  lockPath(id) {
33243
- return path102.join(this.storageRoot, `.${id}.lock`);
33347
+ return path103.join(this.storageRoot, `.${id}.lock`);
33244
33348
  }
33245
33349
  timestamp() {
33246
33350
  return this.now().toISOString();
@@ -34029,7 +34133,7 @@ function hasReportIntegrity(report) {
34029
34133
  return reportHashPattern.test(reportDigest) && sha2564(body) === reportDigest;
34030
34134
  }
34031
34135
  async function resolvePolicySelection(workspaceRoot, canonicalFallback) {
34032
- const configPath = path103.join(workspaceRoot, ...policyExperimentConfigPath);
34136
+ const configPath = path104.join(workspaceRoot, ...policyExperimentConfigPath);
34033
34137
  let configJson;
34034
34138
  try {
34035
34139
  const raw = await readFile50(configPath, "utf8").catch((error) => {
@@ -34227,9 +34331,9 @@ class FwkReadService {
34227
34331
  const recordedAt = nowIso(now);
34228
34332
  const id = `receipt-${randomUUID4().replace(/-/g, "").slice(0, 16)}`;
34229
34333
  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 });
34334
+ const ledger = path104.join(this.options.canonical.workspaceRoot, ".metaproject", "context-operations", "access-receipts.jsonl");
34335
+ const checkpointPath = path104.join(path104.dirname(ledger), "access-receipts.checkpoint.json");
34336
+ await mkdir30(path104.dirname(ledger), { recursive: true, mode: 448 });
34233
34337
  return withFileLock(`${ledger}.lock`, async () => {
34234
34338
  const state = await resolveLedgerState(ledger, checkpointPath, this.options.verifyReceiptLedger ?? verifyAccessReceiptLedger);
34235
34339
  const receipt = sealAccessReceipt(base, state.headHash);
@@ -34333,7 +34437,7 @@ function normalizeFwkResult(result) {
34333
34437
  init_fs();
34334
34438
  import { createHash as createHash29, randomUUID as randomUUID7 } from "crypto";
34335
34439
  import { appendFile as appendFile7, mkdir as mkdir34, readdir as readdir19, readFile as readFile59 } from "fs/promises";
34336
- import path113 from "path";
34440
+ import path114 from "path";
34337
34441
 
34338
34442
  // src/sac/trusted-wrap-up.ts
34339
34443
  import { createHash as createHash23, randomUUID as randomUUID5 } from "crypto";
@@ -34405,7 +34509,7 @@ function bindingHash(owner, intent) {
34405
34509
  // src/sac/session-wrap-up.ts
34406
34510
  import { createHash as createHash25 } from "crypto";
34407
34511
  import { mkdir as mkdir32, writeFile as writeFile21 } from "fs/promises";
34408
- import path107 from "path";
34512
+ import path108 from "path";
34409
34513
 
34410
34514
  // src/session/store.ts
34411
34515
  import {
@@ -34416,7 +34520,7 @@ import {
34416
34520
  renameSync as renameSync2,
34417
34521
  writeFileSync as writeFileSync2
34418
34522
  } from "fs";
34419
- import path106 from "path";
34523
+ import path107 from "path";
34420
34524
 
34421
34525
  // src/lib/config-dir.ts
34422
34526
  import {
@@ -34461,7 +34565,7 @@ function readTranscriptFile(file) {
34461
34565
  // src/session/paths.ts
34462
34566
  import { existsSync as existsSync15 } from "fs";
34463
34567
  import { homedir } from "os";
34464
- import path104 from "path";
34568
+ import path105 from "path";
34465
34569
  function keryxDataDir(override) {
34466
34570
  if (override !== undefined && override.length > 0) {
34467
34571
  return override;
@@ -34473,22 +34577,22 @@ function keryxDataDir(override) {
34473
34577
  const home = homedir();
34474
34578
  if (process.platform === "win32") {
34475
34579
  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");
34580
+ const base = appData !== undefined && appData.length > 0 ? appData : path105.join(home, "AppData", "Roaming");
34581
+ return path105.join(base, "keryx");
34478
34582
  }
34479
34583
  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");
34584
+ const base = xdg !== undefined && xdg.length > 0 ? xdg : path105.join(home, ".local", "share");
34585
+ return path105.join(base, "keryx");
34482
34586
  }
34483
34587
  function resolveProjectRoot2(cwd) {
34484
- const abs = path104.resolve(cwd);
34588
+ const abs = path105.resolve(cwd);
34485
34589
  let dir = abs;
34486
34590
  for (;; ) {
34487
- const gitPath = path104.join(dir, ".git");
34591
+ const gitPath = path105.join(dir, ".git");
34488
34592
  if (existsSync15(gitPath)) {
34489
34593
  return dir;
34490
34594
  }
34491
- const parent = path104.dirname(dir);
34595
+ const parent = path105.dirname(dir);
34492
34596
  if (parent === dir) {
34493
34597
  break;
34494
34598
  }
@@ -34497,12 +34601,12 @@ function resolveProjectRoot2(cwd) {
34497
34601
  return abs;
34498
34602
  }
34499
34603
  function projectKeyFromPath(projectPath) {
34500
- const abs = path104.resolve(projectPath);
34604
+ const abs = path105.resolve(projectPath);
34501
34605
  const encoded = encodeURIComponent(abs);
34502
34606
  if (encoded.length <= 200) {
34503
34607
  return encoded;
34504
34608
  }
34505
- const base = path104.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 40);
34609
+ const base = path105.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 40);
34506
34610
  let h = 0;
34507
34611
  for (let i = 0;i < abs.length; i++) {
34508
34612
  h = Math.imul(31, h) + abs.charCodeAt(i) | 0;
@@ -34512,17 +34616,17 @@ function projectKeyFromPath(projectPath) {
34512
34616
  }
34513
34617
  function projectSessionsDir(projectPath, dataDir) {
34514
34618
  const key = projectKeyFromPath(resolveProjectRoot2(projectPath));
34515
- return path104.join(keryxDataDir(dataDir), "sessions", key);
34619
+ return path105.join(keryxDataDir(dataDir), "sessions", key);
34516
34620
  }
34517
34621
  function sessionDir(projectPath, sessionId, dataDir) {
34518
- return path104.join(projectSessionsDir(projectPath, dataDir), sessionId);
34622
+ return path105.join(projectSessionsDir(projectPath, dataDir), sessionId);
34519
34623
  }
34520
34624
 
34521
34625
  // src/session/slate.ts
34522
34626
  init_fs();
34523
34627
  init_assembly();
34524
34628
  import { mkdir as mkdir31, readFile as readFile51, rm as rm7 } from "fs/promises";
34525
- import path105 from "path";
34629
+ import path106 from "path";
34526
34630
  init_redact();
34527
34631
  var SLATE_SEED_KINDS = [
34528
34632
  "decision",
@@ -34537,7 +34641,7 @@ function isSlateSeedKind(value) {
34537
34641
  }
34538
34642
  var SEED_TEXT_MAX_LENGTH = 4000;
34539
34643
  function slatePath(dir) {
34540
- return path105.join(dir, "slate.json");
34644
+ return path106.join(dir, "slate.json");
34541
34645
  }
34542
34646
  function slateLockPath(dir) {
34543
34647
  return `${slatePath(dir)}.lock`;
@@ -34740,11 +34844,11 @@ function listSessions(cwd, dataDir) {
34740
34844
  if (name.startsWith(".")) {
34741
34845
  continue;
34742
34846
  }
34743
- const summary = readSummaryFile(path106.join(root, name, "summary.json"));
34847
+ const summary = readSummaryFile(path107.join(root, name, "summary.json"));
34744
34848
  if (summary === undefined) {
34745
34849
  continue;
34746
34850
  }
34747
- if (path106.resolve(summary.projectPath) !== path106.resolve(projectPath)) {
34851
+ if (path107.resolve(summary.projectPath) !== path107.resolve(projectPath)) {
34748
34852
  continue;
34749
34853
  }
34750
34854
  out.push(summary);
@@ -34777,15 +34881,15 @@ async function readSessionSlate(cwd, sessionId, dataDir) {
34777
34881
  }
34778
34882
  function loadContext(cwd, sessionId, dataDir) {
34779
34883
  const dir = sessionDir(resolveProjectRoot2(cwd), sessionId, dataDir);
34780
- const contextPath = path106.join(dir, "context.jsonl");
34884
+ const contextPath = path107.join(dir, "context.jsonl");
34781
34885
  if (existsSync16(contextPath)) {
34782
34886
  return readJsonl2(contextPath);
34783
34887
  }
34784
- return readJsonl2(path106.join(dir, "transcript.jsonl"));
34888
+ return readJsonl2(path107.join(dir, "transcript.jsonl"));
34785
34889
  }
34786
34890
  function loadArchive(cwd, sessionId, dataDir, onDegraded) {
34787
34891
  const dir = sessionDir(resolveProjectRoot2(cwd), sessionId, dataDir);
34788
- const archivePath = path106.join(dir, "archive.jsonl");
34892
+ const archivePath = path107.join(dir, "archive.jsonl");
34789
34893
  if (existsSync16(archivePath)) {
34790
34894
  try {
34791
34895
  const archive = readJsonl2(archivePath);
@@ -34969,7 +35073,7 @@ function sessionEvidenceRef(workspaceId, sessionId) {
34969
35073
  }
34970
35074
  async function resolveSessionWrapUp(input) {
34971
35075
  const now = input.now ?? (() => new Date);
34972
- const sessionId = path107.posix.basename(input.sourceRef, ".md");
35076
+ const sessionId = path108.posix.basename(input.sourceRef, ".md");
34973
35077
  const summary = findSession(input.cwd, sessionId);
34974
35078
  if (summary === undefined || input.sourceRef !== sessionEvidenceRef(input.workspaceId, summary.id)) {
34975
35079
  throw new SessionWrapUpError("session_not_found", `no session matching "${input.sourceRef}" in this project \u2014 use \`keryx sessions list\``);
@@ -34986,7 +35090,7 @@ async function resolveSessionWrapUp(input) {
34986
35090
  throw new SessionWrapUpError("session_unreadable", `session "${summary.id}" could not be read: ${cause.message}`);
34987
35091
  }
34988
35092
  const relPath = sessionEvidenceRef(input.workspaceId, summary.id).slice(2);
34989
- const evidenceDir = path107.dirname(relPath);
35093
+ const evidenceDir = path108.dirname(relPath);
34990
35094
  const slate = await readSessionSlate(input.cwd, summary.id);
34991
35095
  const diff = await gitDiff(input.cwd);
34992
35096
  const diffBody = diff.kind === "measured" ? diff.text : unmeasurableDiffBody(diff.detail);
@@ -35008,23 +35112,23 @@ async function resolveSessionWrapUp(input) {
35008
35112
  ""
35009
35113
  ].join(`
35010
35114
  `);
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`);
35115
+ const wrapUpRelPath = path108.join(evidenceDir, `${summary.id}.wrap-up.md`);
35116
+ const diffRelPath = path108.join(evidenceDir, `${summary.id}.diff.txt`);
35117
+ const noticeRelPath = path108.join(evidenceDir, `${summary.id}.redaction.md`);
35014
35118
  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" }
35119
+ { name: path108.basename(relPath), content: markdown, path: relPath, source: "generated" },
35120
+ { name: path108.basename(wrapUpRelPath), content: wrapUpMarkdown, path: wrapUpRelPath, source: "generated" },
35121
+ { name: path108.basename(diffRelPath), content: diffBody, path: diffRelPath, source: "tool-output" }
35018
35122
  ]);
35019
35123
  if (!floor.ok)
35020
35124
  throw new SessionWrapUpError("security_denied", floor.reason);
35021
35125
  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");
35126
+ await mkdir32(path108.join(input.cwd, evidenceDir), { recursive: true });
35127
+ await writeFile21(path108.join(input.cwd, relPath), safeSession.content, "utf8");
35128
+ await writeFile21(path108.join(input.cwd, wrapUpRelPath), safeWrapUp.content, "utf8");
35129
+ await writeFile21(path108.join(input.cwd, diffRelPath), safeDiff.content, "utf8");
35026
35130
  if (floor.notice !== undefined)
35027
- await writeFile21(path107.join(input.cwd, noticeRelPath), floor.notice, "utf8");
35131
+ await writeFile21(path108.join(input.cwd, noticeRelPath), floor.notice, "utf8");
35028
35132
  const observedAt = now().toISOString();
35029
35133
  const evidence = [
35030
35134
  { kind: "wrap-up", uri: `./${wrapUpRelPath}`, revision: createHash25("sha256").update(safeWrapUp.content).digest("hex"), observedAt },
@@ -35047,13 +35151,13 @@ async function resolveSessionWrapUp(input) {
35047
35151
  init_fs();
35048
35152
  import { createHash as createHash26, randomBytes as randomBytes5 } from "crypto";
35049
35153
  import { readFile as readFile52 } from "fs/promises";
35050
- import path108 from "path";
35154
+ import path109 from "path";
35051
35155
  var CONFIRM_TOKEN_TTL_MS = 2 * 60000;
35052
35156
  function confirmTokenPath2(cwd, workspaceId, proposalId) {
35053
- return path108.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.confirm-token.json`);
35157
+ return path109.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.confirm-token.json`);
35054
35158
  }
35055
35159
  function confirmReceiptPath(cwd, workspaceId, proposalId, idempotencyKey) {
35056
- return path108.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${sha2565(idempotencyKey)}.confirm-receipt.json`);
35160
+ return path109.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${sha2565(idempotencyKey)}.confirm-receipt.json`);
35057
35161
  }
35058
35162
  function sha2565(text) {
35059
35163
  return createHash26("sha256").update(text).digest("hex");
@@ -35094,21 +35198,21 @@ init_store();
35094
35198
  init_config();
35095
35199
  import { readFile as readFile54, readdir as readdir18 } from "fs/promises";
35096
35200
  import { randomUUID as randomUUID6 } from "crypto";
35097
- import path110 from "path";
35201
+ import path111 from "path";
35098
35202
 
35099
35203
  // src/sac/proposal-evidence.ts
35100
35204
  init_fs();
35101
35205
  import { createHash as createHash27 } from "crypto";
35102
35206
  import { readFile as readFile53, rm as rm8 } from "fs/promises";
35103
- import path109 from "path";
35207
+ import path110 from "path";
35104
35208
  function proposalPath(cwd, workspaceId, proposalId) {
35105
- return path109.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.json`);
35209
+ return path110.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.json`);
35106
35210
  }
35107
35211
  function ownerReceiptPath(cwd, owner, workspaceId, idempotencyKey) {
35108
- return path109.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-receipts`, `${idempotencyKey}.json`);
35212
+ return path110.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-receipts`, `${idempotencyKey}.json`);
35109
35213
  }
35110
35214
  function proposalNotePath(cwd, workspaceId, proposalId) {
35111
- return path109.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.note.txt`);
35215
+ return path110.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.note.txt`);
35112
35216
  }
35113
35217
  async function readVerifiedProposalEvidence(cwd, workspaceId, proposalId) {
35114
35218
  let proposal;
@@ -35122,7 +35226,7 @@ async function readVerifiedProposalEvidence(cwd, workspaceId, proposalId) {
35122
35226
  return { ok: false, code: "no_evidence_to_write" };
35123
35227
  let content;
35124
35228
  try {
35125
- content = await readFile53(path109.join(cwd, evidence.uri), "utf8");
35229
+ content = await readFile53(path110.join(cwd, evidence.uri), "utf8");
35126
35230
  } catch {
35127
35231
  return { ok: false, code: "evidence_file_unreadable" };
35128
35232
  }
@@ -35152,22 +35256,22 @@ function targetRelPath(targetRef) {
35152
35256
  return targetRef.replace(/^\.\//, "");
35153
35257
  }
35154
35258
  function targetAbsolutePath(cwd, targetRef) {
35155
- return path109.join(cwd, ".metaproject", targetRelPath(targetRef));
35259
+ return path110.join(cwd, ".metaproject", targetRelPath(targetRef));
35156
35260
  }
35157
35261
  function targetKey(targetRef) {
35158
35262
  return digestOf2(targetRelPath(targetRef)).slice(0, 32);
35159
35263
  }
35160
35264
  function ownerTargetVersionPath(cwd, owner, workspaceId, targetRef) {
35161
- return path109.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-target-versions`, `${targetKey(targetRef)}.json`);
35265
+ return path110.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-target-versions`, `${targetKey(targetRef)}.json`);
35162
35266
  }
35163
35267
  function ownerTargetLockPath(cwd, owner, targetRef) {
35164
- return path109.join(cwd, ".metaproject", "data", "sac", "target-locks", owner, `${targetKey(targetRef)}.lock`);
35268
+ return path110.join(cwd, ".metaproject", "data", "sac", "target-locks", owner, `${targetKey(targetRef)}.lock`);
35165
35269
  }
35166
35270
  function ownerStagingDir(cwd, owner, workspaceId, idempotencyKey) {
35167
- return path109.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-staging`, digestOf2(idempotencyKey).slice(0, 32));
35271
+ return path110.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-staging`, digestOf2(idempotencyKey).slice(0, 32));
35168
35272
  }
35169
35273
  function ownerConflictDir(cwd, owner, workspaceId, idempotencyKey) {
35170
- return path109.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-conflicts`, digestOf2(idempotencyKey).slice(0, 32));
35274
+ return path110.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-conflicts`, digestOf2(idempotencyKey).slice(0, 32));
35171
35275
  }
35172
35276
  async function readJson2(file) {
35173
35277
  try {
@@ -35238,7 +35342,7 @@ async function applyGuardedTargetWrite(input) {
35238
35342
  staged: input.staged,
35239
35343
  stagedAt: receipt.completedAt
35240
35344
  };
35241
- await writeFileAtomic(path109.join(ownerStagingDir(cwd, owner, intent.workspaceId, intent.idempotencyKey), "plan.json"), `${JSON.stringify(staged, null, 2)}
35345
+ await writeFileAtomic(path110.join(ownerStagingDir(cwd, owner, intent.workspaceId, intent.idempotencyKey), "plan.json"), `${JSON.stringify(staged, null, 2)}
35242
35346
  `);
35243
35347
  const applied = await input.apply(input.staged);
35244
35348
  if (!applied.ok) {
@@ -35264,15 +35368,15 @@ async function recoverStagedOwnerWrite(input) {
35264
35368
  });
35265
35369
  }
35266
35370
  async function readStagedOwnerWrite(cwd, owner, workspaceId, idempotencyKey) {
35267
- return readJson2(path109.join(ownerStagingDir(cwd, owner, workspaceId, idempotencyKey), "plan.json"));
35371
+ return readJson2(path110.join(ownerStagingDir(cwd, owner, workspaceId, idempotencyKey), "plan.json"));
35268
35372
  }
35269
35373
  async function recordConflict(input) {
35270
35374
  const base = { targetRef: input.targetRef, expectedVersion: input.expectedVersion, currentVersion: input.currentVersion };
35271
35375
  if (input.proposedContent === undefined)
35272
35376
  return base;
35273
35377
  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`;
35378
+ await writeFileAtomic(path110.join(dir, "proposed"), input.proposedContent);
35379
+ const diffRef = `./workspaces/${input.intent.workspaceId}/${input.owner}-write-conflicts/${path110.basename(dir)}/proposed`;
35276
35380
  return { ...base, diffRef };
35277
35381
  }
35278
35382
 
@@ -35322,7 +35426,7 @@ async function resolveWorkspaceModule(cwd, workspaceId) {
35322
35426
  }
35323
35427
  }
35324
35428
  async function collectWikiDecisionEntries(cwd) {
35325
- const dir = path110.join(cwd, ".metaproject", "wiki", "decisions");
35429
+ const dir = path111.join(cwd, ".metaproject", "wiki", "decisions");
35326
35430
  let files;
35327
35431
  try {
35328
35432
  files = (await readdir18(dir)).filter((name) => name.endsWith(".md"));
@@ -35331,12 +35435,12 @@ async function collectWikiDecisionEntries(cwd) {
35331
35435
  }
35332
35436
  const entries = [];
35333
35437
  for (const file of files) {
35334
- const absolutePath = path110.join(dir, file);
35438
+ const absolutePath = path111.join(dir, file);
35335
35439
  try {
35336
35440
  const content = await readFile54(absolutePath, "utf8");
35337
35441
  entries.push({
35338
35442
  absolutePath,
35339
- relativePath: path110.posix.join("decisions", file),
35443
+ relativePath: path111.posix.join("decisions", file),
35340
35444
  type: extractHeaderField(content, "Type") ?? "decision",
35341
35445
  title: extractTitle(content),
35342
35446
  version: extractHeaderField(content, "Version") ?? null,
@@ -35558,7 +35662,7 @@ function createRealMemoryOwnerWriter(cwd, opts) {
35558
35662
  init_fs();
35559
35663
  init_guard();
35560
35664
  import { readFile as readFile56 } from "fs/promises";
35561
- import path111 from "path";
35665
+ import path112 from "path";
35562
35666
  function renderWrapUpDecisionPage(input) {
35563
35667
  const note = input.note?.trim();
35564
35668
  return `# ${input.title}
@@ -35599,14 +35703,14 @@ export is the source of truth for what actually happened.
35599
35703
  `;
35600
35704
  }
35601
35705
  function wikiPageRelativePath(proposalId) {
35602
- return path111.posix.join("decisions", `sac-${proposalId}.md`);
35706
+ return path112.posix.join("decisions", `sac-${proposalId}.md`);
35603
35707
  }
35604
35708
  function createRealWikiOwnerWriter(cwd, opts) {
35605
35709
  const now = opts?.now ?? (() => new Date);
35606
35710
  const applyStaged = async (staged) => {
35607
35711
  const relativePath = staged.relativePath;
35608
35712
  const content = staged.content;
35609
- await writeFileAtomic(path111.join(cwd, ".metaproject", "wiki", relativePath), content);
35713
+ await writeFileAtomic(path112.join(cwd, ".metaproject", "wiki", relativePath), content);
35610
35714
  return { ok: true };
35611
35715
  };
35612
35716
  return {
@@ -35675,10 +35779,10 @@ init_guard();
35675
35779
  import { createHash as createHash28 } from "crypto";
35676
35780
  import { homedir as homedir2 } from "os";
35677
35781
  import { mkdir as mkdir33, readFile as readFile57, stat as stat14 } from "fs/promises";
35678
- import path112 from "path";
35782
+ import path113 from "path";
35679
35783
  var VERSION = "0.1.0";
35680
35784
  async function createProjectSkill(projectRoot, options) {
35681
- const metaprojectRoot = path112.join(projectRoot, ".metaproject");
35785
+ const metaprojectRoot = path113.join(projectRoot, ".metaproject");
35682
35786
  if (!await pathExists(metaprojectRoot)) {
35683
35787
  throw new Error("Metaproject is not initialized. Run: keryx init");
35684
35788
  }
@@ -35688,8 +35792,8 @@ async function createProjectSkill(projectRoot, options) {
35688
35792
  const moduleName = slugify5(options.module ?? inferModule(options.target));
35689
35793
  const skillName = slugify5(options.name ?? inferSkillName(options.target));
35690
35794
  const format = options.format ?? "auto";
35691
- const packageRoot = path112.join(metaprojectRoot, "project-skills", moduleName, skillName);
35692
- const relativeSkillPath = toPosix(path112.relative(projectRoot, packageRoot));
35795
+ const packageRoot = path113.join(metaprojectRoot, "project-skills", moduleName, skillName);
35796
+ const relativeSkillPath = toPosix(path113.relative(projectRoot, packageRoot));
35693
35797
  const origin = options.origin ? options.originContent !== undefined ? {
35694
35798
  ref: options.origin.trim(),
35695
35799
  hash: hashOriginContent(options.originContent),
@@ -35699,7 +35803,7 @@ async function createProjectSkill(projectRoot, options) {
35699
35803
  const warnings = collectWarnings(evidence, format);
35700
35804
  const files = filesForPackage(packageRoot, format);
35701
35805
  if (!options.dryRun) {
35702
- await withFileLock(path112.join(metaprojectRoot, "data", "gdskills", "project-skills.lock"), async () => {
35806
+ await withFileLock(path113.join(metaprojectRoot, "data", "gdskills", "project-skills.lock"), async () => {
35703
35807
  await writeProjectSkillPackage({
35704
35808
  projectRoot,
35705
35809
  packageRoot,
@@ -35728,7 +35832,7 @@ async function createProjectSkill(projectRoot, options) {
35728
35832
  name: skillName,
35729
35833
  target: options.target,
35730
35834
  skillPath: relativeSkillPath,
35731
- files: files.map((filePath) => toPosix(path112.relative(projectRoot, filePath))),
35835
+ files: files.map((filePath) => toPosix(path113.relative(projectRoot, filePath))),
35732
35836
  warnings,
35733
35837
  dryRun: options.dryRun === true
35734
35838
  };
@@ -35737,9 +35841,9 @@ var MAX_SKILL_TARGET_LENGTH = 80;
35737
35841
  function resolveOriginPath(ref, projectRoot) {
35738
35842
  const trimmed = ref.trim();
35739
35843
  if (trimmed === "~" || trimmed.startsWith("~/")) {
35740
- return path112.join(homedir2(), trimmed.slice(1));
35844
+ return path113.join(homedir2(), trimmed.slice(1));
35741
35845
  }
35742
- return path112.resolve(projectRoot, trimmed);
35846
+ return path113.resolve(projectRoot, trimmed);
35743
35847
  }
35744
35848
  function hashOriginContent(content) {
35745
35849
  return `sha256:${createHash28("sha256").update(content).digest("hex")}`;
@@ -35777,32 +35881,32 @@ async function writeProjectSkillPackage({
35777
35881
  }) {
35778
35882
  const packageFormat = format === "single" ? "single" : "package";
35779
35883
  const skillContent = renderProjectSkill({ moduleName, skillName, target, note, origin, evidence, packageFormat });
35780
- const relativeSkillMdPath = toPosix(path112.join(path112.relative(projectRoot, packageRoot), "SKILL.md"));
35884
+ const relativeSkillMdPath = toPosix(path113.join(path113.relative(projectRoot, packageRoot), "SKILL.md"));
35781
35885
  const guard = await guardOutput({ cwd: projectRoot, content: skillContent, target: "skill", source: "generated", path: relativeSkillMdPath });
35782
35886
  const output = prepareOutputForPersistence(guard, skillContent);
35783
35887
  if (!output.allowed) {
35784
35888
  throw new Error(`Project skill blocked by the security gate: ${output.reason}`);
35785
35889
  }
35786
35890
  await mkdir33(packageRoot, { recursive: true });
35787
- const skillPath = path112.join(packageRoot, "SKILL.md");
35891
+ const skillPath = path113.join(packageRoot, "SKILL.md");
35788
35892
  await writeFileAtomic(skillPath, output.content);
35789
- const changelogPath = path112.join(packageRoot, "skill-changelog.md");
35893
+ const changelogPath = path113.join(packageRoot, "skill-changelog.md");
35790
35894
  if (!await pathExists(changelogPath)) {
35791
35895
  await writeFileAtomic(changelogPath, renderSkillChangelog({ moduleName, skillName, target }));
35792
35896
  }
35793
35897
  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 }));
35898
+ await mkdir33(path113.join(packageRoot, "references"), { recursive: true });
35899
+ await mkdir33(path113.join(packageRoot, "templates"), { recursive: true });
35900
+ await writeFileAtomic(path113.join(packageRoot, "references", "context.md"), renderReferenceContext({ moduleName, skillName, target, evidence }));
35901
+ await writeFileAtomic(path113.join(packageRoot, "templates", "README.md"), renderTemplatesReadme({ moduleName, skillName }));
35902
+ await writeFileAtomic(path113.join(packageRoot, "verification.md"), renderVerification({ moduleName, skillName, evidence }));
35799
35903
  }
35800
35904
  }
35801
35905
  async function collectEvidence(projectRoot, target) {
35802
- const absoluteTarget = path112.resolve(projectRoot, target);
35906
+ const absoluteTarget = path113.resolve(projectRoot, target);
35803
35907
  const targetExists = await pathExists(absoluteTarget);
35804
35908
  const targetKind = await classifyTarget(absoluteTarget, targetExists);
35805
- const maybeRelativeTarget = targetExists ? toPosix(path112.relative(projectRoot, absoluteTarget)) : undefined;
35909
+ const maybeRelativeTarget = targetExists ? toPosix(path113.relative(projectRoot, absoluteTarget)) : undefined;
35806
35910
  const graphArtifacts = await existingRelativePaths(projectRoot, [
35807
35911
  ".metaproject/data/gdgraph/artifacts/summary.md",
35808
35912
  ".metaproject/data/gdgraph/artifacts/module-map.json"
@@ -35832,7 +35936,7 @@ async function classifyTarget(absoluteTarget, targetExists) {
35832
35936
  async function existingRelativePaths(projectRoot, candidates) {
35833
35937
  const existing = [];
35834
35938
  for (const candidate of candidates) {
35835
- if (await pathExists(path112.join(projectRoot, candidate))) {
35939
+ if (await pathExists(path113.join(projectRoot, candidate))) {
35836
35940
  existing.push(candidate);
35837
35941
  }
35838
35942
  }
@@ -35859,17 +35963,17 @@ function collectWarnings(evidence, format) {
35859
35963
  }
35860
35964
  function filesForPackage(packageRoot, format) {
35861
35965
  const base = [
35862
- path112.join(packageRoot, "SKILL.md"),
35863
- path112.join(packageRoot, "skill-changelog.md")
35966
+ path113.join(packageRoot, "SKILL.md"),
35967
+ path113.join(packageRoot, "skill-changelog.md")
35864
35968
  ];
35865
35969
  if (format === "single") {
35866
35970
  return base;
35867
35971
  }
35868
35972
  return [
35869
35973
  ...base,
35870
- path112.join(packageRoot, "verification.md"),
35871
- path112.join(packageRoot, "references", "context.md"),
35872
- path112.join(packageRoot, "templates", "README.md")
35974
+ path113.join(packageRoot, "verification.md"),
35975
+ path113.join(packageRoot, "references", "context.md"),
35976
+ path113.join(packageRoot, "templates", "README.md")
35873
35977
  ];
35874
35978
  }
35875
35979
  function renderProjectSkill({
@@ -36097,7 +36201,7 @@ keryx skills verify ${moduleName}/${skillName}
36097
36201
  `;
36098
36202
  }
36099
36203
  async function updateManifest(projectRoot, entry) {
36100
- const manifestPath = path112.join(projectRoot, ".metaproject", "metaproject.json");
36204
+ const manifestPath = path113.join(projectRoot, ".metaproject", "metaproject.json");
36101
36205
  const manifest = await readJsonFileOr(manifestPath, {});
36102
36206
  manifest.modules ??= {};
36103
36207
  manifest.modules.gdskills ??= {};
@@ -36111,8 +36215,8 @@ async function updateManifest(projectRoot, entry) {
36111
36215
  `);
36112
36216
  }
36113
36217
  async function updateSkillsCatalog(projectRoot) {
36114
- const manifestPath = path112.join(projectRoot, ".metaproject", "metaproject.json");
36115
- const catalogPath = path112.join(projectRoot, ".metaproject", "skills", "catalog.md");
36218
+ const manifestPath = path113.join(projectRoot, ".metaproject", "metaproject.json");
36219
+ const catalogPath = path113.join(projectRoot, ".metaproject", "skills", "catalog.md");
36116
36220
  const manifest = await readJsonFileOr(manifestPath, {});
36117
36221
  const registry = manifest.modules?.gdskills?.projectSkillRegistry ?? [];
36118
36222
  const rows = registry.length > 0 ? registry.map((entry) => `| ${entry.module} | ${entry.name} | \`${entry.target}\` | ${entry.path}/SKILL.md |`).join(`
@@ -36152,7 +36256,7 @@ function inferModule(target) {
36152
36256
  }
36153
36257
  function inferSkillName(target) {
36154
36258
  const normalized = target.trim().replace(/[#:]+/g, "/");
36155
- const base = path112.basename(normalized).replace(/\.[^.]+$/, "");
36259
+ const base = path113.basename(normalized).replace(/\.[^.]+$/, "");
36156
36260
  return base || "entity";
36157
36261
  }
36158
36262
  function slugify5(value) {
@@ -36255,7 +36359,7 @@ class ProposalLifecycleService {
36255
36359
  now;
36256
36360
  constructor(options) {
36257
36361
  this.options = options;
36258
- this.root = path113.resolve(options.workspaceRoot);
36362
+ this.root = path114.resolve(options.workspaceRoot);
36259
36363
  this.now = options.now ?? (() => new Date);
36260
36364
  }
36261
36365
  async create(input) {
@@ -36274,7 +36378,7 @@ class ProposalLifecycleService {
36274
36378
  if (manifest.status === "archived")
36275
36379
  throw new ProposalLifecycleError("guard_denied", "workspace is archived");
36276
36380
  const file = this.proposalPath(workspaceId, proposal.id);
36277
- await mkdir34(path113.dirname(file), { recursive: true, mode: 448 });
36381
+ await mkdir34(path114.dirname(file), { recursive: true, mode: 448 });
36278
36382
  return withFileLock(`${file}.lock`, async () => {
36279
36383
  const consume = this.options.wrapUpAuthority.consume(input.wrapUp, { actor, workspaceId });
36280
36384
  if (consume !== "ok")
@@ -36302,7 +36406,7 @@ class ProposalLifecycleService {
36302
36406
  return this.options.workspaces.withAuthorizedActor({ actorContext: actor, workspaceId: input.workspaceId, action: "review", execute: async (manifest) => {
36303
36407
  const proposal = await this.loadProposal(input.workspaceId, input.proposalId);
36304
36408
  const ledger = this.ledgerPath(input.workspaceId);
36305
- await mkdir34(path113.dirname(ledger), { recursive: true, mode: 448 });
36409
+ await mkdir34(path114.dirname(ledger), { recursive: true, mode: 448 });
36306
36410
  return withFileLock(`${ledger}.lock`, async () => {
36307
36411
  const records = (await this.records(ledger)).filter((record) => record.proposalId === proposal.id);
36308
36412
  const events = records.filter((record) => record.recordType === "proposal-transition");
@@ -36344,7 +36448,7 @@ class ProposalLifecycleService {
36344
36448
  } });
36345
36449
  }
36346
36450
  async listProposedProposals(workspaceId) {
36347
- const proposalsDir = path113.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals");
36451
+ const proposalsDir = path114.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals");
36348
36452
  let entries;
36349
36453
  try {
36350
36454
  entries = (await readdir19(proposalsDir)).filter((name) => name.endsWith(".json"));
@@ -36356,7 +36460,7 @@ class ProposalLifecycleService {
36356
36460
  const proposals = [];
36357
36461
  for (const entry of entries) {
36358
36462
  try {
36359
- const parsed = JSON.parse(await readFile59(path113.join(proposalsDir, entry), "utf8"));
36463
+ const parsed = JSON.parse(await readFile59(path114.join(proposalsDir, entry), "utf8"));
36360
36464
  if (parsed.recordType === "proposal-created")
36361
36465
  proposals.push(parsed);
36362
36466
  } catch {}
@@ -36622,31 +36726,31 @@ class ProposalLifecycleService {
36622
36726
  }
36623
36727
  }
36624
36728
  proposalPath(workspaceId, proposalId) {
36625
- return path113.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.json`);
36729
+ return path114.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.json`);
36626
36730
  }
36627
36731
  decisionRef(proposalId, key) {
36628
36732
  return `./proposals/${proposalId}.${hash(key)}.decision.json`;
36629
36733
  }
36630
36734
  decisionPath(workspaceId, proposalId, key) {
36631
- return path113.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.decision.json`);
36735
+ return path114.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.decision.json`);
36632
36736
  }
36633
36737
  approvalRef(proposalId, key) {
36634
36738
  return `./proposals/${proposalId}.${hash(key)}.approval.json`;
36635
36739
  }
36636
36740
  approvalPath(workspaceId, proposalId, key) {
36637
- return path113.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.approval.json`);
36741
+ return path114.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.approval.json`);
36638
36742
  }
36639
36743
  writeResultPath(workspaceId, proposalId, key) {
36640
- return path113.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.write-result.json`);
36744
+ return path114.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.write-result.json`);
36641
36745
  }
36642
36746
  intentRef(proposalId, key) {
36643
36747
  return `./proposals/${proposalId}.${hash(key)}.write-intent.json`;
36644
36748
  }
36645
36749
  intentPath(workspaceId, proposalId, key) {
36646
- return path113.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.write-intent.json`);
36750
+ return path114.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.write-intent.json`);
36647
36751
  }
36648
36752
  attemptPath(workspaceId, proposalId, key) {
36649
- return path113.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.owner-write-attempt.json`);
36753
+ return path114.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.owner-write-attempt.json`);
36650
36754
  }
36651
36755
  async loadWriteResult(workspaceId, proposalId, key) {
36652
36756
  try {
@@ -36673,7 +36777,7 @@ class ProposalLifecycleService {
36673
36777
  }
36674
36778
  }
36675
36779
  ledgerPath(workspaceId) {
36676
- return path113.join(this.root, ".metaproject", "workspaces", workspaceId, "activity.jsonl");
36780
+ return path114.join(this.root, ".metaproject", "workspaces", workspaceId, "activity.jsonl");
36677
36781
  }
36678
36782
  timestamp() {
36679
36783
  return this.now().toISOString();
@@ -36756,7 +36860,7 @@ function normalizeProposalLifecycleResult(value) {
36756
36860
  // src/sac/collaboration-service.ts
36757
36861
  import { appendFile as appendFile8, mkdir as mkdir35, readFile as readFile60 } from "fs/promises";
36758
36862
  import { randomUUID as randomUUID8 } from "crypto";
36759
- import path114 from "path";
36863
+ import path115 from "path";
36760
36864
  class CollaborationServiceError extends Error {
36761
36865
  code;
36762
36866
  constructor(code, message) {
@@ -36771,7 +36875,7 @@ class CollaborationService {
36771
36875
  this.input = input;
36772
36876
  }
36773
36877
  file(id) {
36774
- return path114.join(this.input.workspaceRoot, ".metaproject", "workspaces", id, "activity.jsonl");
36878
+ return path115.join(this.input.workspaceRoot, ".metaproject", "workspaces", id, "activity.jsonl");
36775
36879
  }
36776
36880
  async overview(input) {
36777
36881
  const manifest = await this.input.workspaces.show(input);
@@ -36808,7 +36912,7 @@ class CollaborationService {
36808
36912
  occurredAt: (this.input.now ?? (() => new Date))().toISOString(),
36809
36913
  ...suppliedHandoff ? { handoff: { ...suppliedHandoff, from: actor.subject } } : {}
36810
36914
  });
36811
- await mkdir35(path114.dirname(this.file(manifest.id)), { recursive: true, mode: 448 });
36915
+ await mkdir35(path115.dirname(this.file(manifest.id)), { recursive: true, mode: 448 });
36812
36916
  await appendFile8(this.file(manifest.id), `${JSON.stringify(activity)}
36813
36917
  `, { mode: 384 });
36814
36918
  return normalizeCollaborationResult(activity);
@@ -36858,13 +36962,13 @@ function normalizeCollaborationResult(value) {
36858
36962
  // src/session/external-slate.ts
36859
36963
  init_fs();
36860
36964
  import { mkdir as mkdir37, readdir as readdir20, readFile as readFile61 } from "fs/promises";
36861
- import path116 from "path";
36965
+ import path117 from "path";
36862
36966
 
36863
36967
  // src/sac/machine-wrap-up.ts
36864
36968
  init_fs();
36865
36969
  import { createHash as createHash30, randomUUID as randomUUID10 } from "crypto";
36866
36970
  import { mkdir as mkdir36 } from "fs/promises";
36867
- import path115 from "path";
36971
+ import path116 from "path";
36868
36972
 
36869
36973
  // src/sac/workspace-resolve.ts
36870
36974
  init_redact();
@@ -37005,11 +37109,11 @@ async function resolveMachineWrapUp(input) {
37005
37109
  `;
37006
37110
  const seedsJson = `${JSON.stringify(seedsForKind.map((seed) => ({ text: seed.text, source: describeSource(seed.source) })), null, 2)}
37007
37111
  `;
37008
- const evidenceRelBase = path115.posix.join(".metaproject", "workspaces", input.workspaceId, "machine-evidence");
37112
+ const evidenceRelBase = path116.posix.join(".metaproject", "workspaces", input.workspaceId, "machine-evidence");
37009
37113
  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" }
37114
+ { name: `${input.kind}.diff.txt`, content: diffBody, path: path116.posix.join(evidenceRelBase, `${input.kind}.diff.txt`), source: "tool-output" },
37115
+ { name: `${input.kind}.flow.json`, content: flowSnapshotJson, path: path116.posix.join(evidenceRelBase, `${input.kind}.flow.json`), source: "generated" },
37116
+ { name: `${input.kind}.seeds.json`, content: seedsJson, path: path116.posix.join(evidenceRelBase, `${input.kind}.seeds.json`), source: "generated" }
37013
37117
  ]);
37014
37118
  if (!floor.ok)
37015
37119
  return { ok: false, code: "security_denied", detail: floor.reason };
@@ -37063,14 +37167,14 @@ ${safeSeeds.content}`;
37063
37167
  }
37064
37168
  summary = result.text.trim().length > 0 ? result.text.trim() : mechanicalSummary(summaryDiff, course);
37065
37169
  }
37066
- const evidenceDir = path115.join(input.cwd, ".metaproject", "workspaces", input.workspaceId, "machine-evidence");
37170
+ const evidenceDir = path116.join(input.cwd, ".metaproject", "workspaces", input.workspaceId, "machine-evidence");
37067
37171
  await mkdir36(evidenceDir, { recursive: true });
37068
37172
  const diffFile = `${input.kind}.${shortHash}.diff.txt`;
37069
37173
  const flowFile = `${input.kind}.${shortHash}.flow.json`;
37070
37174
  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);
37175
+ await writeFileAtomic(path116.join(evidenceDir, diffFile), safeDiff.content);
37176
+ await writeFileAtomic(path116.join(evidenceDir, flowFile), safeFlow.content);
37177
+ await writeFileAtomic(path116.join(evidenceDir, seedsFile), safeSeeds.content);
37074
37178
  const observedAt = now().toISOString();
37075
37179
  const relBase = `./.metaproject/workspaces/${input.workspaceId}/machine-evidence`;
37076
37180
  const evidence = [
@@ -37080,7 +37184,7 @@ ${safeSeeds.content}`;
37080
37184
  ];
37081
37185
  if (floor.notice !== undefined) {
37082
37186
  const noticeFile = `${input.kind}.${shortHash}.redaction.md`;
37083
- await writeFileAtomic(path115.join(evidenceDir, noticeFile), floor.notice);
37187
+ await writeFileAtomic(path116.join(evidenceDir, noticeFile), floor.notice);
37084
37188
  evidence.push({ kind: REDACTION_NOTICE_KIND, uri: `${relBase}/${noticeFile}`, revision: sha2566(floor.notice), observedAt });
37085
37189
  }
37086
37190
  return {
@@ -37099,18 +37203,18 @@ async function writeFlooredArchiveArtifact(params) {
37099
37203
  {
37100
37204
  name: params.filename,
37101
37205
  content: params.content,
37102
- path: path115.posix.join("slate-archive", params.filename),
37206
+ path: path116.posix.join("slate-archive", params.filename),
37103
37207
  source: "generated"
37104
37208
  }
37105
37209
  ]);
37106
37210
  if (!floor.ok)
37107
37211
  return { ok: false, code: "security_denied", detail: floor.reason };
37108
37212
  const body = floor.bodies[0];
37109
- const archiveDir = path115.join(params.dir, "slate-archive");
37213
+ const archiveDir = path116.join(params.dir, "slate-archive");
37110
37214
  await mkdir36(archiveDir, { recursive: true });
37111
- await writeFileAtomic(path115.join(archiveDir, params.filename), body.content);
37215
+ await writeFileAtomic(path116.join(archiveDir, params.filename), body.content);
37112
37216
  if (floor.notice !== undefined) {
37113
- await writeFileAtomic(path115.join(archiveDir, `${params.filename}${ARCHIVE_REDACTION_NOTICE_SUFFIX}`), floor.notice);
37217
+ await writeFileAtomic(path116.join(archiveDir, `${params.filename}${ARCHIVE_REDACTION_NOTICE_SUFFIX}`), floor.notice);
37114
37218
  }
37115
37219
  return { ok: true, altered: body.altered };
37116
37220
  }
@@ -37146,9 +37250,9 @@ async function writeWrapUpOutcomeArtifact(cwd, dir, trigger, now, groups) {
37146
37250
  return;
37147
37251
  const refusalIso = now().toISOString();
37148
37252
  const refusalFilename = `${refusalIso.replace(/[:.]/g, "-")}-wrap-up-outcome.json`;
37149
- const archiveDir = path115.join(dir, "slate-archive");
37253
+ const archiveDir = path116.join(dir, "slate-archive");
37150
37254
  await mkdir36(archiveDir, { recursive: true });
37151
- await writeFileAtomic(path115.join(archiveDir, refusalFilename), `${JSON.stringify({
37255
+ await writeFileAtomic(path116.join(archiveDir, refusalFilename), `${JSON.stringify({
37152
37256
  recordType: "wrap-up-outcome",
37153
37257
  trigger,
37154
37258
  generatedAt: refusalIso,
@@ -37284,7 +37388,7 @@ async function runWrapUp(input) {
37284
37388
 
37285
37389
  // src/session/external-slate.ts
37286
37390
  function externalSlatesDir(cwd) {
37287
- return path116.join(cwd, ".keryx", "external-slates");
37391
+ return path117.join(cwd, ".keryx", "external-slates");
37288
37392
  }
37289
37393
  var EXTERNAL_SESSION_ID_PATTERN = /^[A-Za-z0-9_-]{1,128}$/;
37290
37394
  function assertValidExternalSessionId(externalSessionId) {
@@ -37294,14 +37398,14 @@ function assertValidExternalSessionId(externalSessionId) {
37294
37398
  }
37295
37399
  function externalSlatePath(cwd, externalSessionId) {
37296
37400
  assertValidExternalSessionId(externalSessionId);
37297
- return path116.join(externalSlatesDir(cwd), `${externalSessionId}.json`);
37401
+ return path117.join(externalSlatesDir(cwd), `${externalSessionId}.json`);
37298
37402
  }
37299
37403
  function externalSlateLockPath(cwd, externalSessionId) {
37300
37404
  return `${externalSlatePath(cwd, externalSessionId)}.lock`;
37301
37405
  }
37302
37406
  function externalSlateEvidenceDir(cwd, externalSessionId) {
37303
37407
  assertValidExternalSessionId(externalSessionId);
37304
- return path116.join(externalSlatesDir(cwd), externalSessionId);
37408
+ return path117.join(externalSlatesDir(cwd), externalSessionId);
37305
37409
  }
37306
37410
  async function readExternalSlate(cwd, externalSessionId) {
37307
37411
  try {
@@ -37407,12 +37511,12 @@ __export(exports_service10, {
37407
37511
  runDoctor: () => runDoctor,
37408
37512
  runValidate: () => runValidate
37409
37513
  });
37410
- import path119 from "path";
37514
+ import path120 from "path";
37411
37515
  import { readFile as readFile64 } from "fs/promises";
37412
37516
 
37413
37517
  // src/standard/validate.ts
37414
37518
  init_fs();
37415
- import path118 from "path";
37519
+ import path119 from "path";
37416
37520
  import { readFile as readFile63 } from "fs/promises";
37417
37521
 
37418
37522
  // src/standard/schemas.ts
@@ -37541,7 +37645,7 @@ var SCHEMA_REGISTRY2 = {
37541
37645
 
37542
37646
  // src/standard/profiles.ts
37543
37647
  init_fs();
37544
- import path117 from "path";
37648
+ import path118 from "path";
37545
37649
  import { readFile as readFile62 } from "fs/promises";
37546
37650
  var AGENT_MODULES = ["gdgraph", "gdctx", "gdskills", "gdwiki", "memory"];
37547
37651
  var CI_MODULES = ["health", "testing"];
@@ -37553,7 +37657,7 @@ function enabledModuleKeys(manifest) {
37553
37657
  }
37554
37658
  async function rootEntrypointLinksIndex(cwd) {
37555
37659
  for (const name of ROOT_ENTRYPOINTS) {
37556
- const filePath = path117.join(cwd, name);
37660
+ const filePath = path118.join(cwd, name);
37557
37661
  if (!await pathExists(filePath)) {
37558
37662
  continue;
37559
37663
  }
@@ -37565,16 +37669,16 @@ async function rootEntrypointLinksIndex(cwd) {
37565
37669
  return false;
37566
37670
  }
37567
37671
  async function minimalSatisfied(cwd) {
37568
- const metaprojectRoot = path117.join(cwd, ".metaproject");
37672
+ const metaprojectRoot = path118.join(cwd, ".metaproject");
37569
37673
  const requiredFiles = ["index.md", "README.md", "metaproject.json"];
37570
37674
  const requiredDirs = ["modules", "rules", "skills", "data"];
37571
37675
  for (const file of requiredFiles) {
37572
- if (!await pathExists(path117.join(metaprojectRoot, file))) {
37676
+ if (!await pathExists(path118.join(metaprojectRoot, file))) {
37573
37677
  return false;
37574
37678
  }
37575
37679
  }
37576
37680
  for (const dir of requiredDirs) {
37577
- if (!await pathExists(path117.join(metaprojectRoot, dir))) {
37681
+ if (!await pathExists(path118.join(metaprojectRoot, dir))) {
37578
37682
  return false;
37579
37683
  }
37580
37684
  }
@@ -37587,7 +37691,7 @@ async function ciSatisfied(cwd, manifest) {
37587
37691
  return false;
37588
37692
  }
37589
37693
  for (const key of ciModules) {
37590
- if (await pathExists(path117.join(cwd, ".metaproject", "data", key, "artifacts"))) {
37694
+ if (await pathExists(path118.join(cwd, ".metaproject", "data", key, "artifacts"))) {
37591
37695
  return true;
37592
37696
  }
37593
37697
  }
@@ -37600,7 +37704,7 @@ async function evaluateProfiles(cwd, manifest) {
37600
37704
  satisfied.push("minimal");
37601
37705
  }
37602
37706
  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"));
37707
+ const agent = minimal && hasAgentModule && await rootEntrypointLinksIndex(cwd) && await pathExists(path118.join(cwd, ".metaproject", "rules"));
37604
37708
  if (agent) {
37605
37709
  satisfied.push("agent");
37606
37710
  }
@@ -37770,20 +37874,20 @@ var MANIFEST_TOP_LEVEL_SCHEMA = {
37770
37874
  async function validateWorkspace2(cwd) {
37771
37875
  const errors = [];
37772
37876
  const warnings = [];
37773
- const metaprojectRoot = path118.join(cwd, ".metaproject");
37877
+ const metaprojectRoot = path119.join(cwd, ".metaproject");
37774
37878
  const requiredFiles = ["index.md", "README.md", "metaproject.json"];
37775
37879
  for (const file of requiredFiles) {
37776
- if (!await pathExists(path118.join(metaprojectRoot, file))) {
37880
+ if (!await pathExists(path119.join(metaprojectRoot, file))) {
37777
37881
  errors.push(issue("missing-required-file", `Required file .metaproject/${file} is missing`, `Run \`keryx init\` to scaffold .metaproject/${file}.`));
37778
37882
  }
37779
37883
  }
37780
37884
  const requiredDirs = ["modules", "rules", "skills", "data"];
37781
37885
  for (const dir of requiredDirs) {
37782
- if (!await pathExists(path118.join(metaprojectRoot, dir))) {
37886
+ if (!await pathExists(path119.join(metaprojectRoot, dir))) {
37783
37887
  errors.push(issue("missing-required-dir", `Required directory .metaproject/${dir}/ is missing`, `Run \`keryx init\` to create .metaproject/${dir}/.`));
37784
37888
  }
37785
37889
  }
37786
- const manifestPath = path118.join(metaprojectRoot, "metaproject.json");
37890
+ const manifestPath = path119.join(metaprojectRoot, "metaproject.json");
37787
37891
  if (!await pathExists(manifestPath)) {
37788
37892
  return { ok: errors.length === 0, errors, warnings };
37789
37893
  }
@@ -37815,7 +37919,7 @@ async function validateWorkspace2(cwd) {
37815
37919
  if (typeof value !== "string") {
37816
37920
  continue;
37817
37921
  }
37818
- if (!await pathExists(path118.join(cwd, value))) {
37922
+ if (!await pathExists(path119.join(cwd, value))) {
37819
37923
  errors.push(issue("missing-declared-path", `Declared path paths.${key} -> ${value} does not exist`, `Create ${value} or remove paths.${key} from metaproject.json.`));
37820
37924
  }
37821
37925
  }
@@ -37825,7 +37929,7 @@ async function validateWorkspace2(cwd) {
37825
37929
  continue;
37826
37930
  }
37827
37931
  if (typeof entry.manifest === "string") {
37828
- if (!await pathExists(path118.join(cwd, entry.manifest))) {
37932
+ if (!await pathExists(path119.join(cwd, entry.manifest))) {
37829
37933
  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
37934
  }
37831
37935
  }
@@ -37834,14 +37938,14 @@ async function validateWorkspace2(cwd) {
37834
37938
  if (typeof value !== "string") {
37835
37939
  continue;
37836
37940
  }
37837
- if (!await pathExists(path118.join(cwd, value))) {
37941
+ if (!await pathExists(path119.join(cwd, value))) {
37838
37942
  const sink = field === "data" ? warnings : errors;
37839
37943
  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
37944
  }
37841
37945
  }
37842
37946
  }
37843
37947
  for (const name of ROOT_ENTRYPOINTS2) {
37844
- const filePath = path118.join(cwd, name);
37948
+ const filePath = path119.join(cwd, name);
37845
37949
  if (!await pathExists(filePath)) {
37846
37950
  continue;
37847
37951
  }
@@ -38685,7 +38789,7 @@ async function runDoctor(cwd) {
38685
38789
  return validateWorkspace2(cwd);
38686
38790
  }
38687
38791
  async function readManifest(cwd) {
38688
- const manifestPath = path119.join(cwd, ".metaproject", "metaproject.json");
38792
+ const manifestPath = path120.join(cwd, ".metaproject", "metaproject.json");
38689
38793
  if (!await pathExists(manifestPath)) {
38690
38794
  throw new Error("Metaproject is not initialized (missing .metaproject/metaproject.json). Run `keryx init` first.");
38691
38795
  }