@mrciphersmith/keryx 0.3.81 → 0.3.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/core.js CHANGED
@@ -10853,7 +10853,7 @@ var init_skill_length_ceilings = __esm(() => {
10853
10853
  "review/review-jev-scenarios": 187,
10854
10854
  "review/review-layout": 238,
10855
10855
  "review/review-logic": 377,
10856
- "review/review-orchestrator": 1723,
10856
+ "review/review-orchestrator": 1712,
10857
10857
  "review/review-performance": 374,
10858
10858
  "review/review-pr-feedback": 895,
10859
10859
  "review/review-regression": 216,
@@ -22803,7 +22803,7 @@ var MARKER_VERSION = 1, BEGIN, END, REFERENCE_HEADING;
22803
22803
  var init_managed_block = __esm(() => {
22804
22804
  BEGIN = /^<!--\s*keryx:reference:begin\s+v=(\d+)(?:\s+hash=([0-9a-f]{64}))?\s*-->$/;
22805
22805
  END = /^<!--\s*keryx:reference:end\s*-->$/;
22806
- REFERENCE_HEADING = /^##\s+Reference\b/i;
22806
+ REFERENCE_HEADING = /^##\s+Reference(?:\s*\([^)]*\))?\s*$/i;
22807
22807
  });
22808
22808
 
22809
22809
  // src/wiki/page-invariants.ts
@@ -23010,6 +23010,49 @@ ${entry}
23010
23010
  return all.join(`
23011
23011
  `);
23012
23012
  }
23013
+ function repairVersionAndOrder(markdown) {
23014
+ let next = markdown;
23015
+ const all = next.split(`
23016
+ `);
23017
+ const range = changelogRange(all);
23018
+ if (range !== null) {
23019
+ const mask = fencedLines2(all);
23020
+ const starts = [];
23021
+ for (let index = range.heading + 1;index < range.end; index += 1) {
23022
+ if (!mask[index] && ENTRY_START.test(all[index]))
23023
+ starts.push(index);
23024
+ }
23025
+ const chunks = starts.map((start, position) => {
23026
+ const end = position + 1 < starts.length ? starts[position + 1] : range.end;
23027
+ const body = all.slice(start, end);
23028
+ while (body.length > 1 && body[body.length - 1].trim() === "")
23029
+ body.pop();
23030
+ return { body, version: ENTRY_VERSION.exec(body[0])?.[1] ?? null };
23031
+ });
23032
+ const ordered = chunks.every((chunk) => chunk.version !== null) ? [...chunks].sort((left, right) => compareVersions(right.version, left.version)) : chunks;
23033
+ if (ordered.some((chunk, index) => chunk !== chunks[index])) {
23034
+ const spaced = starts.length > 1 && all[starts[1] - 1].trim() === "";
23035
+ const rebuilt = [];
23036
+ ordered.forEach((chunk, index) => {
23037
+ if (index > 0 && spaced)
23038
+ rebuilt.push("");
23039
+ rebuilt.push(...chunk.body);
23040
+ });
23041
+ let tail = range.end;
23042
+ while (tail > starts[0] && all[tail - 1].trim() === "")
23043
+ tail -= 1;
23044
+ all.splice(starts[0], tail - starts[0], ...rebuilt);
23045
+ next = all.join(`
23046
+ `);
23047
+ }
23048
+ }
23049
+ const version = pageVersion(next);
23050
+ const newest = newestChangelogVersion(parseChangelog(next));
23051
+ if (version !== null && newest !== null && compareVersions(version, newest) < 0) {
23052
+ next = setPageVersion(next, newest);
23053
+ }
23054
+ return next;
23055
+ }
23013
23056
  function sectionsOf(markdown) {
23014
23057
  const all = lines2(markdown);
23015
23058
  const mask = fencedLines2(all);
@@ -23095,6 +23138,8 @@ function withAddedLines(fresh, existingBody) {
23095
23138
  return false;
23096
23139
  if (/^[-*]\s+\[Module [^\]]+\]\([^)]+\.md\)$/.test(text))
23097
23140
  return false;
23141
+ if (/^[-*]\s+`[^`]+`\s+\(no wiki page\)$/.test(text))
23142
+ return false;
23098
23143
  if (/^graph-derived\b/i.test(text))
23099
23144
  return false;
23100
23145
  return !freshText.includes(text);
@@ -23155,10 +23200,11 @@ ${replacement.lines.join(`
23155
23200
  `);
23156
23201
  }
23157
23202
  }
23203
+ const repaired = repairVersionAndOrder(next);
23158
23204
  if (next === source)
23159
- return existing;
23160
- const version = nextPageVersion(source);
23161
- return inEolOf(existing, prependChangelogEntry(setPageVersion(next, version), `- ${version} - ${entryNote}`));
23205
+ return repaired === source ? existing : inEolOf(existing, repaired);
23206
+ const version = nextPageVersion(repaired);
23207
+ return inEolOf(existing, prependChangelogEntry(setPageVersion(repaired, version), `- ${version} - ${entryNote}`));
23162
23208
  }
23163
23209
  var CHANGELOG_HEADING, SECTION_HEADING, H2, ENTRY_START, ENTRY_VERSION, LEGACY_META_KEYS;
23164
23210
  var init_page_invariants = __esm(() => {
@@ -23182,6 +23228,55 @@ var init_page_invariants = __esm(() => {
23182
23228
  ]);
23183
23229
  });
23184
23230
 
23231
+ // src/wiki/readme-links.ts
23232
+ import path76 from "path";
23233
+ function rewriteReadmeLinks(text, readmeDir, pageLink) {
23234
+ return text.replace(MARKDOWN_LINK, (whole, bang, label, target) => {
23235
+ if (target === "" || HAS_SCHEME.test(target)) {
23236
+ return whole;
23237
+ }
23238
+ const filePart = target.split(/[#?]/)[0] ?? "";
23239
+ if (filePart === "") {
23240
+ return label;
23241
+ }
23242
+ const resolved = path76.posix.normalize(filePart.startsWith("/") ? filePart.replace(/^\/+/, "") : path76.posix.join(readmeDir, filePart));
23243
+ const codePath = resolved.replace(/\/+$/, "");
23244
+ if (codePath === "" || codePath === "." || codePath === ".." || codePath.startsWith("../")) {
23245
+ return label;
23246
+ }
23247
+ const named = label.length > 0 ? `${label} (\`${codePath}\`)` : `\`${codePath}\``;
23248
+ if (bang === "!") {
23249
+ return named;
23250
+ }
23251
+ const moduleName = moduleOfTarget(filePart, codePath);
23252
+ const page = moduleName === null ? null : pageLink(moduleName);
23253
+ return page === null ? named : `[${label.length > 0 ? label : moduleName}](${page})`;
23254
+ });
23255
+ }
23256
+ function moduleOfTarget(filePart, codePath) {
23257
+ const base = path76.posix.basename(codePath);
23258
+ if (filePart.endsWith("/") || !/\.[A-Za-z0-9]+$/.test(base)) {
23259
+ return codePath;
23260
+ }
23261
+ if (DOC_ENTRY.test(base)) {
23262
+ const dir = path76.posix.dirname(codePath);
23263
+ return dir === "." ? null : dir;
23264
+ }
23265
+ return null;
23266
+ }
23267
+ function truncateMarkdown(text, max) {
23268
+ if (text.length <= max) {
23269
+ return text;
23270
+ }
23271
+ return text.slice(0, max).replace(/\s*!?\[[^\]]*$|\s*!?\[[^\]]*\]\([^)]*$/, "").trimEnd();
23272
+ }
23273
+ var MARKDOWN_LINK, HAS_SCHEME, DOC_ENTRY;
23274
+ var init_readme_links = __esm(() => {
23275
+ MARKDOWN_LINK = /(!?)\[([^[\]]*)\]\(\s*<?([^)\s>]*)>?(?:\s+(?:"[^"]*"|'[^']*'))?\s*\)/g;
23276
+ HAS_SCHEME = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
23277
+ DOC_ENTRY = /^(?:readme|index)\.(?:md|mdx)$/i;
23278
+ });
23279
+
23185
23280
  // src/wiki/think-tags.ts
23186
23281
  function maskCodeRegions(text) {
23187
23282
  const maskMatch = (m) => "\x00".repeat(m.length);
@@ -23570,15 +23665,15 @@ __export(exports_service4, {
23570
23665
  import { spawn as spawn3 } from "child_process";
23571
23666
  import { createHash as createHash15 } from "crypto";
23572
23667
  import { mkdir as mkdir20, readFile as readFile39, readdir as readdir13, writeFile as writeFile14 } from "fs/promises";
23573
- import path76 from "path";
23668
+ import path77 from "path";
23574
23669
  function wikiRootPath3(cwd) {
23575
- return path76.join(cwd, ".metaproject", "wiki");
23670
+ return path77.join(cwd, ".metaproject", "wiki");
23576
23671
  }
23577
23672
  function dataRootPath(cwd) {
23578
- return path76.join(cwd, ".metaproject", "data", "gdwiki");
23673
+ return path77.join(cwd, ".metaproject", "data", "gdwiki");
23579
23674
  }
23580
23675
  function linkCheckReportPath(cwd) {
23581
- return path76.join(dataRootPath(cwd), "link-check", "latest.md");
23676
+ return path77.join(dataRootPath(cwd), "link-check", "latest.md");
23582
23677
  }
23583
23678
  async function wikiStatus(cwd) {
23584
23679
  const root = wikiRootPath3(cwd);
@@ -23586,7 +23681,7 @@ async function wikiStatus(cwd) {
23586
23681
  const pages = enabled ? await collectPages(cwd) : [];
23587
23682
  return {
23588
23683
  enabled,
23589
- wikiRoot: path76.relative(cwd, root),
23684
+ wikiRoot: path77.relative(cwd, root),
23590
23685
  totalPages: pages.length,
23591
23686
  countsByType: WIKI_PAGE_TYPES.map(({ type }) => ({
23592
23687
  type,
@@ -23617,9 +23712,9 @@ async function wikiCreatePage(input) {
23617
23712
  if (!/^[a-z0-9][a-z0-9-]*$/.test(input.slug)) {
23618
23713
  throw new Error(`Invalid slug: ${input.slug}. Use lowercase letters, digits, and hyphens.`);
23619
23714
  }
23620
- const dir = path76.join(wikiRootPath3(input.cwd), typeConfig.folder);
23621
- const filePath = path76.join(dir, `${input.slug}.md`);
23622
- const relativePath = path76.relative(input.cwd, filePath);
23715
+ const dir = path77.join(wikiRootPath3(input.cwd), typeConfig.folder);
23716
+ const filePath = path77.join(dir, `${input.slug}.md`);
23717
+ const relativePath = path77.relative(input.cwd, filePath);
23623
23718
  if (await pathExists(filePath) && !input.force) {
23624
23719
  throw new Error(`Page already exists: ${relativePath}. Use --force to overwrite.`);
23625
23720
  }
@@ -23631,7 +23726,7 @@ async function wikiCreatePage(input) {
23631
23726
  }
23632
23727
  async function wikiGenerateIndex(cwd, history) {
23633
23728
  const root = wikiRootPath3(cwd);
23634
- const indexPath = path76.join(root, "index.md");
23729
+ const indexPath = path77.join(root, "index.md");
23635
23730
  const pages = await collectPages(cwd);
23636
23731
  const generatedAt = new Date().toISOString();
23637
23732
  const managedBlock = `${WIKI_INDEX_BEGIN}
@@ -23648,7 +23743,7 @@ ${managedBlock}
23648
23743
  `;
23649
23744
  await writeWikiPage(history ?? await openWikiWriteContext(cwd, "wiki index"), indexPath, next);
23650
23745
  return {
23651
- path: path76.relative(cwd, indexPath),
23746
+ path: path77.relative(cwd, indexPath),
23652
23747
  pageCount: pages.length,
23653
23748
  generatedAt
23654
23749
  };
@@ -23656,13 +23751,13 @@ ${managedBlock}
23656
23751
  async function wikiCheckLinks(cwd) {
23657
23752
  const root = wikiRootPath3(cwd);
23658
23753
  const allFiles = await pathExists(root) ? await walkMarkdown(root) : [];
23659
- const files = allFiles.filter((absolutePath) => !path76.relative(root, absolutePath).startsWith(`templates${path76.sep}`));
23754
+ const files = allFiles.filter((absolutePath) => !path77.relative(root, absolutePath).startsWith(`templates${path77.sep}`));
23660
23755
  const broken = [];
23661
23756
  let checkedLinks = 0;
23662
23757
  let skippedExternal = 0;
23663
23758
  for (const absolutePath of files) {
23664
23759
  const content = await readFile39(absolutePath, "utf8");
23665
- const pageRelative = path76.relative(cwd, absolutePath);
23760
+ const pageRelative = path77.relative(cwd, absolutePath);
23666
23761
  for (const target of extractLinkTargets(content)) {
23667
23762
  if (EXTERNAL_LINK.test(target)) {
23668
23763
  skippedExternal += 1;
@@ -23673,7 +23768,7 @@ async function wikiCheckLinks(cwd) {
23673
23768
  continue;
23674
23769
  }
23675
23770
  checkedLinks += 1;
23676
- const resolved = path76.resolve(path76.dirname(absolutePath), filePart);
23771
+ const resolved = path77.resolve(path77.dirname(absolutePath), filePart);
23677
23772
  if (!await pathExists(resolved)) {
23678
23773
  broken.push({
23679
23774
  page: pageRelative,
@@ -23685,7 +23780,7 @@ async function wikiCheckLinks(cwd) {
23685
23780
  }
23686
23781
  const generatedAt = new Date().toISOString();
23687
23782
  const reportPath = linkCheckReportPath(cwd);
23688
- await mkdir20(path76.dirname(reportPath), { recursive: true });
23783
+ await mkdir20(path77.dirname(reportPath), { recursive: true });
23689
23784
  await writeFile14(reportPath, renderLinkCheckReport({
23690
23785
  generatedAt,
23691
23786
  checkedPages: files.length,
@@ -23694,7 +23789,7 @@ async function wikiCheckLinks(cwd) {
23694
23789
  broken
23695
23790
  }), "utf8");
23696
23791
  return {
23697
- reportPath: path76.relative(cwd, reportPath),
23792
+ reportPath: path77.relative(cwd, reportPath),
23698
23793
  checkedPages: files.length,
23699
23794
  checkedLinks,
23700
23795
  skippedExternal,
@@ -23745,7 +23840,7 @@ async function wikiValidate(cwd) {
23745
23840
  }
23746
23841
  if (await isIndexStale(cwd, pages)) {
23747
23842
  issues.push({
23748
- page: path76.join(path76.relative(cwd, wikiRootPath3(cwd)), "index.md"),
23843
+ page: path77.join(path77.relative(cwd, wikiRootPath3(cwd)), "index.md"),
23749
23844
  kind: "index",
23750
23845
  message: "index out of date, run `keryx wiki index`"
23751
23846
  });
@@ -23791,7 +23886,7 @@ function collectCommandLabel(input) {
23791
23886
  return ["wiki collect", ...flags].join(" ");
23792
23887
  }
23793
23888
  async function wikiPruneOrphans(cwd, history) {
23794
- const componentsDir = path76.join(wikiRootPath3(cwd), "components");
23889
+ const componentsDir = path77.join(wikiRootPath3(cwd), "components");
23795
23890
  if (!await pathExists(componentsDir)) {
23796
23891
  return { pruned: [], orphanedAccepted: [] };
23797
23892
  }
@@ -23811,15 +23906,15 @@ async function wikiPruneOrphans(cwd, history) {
23811
23906
  if (validSlugs.has(slug)) {
23812
23907
  continue;
23813
23908
  }
23814
- const filePath = path76.join(componentsDir, entry);
23909
+ const filePath = path77.join(componentsDir, entry);
23815
23910
  const current = await readFile39(filePath, "utf8");
23816
23911
  const isUnmodifiedDraft = /\nStatus:\s*draft\s*\n/.test(current) && current.includes("Generated by `keryx wiki collect`");
23817
23912
  if (isUnmodifiedDraft) {
23818
23913
  run ??= history ?? await openWikiWriteContext(cwd, "wiki prune");
23819
23914
  await deleteWikiPage(run, filePath);
23820
- pruned.push(path76.relative(cwd, filePath));
23915
+ pruned.push(path77.relative(cwd, filePath));
23821
23916
  } else {
23822
- orphanedAccepted.push(path76.relative(cwd, filePath));
23917
+ orphanedAccepted.push(path77.relative(cwd, filePath));
23823
23918
  }
23824
23919
  }
23825
23920
  return { pruned, orphanedAccepted };
@@ -23829,7 +23924,7 @@ async function validModuleNames(cwd) {
23829
23924
  return counts === undefined ? undefined : new Set(counts.keys());
23830
23925
  }
23831
23926
  async function moduleFileCounts(cwd) {
23832
- const nodesPath = path76.join(cwd, ".metaproject", "data", "gdgraph", "storage", "nodes.jsonl");
23927
+ const nodesPath = path77.join(cwd, ".metaproject", "data", "gdgraph", "storage", "nodes.jsonl");
23833
23928
  if (!await pathExists(nodesPath)) {
23834
23929
  return;
23835
23930
  }
@@ -23900,9 +23995,9 @@ async function wikiEvidence(input) {
23900
23995
  });
23901
23996
  }
23902
23997
  function resolveEvidenceScope(cwd, override) {
23903
- const absolute = path76.resolve(cwd);
23998
+ const absolute = path77.resolve(cwd);
23904
23999
  return {
23905
- projectId: override?.projectId ?? (path76.basename(absolute) || "project"),
24000
+ projectId: override?.projectId ?? (path77.basename(absolute) || "project"),
23906
24001
  checkoutId: override?.checkoutId ?? `checkout:${createHash15("sha256").update(absolute).digest("hex").slice(0, 16)}`,
23907
24002
  ...override?.workspaceId ? { workspaceId: override.workspaceId } : {},
23908
24003
  ...override?.taskId ? { taskId: override.taskId } : {}
@@ -23917,7 +24012,7 @@ function isMachineAuthoredPage(pageType, relativePath, content) {
23917
24012
  if (source === null) {
23918
24013
  return false;
23919
24014
  }
23920
- const normalised = relativePath.split(path76.sep).join("/").replace(/^wiki\//, "");
24015
+ const normalised = relativePath.split(path77.sep).join("/").replace(/^wiki\//, "");
23921
24016
  return WIKI_PAGE_PRODUCERS.some((producer) => producer.source === source && producer.pageType === pageType && producer.path.test(normalised) && /^-[ \t]+Link:.*\bsha256\b/m.test(content));
23922
24017
  }
23923
24018
  function createGdWikiService() {
@@ -23933,8 +24028,8 @@ function createGdWikiService() {
23933
24028
  };
23934
24029
  }
23935
24030
  async function collectGraphWikiCandidates(cwd, generatedAt, limit, onlyModules) {
23936
- const nodesPath = path76.join(cwd, ".metaproject", "data", "gdgraph", "storage", "nodes.jsonl");
23937
- const edgesPath = path76.join(cwd, ".metaproject", "data", "gdgraph", "storage", "edges.jsonl");
24031
+ const nodesPath = path77.join(cwd, ".metaproject", "data", "gdgraph", "storage", "nodes.jsonl");
24032
+ const edgesPath = path77.join(cwd, ".metaproject", "data", "gdgraph", "storage", "edges.jsonl");
23938
24033
  if (!await pathExists(nodesPath) || !await pathExists(edgesPath)) {
23939
24034
  return [];
23940
24035
  }
@@ -24021,6 +24116,12 @@ async function collectGraphWikiCandidates(cwd, generatedAt, limit, onlyModules)
24021
24116
  };
24022
24117
  const moduleCandidates = [];
24023
24118
  const pageModules = new Set(topModules.map((entry) => entry.name));
24119
+ const componentsDir = path77.join(wikiRootPath3(cwd), "components");
24120
+ const existingSlugs = new Set((await pathExists(componentsDir) ? await readdir13(componentsDir) : []).filter((entry) => entry.endsWith(".md")).map((entry) => entry.slice(0, -3)));
24121
+ const pageLink = (name) => {
24122
+ const slug = slugifyPath(name);
24123
+ return pageModules.has(name) || existingSlugs.has(slug) ? `${slug}.md` : null;
24124
+ };
24024
24125
  for (const item of topModules) {
24025
24126
  const moduleName = item.name;
24026
24127
  const moduleFileList = moduleFiles.get(moduleName) ?? [];
@@ -24032,7 +24133,7 @@ async function collectGraphWikiCandidates(cwd, generatedAt, limit, onlyModules)
24032
24133
  const entryFiles = moduleFileList.filter((file) => /(^|\/)index\.[jt]sx?$/.test(file)).slice(0, 4);
24033
24134
  const deps = topCounts(moduleDeps.get(moduleName), 6);
24034
24135
  const dependents = topCounts(moduleDependents.get(moduleName), 6);
24035
- const readme = await readModuleReadme(cwd, moduleName);
24136
+ const readme = await readModuleReadme(cwd, moduleName, pageLink);
24036
24137
  const exportsFrom = entryFiles.length > 0 ? entryFiles : keyFiles.slice(0, 2).map((entry) => entry.file);
24037
24138
  const exportApi = await extractModuleApi(cwd, exportsFrom);
24038
24139
  const reference = [];
@@ -24064,15 +24165,20 @@ async function collectGraphWikiCandidates(cwd, generatedAt, limit, onlyModules)
24064
24165
  if (exportApi.length > 0) {
24065
24166
  summaryParts.push("Exposes " + exportApi.length + " public symbol(s).");
24066
24167
  }
24067
- const relatedNames = [];
24168
+ const linkedNames = [];
24169
+ const unlinkedNames = [];
24068
24170
  const seenRelated = new Set([moduleName]);
24069
24171
  for (const [name] of [...deps, ...dependents]) {
24070
- if (!seenRelated.has(name) && pageModules.has(name)) {
24071
- seenRelated.add(name);
24072
- relatedNames.push(name);
24172
+ if (seenRelated.has(name)) {
24173
+ continue;
24073
24174
  }
24175
+ seenRelated.add(name);
24176
+ (pageLink(name) === null ? unlinkedNames : linkedNames).push(name);
24074
24177
  }
24075
- const related = relatedNames.slice(0, 8).map((name) => ({ name, slug: slugifyPath(name) }));
24178
+ const related = [
24179
+ ...linkedNames.slice(0, 8).map((name) => ({ name, page: pageLink(name) })),
24180
+ ...unlinkedNames.slice(0, 8).map((name) => ({ name, page: null }))
24181
+ ];
24076
24182
  moduleCandidates.push({
24077
24183
  type: "component",
24078
24184
  slug: slugifyPath(moduleName),
@@ -24117,8 +24223,8 @@ function topCounts(bucket, limit) {
24117
24223
  }
24118
24224
  return [...bucket.entries()].sort((a, b) => b[1] - a[1]).slice(0, limit);
24119
24225
  }
24120
- async function readModuleReadme(cwd, moduleName) {
24121
- const readmePath = path76.join(cwd, ...moduleName.split("/"), "README.md");
24226
+ async function readModuleReadme(cwd, moduleName, pageLink) {
24227
+ const readmePath = path77.join(cwd, ...moduleName.split("/"), "README.md");
24122
24228
  if (!await pathExists(readmePath)) {
24123
24229
  return null;
24124
24230
  }
@@ -24128,7 +24234,7 @@ async function readModuleReadme(cwd, moduleName) {
24128
24234
  if (!paragraph) {
24129
24235
  return null;
24130
24236
  }
24131
- const normalized = paragraph.replace(/\s+/g, " ").slice(0, 400);
24237
+ const normalized = truncateMarkdown(rewriteReadmeLinks(paragraph.replace(/\s+/g, " "), moduleName, pageLink), 400);
24132
24238
  return "- " + normalized + " (from module README)";
24133
24239
  } catch {
24134
24240
  return null;
@@ -24139,7 +24245,7 @@ async function extractModuleExports(cwd, files) {
24139
24245
  const declRe = /export\s+(?:async\s+)?(?:default\s+)?(?:const|let|var|function|class|type|interface|enum)\s+([A-Za-z_$][\w$]*)/g;
24140
24246
  const braceRe = /export\s*\{([^}]+)\}/g;
24141
24247
  for (const file of files.slice(0, 4)) {
24142
- const filePath = path76.join(cwd, ...file.split("/"));
24248
+ const filePath = path77.join(cwd, ...file.split("/"));
24143
24249
  if (!await pathExists(filePath)) {
24144
24250
  continue;
24145
24251
  }
@@ -24170,7 +24276,7 @@ async function extractModuleExports(cwd, files) {
24170
24276
  }
24171
24277
  async function extractModuleApi(cwd, files) {
24172
24278
  const names = await extractModuleExports(cwd, files);
24173
- const symbolsPath = path76.join(cwd, ".metaproject", "data", "gdgraph", "storage", "symbols.jsonl");
24279
+ const symbolsPath = path77.join(cwd, ".metaproject", "data", "gdgraph", "storage", "symbols.jsonl");
24174
24280
  if (names.length === 0 || !await pathExists(symbolsPath)) {
24175
24281
  return names.map((name) => "`" + name + "`");
24176
24282
  }
@@ -24196,7 +24302,7 @@ async function extractModuleApi(cwd, files) {
24196
24302
  });
24197
24303
  }
24198
24304
  async function collectHealthWikiCandidates(cwd, generatedAt) {
24199
- const healthPath = path76.join(cwd, ".metaproject", "data", "health", "artifacts", "latest.json");
24305
+ const healthPath = path77.join(cwd, ".metaproject", "data", "health", "artifacts", "latest.json");
24200
24306
  if (!await pathExists(healthPath)) {
24201
24307
  return [];
24202
24308
  }
@@ -24238,7 +24344,7 @@ async function collectHealthWikiCandidates(cwd, generatedAt) {
24238
24344
  }];
24239
24345
  }
24240
24346
  async function collectTestingWikiCandidates(cwd, generatedAt) {
24241
- const contextPath = path76.join(cwd, ".metaproject", "data", "testing", "context.md");
24347
+ const contextPath = path77.join(cwd, ".metaproject", "data", "testing", "context.md");
24242
24348
  if (!await pathExists(contextPath)) {
24243
24349
  return [];
24244
24350
  }
@@ -24269,8 +24375,8 @@ async function writeCollectedPage(cwd, candidate, force, history) {
24269
24375
  if (!folder) {
24270
24376
  throw new Error(`Unsupported collected wiki type: ${candidate.type}`);
24271
24377
  }
24272
- const filePath = path76.join(wikiRootPath3(cwd), folder, `${candidate.slug}.md`);
24273
- const relativePath = path76.relative(cwd, filePath);
24378
+ const filePath = path77.join(wikiRootPath3(cwd), folder, `${candidate.slug}.md`);
24379
+ const relativePath = path77.relative(cwd, filePath);
24274
24380
  const exists = await pathExists(filePath);
24275
24381
  if (exists && !force) {
24276
24382
  return { path: relativePath, type: candidate.type, source: candidate.source, action: "skipped" };
@@ -24321,7 +24427,7 @@ async function writeCollectedPage(cwd, candidate, force, history) {
24321
24427
  async function wikiPagesForFile(cwd, targetRepoPath) {
24322
24428
  const pages = await collectPages(cwd);
24323
24429
  const refs = await Promise.all(pages.map(async (page) => ({
24324
- repoPath: path76.relative(cwd, page.absolutePath).split(path76.sep).join("/"),
24430
+ repoPath: path77.relative(cwd, page.absolutePath).split(path77.sep).join("/"),
24325
24431
  content: await readFile39(page.absolutePath, "utf8")
24326
24432
  })));
24327
24433
  return backlinksFor(buildBacklinkIndex(refs), targetRepoPath);
@@ -24360,7 +24466,7 @@ function renderIndexBody(pages, generatedAt) {
24360
24466
  `).trimEnd();
24361
24467
  }
24362
24468
  async function isIndexStale(cwd, pages) {
24363
- const indexPath = path76.join(wikiRootPath3(cwd), "index.md");
24469
+ const indexPath = path77.join(wikiRootPath3(cwd), "index.md");
24364
24470
  if (!await pathExists(indexPath)) {
24365
24471
  return true;
24366
24472
  }
@@ -24378,7 +24484,7 @@ async function walkMarkdown(root) {
24378
24484
  const results = [];
24379
24485
  const entries = await readdir13(root, { withFileTypes: true });
24380
24486
  for (const entry of entries) {
24381
- const absolutePath = path76.join(root, entry.name);
24487
+ const absolutePath = path77.join(root, entry.name);
24382
24488
  if (entry.isDirectory()) {
24383
24489
  results.push(...await walkMarkdown(absolutePath));
24384
24490
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
@@ -24435,7 +24541,7 @@ ${JSON.stringify(state, null, 2)}
24435
24541
  `;
24436
24542
  }
24437
24543
  async function readIndexGeneratedAt(cwd) {
24438
- const indexPath = path76.join(wikiRootPath3(cwd), "index.md");
24544
+ const indexPath = path77.join(wikiRootPath3(cwd), "index.md");
24439
24545
  if (!await pathExists(indexPath)) {
24440
24546
  return null;
24441
24547
  }
@@ -24518,10 +24624,11 @@ ${reference.join(`
24518
24624
  ## Related Wiki
24519
24625
 
24520
24626
  Graph-derived - regenerated by \`keryx wiki collect --force\`. Only pages that
24521
- exist are linked; when enriching, add new links only to pages you have verified.
24627
+ exist are linked, other modules are named as code paths; when enriching, add
24628
+ new links only to pages you have verified.
24522
24629
 
24523
24630
  - [Wiki Index](../index.md)
24524
- ${related.map((entry) => "- [Module " + entry.name + "](" + entry.slug + ".md)").join(`
24631
+ ${related.map((entry) => entry.page === null ? "- `" + entry.name + "` (no wiki page)" : "- [Module " + entry.name + "](" + entry.page + ")").join(`
24525
24632
  `)}
24526
24633
 
24527
24634
  ## Changelog
@@ -24672,7 +24779,7 @@ async function validateStructure(cwd, pages, issues) {
24672
24779
  if (pattern.includes("*")) {
24673
24780
  continue;
24674
24781
  }
24675
- if (!await pathExists(path76.join(cwd, pattern))) {
24782
+ if (!await pathExists(path77.join(cwd, pattern))) {
24676
24783
  issues.push({
24677
24784
  page: page.relativePath,
24678
24785
  kind: "describes",
@@ -24742,7 +24849,7 @@ async function validatePageInvariants(cwd, pages, issues) {
24742
24849
  }
24743
24850
  }
24744
24851
  function toPosixPath(value) {
24745
- return value.split(path76.sep).join("/");
24852
+ return value.split(path77.sep).join("/");
24746
24853
  }
24747
24854
  function compareSemver(a, b) {
24748
24855
  const pa = a.split(".").map(Number);
@@ -24764,6 +24871,7 @@ var init_service4 = __esm(() => {
24764
24871
  init_evidence();
24765
24872
  init_history();
24766
24873
  init_page_invariants();
24874
+ init_readme_links();
24767
24875
  init_section_index();
24768
24876
  init_section_tombstone();
24769
24877
  init_staleness2();
@@ -24785,9 +24893,9 @@ var init_service4 = __esm(() => {
24785
24893
  // src/gdgraph/wiki-layer.ts
24786
24894
  import { createHash as createHash16 } from "crypto";
24787
24895
  import { mkdir as mkdir21, stat as stat12, writeFile as writeFile15 } from "fs/promises";
24788
- import path77 from "path";
24896
+ import path78 from "path";
24789
24897
  function storageDir(projectRoot) {
24790
- return path77.join(projectRoot, ".metaproject", "data", "gdgraph", "storage");
24898
+ return path78.join(projectRoot, ".metaproject", "data", "gdgraph", "storage");
24791
24899
  }
24792
24900
  function wikiPageId(relativePath) {
24793
24901
  return `wiki:${relativePath}`;
@@ -24853,11 +24961,11 @@ async function enrichBuildWithWikiLayer(input) {
24853
24961
  const mtimes = new Map;
24854
24962
  for (const record of input.fileRecords) {
24855
24963
  try {
24856
- const info = await stat12(path77.join(input.projectRoot, record.path));
24964
+ const info = await stat12(path78.join(input.projectRoot, record.path));
24857
24965
  mtimes.set(record.path, info.mtimeMs);
24858
24966
  } catch {}
24859
24967
  }
24860
- await writeFile15(path77.join(dir, BUILD_MANIFEST_FILE), `${JSON.stringify({ version: 1, files: computeFingerprints(input.fileRecords, mtimes) }, null, 2)}
24968
+ await writeFile15(path78.join(dir, BUILD_MANIFEST_FILE), `${JSON.stringify({ version: 1, files: computeFingerprints(input.fileRecords, mtimes) }, null, 2)}
24861
24969
  `, "utf8");
24862
24970
  const validModules = input.validModules !== undefined ? input.validModules : await (input.loadValidModules ?? defaultLoadValidModules)(input.projectRoot);
24863
24971
  const wikiPages = await collectPages(input.projectRoot);
@@ -24882,8 +24990,8 @@ async function enrichBuildWithWikiLayer(input) {
24882
24990
  version: page.version
24883
24991
  }))
24884
24992
  });
24885
- await writeJsonl(path77.join(dir, WIKI_PAGES_FILE), layer.pages);
24886
- await writeJsonl(path77.join(dir, DESCRIBES_FILE), layer.describes);
24993
+ await writeJsonl(path78.join(dir, WIKI_PAGES_FILE), layer.pages);
24994
+ await writeJsonl(path78.join(dir, DESCRIBES_FILE), layer.describes);
24887
24995
  return layer;
24888
24996
  }
24889
24997
  async function defaultLoadValidModules(projectRoot) {
@@ -24901,7 +25009,7 @@ var init_wiki_layer = __esm(() => {
24901
25009
  // src/gdskills/contracts.ts
24902
25010
  import { readFile as readFile51 } from "fs/promises";
24903
25011
  import { existsSync as existsSync15 } from "fs";
24904
- import path105 from "path";
25012
+ import path106 from "path";
24905
25013
  import { fileURLToPath as fileURLToPath2 } from "url";
24906
25014
  async function loadSchema(name) {
24907
25015
  const contract = CONTRACTS.find((entry) => entry.name === name);
@@ -24912,10 +25020,10 @@ async function loadSchema(name) {
24912
25020
  return JSON.parse(raw);
24913
25021
  }
24914
25022
  function contractPath(contract) {
24915
- const here = path105.dirname(fileURLToPath2(import.meta.url));
25023
+ const here = path106.dirname(fileURLToPath2(import.meta.url));
24916
25024
  if (contract.sourcePath) {
24917
- for (const root of [path105.join(here, "..", ".."), path105.join(here, ".."), here]) {
24918
- const candidate = path105.resolve(root, contract.sourcePath);
25025
+ for (const root of [path106.join(here, "..", ".."), path106.join(here, ".."), here]) {
25026
+ const candidate = path106.resolve(root, contract.sourcePath);
24919
25027
  if (existsSync15(candidate)) {
24920
25028
  return candidate;
24921
25029
  }
@@ -24925,7 +25033,7 @@ function contractPath(contract) {
24925
25033
  if (existsSync15(directPath)) {
24926
25034
  return directPath;
24927
25035
  }
24928
- const packagedSourcePath = path105.join(here, "..", "src", "gdskills", "contracts", contract.fileName);
25036
+ const packagedSourcePath = path106.join(here, "..", "src", "gdskills", "contracts", contract.fileName);
24929
25037
  if (existsSync15(packagedSourcePath)) {
24930
25038
  return packagedSourcePath;
24931
25039
  }
@@ -29959,7 +30067,7 @@ __export(exports_service5, {
29959
30067
  // src/gdgraph/build.ts
29960
30068
  import { mkdir as mkdir22, readdir as readdir14, readFile as readFile40, writeFile as writeFile16 } from "fs/promises";
29961
30069
  import { existsSync as existsSync7 } from "fs";
29962
- import path78 from "path";
30070
+ import path79 from "path";
29963
30071
 
29964
30072
  // src/gdgraph/types.ts
29965
30073
  var UNKNOWN_IMPORT_KIND = "unknown-static";
@@ -30024,7 +30132,7 @@ async function buildGraph(projectRoot) {
30024
30132
  const assetNodes = new Map;
30025
30133
  const fileRecords = [];
30026
30134
  for (const file of files) {
30027
- const absolutePath = path78.join(projectRoot, file);
30135
+ const absolutePath = path79.join(projectRoot, file);
30028
30136
  const content = await readFile40(absolutePath, "utf8");
30029
30137
  fileRecords.push({ path: file, content });
30030
30138
  const language = getLanguage(file);
@@ -30077,24 +30185,24 @@ async function collectSourceFiles(projectRoot) {
30077
30185
  const result = [];
30078
30186
  const skippedDirectories = [];
30079
30187
  async function walk(relativeDir) {
30080
- const absoluteDir = path78.join(projectRoot, relativeDir);
30188
+ const absoluteDir = path79.join(projectRoot, relativeDir);
30081
30189
  const entries = await readdir14(absoluteDir, { withFileTypes: true });
30082
30190
  for (const entry of entries) {
30083
30191
  if (entry.isDirectory()) {
30084
30192
  if (IGNORE_DIRS.has(entry.name)) {
30085
- skippedDirectories.push(normalizePath2(path78.posix.join(relativeDir, entry.name)).replace(/^\.\//, ""));
30193
+ skippedDirectories.push(normalizePath2(path79.posix.join(relativeDir, entry.name)).replace(/^\.\//, ""));
30086
30194
  continue;
30087
30195
  }
30088
- await walk(normalizePath2(path78.posix.join(relativeDir, entry.name)));
30196
+ await walk(normalizePath2(path79.posix.join(relativeDir, entry.name)));
30089
30197
  continue;
30090
30198
  }
30091
30199
  if (!entry.isFile()) {
30092
30200
  continue;
30093
30201
  }
30094
- if (!SOURCE_EXTENSIONS.includes(path78.extname(entry.name))) {
30202
+ if (!SOURCE_EXTENSIONS.includes(path79.extname(entry.name))) {
30095
30203
  continue;
30096
30204
  }
30097
- result.push(normalizePath2(path78.posix.join(relativeDir, entry.name)).replace(/^\.\//, ""));
30205
+ result.push(normalizePath2(path79.posix.join(relativeDir, entry.name)).replace(/^\.\//, ""));
30098
30206
  }
30099
30207
  }
30100
30208
  await walk(".");
@@ -30176,8 +30284,8 @@ function resolveImport(projectRoot, fromFile, specifier, fileSet, resolver) {
30176
30284
  }
30177
30285
  function resolveAssetImport(projectRoot, fromFile, specifier, resolver) {
30178
30286
  for (const candidate of importCandidateBases(projectRoot, fromFile, specifier, resolver)) {
30179
- const extension = path78.posix.extname(candidate);
30180
- if (ASSET_EXTENSIONS.includes(extension) && existsSync7(path78.join(projectRoot, candidate))) {
30287
+ const extension = path79.posix.extname(candidate);
30288
+ if (ASSET_EXTENSIONS.includes(extension) && existsSync7(path79.join(projectRoot, candidate))) {
30181
30289
  return candidate;
30182
30290
  }
30183
30291
  }
@@ -30186,17 +30294,17 @@ function resolveAssetImport(projectRoot, fromFile, specifier, resolver) {
30186
30294
  function importCandidateBases(projectRoot, fromFile, specifier, resolver) {
30187
30295
  const normalizedSpecifier = stripImportSuffix(specifier);
30188
30296
  if (normalizedSpecifier.startsWith(".") && getLanguage(fromFile) !== "python") {
30189
- const fromDir = path78.posix.dirname(fromFile);
30190
- return [normalizePath2(path78.posix.normalize(path78.posix.join(fromDir, normalizedSpecifier)))];
30297
+ const fromDir = path79.posix.dirname(fromFile);
30298
+ return [normalizePath2(path79.posix.normalize(path79.posix.join(fromDir, normalizedSpecifier)))];
30191
30299
  }
30192
- return resolver.candidateBases(normalizedSpecifier, fromFile).map((candidate) => normalizePath2(path78.relative(projectRoot, path78.join(projectRoot, candidate))));
30300
+ return resolver.candidateBases(normalizedSpecifier, fromFile).map((candidate) => normalizePath2(path79.relative(projectRoot, path79.join(projectRoot, candidate))));
30193
30301
  }
30194
30302
  function resolveSourceCandidate(base, fileSet) {
30195
30303
  const candidates = [
30196
30304
  base,
30197
30305
  ...SOURCE_RESOLUTION_EXTENSIONS.map((extension) => `${base}${extension}`),
30198
- ...SOURCE_RESOLUTION_EXTENSIONS.map((extension) => path78.posix.join(base, `index${extension}`)),
30199
- path78.posix.join(base, "__init__.py")
30306
+ ...SOURCE_RESOLUTION_EXTENSIONS.map((extension) => path79.posix.join(base, `index${extension}`)),
30307
+ path79.posix.join(base, "__init__.py")
30200
30308
  ];
30201
30309
  return candidates.find((candidate) => fileSet.has(candidate)) ?? null;
30202
30310
  }
@@ -30226,7 +30334,7 @@ async function loadJavaResolver(projectRoot) {
30226
30334
  return createJavaResolver(roots);
30227
30335
  }
30228
30336
  async function discoverJavaSourceRoots(projectRoot) {
30229
- const pomPath = path78.join(projectRoot, "pom.xml");
30337
+ const pomPath = path79.join(projectRoot, "pom.xml");
30230
30338
  if (existsSync7(pomPath)) {
30231
30339
  try {
30232
30340
  const roots = parseMavenSourceRoots(await readFile40(pomPath, "utf8"));
@@ -30236,7 +30344,7 @@ async function discoverJavaSourceRoots(projectRoot) {
30236
30344
  } catch {}
30237
30345
  }
30238
30346
  for (const gradleName of ["build.gradle", "build.gradle.kts"]) {
30239
- const gradlePath = path78.join(projectRoot, gradleName);
30347
+ const gradlePath = path79.join(projectRoot, gradleName);
30240
30348
  if (existsSync7(gradlePath)) {
30241
30349
  try {
30242
30350
  const roots = parseGradleSourceRoots(await readFile40(gradlePath, "utf8"));
@@ -30258,12 +30366,12 @@ function createJavaResolver(sourceRoots) {
30258
30366
  return [];
30259
30367
  }
30260
30368
  const relative = specifier.split(".").join("/");
30261
- return sourceRoots.map((root) => normalizePath2(path78.posix.join(root, relative)));
30369
+ return sourceRoots.map((root) => normalizePath2(path79.posix.join(root, relative)));
30262
30370
  }
30263
30371
  };
30264
30372
  }
30265
30373
  function loadPythonResolver(projectRoot) {
30266
- const hasSrc = existsSync7(path78.join(projectRoot, "src"));
30374
+ const hasSrc = existsSync7(path79.join(projectRoot, "src"));
30267
30375
  return createPythonResolver(hasSrc);
30268
30376
  }
30269
30377
  function createPythonResolver(hasSrc) {
@@ -30276,16 +30384,16 @@ function createPythonResolver(hasSrc) {
30276
30384
  if (specifier.startsWith(".")) {
30277
30385
  const dots = /^\.+/.exec(specifier)?.[0].length ?? 0;
30278
30386
  const rest = specifier.slice(dots);
30279
- let baseDir = path78.posix.dirname(fromFile);
30387
+ let baseDir = path79.posix.dirname(fromFile);
30280
30388
  for (let level = 1;level < dots; level += 1) {
30281
- baseDir = path78.posix.dirname(baseDir);
30389
+ baseDir = path79.posix.dirname(baseDir);
30282
30390
  }
30283
30391
  const suffix = rest ? rest.split(".").join("/") : "";
30284
- const base = suffix ? path78.posix.join(baseDir, suffix) : baseDir;
30392
+ const base = suffix ? path79.posix.join(baseDir, suffix) : baseDir;
30285
30393
  return [normalizePath2(base)];
30286
30394
  }
30287
30395
  const relative = specifier.split(".").join("/");
30288
- return roots.map((root) => normalizePath2(root ? path78.posix.join(root, relative) : relative));
30396
+ return roots.map((root) => normalizePath2(root ? path79.posix.join(root, relative) : relative));
30289
30397
  }
30290
30398
  };
30291
30399
  }
@@ -30294,8 +30402,8 @@ function parseMavenSourceRoots(pomXml) {
30294
30402
  for (const match of pomXml.matchAll(/<module>\s*([^<]+?)\s*<\/module>/g)) {
30295
30403
  const moduleDir = match[1]?.trim();
30296
30404
  if (moduleDir && !moduleDir.includes("${")) {
30297
- roots.add(normalizePath2(path78.posix.join(moduleDir, "src/main/java")));
30298
- roots.add(normalizePath2(path78.posix.join(moduleDir, "src/test/java")));
30405
+ roots.add(normalizePath2(path79.posix.join(moduleDir, "src/main/java")));
30406
+ roots.add(normalizePath2(path79.posix.join(moduleDir, "src/test/java")));
30299
30407
  }
30300
30408
  }
30301
30409
  for (const tag of ["sourceDirectory", "testSourceDirectory"]) {
@@ -30328,7 +30436,7 @@ function parseGradleSourceRoots(buildGradle) {
30328
30436
  var TSCONFIG_EXTENDS_MAX_DEPTH = 10;
30329
30437
  async function loadTsconfigResolver(projectRoot) {
30330
30438
  const empty = createTsconfigResolver(null, []);
30331
- const tsconfigPath = path78.join(projectRoot, "tsconfig.json");
30439
+ const tsconfigPath = path79.join(projectRoot, "tsconfig.json");
30332
30440
  if (!existsSync7(tsconfigPath)) {
30333
30441
  return empty;
30334
30442
  }
@@ -30341,7 +30449,7 @@ async function loadTsconfigResolver(projectRoot) {
30341
30449
  return createTsconfigResolver(resolved.baseUrl, paths);
30342
30450
  }
30343
30451
  function toProjectRelativeDir(projectRoot, absoluteDir) {
30344
- const relative = normalizePath2(path78.relative(projectRoot, absoluteDir)).replace(/^\.\//, "");
30452
+ const relative = normalizePath2(path79.relative(projectRoot, absoluteDir)).replace(/^\.\//, "");
30345
30453
  return relative === "." ? "" : relative;
30346
30454
  }
30347
30455
  async function readTsconfigJson(configPath) {
@@ -30356,11 +30464,11 @@ function resolveTsconfigExtendsPath(configDir, extendsSpecifier) {
30356
30464
  if (!extendsSpecifier.startsWith(".") && !extendsSpecifier.startsWith("/")) {
30357
30465
  return null;
30358
30466
  }
30359
- const resolved = path78.resolve(configDir, extendsSpecifier);
30467
+ const resolved = path79.resolve(configDir, extendsSpecifier);
30360
30468
  return resolved.endsWith(".json") ? resolved : `${resolved}.json`;
30361
30469
  }
30362
30470
  async function resolveTsconfigOptions(configPath, visited, depth, projectRoot) {
30363
- const resolvedPath = path78.resolve(configPath);
30471
+ const resolvedPath = path79.resolve(configPath);
30364
30472
  if (depth > TSCONFIG_EXTENDS_MAX_DEPTH || visited.has(resolvedPath)) {
30365
30473
  return null;
30366
30474
  }
@@ -30371,15 +30479,15 @@ async function resolveTsconfigOptions(configPath, visited, depth, projectRoot) {
30371
30479
  }
30372
30480
  let inherited = null;
30373
30481
  if (typeof parsed.extends === "string") {
30374
- const basePath = resolveTsconfigExtendsPath(path78.dirname(resolvedPath), parsed.extends);
30482
+ const basePath = resolveTsconfigExtendsPath(path79.dirname(resolvedPath), parsed.extends);
30375
30483
  if (basePath) {
30376
30484
  inherited = await resolveTsconfigOptions(basePath, visited, depth + 1, projectRoot);
30377
30485
  }
30378
30486
  }
30379
- const configDir = path78.dirname(resolvedPath);
30487
+ const configDir = path79.dirname(resolvedPath);
30380
30488
  const declaringDir = toProjectRelativeDir(projectRoot, configDir);
30381
30489
  const options = parsed.compilerOptions ?? {};
30382
- const ownBaseUrl = typeof options.baseUrl === "string" ? toProjectRelativeDir(projectRoot, path78.resolve(configDir, options.baseUrl)) : null;
30490
+ const ownBaseUrl = typeof options.baseUrl === "string" ? toProjectRelativeDir(projectRoot, path79.resolve(configDir, options.baseUrl)) : null;
30383
30491
  const baseUrl = ownBaseUrl ?? inherited?.baseUrl ?? null;
30384
30492
  const ownPaths = isRecord4(options.paths) ? Object.entries(options.paths).filter((entry) => Array.isArray(entry[1])).map(([pattern, targets]) => ({
30385
30493
  pattern,
@@ -30408,7 +30516,7 @@ function createTsconfigResolver(baseUrl, mappings) {
30408
30516
  }
30409
30517
  }
30410
30518
  if (baseUrl !== null) {
30411
- candidates.push(normalizePath2(path78.posix.join(baseUrl, normalizedSpecifier)));
30519
+ candidates.push(normalizePath2(path79.posix.join(baseUrl, normalizedSpecifier)));
30412
30520
  }
30413
30521
  return [...new Set(candidates.map((candidate) => candidate.replace(/^\.\//, "")))];
30414
30522
  }
@@ -30428,7 +30536,7 @@ function matchPathPattern(pattern, specifier) {
30428
30536
  }
30429
30537
  function applyPathTarget(base, target, wildcard) {
30430
30538
  const replaced = target.includes("*") ? target.replace("*", wildcard) : target;
30431
- return normalizePath2(path78.posix.normalize(path78.posix.join(base, replaced)));
30539
+ return normalizePath2(path79.posix.normalize(path79.posix.join(base, replaced)));
30432
30540
  }
30433
30541
  function stripJsonComments(source) {
30434
30542
  let out = "";
@@ -30481,21 +30589,21 @@ function isRecord4(value) {
30481
30589
  return typeof value === "object" && value !== null && !Array.isArray(value);
30482
30590
  }
30483
30591
  async function writeGraph(projectRoot, graph) {
30484
- const storageDir = path78.join(projectRoot, ".metaproject", "data", "gdgraph", "storage");
30485
- const artifactsDir = path78.join(projectRoot, ".metaproject", "data", "gdgraph", "artifacts");
30592
+ const storageDir = path79.join(projectRoot, ".metaproject", "data", "gdgraph", "storage");
30593
+ const artifactsDir = path79.join(projectRoot, ".metaproject", "data", "gdgraph", "artifacts");
30486
30594
  await mkdir22(storageDir, { recursive: true });
30487
30595
  await mkdir22(artifactsDir, { recursive: true });
30488
- await writeFile16(path78.join(storageDir, "nodes.jsonl"), graph.nodes.map((node) => JSON.stringify(node)).join(`
30596
+ await writeFile16(path79.join(storageDir, "nodes.jsonl"), graph.nodes.map((node) => JSON.stringify(node)).join(`
30489
30597
  `) + `
30490
30598
  `, "utf8");
30491
- await writeFile16(path78.join(storageDir, "edges.jsonl"), graph.edges.map((edge) => JSON.stringify(edge)).join(`
30599
+ await writeFile16(path79.join(storageDir, "edges.jsonl"), graph.edges.map((edge) => JSON.stringify(edge)).join(`
30492
30600
  `) + `
30493
30601
  `, "utf8");
30494
- await writeFile16(path78.join(artifactsDir, "module-map.json"), JSON.stringify(buildModuleMap(graph), null, 2) + `
30602
+ await writeFile16(path79.join(artifactsDir, "module-map.json"), JSON.stringify(buildModuleMap(graph), null, 2) + `
30495
30603
  `, "utf8");
30496
30604
  }
30497
30605
  async function writeSummary(projectRoot, graph, collection) {
30498
- const artifactsDir = path78.join(projectRoot, ".metaproject", "data", "gdgraph", "artifacts");
30606
+ const artifactsDir = path79.join(projectRoot, ".metaproject", "data", "gdgraph", "artifacts");
30499
30607
  await mkdir22(artifactsDir, { recursive: true });
30500
30608
  const unresolved = graph.edges.filter((edge) => edge.kind === "unresolved");
30501
30609
  const imports = graph.edges.filter((edge) => edge.kind === "imports");
@@ -30510,7 +30618,7 @@ async function writeSummary(projectRoot, graph, collection) {
30510
30618
  `);
30511
30619
  const skippedList = collection.skippedDirectories.length > 0 ? collection.skippedDirectories.slice(0, 30).map((dir) => `- \`${dir}\``).join(`
30512
30620
  `) : "- none";
30513
- const summaryPath = path78.join(artifactsDir, "summary.md");
30621
+ const summaryPath = path79.join(artifactsDir, "summary.md");
30514
30622
  const content = `# gdgraph Summary
30515
30623
 
30516
30624
  ## Stats
@@ -30591,7 +30699,7 @@ function groupBy(items, getKey) {
30591
30699
  }
30592
30700
  function unresolvedType(specifier) {
30593
30701
  const stripped = stripImportSuffix(specifier);
30594
- const extension = path78.posix.extname(stripped);
30702
+ const extension = path79.posix.extname(stripped);
30595
30703
  if (extension) {
30596
30704
  return extension;
30597
30705
  }
@@ -30601,13 +30709,13 @@ function unresolvedType(specifier) {
30601
30709
  return "package";
30602
30710
  }
30603
30711
  function normalizePath2(value) {
30604
- return value.split(path78.sep).join("/");
30712
+ return value.split(path79.sep).join("/");
30605
30713
  }
30606
30714
 
30607
30715
  // src/gdgraph/target.ts
30608
- import path79 from "path";
30716
+ import path80 from "path";
30609
30717
  function normalizeTarget(target) {
30610
- return target.replace(/^\.\//, "").split(path79.sep).join("/");
30718
+ return target.replace(/^\.\//, "").split(path80.sep).join("/");
30611
30719
  }
30612
30720
  function resolveGraphTarget(graph, target) {
30613
30721
  const normalized = normalizeTarget(target);
@@ -30700,15 +30808,15 @@ init_config3();
30700
30808
 
30701
30809
  // src/gdgraph/query.ts
30702
30810
  import { readFile as readFile41 } from "fs/promises";
30703
- import path80 from "path";
30811
+ import path81 from "path";
30704
30812
  async function loadGraph(projectRoot) {
30705
- const storageDir = path80.join(projectRoot, ".metaproject", "data", "gdgraph", "storage");
30706
- const nodes = await readJsonl(path80.join(storageDir, "nodes.jsonl"));
30707
- const edges = await readJsonl(path80.join(storageDir, "edges.jsonl"));
30708
- const symbols = await readJsonl(path80.join(storageDir, "symbols.jsonl"));
30709
- const calls = await readJsonl(path80.join(storageDir, "calls.jsonl"));
30710
- const wikiPages = await readJsonl(path80.join(storageDir, "wiki-pages.jsonl"));
30711
- const describes = await readJsonl(path80.join(storageDir, "describes.jsonl"));
30813
+ const storageDir = path81.join(projectRoot, ".metaproject", "data", "gdgraph", "storage");
30814
+ const nodes = await readJsonl(path81.join(storageDir, "nodes.jsonl"));
30815
+ const edges = await readJsonl(path81.join(storageDir, "edges.jsonl"));
30816
+ const symbols = await readJsonl(path81.join(storageDir, "symbols.jsonl"));
30817
+ const calls = await readJsonl(path81.join(storageDir, "calls.jsonl"));
30818
+ const wikiPages = await readJsonl(path81.join(storageDir, "wiki-pages.jsonl"));
30819
+ const describes = await readJsonl(path81.join(storageDir, "describes.jsonl"));
30712
30820
  const graph = { nodes, edges };
30713
30821
  if (symbols.length > 0) {
30714
30822
  graph.symbols = symbols;
@@ -30768,7 +30876,7 @@ async function bunfigPreloadRoots(projectRoot) {
30768
30876
  const roots = new Set;
30769
30877
  let text;
30770
30878
  try {
30771
- text = await readFile41(path80.join(projectRoot, "bunfig.toml"), "utf8");
30879
+ text = await readFile41(path81.join(projectRoot, "bunfig.toml"), "utf8");
30772
30880
  } catch {
30773
30881
  return roots;
30774
30882
  }
@@ -30782,8 +30890,8 @@ async function bunfigPreloadRoots(projectRoot) {
30782
30890
  if (raw.length === 0) {
30783
30891
  continue;
30784
30892
  }
30785
- const absolute = path80.resolve(projectRoot, raw);
30786
- const relative = path80.relative(projectRoot, absolute).split(path80.sep).join("/");
30893
+ const absolute = path81.resolve(projectRoot, raw);
30894
+ const relative = path81.relative(projectRoot, absolute).split(path81.sep).join("/");
30787
30895
  roots.add(relative);
30788
30896
  }
30789
30897
  }
@@ -30856,7 +30964,7 @@ function canonicalCycle(cycle) {
30856
30964
 
30857
30965
  // src/gdgraph/repomap.ts
30858
30966
  import { mkdir as mkdir23, writeFile as writeFile17 } from "fs/promises";
30859
- import path81 from "path";
30967
+ import path82 from "path";
30860
30968
 
30861
30969
  // src/gdgraph/pagerank.ts
30862
30970
  function personalizedPageRank(nodes, edges, options) {
@@ -30967,7 +31075,7 @@ function overflowContent(required, missing, budget) {
30967
31075
  `);
30968
31076
  }
30969
31077
  function repomapArtifactPath(cwd) {
30970
- return path81.join(cwd, ".metaproject", "data", "gdgraph", "artifacts", "repomap.md");
31078
+ return path82.join(cwd, ".metaproject", "data", "gdgraph", "artifacts", "repomap.md");
30971
31079
  }
30972
31080
  function buildRankEdges(graph, config) {
30973
31081
  const edges = [];
@@ -31112,7 +31220,7 @@ function computeRepomap(graph, config, options = {}) {
31112
31220
  async function writeRepomap(cwd, graph, config, options = {}) {
31113
31221
  const result = computeRepomap(graph, config, options);
31114
31222
  const artifactPath = repomapArtifactPath(cwd);
31115
- await mkdir23(path81.dirname(artifactPath), { recursive: true });
31223
+ await mkdir23(path82.dirname(artifactPath), { recursive: true });
31116
31224
  await writeFile17(artifactPath, result.content, "utf8");
31117
31225
  return { ...result, path: artifactPath };
31118
31226
  }
@@ -31195,12 +31303,12 @@ init_section_tombstone();
31195
31303
  // src/forgetting/journal.ts
31196
31304
  init_fs();
31197
31305
  import { appendFile as appendFile5, mkdir as mkdir24, readFile as readFile42, stat as stat13 } from "fs/promises";
31198
- import path82 from "path";
31306
+ import path83 from "path";
31199
31307
  function forgettingDataDir(cwd) {
31200
- return path82.join(cwd, ".metaproject", "data", "forgetting");
31308
+ return path83.join(cwd, ".metaproject", "data", "forgetting");
31201
31309
  }
31202
31310
  function deletionJournalPath(cwd) {
31203
- return path82.join(forgettingDataDir(cwd), "journal.jsonl");
31311
+ return path83.join(forgettingDataDir(cwd), "journal.jsonl");
31204
31312
  }
31205
31313
  async function readDeletionJournal(cwd) {
31206
31314
  const file = deletionJournalPath(cwd);
@@ -31619,12 +31727,12 @@ __export(exports_service7, {
31619
31727
  gateExitCode: () => gateExitCode,
31620
31728
  readWikiFreshnessMetric: () => readWikiFreshnessMetric
31621
31729
  });
31622
- import path102 from "path";
31730
+ import path103 from "path";
31623
31731
 
31624
31732
  // src/health/config.ts
31625
31733
  init_fs();
31626
31734
  init_json();
31627
- import path83 from "path";
31735
+ import path84 from "path";
31628
31736
  var DEFAULT_HEALTH_CONFIG = {
31629
31737
  schemaVersion: 2,
31630
31738
  ignore: {
@@ -31680,7 +31788,7 @@ var DEFAULT_HEALTH_CONFIG = {
31680
31788
  }
31681
31789
  };
31682
31790
  function configPath2(cwd) {
31683
- return path83.join(cwd, ".metaproject", "health.config.json");
31791
+ return path84.join(cwd, ".metaproject", "health.config.json");
31684
31792
  }
31685
31793
  var STRICTEST_GATE = {
31686
31794
  failOnPriorities: ["P0", "P1", "P2", "P3"],
@@ -31731,7 +31839,7 @@ async function loadHealthConfig(cwd) {
31731
31839
  // src/health/run.ts
31732
31840
  init_fs();
31733
31841
  import { mkdir as mkdir28, writeFile as writeFile21 } from "fs/promises";
31734
- import path101 from "path";
31842
+ import path102 from "path";
31735
31843
 
31736
31844
  // src/metrics/provenance.ts
31737
31845
  async function collectGitProvenance(cwd) {
@@ -31831,12 +31939,12 @@ function computeGate2(input) {
31831
31939
  }
31832
31940
 
31833
31941
  // src/health/scopes.ts
31834
- import path86 from "path";
31942
+ import path87 from "path";
31835
31943
 
31836
31944
  // src/health/util.ts
31837
31945
  init_fs();
31838
31946
  import { mkdir as mkdir25, readFile as readFile43, readdir as readdir15, writeFile as writeFile18 } from "fs/promises";
31839
- import path84 from "path";
31947
+ import path85 from "path";
31840
31948
  var IGNORED_DIRS = new Set([
31841
31949
  "node_modules",
31842
31950
  ".git",
@@ -31880,14 +31988,14 @@ async function toolVersion(command, cwd) {
31880
31988
  }
31881
31989
  }
31882
31990
  function dataRoot3(cwd) {
31883
- return path84.join(cwd, ".metaproject", "data", "health");
31991
+ return path85.join(cwd, ".metaproject", "data", "health");
31884
31992
  }
31885
31993
  async function writeRaw(cwd, source, content, stamp) {
31886
- const dir = path84.join(dataRoot3(cwd), "raw", source);
31994
+ const dir = path85.join(dataRoot3(cwd), "raw", source);
31887
31995
  await mkdir25(dir, { recursive: true });
31888
- const file = path84.join(dir, `${stamp}.log`);
31996
+ const file = path85.join(dir, `${stamp}.log`);
31889
31997
  await writeFile18(file, content, "utf8");
31890
- return path84.relative(cwd, file);
31998
+ return path85.relative(cwd, file);
31891
31999
  }
31892
32000
  async function listSourceFiles(cwd, ignorePaths = []) {
31893
32001
  const { files } = await listSourceFilesWithReasons(cwd, ignorePaths);
@@ -31907,7 +32015,7 @@ async function walk2(root, dir, out, incompleteReasons) {
31907
32015
  try {
31908
32016
  entries = await readdir15(dir, { withFileTypes: true });
31909
32017
  } catch (error) {
31910
- incompleteReasons.push(`${path84.relative(root, dir) || "."}: ${error instanceof Error ? error.message : String(error)}`);
32018
+ incompleteReasons.push(`${path85.relative(root, dir) || "."}: ${error instanceof Error ? error.message : String(error)}`);
31911
32019
  return;
31912
32020
  }
31913
32021
  for (const entry of entries) {
@@ -31915,14 +32023,14 @@ async function walk2(root, dir, out, incompleteReasons) {
31915
32023
  if (entry.isDirectory() && !IGNORED_DIRS.has(entry.name)) {}
31916
32024
  continue;
31917
32025
  }
31918
- const abs = path84.join(dir, entry.name);
32026
+ const abs = path85.join(dir, entry.name);
31919
32027
  if (entry.isDirectory()) {
31920
32028
  if (IGNORED_DIRS.has(entry.name)) {
31921
32029
  continue;
31922
32030
  }
31923
32031
  await walk2(root, abs, out, incompleteReasons);
31924
- } else if (entry.isFile() && SOURCE_EXT.has(path84.extname(entry.name))) {
31925
- out.push(path84.relative(root, abs));
32032
+ } else if (entry.isFile() && SOURCE_EXT.has(path85.extname(entry.name))) {
32033
+ out.push(path85.relative(root, abs));
31926
32034
  }
31927
32035
  }
31928
32036
  }
@@ -31937,7 +32045,7 @@ function moduleOfFile(file) {
31937
32045
  return null;
31938
32046
  }
31939
32047
  function isSourceFile(file) {
31940
- return SOURCE_EXT.has(path84.extname(file));
32048
+ return SOURCE_EXT.has(path85.extname(file));
31941
32049
  }
31942
32050
  function matchesAnyPattern(file, patterns) {
31943
32051
  const normalized = file.replace(/\\/g, "/").replace(/^\.\//, "");
@@ -32037,7 +32145,7 @@ function rankHotspots(files, churn, sourceAnalysis) {
32037
32145
  // src/health/source-analysis.ts
32038
32146
  init_fs();
32039
32147
  import { readFile as readFile44 } from "fs/promises";
32040
- import path85 from "path";
32148
+ import path86 from "path";
32041
32149
 
32042
32150
  // src/health/metrics/complexity.ts
32043
32151
  var CONTROL_KEYWORDS = new Set([
@@ -32271,7 +32379,7 @@ async function analyzeSourceFiles(cwd, sourceFiles) {
32271
32379
  return new Map(entries.filter((entry) => entry !== null));
32272
32380
  }
32273
32381
  async function analyzeSourceFile(cwd, file) {
32274
- const abs = path85.join(cwd, file);
32382
+ const abs = path86.join(cwd, file);
32275
32383
  if (!await pathExists(abs)) {
32276
32384
  return null;
32277
32385
  }
@@ -32344,14 +32452,14 @@ async function computeMetrics(input) {
32344
32452
  }
32345
32453
  const components = new Map;
32346
32454
  for (const file of sourceFiles) {
32347
- const dir = path86.posix.dirname(file);
32455
+ const dir = path87.posix.dirname(file);
32348
32456
  if (dir === "." || dir === moduleOfFile(file)) {
32349
32457
  continue;
32350
32458
  }
32351
32459
  components.set(dir, [...components.get(dir) ?? [], file]);
32352
32460
  }
32353
32461
  for (const [name, files] of [...components.entries()].sort()) {
32354
- const compFindings = findings.filter((f) => f.file && path86.posix.dirname(f.file) === name);
32462
+ const compFindings = findings.filter((f) => f.file && path87.posix.dirname(f.file) === name);
32355
32463
  scopes.push(build("component", `component:${name}`, name, files, compFindings, averageCoverage(files, coverage)));
32356
32464
  }
32357
32465
  const findingFiles = findings.map((f) => f.file).filter((f) => Boolean(f));
@@ -32396,9 +32504,9 @@ function tally2(values) {
32396
32504
  // src/health/baseline.ts
32397
32505
  init_fs();
32398
32506
  import { mkdir as mkdir26, readFile as readFile45, writeFile as writeFile19 } from "fs/promises";
32399
- import path87 from "path";
32507
+ import path88 from "path";
32400
32508
  function baselinePath(cwd) {
32401
- return path87.join(cwd, ".metaproject", "health", "baselines", "scores.json");
32509
+ return path88.join(cwd, ".metaproject", "health", "baselines", "scores.json");
32402
32510
  }
32403
32511
  async function loadBaseline(cwd) {
32404
32512
  const file = baselinePath(cwd);
@@ -32430,7 +32538,7 @@ async function writeBaseline(cwd, metrics, generatedAt, selector) {
32430
32538
  scopes[key] = value;
32431
32539
  }
32432
32540
  const file = baselinePath(cwd);
32433
- await mkdir26(path87.dirname(file), { recursive: true });
32541
+ await mkdir26(path88.dirname(file), { recursive: true });
32434
32542
  await writeFile19(file, `${JSON.stringify({ generatedAt, scopes }, null, 2)}
32435
32543
  `, "utf8");
32436
32544
  return updated;
@@ -32484,10 +32592,10 @@ async function getChurn(cwd, windowDays) {
32484
32592
 
32485
32593
  // src/health/metrics/wiki-freshness.ts
32486
32594
  import { readFile as readFile46, stat as stat14 } from "fs/promises";
32487
- import path88 from "path";
32595
+ import path89 from "path";
32488
32596
  var DEFAULT_STALE_EVIDENCE_DAYS = 7;
32489
32597
  function freshnessReportPath(cwd) {
32490
- return path88.join(cwd, ".metaproject", "data", "wiki", "freshness", "latest.json");
32598
+ return path89.join(cwd, ".metaproject", "data", "wiki", "freshness", "latest.json");
32491
32599
  }
32492
32600
  async function readWikiFreshnessMetric(cwd, options = {}) {
32493
32601
  const file = freshnessReportPath(cwd);
@@ -32508,7 +32616,7 @@ async function readWikiFreshnessMetric(cwd, options = {}) {
32508
32616
  } catch {
32509
32617
  return {
32510
32618
  status: "unreadable-report",
32511
- reason: `${path88.relative(cwd, file)} is not valid JSON; re-run \`keryx wiki freshness\`.`
32619
+ reason: `${path89.relative(cwd, file)} is not valid JSON; re-run \`keryx wiki freshness\`.`
32512
32620
  };
32513
32621
  }
32514
32622
  const report = parsed;
@@ -32518,7 +32626,7 @@ async function readWikiFreshnessMetric(cwd, options = {}) {
32518
32626
  if (pagesTotal === null || pagesFresh === null) {
32519
32627
  return {
32520
32628
  status: "unreadable-report",
32521
- reason: `${path88.relative(cwd, file)} is missing its totals; re-run \`keryx wiki freshness\`.`
32629
+ reason: `${path89.relative(cwd, file)} is missing its totals; re-run \`keryx wiki freshness\`.`
32522
32630
  };
32523
32631
  }
32524
32632
  const pagesUndecidable = numberOr3(totals.pagesUndecidable) ?? 0;
@@ -32572,12 +32680,12 @@ function renderWikiFreshnessLine(metric) {
32572
32680
  }
32573
32681
 
32574
32682
  // src/health/sources/helpers.ts
32575
- import path89 from "path";
32683
+ import path90 from "path";
32576
32684
  import { existsSync as existsSync8 } from "fs";
32577
32685
  class NoImportError extends Error {
32578
32686
  }
32579
32687
  function resolveBin(cwd, name) {
32580
- const local = path89.join(cwd, "node_modules", ".bin", name);
32688
+ const local = path90.join(cwd, "node_modules", ".bin", name);
32581
32689
  if (existsSync8(local)) {
32582
32690
  return local;
32583
32691
  }
@@ -32658,13 +32766,13 @@ async function getComplexityFindings(cwd, sourceFiles, config, sourceAnalysis) {
32658
32766
 
32659
32767
  // src/health/metrics/coverage.ts
32660
32768
  import { existsSync as existsSync9 } from "fs";
32661
- import path90 from "path";
32769
+ import path91 from "path";
32662
32770
  var SUMMARY_PATHS = [
32663
32771
  "coverage/coverage-summary.json",
32664
32772
  "coverage/coverage-final.json"
32665
32773
  ];
32666
32774
  async function getCoverage(cwd) {
32667
- const summary = SUMMARY_PATHS.map((rel) => path90.join(cwd, rel)).find((abs) => existsSync9(abs));
32775
+ const summary = SUMMARY_PATHS.map((rel) => path91.join(cwd, rel)).find((abs) => existsSync9(abs));
32668
32776
  if (!summary) {
32669
32777
  return { status: "missing", total: null, byFile: new Map };
32670
32778
  }
@@ -32685,7 +32793,7 @@ async function getCoverage(cwd) {
32685
32793
  total = pct;
32686
32794
  continue;
32687
32795
  }
32688
- const relative = path90.isAbsolute(key) ? path90.relative(cwd, key) : key;
32796
+ const relative = path91.isAbsolute(key) ? path91.relative(cwd, key) : key;
32689
32797
  byFile.set(relative.replace(/\\/g, "/"), pct);
32690
32798
  }
32691
32799
  return { status: "available", total, byFile };
@@ -32818,10 +32926,10 @@ function renderWikiFreshness(metric) {
32818
32926
  // src/health/skills.ts
32819
32927
  init_fs();
32820
32928
  import { readFile as readFile47 } from "fs/promises";
32821
- import path91 from "path";
32929
+ import path92 from "path";
32822
32930
  var EMPTY = { skills: [], skillForFile: () => null };
32823
32931
  async function loadSkillOwnership(cwd) {
32824
- const manifestPath = path91.join(cwd, ".metaproject", "metaproject.json");
32932
+ const manifestPath = path92.join(cwd, ".metaproject", "metaproject.json");
32825
32933
  if (!await pathExists(manifestPath)) {
32826
32934
  return EMPTY;
32827
32935
  }
@@ -32859,7 +32967,7 @@ function normalize(value) {
32859
32967
 
32860
32968
  // src/health/sources/eslint.ts
32861
32969
  import { existsSync as existsSync10 } from "fs";
32862
- import path92 from "path";
32970
+ import path93 from "path";
32863
32971
  var CONFIG_FILES = [
32864
32972
  ".eslintrc",
32865
32973
  ".eslintrc.js",
@@ -32873,7 +32981,7 @@ var CONFIG_FILES = [
32873
32981
  "eslint.config.ts"
32874
32982
  ];
32875
32983
  function hasConfig(cwd) {
32876
- return CONFIG_FILES.some((file) => existsSync10(path92.join(cwd, file)));
32984
+ return CONFIG_FILES.some((file) => existsSync10(path93.join(cwd, file)));
32877
32985
  }
32878
32986
  var eslintAdapter = {
32879
32987
  id: "eslint",
@@ -32898,7 +33006,7 @@ var eslintAdapter = {
32898
33006
  };
32899
33007
  },
32900
33008
  async import(ctx) {
32901
- const report = path92.join(ctx.cwd, "eslint-report.json");
33009
+ const report = path93.join(ctx.cwd, "eslint-report.json");
32902
33010
  if (!existsSync10(report)) {
32903
33011
  throw new NoImportError("no eslint-report.json");
32904
33012
  }
@@ -32925,7 +33033,7 @@ var eslintAdapter = {
32925
33033
  }
32926
33034
  const findings = [];
32927
33035
  for (const file of data) {
32928
- const relative = path92.isAbsolute(file.filePath) ? path92.relative(ctx.cwd, file.filePath) : file.filePath;
33036
+ const relative = path93.isAbsolute(file.filePath) ? path93.relative(ctx.cwd, file.filePath) : file.filePath;
32929
33037
  for (const message of file.messages ?? []) {
32930
33038
  const isError = message.severity === 2;
32931
33039
  findings.push(makeFinding({
@@ -32957,9 +33065,9 @@ var eslintAdapter = {
32957
33065
 
32958
33066
  // src/health/sources/typescript.ts
32959
33067
  import { existsSync as existsSync11 } from "fs";
32960
- import path93 from "path";
33068
+ import path94 from "path";
32961
33069
  function hasTsconfig(cwd) {
32962
- return existsSync11(path93.join(cwd, "tsconfig.json"));
33070
+ return existsSync11(path94.join(cwd, "tsconfig.json"));
32963
33071
  }
32964
33072
  var typescriptAdapter = {
32965
33073
  id: "typescript",
@@ -33035,7 +33143,7 @@ __export(exports_service6, {
33035
33143
  });
33036
33144
  import { existsSync as existsSync12 } from "fs";
33037
33145
  import { readFile as readFile50, readdir as readdir16 } from "fs/promises";
33038
- import path98 from "path";
33146
+ import path99 from "path";
33039
33147
 
33040
33148
  // src/lib/git-env.ts
33041
33149
  var GIT_DISCOVERY_OVERRIDE_VARS = [
@@ -33060,7 +33168,7 @@ function withoutGitDiscoveryOverrides(env) {
33060
33168
  init_fs();
33061
33169
  init_guard();
33062
33170
  import { readFile as readFile48 } from "fs/promises";
33063
- import path94 from "path";
33171
+ import path95 from "path";
33064
33172
 
33065
33173
  // src/metrics/record.ts
33066
33174
  var RELIABILITIES = new Set(["exact", "estimated", "unknown"]);
@@ -33075,7 +33183,7 @@ var RETRY_TYPES = new Set([
33075
33183
 
33076
33184
  // src/metrics/lifecycle.ts
33077
33185
  async function readArtifactPointer(root, expected) {
33078
- const pointerFile = path94.join(root, "latest.json");
33186
+ const pointerFile = path95.join(root, "latest.json");
33079
33187
  if (!await pathExists(pointerFile))
33080
33188
  return { status: "missing", pointer: null };
33081
33189
  let pointer;
@@ -33084,7 +33192,7 @@ async function readArtifactPointer(root, expected) {
33084
33192
  } catch {
33085
33193
  return { status: "stale", pointer: null, reason: "latest pointer is invalid JSON" };
33086
33194
  }
33087
- const recordFile = pointer.record ? path94.join(root, pointer.record) : null;
33195
+ const recordFile = pointer.record ? path95.join(root, pointer.record) : null;
33088
33196
  if (!recordFile || !isPathInside(root, recordFile) || !await pathExists(recordFile)) {
33089
33197
  return { status: "stale", pointer, reason: "pointer record is missing" };
33090
33198
  }
@@ -33100,9 +33208,9 @@ init_guard();
33100
33208
  // src/testing/capability.ts
33101
33209
  init_fs();
33102
33210
  init_json();
33103
- import path95 from "path";
33211
+ import path96 from "path";
33104
33212
  async function isTestingCapabilityEnabled(cwd, capability) {
33105
- const manifestPath = path95.join(cwd, ".metaproject", "metaproject.json");
33213
+ const manifestPath = path96.join(cwd, ".metaproject", "metaproject.json");
33106
33214
  if (!await pathExists(manifestPath)) {
33107
33215
  return false;
33108
33216
  }
@@ -33128,10 +33236,10 @@ async function isTestingCapabilityEnabled(cwd, capability) {
33128
33236
  init_fs();
33129
33237
  init_guard();
33130
33238
  import { readFile as readFile49, mkdir as mkdir27, writeFile as writeFile20 } from "fs/promises";
33131
- import path96 from "path";
33239
+ import path97 from "path";
33132
33240
  var COVERAGE_MAP_SCHEMA_VERSION = 1;
33133
33241
  function coverageMapPath(cwd, cfg) {
33134
- return path96.isAbsolute(cfg.coverageMap.artifact) ? cfg.coverageMap.artifact : path96.join(cwd, cfg.coverageMap.artifact);
33242
+ return path97.isAbsolute(cfg.coverageMap.artifact) ? cfg.coverageMap.artifact : path97.join(cwd, cfg.coverageMap.artifact);
33135
33243
  }
33136
33244
  async function loadCoverageMap(cwd, cfg) {
33137
33245
  const file = coverageMapPath(cwd, cfg);
@@ -33205,20 +33313,20 @@ function normalizePath4(file) {
33205
33313
  }
33206
33314
 
33207
33315
  // src/testing/selection.ts
33208
- import path97 from "path";
33316
+ import path98 from "path";
33209
33317
  var TEST_FILE_RE = /(^|\/)(__tests__\/.*|.*\.(test|spec)\.[cm]?[tj]sx?$|e2e\/.*\.[cm]?[tj]sx?$|tests\/.*\.[cm]?[tj]sx?$)/;
33210
33318
  function normalizePath5(file) {
33211
33319
  return file.replace(/\\/g, "/").replace(/^\.\//, "");
33212
33320
  }
33213
33321
  function relatedByNamingAndDirectory(target, testFiles) {
33214
33322
  const normalized = normalizePath5(target);
33215
- const ext = path97.extname(normalized);
33323
+ const ext = path98.extname(normalized);
33216
33324
  const withoutExt = ext ? normalized.slice(0, -ext.length) : normalized;
33217
- const base = path97.basename(withoutExt);
33218
- const dir = path97.dirname(normalized);
33325
+ const base = path98.basename(withoutExt);
33326
+ const dir = path98.dirname(normalized);
33219
33327
  return testFiles.filter((file) => {
33220
- const fileDir = path97.dirname(file);
33221
- const fileBase = path97.basename(file);
33328
+ const fileDir = path98.dirname(file);
33329
+ const fileBase = path98.basename(file);
33222
33330
  return file.startsWith(`${withoutExt}.`) || file.includes(`${withoutExt}.`) || fileDir === dir && fileBase.startsWith(`${base}.`) || fileDir.startsWith(dir) && fileBase.includes(base);
33223
33331
  }).sort();
33224
33332
  }
@@ -33348,7 +33456,7 @@ var DEFAULT_TESTING_CONFIG = {
33348
33456
  }
33349
33457
  };
33350
33458
  function testingDataRoot(cwd) {
33351
- return path98.join(cwd, ".metaproject", "data", "testing");
33459
+ return path99.join(cwd, ".metaproject", "data", "testing");
33352
33460
  }
33353
33461
  async function computeTestingContext(cwd) {
33354
33462
  const { files, incompleteReasons } = await listProjectFiles(cwd);
@@ -33523,7 +33631,7 @@ async function runTesting(input) {
33523
33631
  return runResult;
33524
33632
  }
33525
33633
  async function loadTestingContext(cwd) {
33526
- const file = path98.join(testingDataRoot(cwd), "context.json");
33634
+ const file = path99.join(testingDataRoot(cwd), "context.json");
33527
33635
  if (!await pathExists(file)) {
33528
33636
  return null;
33529
33637
  }
@@ -33534,18 +33642,18 @@ async function loadTestingContext(cwd) {
33534
33642
  }
33535
33643
  }
33536
33644
  async function loadTestingReport(cwd) {
33537
- const file = path98.join(testingDataRoot(cwd), "artifacts", "latest.json");
33645
+ const file = path99.join(testingDataRoot(cwd), "artifacts", "latest.json");
33538
33646
  if (!await pathExists(file)) {
33539
33647
  return null;
33540
33648
  }
33541
33649
  try {
33542
33650
  const latest = JSON.parse(await readFile50(file, "utf8"));
33543
33651
  if (typeof latest.record === "string") {
33544
- const pointer = await readArtifactPointer(path98.join(testingDataRoot(cwd), "artifacts"), await collectGitProvenance(cwd));
33652
+ const pointer = await readArtifactPointer(path99.join(testingDataRoot(cwd), "artifacts"), await collectGitProvenance(cwd));
33545
33653
  if (pointer.status !== "fresh")
33546
33654
  return null;
33547
- const recordFile = path98.join(testingDataRoot(cwd), "artifacts", latest.record);
33548
- if (!isPathInside(path98.join(testingDataRoot(cwd), "artifacts"), recordFile))
33655
+ const recordFile = path99.join(testingDataRoot(cwd), "artifacts", latest.record);
33656
+ if (!isPathInside(path99.join(testingDataRoot(cwd), "artifacts"), recordFile))
33549
33657
  return null;
33550
33658
  if (!await pathExists(recordFile))
33551
33659
  return null;
@@ -33592,28 +33700,28 @@ async function ensureContext(cwd) {
33592
33700
  }
33593
33701
  async function writeContext(cwd, context) {
33594
33702
  const root = testingDataRoot(cwd);
33595
- const rel = (p) => path98.relative(cwd, p);
33703
+ const rel = (p) => path99.relative(cwd, p);
33596
33704
  await mkdirContained(cwd, rel(root));
33597
- await writeContained(cwd, rel(path98.join(root, "context.json")), `${JSON.stringify(context, null, 2)}
33705
+ await writeContained(cwd, rel(path99.join(root, "context.json")), `${JSON.stringify(context, null, 2)}
33598
33706
  `);
33599
- await writeContained(cwd, rel(path98.join(root, "context.md")), renderContextMarkdown(context));
33600
- await writeContained(cwd, rel(path98.join(root, "recommendations.md")), renderRecommendationsMarkdown(context));
33707
+ await writeContained(cwd, rel(path99.join(root, "context.md")), renderContextMarkdown(context));
33708
+ await writeContained(cwd, rel(path99.join(root, "recommendations.md")), renderRecommendationsMarkdown(context));
33601
33709
  }
33602
33710
  async function writeReport(cwd, report) {
33603
33711
  const root = testingDataRoot(cwd);
33604
- const artifacts = path98.join(root, "artifacts");
33605
- const history = path98.join(root, "history");
33606
- const rel = (p) => path98.relative(cwd, p);
33712
+ const artifacts = path99.join(root, "artifacts");
33713
+ const history = path99.join(root, "history");
33714
+ const rel = (p) => path99.relative(cwd, p);
33607
33715
  await mkdirContained(cwd, rel(artifacts));
33608
33716
  await mkdirContained(cwd, rel(history));
33609
33717
  const stamp = report.generatedAt.replace(/[:.]/g, "-");
33610
- const json = path98.join(artifacts, "latest.json");
33611
- const markdown = path98.join(artifacts, "latest.md");
33718
+ const json = path99.join(artifacts, "latest.json");
33719
+ const markdown = path99.join(artifacts, "latest.md");
33612
33720
  const serialized = `${JSON.stringify(report, null, 2)}
33613
33721
  `;
33614
33722
  if (report.runId) {
33615
- const runJson = path98.join(artifacts, "runs", `${report.runId}.json`);
33616
- const runMarkdown = path98.join(artifacts, "runs", `${report.runId}.md`);
33723
+ const runJson = path99.join(artifacts, "runs", `${report.runId}.json`);
33724
+ const runMarkdown = path99.join(artifacts, "runs", `${report.runId}.md`);
33617
33725
  if (await pathExists(runJson))
33618
33726
  throw new Error(`immutable testing run already exists: ${report.runId}`);
33619
33727
  await writeContained(cwd, rel(runJson), serialized);
@@ -33624,26 +33732,26 @@ async function writeReport(cwd, report) {
33624
33732
  branch: report.provenance?.branch ?? null,
33625
33733
  worktree: report.provenance?.worktree ?? null,
33626
33734
  generated_at: report.generatedAt,
33627
- record: path98.posix.join("runs", `${report.runId}.json`)
33735
+ record: path99.posix.join("runs", `${report.runId}.json`)
33628
33736
  }, null, 2)}
33629
33737
  `);
33630
33738
  } else {
33631
33739
  await writeContained(cwd, rel(json), serialized);
33632
33740
  }
33633
33741
  await writeContained(cwd, rel(markdown), renderReportMarkdown3(report));
33634
- await writeContained(cwd, rel(path98.join(history, `${stamp}.json`)), serialized);
33742
+ await writeContained(cwd, rel(path99.join(history, `${stamp}.json`)), serialized);
33635
33743
  return {
33636
- markdownPath: path98.relative(cwd, markdown),
33637
- jsonPath: path98.relative(cwd, json)
33744
+ markdownPath: path99.relative(cwd, markdown),
33745
+ jsonPath: path99.relative(cwd, json)
33638
33746
  };
33639
33747
  }
33640
33748
  async function writeRawLog(cwd, raw) {
33641
- const logs = path98.join(testingDataRoot(cwd), "logs");
33642
- const rel = (p) => path98.relative(cwd, p);
33749
+ const logs = path99.join(testingDataRoot(cwd), "logs");
33750
+ const rel = (p) => path99.relative(cwd, p);
33643
33751
  await mkdirContained(cwd, rel(logs));
33644
- const latest = path98.join(logs, "latest.raw.log");
33752
+ const latest = path99.join(logs, "latest.raw.log");
33645
33753
  await writeContained(cwd, rel(latest), raw);
33646
- return path98.relative(cwd, latest);
33754
+ return path99.relative(cwd, latest);
33647
33755
  }
33648
33756
  async function listProjectFiles(cwd) {
33649
33757
  const out = [];
@@ -33656,11 +33764,11 @@ async function walk3(root, dir, out, incompleteReasons) {
33656
33764
  try {
33657
33765
  entries = await readdir16(dir, { withFileTypes: true });
33658
33766
  } catch (error) {
33659
- incompleteReasons.push(`${normalizePath6(path98.relative(root, dir)) || "."}: ${error instanceof Error ? error.message : String(error)}`);
33767
+ incompleteReasons.push(`${normalizePath6(path99.relative(root, dir)) || "."}: ${error instanceof Error ? error.message : String(error)}`);
33660
33768
  return;
33661
33769
  }
33662
33770
  for (const entry of entries) {
33663
- const abs = path98.join(dir, entry.name);
33771
+ const abs = path99.join(dir, entry.name);
33664
33772
  if (entry.isDirectory()) {
33665
33773
  if (IGNORED_DIRS2.has(entry.name) || entry.name.startsWith(".tmp-")) {
33666
33774
  continue;
@@ -33669,12 +33777,12 @@ async function walk3(root, dir, out, incompleteReasons) {
33669
33777
  continue;
33670
33778
  }
33671
33779
  if (entry.isFile()) {
33672
- out.push(normalizePath6(path98.relative(root, abs)));
33780
+ out.push(normalizePath6(path99.relative(root, abs)));
33673
33781
  }
33674
33782
  }
33675
33783
  }
33676
33784
  async function readPackageJson(cwd) {
33677
- const file = path98.join(cwd, "package.json");
33785
+ const file = path99.join(cwd, "package.json");
33678
33786
  if (!await pathExists(file)) {
33679
33787
  return null;
33680
33788
  }
@@ -33685,7 +33793,7 @@ async function readPackageJson(cwd) {
33685
33793
  }
33686
33794
  }
33687
33795
  async function loadTestingConfig(cwd) {
33688
- const file = path98.join(cwd, ".metaproject", "testing.config.json");
33796
+ const file = path99.join(cwd, ".metaproject", "testing.config.json");
33689
33797
  if (!await pathExists(file)) {
33690
33798
  return DEFAULT_TESTING_CONFIG;
33691
33799
  }
@@ -33750,7 +33858,7 @@ function detectFrameworks(input) {
33750
33858
  async function extractConventions(cwd, files) {
33751
33859
  const conventions = new Set;
33752
33860
  for (const file of files.slice(0, 40)) {
33753
- const abs = path98.join(cwd, file);
33861
+ const abs = path99.join(cwd, file);
33754
33862
  if (!await pathExists(abs)) {
33755
33863
  continue;
33756
33864
  }
@@ -33880,7 +33988,7 @@ async function findTestsByImportedTargets(cwd, targets, testFiles) {
33880
33988
  const targetKeys = new Set(targets.map((target) => modulePathKey(normalizePath6(target))));
33881
33989
  const selected = new Set;
33882
33990
  for (const testFile of testFiles) {
33883
- const absoluteTest = path98.join(cwd, testFile);
33991
+ const absoluteTest = path99.join(cwd, testFile);
33884
33992
  if (!await pathExists(absoluteTest)) {
33885
33993
  continue;
33886
33994
  }
@@ -33914,10 +34022,10 @@ function resolveImportPath(cwd, testFile, importPath) {
33914
34022
  if (!importPath.startsWith(".")) {
33915
34023
  return null;
33916
34024
  }
33917
- const importerDir = path98.dirname(testFile);
33918
- const absoluteResolved = path98.resolve(path98.join(cwd, importerDir), importPath);
33919
- const relative = path98.relative(cwd, absoluteResolved);
33920
- if (relative.startsWith(`..${path98.sep}`) || relative === "..") {
34025
+ const importerDir = path99.dirname(testFile);
34026
+ const absoluteResolved = path99.resolve(path99.join(cwd, importerDir), importPath);
34027
+ const relative = path99.relative(cwd, absoluteResolved);
34028
+ if (relative.startsWith(`..${path99.sep}`) || relative === "..") {
33921
34029
  return null;
33922
34030
  }
33923
34031
  const relativeNormalized = normalizePath6(relative);
@@ -33969,13 +34077,13 @@ function resolveTestCommand(cwd, context, input) {
33969
34077
  }
33970
34078
  var BUN_LOCKFILES = ["bun.lock", "bun.lockb"];
33971
34079
  function detectPackageManager(cwd) {
33972
- if (resolveBunBin() && BUN_LOCKFILES.some((name) => pathExistsSync(path98.join(cwd, name)))) {
34080
+ if (resolveBunBin() && BUN_LOCKFILES.some((name) => pathExistsSync(path99.join(cwd, name)))) {
33973
34081
  return "bun";
33974
34082
  }
33975
- if (Bun.which("pnpm") && pathExistsSync(path98.join(cwd, "pnpm-lock.yaml"))) {
34083
+ if (Bun.which("pnpm") && pathExistsSync(path99.join(cwd, "pnpm-lock.yaml"))) {
33976
34084
  return "pnpm";
33977
34085
  }
33978
- if (Bun.which("yarn") && pathExistsSync(path98.join(cwd, "yarn.lock"))) {
34086
+ if (Bun.which("yarn") && pathExistsSync(path99.join(cwd, "yarn.lock"))) {
33979
34087
  return "yarn";
33980
34088
  }
33981
34089
  return "npm";
@@ -34315,7 +34423,7 @@ async function compatibleReportForHealth(ctx) {
34315
34423
 
34316
34424
  // src/health/sources/dependency-audit.ts
34317
34425
  import { existsSync as existsSync13 } from "fs";
34318
- import path99 from "path";
34426
+ import path100 from "path";
34319
34427
  function auditSeverityToPriority(severity) {
34320
34428
  if (severity === "critical" || severity === "high")
34321
34429
  return "P0";
@@ -34434,7 +34542,7 @@ var LOCKFILE_COMMANDS = [
34434
34542
  ];
34435
34543
  function auditCommand(cwd) {
34436
34544
  for (const entry of LOCKFILE_COMMANDS) {
34437
- if (!entry.lockfiles.some((name) => existsSync13(path99.join(cwd, name))))
34545
+ if (!entry.lockfiles.some((name) => existsSync13(path100.join(cwd, name))))
34438
34546
  continue;
34439
34547
  const bin = resolveBin(cwd, entry.bin);
34440
34548
  if (bin)
@@ -34493,13 +34601,13 @@ var dependencyAuditAdapter = {
34493
34601
 
34494
34602
  // src/health/sources/sonarqube.ts
34495
34603
  import { existsSync as existsSync14 } from "fs";
34496
- import path100 from "path";
34604
+ import path101 from "path";
34497
34605
  var REPORT_FILES = ["sonar-issues.json", ".metaproject/data/health/sonar-issues.json"];
34498
34606
  function reportPath(cwd) {
34499
34607
  const fromEnv = process.env.SONAR_ISSUES_FILE;
34500
34608
  const candidates = fromEnv ? [fromEnv, ...REPORT_FILES] : REPORT_FILES;
34501
34609
  for (const rel of candidates) {
34502
- const abs = path100.isAbsolute(rel) ? rel : path100.join(cwd, rel);
34610
+ const abs = path101.isAbsolute(rel) ? rel : path101.join(cwd, rel);
34503
34611
  if (existsSync14(abs)) {
34504
34612
  return abs;
34505
34613
  }
@@ -34583,7 +34691,7 @@ var sonarqubeAdapter = {
34583
34691
  function relativizeComponent(component, cwd) {
34584
34692
  const colon = component.indexOf(":");
34585
34693
  const value = colon >= 0 ? component.slice(colon + 1) : component;
34586
- return path100.isAbsolute(value) ? path100.relative(cwd, value) : value;
34694
+ return path101.isAbsolute(value) ? path101.relative(cwd, value) : value;
34587
34695
  }
34588
34696
 
34589
34697
  // src/health/sources/index.ts
@@ -34920,19 +35028,19 @@ function filteredInfo(source, cfg) {
34920
35028
  };
34921
35029
  }
34922
35030
  async function writeOutputs(cwd, report, config, stamp) {
34923
- const artifacts = path101.join(dataRoot3(cwd), "artifacts");
34924
- const history = path101.join(dataRoot3(cwd), "history");
35031
+ const artifacts = path102.join(dataRoot3(cwd), "artifacts");
35032
+ const history = path102.join(dataRoot3(cwd), "history");
34925
35033
  await mkdir28(artifacts, { recursive: true });
34926
35034
  await mkdir28(history, { recursive: true });
34927
- const markdown = path101.join(artifacts, "latest.md");
34928
- const json = path101.join(artifacts, "latest.json");
34929
- const historyJson = path101.join(history, `${stamp}.json`);
35035
+ const markdown = path102.join(artifacts, "latest.md");
35036
+ const json = path102.join(artifacts, "latest.json");
35037
+ const historyJson = path102.join(history, `${stamp}.json`);
34930
35038
  const serialized = `${JSON.stringify(report, null, 2)}
34931
35039
  `;
34932
35040
  await writeFile21(markdown, renderReportMarkdown2(report, config), "utf8");
34933
35041
  if (report.runId) {
34934
- const runJson = path101.join(artifacts, "runs", `${report.runId}.json`);
34935
- const runMarkdown = path101.join(artifacts, "runs", `${report.runId}.md`);
35042
+ const runJson = path102.join(artifacts, "runs", `${report.runId}.json`);
35043
+ const runMarkdown = path102.join(artifacts, "runs", `${report.runId}.md`);
34936
35044
  if (await pathExists(runJson))
34937
35045
  throw new Error(`immutable health run already exists: ${report.runId}`);
34938
35046
  await writeFileAtomic(runJson, serialized);
@@ -34943,7 +35051,7 @@ async function writeOutputs(cwd, report, config, stamp) {
34943
35051
  branch: report.provenance?.branch ?? null,
34944
35052
  worktree: report.provenance?.worktree ?? null,
34945
35053
  generated_at: report.generatedAt,
34946
- record: path101.posix.join("runs", `${report.runId}.json`)
35054
+ record: path102.posix.join("runs", `${report.runId}.json`)
34947
35055
  }, null, 2)}
34948
35056
  `);
34949
35057
  } else {
@@ -34951,8 +35059,8 @@ async function writeOutputs(cwd, report, config, stamp) {
34951
35059
  }
34952
35060
  await writeFile21(historyJson, serialized, "utf8");
34953
35061
  return {
34954
- markdownPath: path101.relative(cwd, markdown),
34955
- jsonPath: path101.relative(cwd, json)
35062
+ markdownPath: path102.relative(cwd, markdown),
35063
+ jsonPath: path102.relative(cwd, json)
34956
35064
  };
34957
35065
  }
34958
35066
  async function resolveChanged(cwd, selector) {
@@ -35005,7 +35113,7 @@ function hasGateShape(value) {
35005
35113
  return Array.isArray(report.metrics) && Array.isArray(report.sources) && Array.isArray(report.findings);
35006
35114
  }
35007
35115
  async function readLatest(cwd) {
35008
- const file = path102.join(dataRoot3(cwd), "artifacts", "latest.json");
35116
+ const file = path103.join(dataRoot3(cwd), "artifacts", "latest.json");
35009
35117
  if (!await pathExists(file)) {
35010
35118
  return null;
35011
35119
  }
@@ -35016,11 +35124,11 @@ async function readLatest(cwd) {
35016
35124
  const latest = read.value;
35017
35125
  const record = latest.record;
35018
35126
  if (typeof record === "string") {
35019
- const pointer = await readArtifactPointer(path102.join(dataRoot3(cwd), "artifacts"), await collectGitProvenance(cwd));
35127
+ const pointer = await readArtifactPointer(path103.join(dataRoot3(cwd), "artifacts"), await collectGitProvenance(cwd));
35020
35128
  if (pointer.status !== "fresh")
35021
35129
  return null;
35022
- const recordFile = path102.join(dataRoot3(cwd), "artifacts", record);
35023
- if (!isPathInside(path102.join(dataRoot3(cwd), "artifacts"), recordFile))
35130
+ const recordFile = path103.join(dataRoot3(cwd), "artifacts", record);
35131
+ if (!isPathInside(path103.join(dataRoot3(cwd), "artifacts"), recordFile))
35024
35132
  return null;
35025
35133
  if (!await pathExists(recordFile))
35026
35134
  return null;
@@ -35093,7 +35201,7 @@ function createCodeHealthService() {
35093
35201
  return {
35094
35202
  run: (input) => runHealth(input),
35095
35203
  async status(input) {
35096
- const enabled = await pathExists(path102.join(input.cwd, ".metaproject", "health.config.json"));
35204
+ const enabled = await pathExists(path103.join(input.cwd, ".metaproject", "health.config.json"));
35097
35205
  const latest = await readLatest(input.cwd);
35098
35206
  const project = latest?.metrics.find((m) => m.key === "project") ?? null;
35099
35207
  const decliningScopes = latest ? latest.metrics.filter((m) => m.regression_score > 0).length : 0;
@@ -35251,10 +35359,10 @@ function renderEvidenceBlock(evidences, siblings) {
35251
35359
  init_fs();
35252
35360
  init_contained_write();
35253
35361
  init_json();
35254
- import path103 from "path";
35362
+ import path104 from "path";
35255
35363
  import { createHash as createHash17 } from "crypto";
35256
35364
  function impactEvidenceDataRoot(root) {
35257
- return path103.join(root, ".metaproject", "data", "security", "impact-evidence");
35365
+ return path104.join(root, ".metaproject", "data", "security", "impact-evidence");
35258
35366
  }
35259
35367
  function sanitizeSessionId(sessionId) {
35260
35368
  const cleaned = sessionId.replace(/[^A-Za-z0-9._-]/g, "_");
@@ -35266,7 +35374,7 @@ function sessionStateFilename(sessionId) {
35266
35374
  return `${sanitized}-${suffix}.json`;
35267
35375
  }
35268
35376
  function sessionStatePath(root, sessionId) {
35269
- return path103.join(impactEvidenceDataRoot(root), "sessions", sessionStateFilename(sessionId));
35377
+ return path104.join(impactEvidenceDataRoot(root), "sessions", sessionStateFilename(sessionId));
35270
35378
  }
35271
35379
  async function loadSessionState(root, sessionId) {
35272
35380
  const file = sessionStatePath(root, sessionId);
@@ -35285,11 +35393,11 @@ async function loadSessionState(root, sessionId) {
35285
35393
  }
35286
35394
  async function saveSessionState(root, sessionId, state) {
35287
35395
  const file = sessionStatePath(root, sessionId);
35288
- await writeContained(root, path103.relative(root, file), `${JSON.stringify(state, null, 2)}
35396
+ await writeContained(root, path104.relative(root, file), `${JSON.stringify(state, null, 2)}
35289
35397
  `);
35290
35398
  }
35291
35399
  function logPath(root) {
35292
- return path103.join(impactEvidenceDataRoot(root), "log.jsonl");
35400
+ return path104.join(impactEvidenceDataRoot(root), "log.jsonl");
35293
35401
  }
35294
35402
  async function appendLogRecord(root, record) {
35295
35403
  const full = {
@@ -35300,7 +35408,7 @@ async function appendLogRecord(root, record) {
35300
35408
  ...record.detail !== undefined ? { detail: record.detail } : {}
35301
35409
  };
35302
35410
  const file = logPath(root);
35303
- await appendContained(root, path103.relative(root, file), `${JSON.stringify(full)}
35411
+ await appendContained(root, path104.relative(root, file), `${JSON.stringify(full)}
35304
35412
  `);
35305
35413
  return full;
35306
35414
  }
@@ -35327,7 +35435,7 @@ init_command_risk();
35327
35435
  init_shell_syntax();
35328
35436
  init_fs();
35329
35437
  init_service2();
35330
- import path104 from "path";
35438
+ import path105 from "path";
35331
35439
  import { createHash as createHash18 } from "crypto";
35332
35440
  import { realpathSync as realpathSync2 } from "fs";
35333
35441
  function impactEvidenceHookClass(strict) {
@@ -35343,29 +35451,29 @@ function realpathNearestExisting(p) {
35343
35451
  for (;; ) {
35344
35452
  try {
35345
35453
  const real = realpathSync2(current);
35346
- return tail.length > 0 ? path104.join(real, ...tail) : real;
35454
+ return tail.length > 0 ? path105.join(real, ...tail) : real;
35347
35455
  } catch {
35348
- const parent = path104.dirname(current);
35456
+ const parent = path105.dirname(current);
35349
35457
  if (parent === current) {
35350
- return tail.length > 0 ? path104.join(current, ...tail) : current;
35458
+ return tail.length > 0 ? path105.join(current, ...tail) : current;
35351
35459
  }
35352
- tail.unshift(path104.basename(current));
35460
+ tail.unshift(path105.basename(current));
35353
35461
  current = parent;
35354
35462
  }
35355
35463
  }
35356
35464
  }
35357
35465
  function normalizeRequestFiles(root, files) {
35358
- const rootReal = realpathNearestExisting(path104.resolve(root));
35466
+ const rootReal = realpathNearestExisting(path105.resolve(root));
35359
35467
  const normalized = [];
35360
35468
  const rejected = [];
35361
35469
  for (const file of files) {
35362
- const lexicalAbsolute = path104.isAbsolute(file) ? path104.resolve(file) : path104.resolve(rootReal, toPosix(file).replace(/^\.\//, ""));
35470
+ const lexicalAbsolute = path105.isAbsolute(file) ? path105.resolve(file) : path105.resolve(rootReal, toPosix(file).replace(/^\.\//, ""));
35363
35471
  const effective = realpathNearestExisting(lexicalAbsolute);
35364
35472
  if (!isPathInside(rootReal, effective)) {
35365
35473
  rejected.push(file);
35366
35474
  continue;
35367
35475
  }
35368
- normalized.push(toPosix(path104.relative(rootReal, effective)));
35476
+ normalized.push(toPosix(path105.relative(rootReal, effective)));
35369
35477
  }
35370
35478
  return { files: [...new Set(normalized)], rejected };
35371
35479
  }
@@ -35651,7 +35759,7 @@ __export(exports_service8, {
35651
35759
  createJobService: () => createJobService
35652
35760
  });
35653
35761
  import { copyFile, mkdir as mkdir30 } from "fs/promises";
35654
- import path107 from "path";
35762
+ import path108 from "path";
35655
35763
 
35656
35764
  // src/job/types.ts
35657
35765
  var JOB_INTENTS = ["implement", "analyze", "review", "custom"];
@@ -35792,15 +35900,15 @@ init_validator();
35792
35900
  init_contracts();
35793
35901
  init_fs();
35794
35902
  import { appendFile as appendFile6, mkdir as mkdir29, readFile as readFile52, readdir as readdir17 } from "fs/promises";
35795
- import path106 from "path";
35903
+ import path107 from "path";
35796
35904
  function jobsRoot(cwd) {
35797
- return path106.join(cwd, ".metaproject", "jobs");
35905
+ return path107.join(cwd, ".metaproject", "jobs");
35798
35906
  }
35799
35907
  function jobDir(cwd, name) {
35800
- return path106.join(jobsRoot(cwd), name);
35908
+ return path107.join(jobsRoot(cwd), name);
35801
35909
  }
35802
35910
  function jobStatePath(cwd, name) {
35803
- return path106.join(jobDir(cwd, name), "state.json");
35911
+ return path107.join(jobDir(cwd, name), "state.json");
35804
35912
  }
35805
35913
  var JOB_NAME_PATTERN = /^[a-z0-9-]+$/;
35806
35914
  function assertJobName(name) {
@@ -35837,12 +35945,12 @@ async function writeJob(cwd, name, state) {
35837
35945
  `));
35838
35946
  }
35839
35947
  const file = jobStatePath(cwd, name);
35840
- await mkdir29(path106.dirname(file), { recursive: true });
35948
+ await mkdir29(path107.dirname(file), { recursive: true });
35841
35949
  await writeFileAtomic(file, `${JSON.stringify(state, null, 2)}
35842
35950
  `);
35843
35951
  }
35844
35952
  async function appendJournal2(cwd, name, at, line) {
35845
- await appendFile6(path106.join(jobDir(cwd, name), "journal.md"), `- ${at} - ${line}
35953
+ await appendFile6(path107.join(jobDir(cwd, name), "journal.md"), `- ${at} - ${line}
35846
35954
  `, "utf8");
35847
35955
  }
35848
35956
  function renderJournal2(name, at) {
@@ -35863,7 +35971,7 @@ function assertDocumentType(raw) {
35863
35971
  return raw;
35864
35972
  }
35865
35973
  function documentFileName(type, sourcePath) {
35866
- const extension = path106.extname(sourcePath) || ".md";
35974
+ const extension = path107.extname(sourcePath) || ".md";
35867
35975
  return `${type}${extension}`;
35868
35976
  }
35869
35977
 
@@ -35871,7 +35979,7 @@ function documentFileName(type, sourcePath) {
35871
35979
  function createJobService(deps) {
35872
35980
  const now = () => deps.now().toISOString();
35873
35981
  function lockPath(cwd, name) {
35874
- return path107.join(jobsRoot(cwd), `.job-lock-${name}`);
35982
+ return path108.join(jobsRoot(cwd), `.job-lock-${name}`);
35875
35983
  }
35876
35984
  async function mutate(cwd, name, run) {
35877
35985
  assertJobName(name);
@@ -35920,20 +36028,20 @@ function createJobService(deps) {
35920
36028
  },
35921
36029
  plan: { steps: defaultPlan(intent) },
35922
36030
  documentation: {
35923
- job_path: path107.join(".metaproject", "jobs", name),
36031
+ job_path: path108.join(".metaproject", "jobs", name),
35924
36032
  documents_created: []
35925
36033
  },
35926
36034
  metrics: { steps: [] },
35927
- jobs_root: path107.join(".metaproject", "jobs"),
36035
+ jobs_root: path108.join(".metaproject", "jobs"),
35928
36036
  updated_at: createdAt
35929
36037
  };
35930
36038
  const first = firstOpenStep(state.plan.steps);
35931
36039
  if (first) {
35932
36040
  state.plan.current_step = first.id;
35933
36041
  }
35934
- await writeFileAtomic(path107.join(absolute, "journal.md"), renderJournal2(name, createdAt));
36042
+ await writeFileAtomic(path108.join(absolute, "journal.md"), renderJournal2(name, createdAt));
35935
36043
  await writeJob(input.cwd, name, state);
35936
- return { state, dir: path107.relative(input.cwd, absolute) };
36044
+ return { state, dir: path108.relative(input.cwd, absolute) };
35937
36045
  },
35938
36046
  async status({ cwd, name }) {
35939
36047
  assertJobName(name);
@@ -35945,7 +36053,7 @@ function createJobService(deps) {
35945
36053
  }
35946
36054
  return {
35947
36055
  state,
35948
- dir: path107.join(".metaproject", "jobs", name),
36056
+ dir: path108.join(".metaproject", "jobs", name),
35949
36057
  stepsDone: state.plan.steps.filter((step) => isTerminalStep(step.status)).length,
35950
36058
  stepsTotal: state.plan.steps.length,
35951
36059
  nextStep: firstOpenStep(state.plan.steps),
@@ -36002,23 +36110,23 @@ function createJobService(deps) {
36002
36110
  if (!input.file) {
36003
36111
  throw new Error("Missing --file. Usage: keryx job document <name> --type <type> --file <path>");
36004
36112
  }
36005
- const source = path107.isAbsolute(input.file) ? input.file : path107.join(input.cwd, input.file);
36113
+ const source = path108.isAbsolute(input.file) ? input.file : path108.join(input.cwd, input.file);
36006
36114
  if (!await pathExists(source)) {
36007
36115
  throw new Error(`--file not found: ${input.file}. Write the document first, then record it.`);
36008
36116
  }
36009
36117
  let recorded;
36010
36118
  await mutate(input.cwd, input.name, async (state) => {
36011
36119
  const fileName = documentFileName(type, source);
36012
- const target = path107.join(jobDir(input.cwd, state.job_name), fileName);
36120
+ const target = path108.join(jobDir(input.cwd, state.job_name), fileName);
36013
36121
  await copyFile(source, target);
36014
36122
  state.documentation ??= {};
36015
- state.documentation.job_path ??= path107.join(".metaproject", "jobs", state.job_name);
36123
+ state.documentation.job_path ??= path108.join(".metaproject", "jobs", state.job_name);
36016
36124
  const created = state.documentation.documents_created ?? [];
36017
36125
  state.documentation.documents_created = created.includes(fileName) ? created : [...created, fileName];
36018
36126
  recorded = {
36019
36127
  state,
36020
36128
  document: fileName,
36021
- path: path107.join(".metaproject", "jobs", state.job_name, fileName)
36129
+ path: path108.join(".metaproject", "jobs", state.job_name, fileName)
36022
36130
  };
36023
36131
  return { state, event: "document", detail: `${type} -> ${fileName}` };
36024
36132
  });
@@ -36053,7 +36161,7 @@ function createJobService(deps) {
36053
36161
  name: state.job_name,
36054
36162
  phase: state.phase,
36055
36163
  intent: state.intent,
36056
- dir: path107.join(".metaproject", "jobs", name),
36164
+ dir: path108.join(".metaproject", "jobs", name),
36057
36165
  stepsDone: state.plan.steps.filter((step) => isTerminalStep(step.status)).length,
36058
36166
  stepsTotal: state.plan.steps.length,
36059
36167
  nextStep: firstOpenStep(state.plan.steps)?.id ?? null
@@ -36158,12 +36266,12 @@ function normalizeWorkspaceReference(raw) {
36158
36266
  // src/sac/fwk-service.ts
36159
36267
  init_assembly();
36160
36268
  import { appendFile as appendFile7, mkdir as mkdir32, open as open4, readFile as readFile55, rename as rename7, rm as rm6, stat as stat15, writeFile as writeFile22 } from "fs/promises";
36161
- import path111 from "path";
36269
+ import path112 from "path";
36162
36270
 
36163
36271
  // src/sac/index.ts
36164
36272
  import { access as access3, readFile as readFile53, realpath as realpath12 } from "fs/promises";
36165
36273
  import { createHash as createHash19 } from "crypto";
36166
- import path108 from "path";
36274
+ import path109 from "path";
36167
36275
  import { fileURLToPath as fileURLToPath3 } from "url";
36168
36276
  var idPattern = /^[a-z][a-z0-9-]{2,63}$/;
36169
36277
  var subjectPattern = /^(?:user|team|service|agent):[a-z0-9][a-z0-9._-]{0,127}$/;
@@ -36181,21 +36289,21 @@ var normativeSchemaFiles = {
36181
36289
  "review-decision": "review-decision.schema.json"
36182
36290
  };
36183
36291
  var normativeSchemas = new Map;
36184
- var NORMATIVE_SCHEMA_DIR = path108.join("docs", "requirements", "shared-agent-context", "schemas");
36292
+ var NORMATIVE_SCHEMA_DIR = path109.join("docs", "requirements", "shared-agent-context", "schemas");
36185
36293
  async function resolveSacNormativeSchemaPath(fileName, searchFrom = [fileURLToPath3(new URL(".", import.meta.url)), process.cwd()]) {
36186
36294
  const seen = new Set;
36187
36295
  for (const start of searchFrom) {
36188
- let dir = path108.resolve(start);
36296
+ let dir = path109.resolve(start);
36189
36297
  for (let i = 0;i < 10; i++) {
36190
36298
  if (seen.has(dir))
36191
36299
  break;
36192
36300
  seen.add(dir);
36193
- const candidate = path108.join(dir, NORMATIVE_SCHEMA_DIR, fileName);
36301
+ const candidate = path109.join(dir, NORMATIVE_SCHEMA_DIR, fileName);
36194
36302
  try {
36195
36303
  await access3(candidate);
36196
36304
  return candidate;
36197
36305
  } catch {}
36198
- const parent = path108.dirname(dir);
36306
+ const parent = path109.dirname(dir);
36199
36307
  if (parent === dir)
36200
36308
  break;
36201
36309
  dir = parent;
@@ -36864,12 +36972,12 @@ class SacReferenceError extends Error {
36864
36972
  code = "unsafe_workspace_reference";
36865
36973
  }
36866
36974
  async function resolveWorkspaceReference(input) {
36867
- if (!workspacePathPattern.test(input.uri) || path108.isAbsolute(input.uri) || /^[a-z][a-z0-9+.-]*:/i.test(input.uri) || input.uri.includes("\\"))
36975
+ if (!workspacePathPattern.test(input.uri) || path109.isAbsolute(input.uri) || /^[a-z][a-z0-9+.-]*:/i.test(input.uri) || input.uri.includes("\\"))
36868
36976
  throw new SacReferenceError("unsafe workspace reference");
36869
- const lexicalRoot = path108.resolve(input.workspaceRoot);
36977
+ const lexicalRoot = path109.resolve(input.workspaceRoot);
36870
36978
  const root = await realpath12(lexicalRoot);
36871
- const candidate = path108.resolve(lexicalRoot, input.uri.slice(2));
36872
- if (candidate !== lexicalRoot && !candidate.startsWith(`${lexicalRoot}${path108.sep}`))
36979
+ const candidate = path109.resolve(lexicalRoot, input.uri.slice(2));
36980
+ if (candidate !== lexicalRoot && !candidate.startsWith(`${lexicalRoot}${path109.sep}`))
36873
36981
  throw new SacReferenceError("workspace reference escapes root");
36874
36982
  let resolved;
36875
36983
  try {
@@ -36877,7 +36985,7 @@ async function resolveWorkspaceReference(input) {
36877
36985
  } catch {
36878
36986
  throw new SacReferenceError("workspace reference is not resolvable");
36879
36987
  }
36880
- if (resolved !== root && !resolved.startsWith(`${root}${path108.sep}`))
36988
+ if (resolved !== root && !resolved.startsWith(`${root}${path109.sep}`))
36881
36989
  throw new SacReferenceError("workspace reference escapes root after realpath");
36882
36990
  return candidate;
36883
36991
  }
@@ -36933,16 +37041,16 @@ async function evaluateStrictSacGuard(input) {
36933
37041
  init_fs();
36934
37042
  import { mkdir as mkdir31, readdir as readdir18, readFile as readFile54 } from "fs/promises";
36935
37043
  import { createHash as createHash20, randomUUID as randomUUID3 } from "crypto";
36936
- import path110 from "path";
37044
+ import path111 from "path";
36937
37045
 
36938
37046
  // src/sac/secure-resource-read.ts
36939
37047
  init_contained_read();
36940
37048
  init_descriptor_read();
36941
- import path109 from "path";
37049
+ import path110 from "path";
36942
37050
  function readWorkspaceFileNoFollow(workspaceRoot, absolutePath) {
36943
- const relativePath = path109.relative(workspaceRoot, absolutePath);
36944
- const components = relativePath.split(path109.sep);
36945
- if (!relativePath || path109.isAbsolute(relativePath) || components.some((component) => !component || component === "." || component === "..")) {
37051
+ const relativePath = path110.relative(workspaceRoot, absolutePath);
37052
+ const components = relativePath.split(path110.sep);
37053
+ if (!relativePath || path110.isAbsolute(relativePath) || components.some((component) => !component || component === "." || component === "..")) {
36946
37054
  throw new Error("safe source path is not workspace-relative");
36947
37055
  }
36948
37056
  return readDescriptorChain(workspaceRoot, absolutePath, {
@@ -36969,8 +37077,8 @@ class WorkspaceService {
36969
37077
  now;
36970
37078
  constructor(options) {
36971
37079
  this.options = options;
36972
- this.root = path110.resolve(options.workspaceRoot);
36973
- this.storageRoot = path110.resolve(options.storageRoot ?? path110.join(this.root, ".metaproject", "workspaces"));
37080
+ this.root = path111.resolve(options.workspaceRoot);
37081
+ this.storageRoot = path111.resolve(options.storageRoot ?? path111.join(this.root, ".metaproject", "workspaces"));
36974
37082
  this.now = options.now ?? (() => new Date);
36975
37083
  }
36976
37084
  async create(input) {
@@ -37295,13 +37403,13 @@ class WorkspaceService {
37295
37403
  return parsed;
37296
37404
  }
37297
37405
  workspaceDir(id) {
37298
- return path110.join(this.storageRoot, id);
37406
+ return path111.join(this.storageRoot, id);
37299
37407
  }
37300
37408
  manifestPath(id) {
37301
- return path110.join(this.workspaceDir(id), "workspace.json");
37409
+ return path111.join(this.workspaceDir(id), "workspace.json");
37302
37410
  }
37303
37411
  lockPath(id) {
37304
- return path110.join(this.storageRoot, `.${id}.lock`);
37412
+ return path111.join(this.storageRoot, `.${id}.lock`);
37305
37413
  }
37306
37414
  timestamp() {
37307
37415
  return this.now().toISOString();
@@ -38090,7 +38198,7 @@ function hasReportIntegrity(report) {
38090
38198
  return reportHashPattern.test(reportDigest) && sha2565(body) === reportDigest;
38091
38199
  }
38092
38200
  async function resolvePolicySelection(workspaceRoot, canonicalFallback) {
38093
- const configPath = path111.join(workspaceRoot, ...policyExperimentConfigPath);
38201
+ const configPath = path112.join(workspaceRoot, ...policyExperimentConfigPath);
38094
38202
  let configJson;
38095
38203
  try {
38096
38204
  const raw = await readFile55(configPath, "utf8").catch((error) => {
@@ -38288,9 +38396,9 @@ class FwkReadService {
38288
38396
  const recordedAt = nowIso(now);
38289
38397
  const id = `receipt-${randomUUID4().replace(/-/g, "").slice(0, 16)}`;
38290
38398
  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"}` } : {} };
38291
- const ledger = path111.join(this.options.canonical.workspaceRoot, ".metaproject", "context-operations", "access-receipts.jsonl");
38292
- const checkpointPath = path111.join(path111.dirname(ledger), "access-receipts.checkpoint.json");
38293
- await mkdir32(path111.dirname(ledger), { recursive: true, mode: 448 });
38399
+ const ledger = path112.join(this.options.canonical.workspaceRoot, ".metaproject", "context-operations", "access-receipts.jsonl");
38400
+ const checkpointPath = path112.join(path112.dirname(ledger), "access-receipts.checkpoint.json");
38401
+ await mkdir32(path112.dirname(ledger), { recursive: true, mode: 448 });
38294
38402
  return withFileLock(`${ledger}.lock`, async () => {
38295
38403
  const state = await resolveLedgerState(ledger, checkpointPath, this.options.verifyReceiptLedger ?? verifyAccessReceiptLedger);
38296
38404
  const receipt = sealAccessReceipt(base, state.headHash);
@@ -38394,7 +38502,7 @@ function normalizeFwkResult(result) {
38394
38502
  init_fs();
38395
38503
  import { createHash as createHash30, randomUUID as randomUUID7 } from "crypto";
38396
38504
  import { appendFile as appendFile8, mkdir as mkdir35, readdir as readdir21, readFile as readFile64 } from "fs/promises";
38397
- import path121 from "path";
38505
+ import path122 from "path";
38398
38506
 
38399
38507
  // src/sac/trusted-wrap-up.ts
38400
38508
  import { createHash as createHash24, randomUUID as randomUUID5 } from "crypto";
@@ -38466,7 +38574,7 @@ function bindingHash(owner, intent) {
38466
38574
  // src/sac/session-wrap-up.ts
38467
38575
  import { createHash as createHash26 } from "crypto";
38468
38576
  import { mkdir as mkdir34, writeFile as writeFile23 } from "fs/promises";
38469
- import path115 from "path";
38577
+ import path116 from "path";
38470
38578
 
38471
38579
  // src/session/store.ts
38472
38580
  init_config_dir();
@@ -38478,12 +38586,12 @@ import {
38478
38586
  renameSync as renameSync2,
38479
38587
  writeFileSync as writeFileSync2
38480
38588
  } from "fs";
38481
- import path114 from "path";
38589
+ import path115 from "path";
38482
38590
 
38483
38591
  // src/session/paths.ts
38484
38592
  import { existsSync as existsSync16 } from "fs";
38485
38593
  import { homedir } from "os";
38486
- import path112 from "path";
38594
+ import path113 from "path";
38487
38595
  function keryxDataDir(override) {
38488
38596
  if (override !== undefined && override.length > 0) {
38489
38597
  return override;
@@ -38495,22 +38603,22 @@ function keryxDataDir(override) {
38495
38603
  const home = homedir();
38496
38604
  if (process.platform === "win32") {
38497
38605
  const appData = process.env.APPDATA;
38498
- const base = appData !== undefined && appData.length > 0 ? appData : path112.join(home, "AppData", "Roaming");
38499
- return path112.join(base, "keryx");
38606
+ const base = appData !== undefined && appData.length > 0 ? appData : path113.join(home, "AppData", "Roaming");
38607
+ return path113.join(base, "keryx");
38500
38608
  }
38501
38609
  const xdg = process.env.XDG_DATA_HOME;
38502
- const base = xdg !== undefined && xdg.length > 0 ? xdg : path112.join(home, ".local", "share");
38503
- return path112.join(base, "keryx");
38610
+ const base = xdg !== undefined && xdg.length > 0 ? xdg : path113.join(home, ".local", "share");
38611
+ return path113.join(base, "keryx");
38504
38612
  }
38505
38613
  function resolveProjectRoot2(cwd) {
38506
- const abs = path112.resolve(cwd);
38614
+ const abs = path113.resolve(cwd);
38507
38615
  let dir = abs;
38508
38616
  for (;; ) {
38509
- const gitPath = path112.join(dir, ".git");
38617
+ const gitPath = path113.join(dir, ".git");
38510
38618
  if (existsSync16(gitPath)) {
38511
38619
  return dir;
38512
38620
  }
38513
- const parent = path112.dirname(dir);
38621
+ const parent = path113.dirname(dir);
38514
38622
  if (parent === dir) {
38515
38623
  break;
38516
38624
  }
@@ -38519,12 +38627,12 @@ function resolveProjectRoot2(cwd) {
38519
38627
  return abs;
38520
38628
  }
38521
38629
  function projectKeyFromPath(projectPath) {
38522
- const abs = path112.resolve(projectPath);
38630
+ const abs = path113.resolve(projectPath);
38523
38631
  const encoded = encodeURIComponent(abs);
38524
38632
  if (encoded.length <= 200) {
38525
38633
  return encoded;
38526
38634
  }
38527
- const base = path112.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 40);
38635
+ const base = path113.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 40);
38528
38636
  let h = 0;
38529
38637
  for (let i = 0;i < abs.length; i++) {
38530
38638
  h = Math.imul(31, h) + abs.charCodeAt(i) | 0;
@@ -38534,17 +38642,17 @@ function projectKeyFromPath(projectPath) {
38534
38642
  }
38535
38643
  function projectSessionsDir(projectPath, dataDir) {
38536
38644
  const key = projectKeyFromPath(resolveProjectRoot2(projectPath));
38537
- return path112.join(keryxDataDir(dataDir), "sessions", key);
38645
+ return path113.join(keryxDataDir(dataDir), "sessions", key);
38538
38646
  }
38539
38647
  function sessionDir(projectPath, sessionId, dataDir) {
38540
- return path112.join(projectSessionsDir(projectPath, dataDir), sessionId);
38648
+ return path113.join(projectSessionsDir(projectPath, dataDir), sessionId);
38541
38649
  }
38542
38650
 
38543
38651
  // src/session/slate.ts
38544
38652
  init_fs();
38545
38653
  init_assembly();
38546
38654
  import { mkdir as mkdir33, readFile as readFile56, readdir as readdir19, rm as rm7, stat as stat16 } from "fs/promises";
38547
- import path113 from "path";
38655
+ import path114 from "path";
38548
38656
  init_redact();
38549
38657
  var SLATE_SEED_KINDS = [
38550
38658
  "decision",
@@ -38559,7 +38667,7 @@ function isSlateSeedKind(value) {
38559
38667
  }
38560
38668
  var SEED_TEXT_MAX_LENGTH = 4000;
38561
38669
  function slatePath(dir) {
38562
- return path113.join(dir, "slate.json");
38670
+ return path114.join(dir, "slate.json");
38563
38671
  }
38564
38672
  function slateLockPath(dir) {
38565
38673
  return `${slatePath(dir)}.lock`;
@@ -38789,11 +38897,11 @@ function listSessions(cwd, dataDir) {
38789
38897
  if (name.startsWith(".")) {
38790
38898
  continue;
38791
38899
  }
38792
- const summary = readSummaryFile(path114.join(root, name, "summary.json"));
38900
+ const summary = readSummaryFile(path115.join(root, name, "summary.json"));
38793
38901
  if (summary === undefined) {
38794
38902
  continue;
38795
38903
  }
38796
- if (path114.resolve(summary.projectPath) !== path114.resolve(projectPath)) {
38904
+ if (path115.resolve(summary.projectPath) !== path115.resolve(projectPath)) {
38797
38905
  continue;
38798
38906
  }
38799
38907
  out.push(summary);
@@ -38826,15 +38934,15 @@ async function readSessionSlate(cwd, sessionId, dataDir) {
38826
38934
  }
38827
38935
  function loadContext(cwd, sessionId, dataDir) {
38828
38936
  const dir = sessionDir(resolveProjectRoot2(cwd), sessionId, dataDir);
38829
- const contextPath = path114.join(dir, "context.jsonl");
38937
+ const contextPath = path115.join(dir, "context.jsonl");
38830
38938
  if (existsSync17(contextPath)) {
38831
38939
  return readJsonl2(contextPath);
38832
38940
  }
38833
- return readJsonl2(path114.join(dir, "transcript.jsonl"));
38941
+ return readJsonl2(path115.join(dir, "transcript.jsonl"));
38834
38942
  }
38835
38943
  function loadArchive(cwd, sessionId, dataDir, onDegraded) {
38836
38944
  const dir = sessionDir(resolveProjectRoot2(cwd), sessionId, dataDir);
38837
- const archivePath = path114.join(dir, "archive.jsonl");
38945
+ const archivePath = path115.join(dir, "archive.jsonl");
38838
38946
  if (existsSync17(archivePath)) {
38839
38947
  try {
38840
38948
  const archive = readJsonl2(archivePath);
@@ -39018,7 +39126,7 @@ function sessionEvidenceRef(workspaceId, sessionId) {
39018
39126
  }
39019
39127
  async function resolveSessionWrapUp(input) {
39020
39128
  const now = input.now ?? (() => new Date);
39021
- const sessionId = path115.posix.basename(input.sourceRef, ".md");
39129
+ const sessionId = path116.posix.basename(input.sourceRef, ".md");
39022
39130
  const summary = findSession(input.cwd, sessionId);
39023
39131
  if (summary === undefined || input.sourceRef !== sessionEvidenceRef(input.workspaceId, summary.id)) {
39024
39132
  throw new SessionWrapUpError("session_not_found", `no session matching "${input.sourceRef}" in this project \u2014 use \`keryx sessions list\``);
@@ -39035,7 +39143,7 @@ async function resolveSessionWrapUp(input) {
39035
39143
  throw new SessionWrapUpError("session_unreadable", `session "${summary.id}" could not be read: ${cause.message}`);
39036
39144
  }
39037
39145
  const relPath = sessionEvidenceRef(input.workspaceId, summary.id).slice(2);
39038
- const evidenceDir = path115.dirname(relPath);
39146
+ const evidenceDir = path116.dirname(relPath);
39039
39147
  const slate = await readSessionSlate(input.cwd, summary.id);
39040
39148
  const diff = await gitDiff(input.cwd);
39041
39149
  const diffBody = diff.kind === "measured" ? diff.text : unmeasurableDiffBody(diff.detail);
@@ -39057,23 +39165,23 @@ async function resolveSessionWrapUp(input) {
39057
39165
  ""
39058
39166
  ].join(`
39059
39167
  `);
39060
- const wrapUpRelPath = path115.join(evidenceDir, `${summary.id}.wrap-up.md`);
39061
- const diffRelPath = path115.join(evidenceDir, `${summary.id}.diff.txt`);
39062
- const noticeRelPath = path115.join(evidenceDir, `${summary.id}.redaction.md`);
39168
+ const wrapUpRelPath = path116.join(evidenceDir, `${summary.id}.wrap-up.md`);
39169
+ const diffRelPath = path116.join(evidenceDir, `${summary.id}.diff.txt`);
39170
+ const noticeRelPath = path116.join(evidenceDir, `${summary.id}.redaction.md`);
39063
39171
  const floor = await applyEvidenceRedactionFloor(input.cwd, [
39064
- { name: path115.basename(relPath), content: markdown, path: relPath, source: "generated" },
39065
- { name: path115.basename(wrapUpRelPath), content: wrapUpMarkdown, path: wrapUpRelPath, source: "generated" },
39066
- { name: path115.basename(diffRelPath), content: diffBody, path: diffRelPath, source: "tool-output" }
39172
+ { name: path116.basename(relPath), content: markdown, path: relPath, source: "generated" },
39173
+ { name: path116.basename(wrapUpRelPath), content: wrapUpMarkdown, path: wrapUpRelPath, source: "generated" },
39174
+ { name: path116.basename(diffRelPath), content: diffBody, path: diffRelPath, source: "tool-output" }
39067
39175
  ]);
39068
39176
  if (!floor.ok)
39069
39177
  throw new SessionWrapUpError("security_denied", floor.reason);
39070
39178
  const [safeSession, safeWrapUp, safeDiff] = floor.bodies;
39071
- await mkdir34(path115.join(input.cwd, evidenceDir), { recursive: true });
39072
- await writeFile23(path115.join(input.cwd, relPath), safeSession.content, "utf8");
39073
- await writeFile23(path115.join(input.cwd, wrapUpRelPath), safeWrapUp.content, "utf8");
39074
- await writeFile23(path115.join(input.cwd, diffRelPath), safeDiff.content, "utf8");
39179
+ await mkdir34(path116.join(input.cwd, evidenceDir), { recursive: true });
39180
+ await writeFile23(path116.join(input.cwd, relPath), safeSession.content, "utf8");
39181
+ await writeFile23(path116.join(input.cwd, wrapUpRelPath), safeWrapUp.content, "utf8");
39182
+ await writeFile23(path116.join(input.cwd, diffRelPath), safeDiff.content, "utf8");
39075
39183
  if (floor.notice !== undefined)
39076
- await writeFile23(path115.join(input.cwd, noticeRelPath), floor.notice, "utf8");
39184
+ await writeFile23(path116.join(input.cwd, noticeRelPath), floor.notice, "utf8");
39077
39185
  const observedAt = now().toISOString();
39078
39186
  const evidence = [
39079
39187
  { kind: "wrap-up", uri: `./${wrapUpRelPath}`, revision: createHash26("sha256").update(safeWrapUp.content).digest("hex"), observedAt },
@@ -39096,13 +39204,13 @@ async function resolveSessionWrapUp(input) {
39096
39204
  init_fs();
39097
39205
  import { createHash as createHash27, randomBytes as randomBytes6 } from "crypto";
39098
39206
  import { readFile as readFile57 } from "fs/promises";
39099
- import path116 from "path";
39207
+ import path117 from "path";
39100
39208
  var CONFIRM_TOKEN_TTL_MS = 2 * 60000;
39101
39209
  function confirmTokenPath2(cwd, workspaceId, proposalId) {
39102
- return path116.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.confirm-token.json`);
39210
+ return path117.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.confirm-token.json`);
39103
39211
  }
39104
39212
  function confirmReceiptPath(cwd, workspaceId, proposalId, idempotencyKey) {
39105
- return path116.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${sha2566(idempotencyKey)}.confirm-receipt.json`);
39213
+ return path117.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${sha2566(idempotencyKey)}.confirm-receipt.json`);
39106
39214
  }
39107
39215
  function sha2566(text) {
39108
39216
  return createHash27("sha256").update(text).digest("hex");
@@ -39143,21 +39251,21 @@ init_store();
39143
39251
  init_config();
39144
39252
  import { readFile as readFile59, readdir as readdir20 } from "fs/promises";
39145
39253
  import { randomUUID as randomUUID6 } from "crypto";
39146
- import path118 from "path";
39254
+ import path119 from "path";
39147
39255
 
39148
39256
  // src/sac/proposal-evidence.ts
39149
39257
  init_fs();
39150
39258
  import { createHash as createHash28 } from "crypto";
39151
39259
  import { readFile as readFile58, rm as rm8 } from "fs/promises";
39152
- import path117 from "path";
39260
+ import path118 from "path";
39153
39261
  function proposalPath(cwd, workspaceId, proposalId) {
39154
- return path117.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.json`);
39262
+ return path118.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.json`);
39155
39263
  }
39156
39264
  function ownerReceiptPath(cwd, owner, workspaceId, idempotencyKey) {
39157
- return path117.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-receipts`, `${idempotencyKey}.json`);
39265
+ return path118.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-receipts`, `${idempotencyKey}.json`);
39158
39266
  }
39159
39267
  function proposalNotePath(cwd, workspaceId, proposalId) {
39160
- return path117.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.note.txt`);
39268
+ return path118.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.note.txt`);
39161
39269
  }
39162
39270
  async function readVerifiedProposalEvidence(cwd, workspaceId, proposalId) {
39163
39271
  let proposal;
@@ -39171,7 +39279,7 @@ async function readVerifiedProposalEvidence(cwd, workspaceId, proposalId) {
39171
39279
  return { ok: false, code: "no_evidence_to_write" };
39172
39280
  let content;
39173
39281
  try {
39174
- content = await readFile58(path117.join(cwd, evidence.uri), "utf8");
39282
+ content = await readFile58(path118.join(cwd, evidence.uri), "utf8");
39175
39283
  } catch {
39176
39284
  return { ok: false, code: "evidence_file_unreadable" };
39177
39285
  }
@@ -39201,22 +39309,22 @@ function targetRelPath(targetRef) {
39201
39309
  return targetRef.replace(/^\.\//, "");
39202
39310
  }
39203
39311
  function targetAbsolutePath(cwd, targetRef) {
39204
- return path117.join(cwd, ".metaproject", targetRelPath(targetRef));
39312
+ return path118.join(cwd, ".metaproject", targetRelPath(targetRef));
39205
39313
  }
39206
39314
  function targetKey(targetRef) {
39207
39315
  return digestOf2(targetRelPath(targetRef)).slice(0, 32);
39208
39316
  }
39209
39317
  function ownerTargetVersionPath(cwd, owner, workspaceId, targetRef) {
39210
- return path117.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-target-versions`, `${targetKey(targetRef)}.json`);
39318
+ return path118.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-target-versions`, `${targetKey(targetRef)}.json`);
39211
39319
  }
39212
39320
  function ownerTargetLockPath(cwd, owner, targetRef) {
39213
- return path117.join(cwd, ".metaproject", "data", "sac", "target-locks", owner, `${targetKey(targetRef)}.lock`);
39321
+ return path118.join(cwd, ".metaproject", "data", "sac", "target-locks", owner, `${targetKey(targetRef)}.lock`);
39214
39322
  }
39215
39323
  function ownerStagingDir(cwd, owner, workspaceId, idempotencyKey) {
39216
- return path117.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-staging`, digestOf2(idempotencyKey).slice(0, 32));
39324
+ return path118.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-staging`, digestOf2(idempotencyKey).slice(0, 32));
39217
39325
  }
39218
39326
  function ownerConflictDir(cwd, owner, workspaceId, idempotencyKey) {
39219
- return path117.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-conflicts`, digestOf2(idempotencyKey).slice(0, 32));
39327
+ return path118.join(cwd, ".metaproject", "workspaces", workspaceId, `${owner}-write-conflicts`, digestOf2(idempotencyKey).slice(0, 32));
39220
39328
  }
39221
39329
  async function readJson2(file) {
39222
39330
  try {
@@ -39287,7 +39395,7 @@ async function applyGuardedTargetWrite(input) {
39287
39395
  staged: input.staged,
39288
39396
  stagedAt: receipt.completedAt
39289
39397
  };
39290
- await writeFileAtomic(path117.join(ownerStagingDir(cwd, owner, intent.workspaceId, intent.idempotencyKey), "plan.json"), `${JSON.stringify(staged, null, 2)}
39398
+ await writeFileAtomic(path118.join(ownerStagingDir(cwd, owner, intent.workspaceId, intent.idempotencyKey), "plan.json"), `${JSON.stringify(staged, null, 2)}
39291
39399
  `);
39292
39400
  const applied = await input.apply(input.staged);
39293
39401
  if (!applied.ok) {
@@ -39313,15 +39421,15 @@ async function recoverStagedOwnerWrite(input) {
39313
39421
  });
39314
39422
  }
39315
39423
  async function readStagedOwnerWrite(cwd, owner, workspaceId, idempotencyKey) {
39316
- return readJson2(path117.join(ownerStagingDir(cwd, owner, workspaceId, idempotencyKey), "plan.json"));
39424
+ return readJson2(path118.join(ownerStagingDir(cwd, owner, workspaceId, idempotencyKey), "plan.json"));
39317
39425
  }
39318
39426
  async function recordConflict(input) {
39319
39427
  const base = { targetRef: input.targetRef, expectedVersion: input.expectedVersion, currentVersion: input.currentVersion };
39320
39428
  if (input.proposedContent === undefined)
39321
39429
  return base;
39322
39430
  const dir = ownerConflictDir(input.cwd, input.owner, input.intent.workspaceId, input.intent.idempotencyKey);
39323
- await writeFileAtomic(path117.join(dir, "proposed"), input.proposedContent);
39324
- const diffRef = `./workspaces/${input.intent.workspaceId}/${input.owner}-write-conflicts/${path117.basename(dir)}/proposed`;
39431
+ await writeFileAtomic(path118.join(dir, "proposed"), input.proposedContent);
39432
+ const diffRef = `./workspaces/${input.intent.workspaceId}/${input.owner}-write-conflicts/${path118.basename(dir)}/proposed`;
39325
39433
  return { ...base, diffRef };
39326
39434
  }
39327
39435
 
@@ -39371,7 +39479,7 @@ async function resolveWorkspaceModule(cwd, workspaceId) {
39371
39479
  }
39372
39480
  }
39373
39481
  async function collectWikiDecisionEntries(cwd) {
39374
- const dir = path118.join(cwd, ".metaproject", "wiki", "decisions");
39482
+ const dir = path119.join(cwd, ".metaproject", "wiki", "decisions");
39375
39483
  let files;
39376
39484
  try {
39377
39485
  files = (await readdir20(dir)).filter((name) => name.endsWith(".md"));
@@ -39380,12 +39488,12 @@ async function collectWikiDecisionEntries(cwd) {
39380
39488
  }
39381
39489
  const entries = [];
39382
39490
  for (const file of files) {
39383
- const absolutePath = path118.join(dir, file);
39491
+ const absolutePath = path119.join(dir, file);
39384
39492
  try {
39385
39493
  const content = await readFile59(absolutePath, "utf8");
39386
39494
  entries.push({
39387
39495
  absolutePath,
39388
- relativePath: path118.posix.join("decisions", file),
39496
+ relativePath: path119.posix.join("decisions", file),
39389
39497
  type: extractHeaderField(content, "Type") ?? "decision",
39390
39498
  title: extractTitle(content),
39391
39499
  version: extractHeaderField(content, "Version") ?? null,
@@ -39607,7 +39715,7 @@ function createRealMemoryOwnerWriter(cwd, opts) {
39607
39715
  init_service4();
39608
39716
  init_guard();
39609
39717
  import { readFile as readFile61 } from "fs/promises";
39610
- import path119 from "path";
39718
+ import path120 from "path";
39611
39719
  function renderWrapUpDecisionPage(input) {
39612
39720
  const note = input.note?.trim();
39613
39721
  return `# ${input.title}
@@ -39648,7 +39756,7 @@ export is the source of truth for what actually happened.
39648
39756
  `;
39649
39757
  }
39650
39758
  function wikiPageRelativePath(proposalId) {
39651
- return path119.posix.join("decisions", `sac-${proposalId}.md`);
39759
+ return path120.posix.join("decisions", `sac-${proposalId}.md`);
39652
39760
  }
39653
39761
  function createRealWikiOwnerWriter(cwd, opts) {
39654
39762
  const now = opts?.now ?? (() => new Date);
@@ -39656,7 +39764,7 @@ function createRealWikiOwnerWriter(cwd, opts) {
39656
39764
  const relativePath = staged.relativePath;
39657
39765
  const content = staged.content;
39658
39766
  const history = await openWikiWriteContext(cwd, "sac proposal accept");
39659
- await writeWikiPage(history, path119.join(cwd, ".metaproject", "wiki", relativePath), content);
39767
+ await writeWikiPage(history, path120.join(cwd, ".metaproject", "wiki", relativePath), content);
39660
39768
  return { ok: true };
39661
39769
  };
39662
39770
  return {
@@ -39726,7 +39834,7 @@ init_guard();
39726
39834
  import { createHash as createHash29 } from "crypto";
39727
39835
  import { homedir as homedir2 } from "os";
39728
39836
  import { readFile as readFile62, stat as stat17 } from "fs/promises";
39729
- import path120 from "path";
39837
+ import path121 from "path";
39730
39838
  var VERSION = "0.1.0";
39731
39839
  var PROJECT_SKILLS_DIR = ".metaproject/project-skills";
39732
39840
  var PROJECT_SKILLS_MANIFEST_PATH = ".metaproject/metaproject.json";
@@ -39756,7 +39864,7 @@ async function assertProjectWritesContained(projectRoot, paths) {
39756
39864
  }
39757
39865
  }
39758
39866
  async function createProjectSkill(projectRoot, options) {
39759
- const metaprojectRoot = path120.join(projectRoot, ".metaproject");
39867
+ const metaprojectRoot = path121.join(projectRoot, ".metaproject");
39760
39868
  if (!await pathExists(metaprojectRoot)) {
39761
39869
  throw new Error("Metaproject is not initialized. Run: keryx init");
39762
39870
  }
@@ -39767,7 +39875,7 @@ async function createProjectSkill(projectRoot, options) {
39767
39875
  const skillName = projectSkillSlug(options.name ?? inferSkillName(options.target));
39768
39876
  const format = options.format ?? "auto";
39769
39877
  const relativeSkillPath = projectSkillPackagePath(moduleName, skillName);
39770
- const packageRoot = path120.join(projectRoot, relativeSkillPath);
39878
+ const packageRoot = path121.join(projectRoot, relativeSkillPath);
39771
39879
  await assertProjectWritesContained(projectRoot, projectSkillWritePaths(moduleName, skillName, format));
39772
39880
  const origin = options.origin ? options.originContent !== undefined ? {
39773
39881
  ref: options.origin.trim(),
@@ -39778,7 +39886,7 @@ async function createProjectSkill(projectRoot, options) {
39778
39886
  const warnings = collectWarnings(evidence, format);
39779
39887
  const files = filesForPackage(packageRoot, format);
39780
39888
  if (!options.dryRun) {
39781
- await withFileLock(path120.join(projectRoot, PROJECT_SKILLS_LOCK_PATH), async () => {
39889
+ await withFileLock(path121.join(projectRoot, PROJECT_SKILLS_LOCK_PATH), async () => {
39782
39890
  await writeProjectSkillPackage({
39783
39891
  projectRoot,
39784
39892
  packageRoot,
@@ -39807,7 +39915,7 @@ async function createProjectSkill(projectRoot, options) {
39807
39915
  name: skillName,
39808
39916
  target: options.target,
39809
39917
  skillPath: relativeSkillPath,
39810
- files: files.map((filePath) => toPosix(path120.relative(projectRoot, filePath))),
39918
+ files: files.map((filePath) => toPosix(path121.relative(projectRoot, filePath))),
39811
39919
  warnings,
39812
39920
  dryRun: options.dryRun === true
39813
39921
  };
@@ -39816,9 +39924,9 @@ var MAX_SKILL_TARGET_LENGTH = 80;
39816
39924
  function resolveOriginPath(ref, projectRoot) {
39817
39925
  const trimmed = ref.trim();
39818
39926
  if (trimmed === "~" || trimmed.startsWith("~/")) {
39819
- return path120.join(homedir2(), trimmed.slice(1));
39927
+ return path121.join(homedir2(), trimmed.slice(1));
39820
39928
  }
39821
- return path120.resolve(projectRoot, trimmed);
39929
+ return path121.resolve(projectRoot, trimmed);
39822
39930
  }
39823
39931
  function hashOriginContent(content) {
39824
39932
  return `sha256:${createHash29("sha256").update(content).digest("hex")}`;
@@ -39856,16 +39964,16 @@ async function writeProjectSkillPackage({
39856
39964
  }) {
39857
39965
  const packageFormat = format === "single" ? "single" : "package";
39858
39966
  const skillContent = renderProjectSkill({ moduleName, skillName, target, note, origin, evidence, packageFormat });
39859
- const relativeSkillMdPath = toPosix(path120.join(path120.relative(projectRoot, packageRoot), "SKILL.md"));
39967
+ const relativeSkillMdPath = toPosix(path121.join(path121.relative(projectRoot, packageRoot), "SKILL.md"));
39860
39968
  const guard = await guardOutput({ cwd: projectRoot, content: skillContent, target: "skill", source: "generated", path: relativeSkillMdPath });
39861
39969
  const output = prepareOutputForPersistence(guard, skillContent);
39862
39970
  if (!output.allowed) {
39863
39971
  throw new Error(`Project skill blocked by the security gate: ${output.reason}`);
39864
39972
  }
39865
- const packageRel = toPosix(path120.relative(projectRoot, packageRoot));
39973
+ const packageRel = toPosix(path121.relative(projectRoot, packageRoot));
39866
39974
  const write = (file, content) => writeContained(projectRoot, `${packageRel}/${file}`, content);
39867
39975
  await write("SKILL.md", output.content);
39868
- if (!await pathExists(path120.join(packageRoot, "skill-changelog.md"))) {
39976
+ if (!await pathExists(path121.join(packageRoot, "skill-changelog.md"))) {
39869
39977
  await write("skill-changelog.md", renderSkillChangelog({ moduleName, skillName, target }));
39870
39978
  }
39871
39979
  if (packageFormat === "package") {
@@ -39875,10 +39983,10 @@ async function writeProjectSkillPackage({
39875
39983
  }
39876
39984
  }
39877
39985
  async function collectEvidence(projectRoot, target) {
39878
- const absoluteTarget = path120.resolve(projectRoot, target);
39986
+ const absoluteTarget = path121.resolve(projectRoot, target);
39879
39987
  const targetExists = await pathExists(absoluteTarget);
39880
39988
  const targetKind = await classifyTarget(absoluteTarget, targetExists);
39881
- const maybeRelativeTarget = targetExists ? toPosix(path120.relative(projectRoot, absoluteTarget)) : undefined;
39989
+ const maybeRelativeTarget = targetExists ? toPosix(path121.relative(projectRoot, absoluteTarget)) : undefined;
39882
39990
  const graphArtifacts = await existingRelativePaths(projectRoot, [
39883
39991
  ".metaproject/data/gdgraph/artifacts/summary.md",
39884
39992
  ".metaproject/data/gdgraph/artifacts/module-map.json"
@@ -39908,7 +40016,7 @@ async function classifyTarget(absoluteTarget, targetExists) {
39908
40016
  async function existingRelativePaths(projectRoot, candidates) {
39909
40017
  const existing = [];
39910
40018
  for (const candidate of candidates) {
39911
- if (await pathExists(path120.join(projectRoot, candidate))) {
40019
+ if (await pathExists(path121.join(projectRoot, candidate))) {
39912
40020
  existing.push(candidate);
39913
40021
  }
39914
40022
  }
@@ -39935,17 +40043,17 @@ function collectWarnings(evidence, format) {
39935
40043
  }
39936
40044
  function filesForPackage(packageRoot, format) {
39937
40045
  const base = [
39938
- path120.join(packageRoot, "SKILL.md"),
39939
- path120.join(packageRoot, "skill-changelog.md")
40046
+ path121.join(packageRoot, "SKILL.md"),
40047
+ path121.join(packageRoot, "skill-changelog.md")
39940
40048
  ];
39941
40049
  if (format === "single") {
39942
40050
  return base;
39943
40051
  }
39944
40052
  return [
39945
40053
  ...base,
39946
- path120.join(packageRoot, "verification.md"),
39947
- path120.join(packageRoot, "references", "context.md"),
39948
- path120.join(packageRoot, "templates", "README.md")
40054
+ path121.join(packageRoot, "verification.md"),
40055
+ path121.join(packageRoot, "references", "context.md"),
40056
+ path121.join(packageRoot, "templates", "README.md")
39949
40057
  ];
39950
40058
  }
39951
40059
  function renderProjectSkill({
@@ -40173,7 +40281,7 @@ keryx skills verify ${moduleName}/${skillName}
40173
40281
  `;
40174
40282
  }
40175
40283
  async function updateManifest(projectRoot, entry) {
40176
- const manifestPath = path120.join(projectRoot, PROJECT_SKILLS_MANIFEST_PATH);
40284
+ const manifestPath = path121.join(projectRoot, PROJECT_SKILLS_MANIFEST_PATH);
40177
40285
  const manifest = await readJsonFileOr(manifestPath, {});
40178
40286
  manifest.modules ??= {};
40179
40287
  manifest.modules.gdskills ??= {};
@@ -40187,8 +40295,8 @@ async function updateManifest(projectRoot, entry) {
40187
40295
  `);
40188
40296
  }
40189
40297
  async function updateSkillsCatalog(projectRoot) {
40190
- const manifestPath = path120.join(projectRoot, PROJECT_SKILLS_MANIFEST_PATH);
40191
- const catalogPath = path120.join(projectRoot, PROJECT_SKILLS_CATALOG_PATH);
40298
+ const manifestPath = path121.join(projectRoot, PROJECT_SKILLS_MANIFEST_PATH);
40299
+ const catalogPath = path121.join(projectRoot, PROJECT_SKILLS_CATALOG_PATH);
40192
40300
  const manifest = await readJsonFileOr(manifestPath, {});
40193
40301
  const registry = manifest.modules?.gdskills?.projectSkillRegistry ?? [];
40194
40302
  const rows = registry.length > 0 ? registry.map(projectSkillCatalogRow).join(`
@@ -40228,7 +40336,7 @@ function inferModule(target) {
40228
40336
  }
40229
40337
  function inferSkillName(target) {
40230
40338
  const normalized = target.trim().replace(/[#:]+/g, "/");
40231
- const base = path120.basename(normalized).replace(/\.[^.]+$/, "");
40339
+ const base = path121.basename(normalized).replace(/\.[^.]+$/, "");
40232
40340
  return base || "entity";
40233
40341
  }
40234
40342
  function projectSkillSlug(value) {
@@ -40333,7 +40441,7 @@ class ProposalLifecycleService {
40333
40441
  now;
40334
40442
  constructor(options) {
40335
40443
  this.options = options;
40336
- this.root = path121.resolve(options.workspaceRoot);
40444
+ this.root = path122.resolve(options.workspaceRoot);
40337
40445
  this.now = options.now ?? (() => new Date);
40338
40446
  }
40339
40447
  async create(input) {
@@ -40352,7 +40460,7 @@ class ProposalLifecycleService {
40352
40460
  if (manifest.status === "archived")
40353
40461
  throw new ProposalLifecycleError("guard_denied", "workspace is archived");
40354
40462
  const file = this.proposalPath(workspaceId, proposal.id);
40355
- await mkdir35(path121.dirname(file), { recursive: true, mode: 448 });
40463
+ await mkdir35(path122.dirname(file), { recursive: true, mode: 448 });
40356
40464
  return withFileLock(`${file}.lock`, async () => {
40357
40465
  const consume = this.options.wrapUpAuthority.consume(input.wrapUp, { actor, workspaceId });
40358
40466
  if (consume !== "ok")
@@ -40380,7 +40488,7 @@ class ProposalLifecycleService {
40380
40488
  return this.options.workspaces.withAuthorizedActor({ actorContext: actor, workspaceId: input.workspaceId, action: "review", execute: async (manifest) => {
40381
40489
  const proposal = await this.loadProposal(input.workspaceId, input.proposalId);
40382
40490
  const ledger = this.ledgerPath(input.workspaceId);
40383
- await mkdir35(path121.dirname(ledger), { recursive: true, mode: 448 });
40491
+ await mkdir35(path122.dirname(ledger), { recursive: true, mode: 448 });
40384
40492
  return withFileLock(`${ledger}.lock`, async () => {
40385
40493
  const records = (await this.records(ledger)).filter((record) => record.proposalId === proposal.id);
40386
40494
  const events = records.filter((record) => record.recordType === "proposal-transition");
@@ -40422,7 +40530,7 @@ class ProposalLifecycleService {
40422
40530
  } });
40423
40531
  }
40424
40532
  async listProposedProposals(workspaceId) {
40425
- const proposalsDir = path121.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals");
40533
+ const proposalsDir = path122.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals");
40426
40534
  let entries;
40427
40535
  try {
40428
40536
  entries = (await readdir21(proposalsDir)).filter((name) => name.endsWith(".json"));
@@ -40434,7 +40542,7 @@ class ProposalLifecycleService {
40434
40542
  const proposals = [];
40435
40543
  for (const entry of entries) {
40436
40544
  try {
40437
- const parsed = JSON.parse(await readFile64(path121.join(proposalsDir, entry), "utf8"));
40545
+ const parsed = JSON.parse(await readFile64(path122.join(proposalsDir, entry), "utf8"));
40438
40546
  if (parsed.recordType === "proposal-created")
40439
40547
  proposals.push(parsed);
40440
40548
  } catch {}
@@ -40700,31 +40808,31 @@ class ProposalLifecycleService {
40700
40808
  }
40701
40809
  }
40702
40810
  proposalPath(workspaceId, proposalId) {
40703
- return path121.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.json`);
40811
+ return path122.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.json`);
40704
40812
  }
40705
40813
  decisionRef(proposalId, key) {
40706
40814
  return `./proposals/${proposalId}.${hash(key)}.decision.json`;
40707
40815
  }
40708
40816
  decisionPath(workspaceId, proposalId, key) {
40709
- return path121.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.decision.json`);
40817
+ return path122.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.decision.json`);
40710
40818
  }
40711
40819
  approvalRef(proposalId, key) {
40712
40820
  return `./proposals/${proposalId}.${hash(key)}.approval.json`;
40713
40821
  }
40714
40822
  approvalPath(workspaceId, proposalId, key) {
40715
- return path121.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.approval.json`);
40823
+ return path122.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.approval.json`);
40716
40824
  }
40717
40825
  writeResultPath(workspaceId, proposalId, key) {
40718
- return path121.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.write-result.json`);
40826
+ return path122.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.write-result.json`);
40719
40827
  }
40720
40828
  intentRef(proposalId, key) {
40721
40829
  return `./proposals/${proposalId}.${hash(key)}.write-intent.json`;
40722
40830
  }
40723
40831
  intentPath(workspaceId, proposalId, key) {
40724
- return path121.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.write-intent.json`);
40832
+ return path122.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.write-intent.json`);
40725
40833
  }
40726
40834
  attemptPath(workspaceId, proposalId, key) {
40727
- return path121.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.owner-write-attempt.json`);
40835
+ return path122.join(this.root, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${hash(key)}.owner-write-attempt.json`);
40728
40836
  }
40729
40837
  async loadWriteResult(workspaceId, proposalId, key) {
40730
40838
  try {
@@ -40751,7 +40859,7 @@ class ProposalLifecycleService {
40751
40859
  }
40752
40860
  }
40753
40861
  ledgerPath(workspaceId) {
40754
- return path121.join(this.root, ".metaproject", "workspaces", workspaceId, "activity.jsonl");
40862
+ return path122.join(this.root, ".metaproject", "workspaces", workspaceId, "activity.jsonl");
40755
40863
  }
40756
40864
  timestamp() {
40757
40865
  return this.now().toISOString();
@@ -40834,7 +40942,7 @@ function normalizeProposalLifecycleResult(value) {
40834
40942
  // src/sac/collaboration-service.ts
40835
40943
  import { appendFile as appendFile9, mkdir as mkdir36, readFile as readFile65 } from "fs/promises";
40836
40944
  import { randomUUID as randomUUID8 } from "crypto";
40837
- import path122 from "path";
40945
+ import path123 from "path";
40838
40946
  class CollaborationServiceError extends Error {
40839
40947
  code;
40840
40948
  constructor(code, message) {
@@ -40849,7 +40957,7 @@ class CollaborationService {
40849
40957
  this.input = input;
40850
40958
  }
40851
40959
  file(id) {
40852
- return path122.join(this.input.workspaceRoot, ".metaproject", "workspaces", id, "activity.jsonl");
40960
+ return path123.join(this.input.workspaceRoot, ".metaproject", "workspaces", id, "activity.jsonl");
40853
40961
  }
40854
40962
  async overview(input) {
40855
40963
  const manifest = await this.input.workspaces.show(input);
@@ -40886,7 +40994,7 @@ class CollaborationService {
40886
40994
  occurredAt: (this.input.now ?? (() => new Date))().toISOString(),
40887
40995
  ...suppliedHandoff ? { handoff: { ...suppliedHandoff, from: actor.subject } } : {}
40888
40996
  });
40889
- await mkdir36(path122.dirname(this.file(manifest.id)), { recursive: true, mode: 448 });
40997
+ await mkdir36(path123.dirname(this.file(manifest.id)), { recursive: true, mode: 448 });
40890
40998
  await appendFile9(this.file(manifest.id), `${JSON.stringify(activity)}
40891
40999
  `, { mode: 384 });
40892
41000
  return normalizeCollaborationResult(activity);
@@ -40936,13 +41044,13 @@ function normalizeCollaborationResult(value) {
40936
41044
  // src/session/external-slate.ts
40937
41045
  init_fs();
40938
41046
  import { mkdir as mkdir38, readdir as readdir22, readFile as readFile66 } from "fs/promises";
40939
- import path124 from "path";
41047
+ import path125 from "path";
40940
41048
 
40941
41049
  // src/sac/machine-wrap-up.ts
40942
41050
  init_fs();
40943
41051
  import { createHash as createHash31, randomUUID as randomUUID10 } from "crypto";
40944
41052
  import { mkdir as mkdir37 } from "fs/promises";
40945
- import path123 from "path";
41053
+ import path124 from "path";
40946
41054
 
40947
41055
  // src/sac/workspace-resolve.ts
40948
41056
  init_redact();
@@ -41083,11 +41191,11 @@ async function resolveMachineWrapUp(input) {
41083
41191
  `;
41084
41192
  const seedsJson = `${JSON.stringify(seedsForKind.map((seed) => ({ text: seed.text, source: describeSource(seed.source) })), null, 2)}
41085
41193
  `;
41086
- const evidenceRelBase = path123.posix.join(".metaproject", "workspaces", input.workspaceId, "machine-evidence");
41194
+ const evidenceRelBase = path124.posix.join(".metaproject", "workspaces", input.workspaceId, "machine-evidence");
41087
41195
  const floor = await applyEvidenceRedactionFloor(input.cwd, [
41088
- { name: `${input.kind}.diff.txt`, content: diffBody, path: path123.posix.join(evidenceRelBase, `${input.kind}.diff.txt`), source: "tool-output" },
41089
- { name: `${input.kind}.flow.json`, content: flowSnapshotJson, path: path123.posix.join(evidenceRelBase, `${input.kind}.flow.json`), source: "generated" },
41090
- { name: `${input.kind}.seeds.json`, content: seedsJson, path: path123.posix.join(evidenceRelBase, `${input.kind}.seeds.json`), source: "generated" }
41196
+ { name: `${input.kind}.diff.txt`, content: diffBody, path: path124.posix.join(evidenceRelBase, `${input.kind}.diff.txt`), source: "tool-output" },
41197
+ { name: `${input.kind}.flow.json`, content: flowSnapshotJson, path: path124.posix.join(evidenceRelBase, `${input.kind}.flow.json`), source: "generated" },
41198
+ { name: `${input.kind}.seeds.json`, content: seedsJson, path: path124.posix.join(evidenceRelBase, `${input.kind}.seeds.json`), source: "generated" }
41091
41199
  ]);
41092
41200
  if (!floor.ok)
41093
41201
  return { ok: false, code: "security_denied", detail: floor.reason };
@@ -41141,14 +41249,14 @@ ${safeSeeds.content}`;
41141
41249
  }
41142
41250
  summary = result.text.trim().length > 0 ? result.text.trim() : mechanicalSummary(summaryDiff, course);
41143
41251
  }
41144
- const evidenceDir = path123.join(input.cwd, ".metaproject", "workspaces", input.workspaceId, "machine-evidence");
41252
+ const evidenceDir = path124.join(input.cwd, ".metaproject", "workspaces", input.workspaceId, "machine-evidence");
41145
41253
  await mkdir37(evidenceDir, { recursive: true });
41146
41254
  const diffFile = `${input.kind}.${shortHash}.diff.txt`;
41147
41255
  const flowFile = `${input.kind}.${shortHash}.flow.json`;
41148
41256
  const seedsFile = `${input.kind}.${shortHash}.seeds.json`;
41149
- await writeFileAtomic(path123.join(evidenceDir, diffFile), safeDiff.content);
41150
- await writeFileAtomic(path123.join(evidenceDir, flowFile), safeFlow.content);
41151
- await writeFileAtomic(path123.join(evidenceDir, seedsFile), safeSeeds.content);
41257
+ await writeFileAtomic(path124.join(evidenceDir, diffFile), safeDiff.content);
41258
+ await writeFileAtomic(path124.join(evidenceDir, flowFile), safeFlow.content);
41259
+ await writeFileAtomic(path124.join(evidenceDir, seedsFile), safeSeeds.content);
41152
41260
  const observedAt = now().toISOString();
41153
41261
  const relBase = `./.metaproject/workspaces/${input.workspaceId}/machine-evidence`;
41154
41262
  const evidence = [
@@ -41158,7 +41266,7 @@ ${safeSeeds.content}`;
41158
41266
  ];
41159
41267
  if (floor.notice !== undefined) {
41160
41268
  const noticeFile = `${input.kind}.${shortHash}.redaction.md`;
41161
- await writeFileAtomic(path123.join(evidenceDir, noticeFile), floor.notice);
41269
+ await writeFileAtomic(path124.join(evidenceDir, noticeFile), floor.notice);
41162
41270
  evidence.push({ kind: REDACTION_NOTICE_KIND, uri: `${relBase}/${noticeFile}`, revision: sha2567(floor.notice), observedAt });
41163
41271
  }
41164
41272
  return {
@@ -41177,18 +41285,18 @@ async function writeFlooredArchiveArtifact(params) {
41177
41285
  {
41178
41286
  name: params.filename,
41179
41287
  content: params.content,
41180
- path: path123.posix.join("slate-archive", params.filename),
41288
+ path: path124.posix.join("slate-archive", params.filename),
41181
41289
  source: "generated"
41182
41290
  }
41183
41291
  ]);
41184
41292
  if (!floor.ok)
41185
41293
  return { ok: false, code: "security_denied", detail: floor.reason };
41186
41294
  const body = floor.bodies[0];
41187
- const archiveDir = path123.join(params.dir, "slate-archive");
41295
+ const archiveDir = path124.join(params.dir, "slate-archive");
41188
41296
  await mkdir37(archiveDir, { recursive: true });
41189
- await writeFileAtomic(path123.join(archiveDir, params.filename), body.content);
41297
+ await writeFileAtomic(path124.join(archiveDir, params.filename), body.content);
41190
41298
  if (floor.notice !== undefined) {
41191
- await writeFileAtomic(path123.join(archiveDir, `${params.filename}${ARCHIVE_REDACTION_NOTICE_SUFFIX}`), floor.notice);
41299
+ await writeFileAtomic(path124.join(archiveDir, `${params.filename}${ARCHIVE_REDACTION_NOTICE_SUFFIX}`), floor.notice);
41192
41300
  }
41193
41301
  return { ok: true, altered: body.altered };
41194
41302
  }
@@ -41224,9 +41332,9 @@ async function writeWrapUpOutcomeArtifact(cwd, dir, trigger, now, groups) {
41224
41332
  return;
41225
41333
  const refusalIso = now().toISOString();
41226
41334
  const refusalFilename = `${refusalIso.replace(/[:.]/g, "-")}-wrap-up-outcome.json`;
41227
- const archiveDir = path123.join(dir, "slate-archive");
41335
+ const archiveDir = path124.join(dir, "slate-archive");
41228
41336
  await mkdir37(archiveDir, { recursive: true });
41229
- await writeFileAtomic(path123.join(archiveDir, refusalFilename), `${JSON.stringify({
41337
+ await writeFileAtomic(path124.join(archiveDir, refusalFilename), `${JSON.stringify({
41230
41338
  recordType: "wrap-up-outcome",
41231
41339
  trigger,
41232
41340
  generatedAt: refusalIso,
@@ -41362,7 +41470,7 @@ async function runWrapUp(input) {
41362
41470
 
41363
41471
  // src/session/external-slate.ts
41364
41472
  function externalSlatesDir(cwd) {
41365
- return path124.join(cwd, ".keryx", "external-slates");
41473
+ return path125.join(cwd, ".keryx", "external-slates");
41366
41474
  }
41367
41475
  var EXTERNAL_SESSION_ID_PATTERN = /^[A-Za-z0-9_-]{1,128}$/;
41368
41476
  function assertValidExternalSessionId(externalSessionId) {
@@ -41372,14 +41480,14 @@ function assertValidExternalSessionId(externalSessionId) {
41372
41480
  }
41373
41481
  function externalSlatePath(cwd, externalSessionId) {
41374
41482
  assertValidExternalSessionId(externalSessionId);
41375
- return path124.join(externalSlatesDir(cwd), `${externalSessionId}.json`);
41483
+ return path125.join(externalSlatesDir(cwd), `${externalSessionId}.json`);
41376
41484
  }
41377
41485
  function externalSlateLockPath(cwd, externalSessionId) {
41378
41486
  return `${externalSlatePath(cwd, externalSessionId)}.lock`;
41379
41487
  }
41380
41488
  function externalSlateEvidenceDir(cwd, externalSessionId) {
41381
41489
  assertValidExternalSessionId(externalSessionId);
41382
- return path124.join(externalSlatesDir(cwd), externalSessionId);
41490
+ return path125.join(externalSlatesDir(cwd), externalSessionId);
41383
41491
  }
41384
41492
  async function readExternalSlate(cwd, externalSessionId) {
41385
41493
  try {
@@ -41485,12 +41593,12 @@ __export(exports_service10, {
41485
41593
  runDoctor: () => runDoctor,
41486
41594
  runValidate: () => runValidate
41487
41595
  });
41488
- import path127 from "path";
41596
+ import path128 from "path";
41489
41597
  import { readFile as readFile69 } from "fs/promises";
41490
41598
 
41491
41599
  // src/standard/validate.ts
41492
41600
  init_fs();
41493
- import path126 from "path";
41601
+ import path127 from "path";
41494
41602
  import { readFile as readFile68 } from "fs/promises";
41495
41603
 
41496
41604
  // src/standard/schemas.ts
@@ -41620,7 +41728,7 @@ var SCHEMA_REGISTRY2 = {
41620
41728
  // src/standard/profiles.ts
41621
41729
  init_fs();
41622
41730
  init_entrypoint_targets();
41623
- import path125 from "path";
41731
+ import path126 from "path";
41624
41732
  import { readFile as readFile67 } from "fs/promises";
41625
41733
  var AGENT_MODULES = ["gdgraph", "gdctx", "gdskills", "gdwiki", "memory"];
41626
41734
  var CI_MODULES = ["health", "testing"];
@@ -41645,7 +41753,7 @@ function enabledModuleKeys(manifest) {
41645
41753
  }
41646
41754
  async function rootEntrypointLinksIndex(cwd, manifest) {
41647
41755
  for (const { path: name } of namedEntrypoints(manifest)) {
41648
- const filePath = path125.join(cwd, name);
41756
+ const filePath = path126.join(cwd, name);
41649
41757
  if (!await pathExists(filePath)) {
41650
41758
  continue;
41651
41759
  }
@@ -41657,16 +41765,16 @@ async function rootEntrypointLinksIndex(cwd, manifest) {
41657
41765
  return false;
41658
41766
  }
41659
41767
  async function minimalSatisfied(cwd) {
41660
- const metaprojectRoot = path125.join(cwd, ".metaproject");
41768
+ const metaprojectRoot = path126.join(cwd, ".metaproject");
41661
41769
  const requiredFiles = ["index.md", "README.md", "metaproject.json"];
41662
41770
  const requiredDirs = ["modules", "rules", "skills", "data"];
41663
41771
  for (const file of requiredFiles) {
41664
- if (!await pathExists(path125.join(metaprojectRoot, file))) {
41772
+ if (!await pathExists(path126.join(metaprojectRoot, file))) {
41665
41773
  return false;
41666
41774
  }
41667
41775
  }
41668
41776
  for (const dir of requiredDirs) {
41669
- if (!await pathExists(path125.join(metaprojectRoot, dir))) {
41777
+ if (!await pathExists(path126.join(metaprojectRoot, dir))) {
41670
41778
  return false;
41671
41779
  }
41672
41780
  }
@@ -41679,7 +41787,7 @@ async function ciSatisfied(cwd, manifest) {
41679
41787
  return false;
41680
41788
  }
41681
41789
  for (const key of ciModules) {
41682
- if (await pathExists(path125.join(cwd, ".metaproject", "data", key, "artifacts"))) {
41790
+ if (await pathExists(path126.join(cwd, ".metaproject", "data", key, "artifacts"))) {
41683
41791
  return true;
41684
41792
  }
41685
41793
  }
@@ -41692,7 +41800,7 @@ async function evaluateProfiles(cwd, manifest) {
41692
41800
  satisfied.push("minimal");
41693
41801
  }
41694
41802
  const hasAgentModule = AGENT_MODULES.some((key) => new Set(enabledModuleKeys(manifest)).has(key));
41695
- const agent = minimal && hasAgentModule && await rootEntrypointLinksIndex(cwd, manifest) && await pathExists(path125.join(cwd, ".metaproject", "rules"));
41803
+ const agent = minimal && hasAgentModule && await rootEntrypointLinksIndex(cwd, manifest) && await pathExists(path126.join(cwd, ".metaproject", "rules"));
41696
41804
  if (agent) {
41697
41805
  satisfied.push("agent");
41698
41806
  }
@@ -41861,20 +41969,20 @@ var MANIFEST_TOP_LEVEL_SCHEMA = {
41861
41969
  async function validateWorkspace2(cwd) {
41862
41970
  const errors = [];
41863
41971
  const warnings = [];
41864
- const metaprojectRoot = path126.join(cwd, ".metaproject");
41972
+ const metaprojectRoot = path127.join(cwd, ".metaproject");
41865
41973
  const requiredFiles = ["index.md", "README.md", "metaproject.json"];
41866
41974
  for (const file of requiredFiles) {
41867
- if (!await pathExists(path126.join(metaprojectRoot, file))) {
41975
+ if (!await pathExists(path127.join(metaprojectRoot, file))) {
41868
41976
  errors.push(issue("missing-required-file", `Required file .metaproject/${file} is missing`, `Run \`keryx init\` to scaffold .metaproject/${file}.`));
41869
41977
  }
41870
41978
  }
41871
41979
  const requiredDirs = ["modules", "rules", "skills", "data"];
41872
41980
  for (const dir of requiredDirs) {
41873
- if (!await pathExists(path126.join(metaprojectRoot, dir))) {
41981
+ if (!await pathExists(path127.join(metaprojectRoot, dir))) {
41874
41982
  errors.push(issue("missing-required-dir", `Required directory .metaproject/${dir}/ is missing`, `Run \`keryx init\` to create .metaproject/${dir}/.`));
41875
41983
  }
41876
41984
  }
41877
- const manifestPath = path126.join(metaprojectRoot, "metaproject.json");
41985
+ const manifestPath = path127.join(metaprojectRoot, "metaproject.json");
41878
41986
  if (!await pathExists(manifestPath)) {
41879
41987
  return { ok: errors.length === 0, errors, warnings };
41880
41988
  }
@@ -41906,7 +42014,7 @@ async function validateWorkspace2(cwd) {
41906
42014
  if (typeof value !== "string") {
41907
42015
  continue;
41908
42016
  }
41909
- if (!await pathExists(path126.join(cwd, value))) {
42017
+ if (!await pathExists(path127.join(cwd, value))) {
41910
42018
  errors.push(issue("missing-declared-path", `Declared path paths.${key} -> ${value} does not exist`, `Create ${value} or remove paths.${key} from metaproject.json.`));
41911
42019
  }
41912
42020
  }
@@ -41916,7 +42024,7 @@ async function validateWorkspace2(cwd) {
41916
42024
  continue;
41917
42025
  }
41918
42026
  if (typeof entry.manifest === "string") {
41919
- if (!await pathExists(path126.join(cwd, entry.manifest))) {
42027
+ if (!await pathExists(path127.join(cwd, entry.manifest))) {
41920
42028
  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.`));
41921
42029
  }
41922
42030
  }
@@ -41925,14 +42033,14 @@ async function validateWorkspace2(cwd) {
41925
42033
  if (typeof value !== "string") {
41926
42034
  continue;
41927
42035
  }
41928
- if (!await pathExists(path126.join(cwd, value))) {
42036
+ if (!await pathExists(path127.join(cwd, value))) {
41929
42037
  const sink = field === "data" ? warnings : errors;
41930
42038
  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.`));
41931
42039
  }
41932
42040
  }
41933
42041
  }
41934
42042
  for (const { path: name, scope } of namedEntrypoints(manifest)) {
41935
- const filePath = path126.join(cwd, name);
42043
+ const filePath = path127.join(cwd, name);
41936
42044
  if (!await pathExists(filePath)) {
41937
42045
  continue;
41938
42046
  }
@@ -42932,7 +43040,7 @@ async function runDoctor(cwd) {
42932
43040
  return validateWorkspace2(cwd);
42933
43041
  }
42934
43042
  async function readManifest(cwd) {
42935
- const manifestPath = path127.join(cwd, ".metaproject", "metaproject.json");
43043
+ const manifestPath = path128.join(cwd, ".metaproject", "metaproject.json");
42936
43044
  if (!await pathExists(manifestPath)) {
42937
43045
  throw new Error("Metaproject is not initialized (missing .metaproject/metaproject.json). Run `keryx init` first.");
42938
43046
  }