@agentskit/doc-bridge 1.11.1 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/README.md +3 -2
  3. package/action.yml +1 -1
  4. package/dist/cli/program.js +582 -471
  5. package/dist/cli/program.js.map +1 -1
  6. package/dist/index.d.ts +7 -2
  7. package/dist/index.js +500 -389
  8. package/dist/index.js.map +1 -1
  9. package/docs/DESIGN.md +71 -0
  10. package/docs/MARKETPLACE-ECOSYSTEM-PLAN.md +1 -1
  11. package/docs/PRD-enterprise-hardening.md +5 -5
  12. package/docs/PRD-knowledge-retrieval-and-enrichment.md +1 -1
  13. package/docs/knowledge-engine-runbook.md +1 -1
  14. package/docs/loop-workflow.md +15 -15
  15. package/docs/spec/config-v1.md +29 -7
  16. package/docs/spec/documentation-standard-v1.md +5 -0
  17. package/docs/spec/mcp-knowledge-tools-v1.md +1 -1
  18. package/docs/validation-cycle-plan.md +13 -13
  19. package/ecosystem-claims.json +17 -17
  20. package/ecosystem-upstream.json +2 -2
  21. package/ecosystem.json +300 -147
  22. package/mcpb/manifest.json +1 -1
  23. package/package.json +2 -1
  24. package/skills/doc-bridge-handoff/SKILL.md +1 -1
  25. package/skills/doc-bridge-handoff/scripts/resolve-handoff.mjs +1 -1
  26. package/src/conformance/ecosystem-contract.ts +10 -26
  27. package/src/discovery/repository.ts +7 -1
  28. package/src/findings/report.ts +1 -1
  29. package/src/fixes/proposals.ts +4 -2
  30. package/src/gates/run-gates.ts +1 -1
  31. package/src/index-builder/human-adapters/core.ts +10 -4
  32. package/src/lib/ignore-filter.ts +151 -0
  33. package/src/lib/walk.ts +10 -2
  34. package/src/memory/ingest.ts +1 -1
  35. package/src/report/html.ts +1 -1
  36. package/src/safety/repository.ts +9 -0
  37. package/src/version.ts +1 -1
  38. package/docs/DOGFOOD-ROUND2.md +0 -147
  39. package/docs/DOGFOOD-ROUND3.md +0 -79
  40. package/docs/DOGFOOD-V1.md +0 -89
  41. package/docs/DOGFOOD.md +0 -97
@@ -1,6 +1,6 @@
1
1
  // src/cli/program.ts
2
- import { closeSync as closeSync3, existsSync as existsSync30, mkdirSync as mkdirSync13, openSync as openSync3, readFileSync as readFileSync33, renameSync as renameSync6, rmSync as rmSync3, writeFileSync as writeFileSync14 } from "fs";
3
- import { dirname as dirname13, relative as relative12, resolve as resolve33 } from "path";
2
+ import { closeSync as closeSync3, existsSync as existsSync31, mkdirSync as mkdirSync13, openSync as openSync3, readFileSync as readFileSync34, renameSync as renameSync6, rmSync as rmSync3, writeFileSync as writeFileSync14 } from "fs";
3
+ import { dirname as dirname14, relative as relative13, resolve as resolve34 } from "path";
4
4
  import { createInterface } from "readline/promises";
5
5
 
6
6
  // src/config/load-config.ts
@@ -871,8 +871,8 @@ var projectRootFromConfigPath = (configFilePath, projectRootField) => {
871
871
  };
872
872
 
873
873
  // src/conformance/documentation-standard-v1.ts
874
- import { closeSync as closeSync2, existsSync as existsSync11, fstatSync as fstatSync2, openSync as openSync2, readFileSync as readFileSync12, realpathSync as realpathSync7 } from "fs";
875
- import { isAbsolute as isAbsolute5, relative as relative7, resolve as resolve11, sep as sep8 } from "path";
874
+ import { closeSync as closeSync2, existsSync as existsSync12, fstatSync as fstatSync2, openSync as openSync2, readFileSync as readFileSync13, realpathSync as realpathSync8 } from "fs";
875
+ import { isAbsolute as isAbsolute6, relative as relative8, resolve as resolve12, sep as sep9 } from "path";
876
876
 
877
877
  // src/conformance/ecosystem-contract.ts
878
878
  import { z as z2 } from "zod";
@@ -922,10 +922,9 @@ var ManifestSchema = z2.object({
922
922
  schemaVersion: z2.literal(2),
923
923
  parentBrand: z2.object({ id: NonEmptyStringSchema, name: NonEmptyStringSchema }).passthrough(),
924
924
  products: z2.array(ProductSchema).min(1),
925
- // Historical four-product shim or full seven-product projection of products[].
926
- properties: z2.array(LegacyPropertySchema).refine((value) => value.length === 4 || value.length === 7, {
927
- message: "must project either the legacy four products or the full seven-product catalog"
928
- }),
925
+ // Deprecated compatibility shim: when present, every entry projects one products[] record.
926
+ // Membership is whatever the canonical manifest lists; no product is required by name.
927
+ properties: z2.array(LegacyPropertySchema).optional(),
929
928
  builder: z2.object({ id: NonEmptyStringSchema, name: NonEmptyStringSchema, url: HttpsUrlSchema }).passthrough().optional()
930
929
  }).passthrough();
931
930
  var EvidenceSchema = z2.discriminatedUnion("type", [
@@ -959,16 +958,6 @@ var ClaimsSchema = z2.object({
959
958
  manifestSchemaVersion: z2.literal(2),
960
959
  products: z2.array(ClaimProductSchema)
961
960
  }).passthrough();
962
- var LEGACY_FOUR_PRODUCT_IDS = ["agentskit", "akos", "playbook", "registry"];
963
- var FULL_SEVEN_PRODUCT_IDS = [
964
- "agentskit",
965
- "registry",
966
- "agentskit-chat",
967
- "playbook",
968
- "doc-bridge",
969
- "code-review",
970
- "akos"
971
- ];
972
961
  var parseCanonicalEcosystemContract = (manifestInput, claimsInput) => {
973
962
  const manifest = ManifestSchema.parse(manifestInput);
974
963
  const claims = ClaimsSchema.parse(claimsInput);
@@ -994,12 +983,14 @@ var parseCanonicalEcosystemContract = (manifestInput, claimsInput) => {
994
983
  if (!products.has(nextId)) throw new Error(`Product ${product.id} references unknown product ${nextId}.`);
995
984
  }
996
985
  }
997
- const propertyIds = manifest.properties.length === 7 ? FULL_SEVEN_PRODUCT_IDS : LEGACY_FOUR_PRODUCT_IDS;
998
- for (const [index, id] of propertyIds.entries()) {
999
- const legacy = manifest.properties[index];
986
+ const propertyIds = /* @__PURE__ */ new Set();
987
+ for (const [index, legacy] of (manifest.properties ?? []).entries()) {
988
+ const id = legacy.id;
1000
989
  const product = products.get(id);
1001
- if (!legacy || !product || legacy.id !== id || !product.surfaces.home) {
1002
- throw new Error(`Legacy property ${index} must project product ${id}.`);
990
+ if (propertyIds.has(id)) throw new Error(`Legacy property ${id} is listed more than once.`);
991
+ propertyIds.add(id);
992
+ if (!product || !product.surfaces.home) {
993
+ throw new Error(`Legacy property ${index} (${id}) must project a manifest product with a home surface.`);
1003
994
  }
1004
995
  const expected = {
1005
996
  name: product.name,
@@ -1050,8 +1041,8 @@ var parseCanonicalEcosystemContract = (manifestInput, claimsInput) => {
1050
1041
  };
1051
1042
 
1052
1043
  // src/index-builder/build-index.ts
1053
- import { mkdirSync as mkdirSync2, readFileSync as readFileSync11, writeFileSync as writeFileSync2 } from "fs";
1054
- import { dirname as dirname4, join as join10 } from "path";
1044
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync12, writeFileSync as writeFileSync2 } from "fs";
1045
+ import { dirname as dirname5, join as join11 } from "path";
1055
1046
 
1056
1047
  // src/discovery/documentation.ts
1057
1048
  import { parseDocument } from "yaml";
@@ -1419,8 +1410,8 @@ var nodeStart = (node) => {
1419
1410
  var conventionalPackageReference = (path, agentRoot) => {
1420
1411
  const prefix = `${agentRoot.replace(/\/$/, "")}/`;
1421
1412
  if (!path.startsWith(prefix)) return void 0;
1422
- const relative13 = path.slice(prefix.length);
1423
- const [scope, file] = relative13.split("/");
1413
+ const relative14 = path.slice(prefix.length);
1414
+ const [scope, file] = relative14.split("/");
1424
1415
  if (scope !== "packages" && scope !== "apps" || !file) return void 0;
1425
1416
  return file.replace(/\.mdx?$/, "");
1426
1417
  };
@@ -1733,9 +1724,9 @@ var applyDocumentationDeclarations = (snapshot, documents, options = {}) => {
1733
1724
  };
1734
1725
 
1735
1726
  // src/discovery/repository.ts
1736
- import { execFileSync } from "child_process";
1737
- import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
1738
- import { basename as basename2, dirname as dirname2, extname as extname2, join as join5, relative as relative3, resolve as resolve4, sep as sep3 } from "path";
1727
+ import { execFileSync as execFileSync2 } from "child_process";
1728
+ import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
1729
+ import { basename as basename2, dirname as dirname3, extname as extname2, join as join6, relative as relative4, resolve as resolve5, sep as sep4 } from "path";
1739
1730
  import * as ts2 from "typescript";
1740
1731
 
1741
1732
  // src/lib/glob-expand.ts
@@ -1751,9 +1742,9 @@ var containedProjectPath = (root, path) => {
1751
1742
  const unresolved = resolve2(projectRoot, path);
1752
1743
  const unresolvedRelative = relative(projectRoot, unresolved);
1753
1744
  if (isAbsolute(unresolvedRelative) || unresolvedRelative === ".." || unresolvedRelative.startsWith(`..${sep}`)) return void 0;
1754
- const canonical = existsSync2(unresolved) ? realpathSync.native(unresolved) : unresolved;
1755
- const canonicalRelative = relative(projectRoot, canonical);
1756
- return isAbsolute(canonicalRelative) || canonicalRelative === ".." || canonicalRelative.startsWith(`..${sep}`) ? void 0 : canonical;
1745
+ const canonical2 = existsSync2(unresolved) ? realpathSync.native(unresolved) : unresolved;
1746
+ const canonicalRelative = relative(projectRoot, canonical2);
1747
+ return isAbsolute(canonicalRelative) || canonicalRelative === ".." || canonicalRelative.startsWith(`..${sep}`) ? void 0 : canonical2;
1757
1748
  };
1758
1749
 
1759
1750
  // src/lib/glob-expand.ts
@@ -1845,25 +1836,140 @@ var defaultChecksForTarget = (root, opts) => {
1845
1836
  };
1846
1837
 
1847
1838
  // src/safety/repository.ts
1848
- import { lstatSync, readdirSync as readdirSync2, realpathSync as realpathSync2, statSync as statSync2 } from "fs";
1849
- import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve3, sep as sep2 } from "path";
1839
+ import { lstatSync, readdirSync as readdirSync2, realpathSync as realpathSync3, statSync as statSync2 } from "fs";
1840
+ import { isAbsolute as isAbsolute3, relative as relative3, resolve as resolve4, sep as sep3 } from "path";
1850
1841
  import { minimatch } from "minimatch";
1842
+
1843
+ // src/lib/ignore-filter.ts
1844
+ import { execFileSync } from "child_process";
1845
+ import { existsSync as existsSync5, readFileSync as readFileSync3, realpathSync as realpathSync2 } from "fs";
1846
+ import { dirname as dirname2, isAbsolute as isAbsolute2, join as join4, relative as relative2, resolve as resolve3, sep as sep2 } from "path";
1847
+ import ignore from "ignore";
1848
+ var toPosix2 = (value) => value.split(sep2).join("/");
1849
+ var canonical = (path) => {
1850
+ try {
1851
+ return realpathSync2.native(resolve3(path));
1852
+ } catch {
1853
+ return resolve3(path);
1854
+ }
1855
+ };
1856
+ var below = (root, candidate) => {
1857
+ const rel = relative2(root, candidate);
1858
+ if (rel === "") return "";
1859
+ if (isAbsolute2(rel) || rel === ".." || rel.startsWith(`..${sep2}`)) return void 0;
1860
+ return toPosix2(rel);
1861
+ };
1862
+ var gitVisibleFiles = (root) => {
1863
+ try {
1864
+ const inside = execFileSync("git", ["rev-parse", "--is-inside-work-tree"], {
1865
+ cwd: root,
1866
+ encoding: "utf8",
1867
+ stdio: ["ignore", "pipe", "ignore"]
1868
+ }).trim();
1869
+ if (inside !== "true") return void 0;
1870
+ const output = execFileSync("git", ["ls-files", "-z", "--cached", "--others", "--exclude-standard", "--", "."], {
1871
+ cwd: root,
1872
+ encoding: "utf8",
1873
+ maxBuffer: 256 * 1024 * 1024,
1874
+ stdio: ["ignore", "pipe", "ignore"]
1875
+ });
1876
+ return output.split("\0").filter(Boolean);
1877
+ } catch {
1878
+ return void 0;
1879
+ }
1880
+ };
1881
+ var gitFilter = (root, canonicalRoot, visible) => {
1882
+ const files = new Set(visible.filter((path) => !path.endsWith("/")));
1883
+ const directories = /* @__PURE__ */ new Set([""]);
1884
+ for (const file of visible) {
1885
+ let parent = file;
1886
+ for (; ; ) {
1887
+ const slash = parent.lastIndexOf("/");
1888
+ if (slash === -1) break;
1889
+ parent = parent.slice(0, slash);
1890
+ if (directories.has(parent)) break;
1891
+ directories.add(parent);
1892
+ }
1893
+ }
1894
+ return {
1895
+ mode: "git",
1896
+ isIgnored: (absolutePath, isDirectory) => {
1897
+ const rel = below(root, resolve3(absolutePath)) ?? below(canonicalRoot, canonical(absolutePath));
1898
+ if (rel === void 0) return false;
1899
+ return isDirectory ? !directories.has(rel) : !files.has(rel);
1900
+ }
1901
+ };
1902
+ };
1903
+ var gitignoreFilter = (root) => {
1904
+ const rules = /* @__PURE__ */ new Map();
1905
+ const rulesFor = (directory) => {
1906
+ if (rules.has(directory)) return rules.get(directory);
1907
+ const file = join4(directory, ".gitignore");
1908
+ let matcher;
1909
+ if (existsSync5(file)) {
1910
+ try {
1911
+ matcher = ignore().add(readFileSync3(file, "utf8"));
1912
+ } catch {
1913
+ matcher = void 0;
1914
+ }
1915
+ }
1916
+ rules.set(directory, matcher);
1917
+ return matcher;
1918
+ };
1919
+ const ignoredCache = /* @__PURE__ */ new Map();
1920
+ const isIgnored = (absolutePath, isDirectory) => {
1921
+ const target2 = resolve3(absolutePath);
1922
+ const rel = below(root, target2);
1923
+ if (rel === void 0 || rel === "") return false;
1924
+ const key = `${isDirectory ? "d" : "f"}:${rel}`;
1925
+ const cached = ignoredCache.get(key);
1926
+ if (cached !== void 0) return cached;
1927
+ const parent = dirname2(target2);
1928
+ let result = parent !== root && below(root, parent) !== void 0 ? isIgnored(parent, true) : false;
1929
+ if (!result) {
1930
+ let decided;
1931
+ let directory = root;
1932
+ const segments = below(root, parent)?.split("/").filter(Boolean) ?? [];
1933
+ for (let index = 0; index <= segments.length; index += 1) {
1934
+ if (index > 0) directory = join4(directory, segments[index - 1]);
1935
+ const matcher = rulesFor(directory);
1936
+ if (!matcher) continue;
1937
+ const local = toPosix2(relative2(directory, target2)) + (isDirectory ? "/" : "");
1938
+ const verdict = matcher.test(local);
1939
+ if (verdict.ignored) decided = true;
1940
+ else if (verdict.unignored) decided = false;
1941
+ }
1942
+ result = decided ?? false;
1943
+ }
1944
+ ignoredCache.set(key, result);
1945
+ return result;
1946
+ };
1947
+ return { mode: "gitignore", isIgnored };
1948
+ };
1949
+ var createIgnoreFilter = (root) => {
1950
+ const base = resolve3(root);
1951
+ const canonicalRoot = canonical(root);
1952
+ const visible = gitVisibleFiles(canonicalRoot);
1953
+ return visible ? gitFilter(base, canonicalRoot, visible) : gitignoreFilter(base);
1954
+ };
1955
+
1956
+ // src/safety/repository.ts
1851
1957
  var DEFAULT_SAFETY_EXCLUDES = ["**/.git/**", "**/node_modules/**", "**/dist/**", "**/build/**", "**/coverage/**", "**/.doc-bridge/**", "**/.next/**", "**/out/**", "**/.turbo/**", "**/.svelte-kit/**", "**/.mcpb-build/**", "**/.mcpb-output/**", "**/.env", "**/.env.*", "**/*secret*", "**/*credential*", "**/*.pem", "**/*.key"];
1852
1958
  var containedPath = (root, candidate) => {
1853
- const projectRoot = realpathSync2.native(resolve3(root));
1854
- const unresolved = resolve3(projectRoot, candidate);
1855
- const unresolvedRelative = relative2(projectRoot, unresolved);
1856
- if (isAbsolute2(unresolvedRelative) || unresolvedRelative === ".." || unresolvedRelative.startsWith(`..${sep2}`)) return void 0;
1959
+ const projectRoot = realpathSync3.native(resolve4(root));
1960
+ const unresolved = resolve4(projectRoot, candidate);
1961
+ const unresolvedRelative = relative3(projectRoot, unresolved);
1962
+ if (isAbsolute3(unresolvedRelative) || unresolvedRelative === ".." || unresolvedRelative.startsWith(`..${sep3}`)) return void 0;
1857
1963
  try {
1858
- const canonical = realpathSync2.native(unresolved);
1859
- const canonicalRelative = relative2(projectRoot, canonical);
1860
- return isAbsolute2(canonicalRelative) || canonicalRelative === ".." || canonicalRelative.startsWith(`..${sep2}`) ? void 0 : canonical;
1964
+ const canonical2 = realpathSync3.native(unresolved);
1965
+ const canonicalRelative = relative3(projectRoot, canonical2);
1966
+ return isAbsolute3(canonicalRelative) || canonicalRelative === ".." || canonicalRelative.startsWith(`..${sep3}`) ? void 0 : canonical2;
1861
1967
  } catch {
1862
1968
  return unresolved;
1863
1969
  }
1864
1970
  };
1865
1971
  var safeWalkFiles = (root, options = {}) => {
1866
- const projectRoot = resolve3(root);
1972
+ const projectRoot = resolve4(root);
1867
1973
  const extensions = options.extensions ?? [];
1868
1974
  const excludes = options.exclude ?? DEFAULT_SAFETY_EXCLUDES;
1869
1975
  const files = [];
@@ -1871,6 +1977,7 @@ var safeWalkFiles = (root, options = {}) => {
1871
1977
  let reason;
1872
1978
  const started = Date.now();
1873
1979
  const matchesExclude = (path) => excludes.some((pattern) => minimatch(path, pattern, { dot: true }));
1980
+ const ignored = options.respectIgnore === false ? void 0 : createIgnoreFilter(projectRoot);
1874
1981
  const visit2 = (directory) => {
1875
1982
  if (reason) return;
1876
1983
  if (options.maxTimeMs !== void 0 && Date.now() - started >= options.maxTimeMs) {
@@ -1888,8 +1995,8 @@ var safeWalkFiles = (root, options = {}) => {
1888
1995
  return;
1889
1996
  }
1890
1997
  for (const name of entries.sort()) {
1891
- const absolute = resolve3(directory, name);
1892
- const relativePath3 = relative2(projectRoot, absolute).split(sep2).join("/");
1998
+ const absolute = resolve4(directory, name);
1999
+ const relativePath3 = relative3(projectRoot, absolute).split(sep3).join("/");
1893
2000
  if (matchesExclude(relativePath3) || name === ".git") continue;
1894
2001
  let stats;
1895
2002
  try {
@@ -1898,6 +2005,7 @@ var safeWalkFiles = (root, options = {}) => {
1898
2005
  continue;
1899
2006
  }
1900
2007
  if (stats.isSymbolicLink()) continue;
2008
+ if (ignored?.isIgnored(absolute, stats.isDirectory())) continue;
1901
2009
  if (stats.isDirectory()) {
1902
2010
  visit2(absolute);
1903
2011
  if (reason) return;
@@ -2120,11 +2228,11 @@ var relativeToPackage = (modulePath, packagePath) => {
2120
2228
  const prefix = `${packagePath}/`;
2121
2229
  return modulePath.startsWith(prefix) ? modulePath.slice(prefix.length) : void 0;
2122
2230
  };
2123
- var join4 = (...parts) => parts.filter(Boolean).join("/");
2231
+ var join5 = (...parts) => parts.filter(Boolean).join("/");
2124
2232
  var conventionalAreaPath = (module, depth = DEFAULT_AREA_DEPTH, roots = DEFAULT_AREA_ROOTS) => {
2125
- const relative13 = relativeToPackage(normalize(module.path), normalize(module.packagePath));
2126
- if (relative13 === void 0) return void 0;
2127
- const segments = relative13.split("/");
2233
+ const relative14 = relativeToPackage(normalize(module.path), normalize(module.packagePath));
2234
+ if (relative14 === void 0) return void 0;
2235
+ const segments = relative14.split("/");
2128
2236
  segments.pop();
2129
2237
  if (!segments.length) return void 0;
2130
2238
  const rootPrefix = [];
@@ -2136,7 +2244,7 @@ var conventionalAreaPath = (module, depth = DEFAULT_AREA_DEPTH, roots = DEFAULT_
2136
2244
  const taken = rest.slice(0, Math.max(1, depth));
2137
2245
  if (!taken.length) return void 0;
2138
2246
  const packagePath = normalize(module.packagePath);
2139
- return join4(packagePath === "." ? "" : packagePath, ...rootPrefix, ...taken);
2247
+ return join5(packagePath === "." ? "" : packagePath, ...rootPrefix, ...taken);
2140
2248
  };
2141
2249
  var encloses = (candidate, path) => path === candidate || path.startsWith(`${candidate}/`);
2142
2250
  var deriveAreas = (options) => {
@@ -2820,13 +2928,13 @@ var MAX_MARKDOWN_NOTES = 32;
2820
2928
  var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
2821
2929
  var readJson = (path) => {
2822
2930
  try {
2823
- const value = JSON.parse(readFileSync3(path, "utf8"));
2931
+ const value = JSON.parse(readFileSync4(path, "utf8"));
2824
2932
  return isRecord(value) ? { value } : { error: "JSON root is not an object" };
2825
2933
  } catch (error) {
2826
2934
  return { error: error instanceof Error ? error.message : String(error) };
2827
2935
  }
2828
2936
  };
2829
- var relativePath = (root, path) => toPosix(relative3(root, path)) || ".";
2937
+ var relativePath = (root, path) => toPosix(relative4(root, path)) || ".";
2830
2938
  var lineEvidence = (source, root, path, lineStart, lineEnd) => ({
2831
2939
  source,
2832
2940
  path: relativePath(root, path),
@@ -2844,11 +2952,11 @@ var workspacePatterns = (root, rootManifest) => {
2844
2952
  if (isRecord(fromPackageJson) && Array.isArray(fromPackageJson.packages)) {
2845
2953
  return fromPackageJson.packages.filter((value) => typeof value === "string");
2846
2954
  }
2847
- const workspacePath = join5(root, "pnpm-workspace.yaml");
2848
- if (!existsSync5(workspacePath)) return [];
2955
+ const workspacePath = join6(root, "pnpm-workspace.yaml");
2956
+ if (!existsSync6(workspacePath)) return [];
2849
2957
  const patterns = [];
2850
2958
  let inPackages = false;
2851
- for (const line of readFileSync3(workspacePath, "utf8").split(/\r?\n/)) {
2959
+ for (const line of readFileSync4(workspacePath, "utf8").split(/\r?\n/)) {
2852
2960
  const trimmed = line.trim();
2853
2961
  if (trimmed === "packages:") {
2854
2962
  inPackages = true;
@@ -2866,7 +2974,7 @@ var workspacePatterns = (root, rootManifest) => {
2866
2974
  var discoverPackages = (root, rootManifest, config) => {
2867
2975
  const packages = [];
2868
2976
  const coverage = [];
2869
- const rootManifestPath = join5(root, "package.json");
2977
+ const rootManifestPath = join6(root, "package.json");
2870
2978
  if (rootManifest) {
2871
2979
  const name = packageName(rootManifest, "");
2872
2980
  packages.push({
@@ -2886,8 +2994,8 @@ var discoverPackages = (root, rootManifest, config) => {
2886
2994
  }
2887
2995
  const dirs = expandWorkspaceGlobs(root, patterns);
2888
2996
  for (const absPath of dirs) {
2889
- const manifestPath = join5(absPath, "package.json");
2890
- if (!existsSync5(manifestPath)) continue;
2997
+ const manifestPath = join6(absPath, "package.json");
2998
+ if (!existsSync6(manifestPath)) continue;
2891
2999
  const parsed = readJson(manifestPath);
2892
3000
  if (!parsed.value) {
2893
3001
  coverage.push({ status: "partial", reason: `${relativePath(root, manifestPath)}: ${parsed.error ?? "invalid package.json"}` });
@@ -2897,7 +3005,7 @@ var discoverPackages = (root, rootManifest, config) => {
2897
3005
  const name = packageName(parsed.value, path);
2898
3006
  const id = entityId("package", name ?? path);
2899
3007
  const duplicate = packages.find((pkg) => pkg.id === id);
2900
- if (duplicate && duplicate.absPath !== absPath) {
3008
+ if (duplicate && toPosix(duplicate.absPath) !== toPosix(absPath)) {
2901
3009
  throw new Error(`Package identity collision for "${id}": "${duplicate.path}" and "${path}".`);
2902
3010
  }
2903
3011
  if (!duplicate) packages.push({ id, ...name ? { name } : {}, path, absPath, manifestPath, manifest: parsed.value });
@@ -2905,13 +3013,13 @@ var discoverPackages = (root, rootManifest, config) => {
2905
3013
  coverage.push({ status: "complete" });
2906
3014
  return { packages: packages.sort((a, b) => a.id.localeCompare(b.id)), coverage };
2907
3015
  };
2908
- var packageForModule = (packages, absPath) => [...packages].filter((pkg) => absPath === pkg.absPath || absPath.startsWith(`${pkg.absPath}${sep3}`)).sort((a, b) => b.absPath.length - a.absPath.length)[0];
3016
+ var packageForModule = (packages, absPath) => [...packages].filter((pkg) => absPath === pkg.absPath || absPath.startsWith(`${pkg.absPath}${sep4}`)).sort((a, b) => b.absPath.length - a.absPath.length)[0];
2909
3017
  var readCompilerOptions = (root) => {
2910
3018
  const configPath = ts2.findConfigFile(root, ts2.sys.fileExists, "tsconfig.json");
2911
3019
  if (!configPath) return { options: {} };
2912
3020
  const parsed = ts2.readConfigFile(configPath, ts2.sys.readFile);
2913
3021
  if (parsed.error) return { options: {}, error: ts2.flattenDiagnosticMessageText(parsed.error.messageText, "\n") };
2914
- const config = ts2.parseJsonConfigFileContent(parsed.config, ts2.sys, dirname2(configPath));
3022
+ const config = ts2.parseJsonConfigFileContent(parsed.config, ts2.sys, dirname3(configPath));
2915
3023
  if (config.errors.length) {
2916
3024
  return {
2917
3025
  options: config.options,
@@ -3042,17 +3150,17 @@ var moduleReferences = (root, path, sourceFile, runtimeWiringMethods) => {
3042
3150
  };
3043
3151
  };
3044
3152
  var resolveRelativeModule = (specifier, containingFile, modulePaths) => {
3045
- const base = resolve4(dirname2(containingFile), specifier);
3153
+ const base = resolve5(dirname3(containingFile), specifier);
3046
3154
  const extension = extname2(base);
3047
3155
  const extensionlessBase = extension ? base.slice(0, -extension.length) : base;
3048
3156
  const candidates = [
3049
3157
  base,
3050
3158
  ...SOURCE_EXTENSIONS.map((extension2) => `${base}${extension2}`),
3051
- ...SOURCE_EXTENSIONS.map((extension2) => join5(base, `index${extension2}`)),
3159
+ ...SOURCE_EXTENSIONS.map((extension2) => join6(base, `index${extension2}`)),
3052
3160
  ...SOURCE_EXTENSIONS.map((extension2) => `${extensionlessBase}${extension2}`),
3053
- ...SOURCE_EXTENSIONS.map((extension2) => join5(extensionlessBase, `index${extension2}`))
3161
+ ...SOURCE_EXTENSIONS.map((extension2) => join6(extensionlessBase, `index${extension2}`))
3054
3162
  ];
3055
- return candidates.map((candidate) => modulePaths.get(resolve4(candidate))).find(Boolean);
3163
+ return candidates.map((candidate) => modulePaths.get(resolve5(candidate))).find(Boolean);
3056
3164
  };
3057
3165
  var resolveReference = (reference8, containingFile, modules, packages, compilerOptions) => {
3058
3166
  if (reference8.specifier.startsWith(".") || reference8.specifier.startsWith("/")) {
@@ -3062,7 +3170,7 @@ var resolveReference = (reference8, containingFile, modules, packages, compilerO
3062
3170
  const packageTarget = [...packages].filter((pkg) => pkg.name && (reference8.specifier === pkg.name || reference8.specifier.startsWith(`${pkg.name}/`))).sort((a, b) => (b.name?.length ?? 0) - (a.name?.length ?? 0))[0];
3063
3171
  if (packageTarget) return { targetId: packageTarget.id };
3064
3172
  const resolved = ts2.resolveModuleName(reference8.specifier, containingFile, compilerOptions, ts2.sys).resolvedModule?.resolvedFileName;
3065
- const resolvedTarget = resolved ? modules.get(resolve4(resolved)) : void 0;
3173
+ const resolvedTarget = resolved ? modules.get(resolve5(resolved)) : void 0;
3066
3174
  if (resolvedTarget) return { targetId: resolvedTarget.entityId };
3067
3175
  return { targetId: entityId("external", reference8.specifier) };
3068
3176
  };
@@ -3079,26 +3187,26 @@ var sourceRevision = (root, files) => {
3079
3187
  value: sha256NormalizedV1(
3080
3188
  files.map((path) => ({
3081
3189
  path: relativePath(root, path),
3082
- contentHash: sha256NormalizedV1(readFileSync3(path, "utf8"))
3190
+ contentHash: sha256NormalizedV1(readFileSync4(path, "utf8"))
3083
3191
  }))
3084
3192
  ),
3085
3193
  kind: "content"
3086
3194
  });
3087
3195
  try {
3088
- const status = execFileSync("git", ["status", "--porcelain", "--untracked-files=all"], {
3196
+ const status = execFileSync2("git", ["status", "--porcelain", "--untracked-files=all"], {
3089
3197
  cwd: root,
3090
3198
  encoding: "utf8",
3091
3199
  stdio: ["ignore", "pipe", "ignore"]
3092
3200
  }).trim();
3093
3201
  if (status) return contentRevision();
3094
- const value = execFileSync("git", ["rev-parse", "HEAD"], { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
3202
+ const value = execFileSync2("git", ["rev-parse", "HEAD"], { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
3095
3203
  if (value) return { value, kind: "git" };
3096
3204
  } catch {
3097
3205
  }
3098
3206
  return contentRevision();
3099
3207
  };
3100
3208
  var hasPackageManagerMetadata = (root, rootManifest) => Boolean(
3101
- rootManifest?.packageManager || existsSync5(join5(root, "pnpm-lock.yaml")) || existsSync5(join5(root, "pnpm-workspace.yaml")) || existsSync5(join5(root, "yarn.lock")) || existsSync5(join5(root, "bun.lock")) || existsSync5(join5(root, "bun.lockb")) || existsSync5(join5(root, "package-lock.json"))
3209
+ rootManifest?.packageManager || existsSync6(join6(root, "pnpm-lock.yaml")) || existsSync6(join6(root, "pnpm-workspace.yaml")) || existsSync6(join6(root, "yarn.lock")) || existsSync6(join6(root, "bun.lock")) || existsSync6(join6(root, "bun.lockb")) || existsSync6(join6(root, "package-lock.json"))
3102
3210
  );
3103
3211
  var PIPELINE_VERSION = "1.5.0";
3104
3212
  var ANALYZER_VERSIONS = { repository: "1.3.0", "js-ts": "1.3.5", markdown: MARKDOWN_ANALYZER_VERSION, graph: GRAPH_ANALYZER_VERSION };
@@ -3123,12 +3231,12 @@ var artifact = (root, config, files, entities, relations, coverage) => {
3123
3231
  return DiscoverySnapshotV1Schema.parse({ ...base, contentHash: contentHashForArtifactV1(base) });
3124
3232
  };
3125
3233
  var discoverRepository = (opts = {}) => {
3126
- const root = resolve4(opts.root ?? process.cwd());
3234
+ const root = resolve5(opts.root ?? process.cwd());
3127
3235
  const safeOptions = safeWalkOptions(opts.config, {
3128
3236
  maxFiles: opts.maxFiles ?? opts.config?.safety?.maxFiles ?? DEFAULT_MAX_FILES,
3129
3237
  ...opts.maxBytes !== void 0 ? { maxBytes: opts.maxBytes } : {}
3130
3238
  });
3131
- const rootManifestPath = join5(root, "package.json");
3239
+ const rootManifestPath = join6(root, "package.json");
3132
3240
  const rootManifest = readJson(rootManifestPath).value;
3133
3241
  const packageResult = discoverPackages(root, rootManifest, opts.config);
3134
3242
  const sourceWalk = safeWalkFiles(root, { extensions: SOURCE_EXTENSIONS, ...safeOptions });
@@ -3137,7 +3245,7 @@ var discoverRepository = (opts = {}) => {
3137
3245
  const sourcePaths = sourceWalk.files;
3138
3246
  const documentPaths = documentWalk.files;
3139
3247
  const configPaths = configWalk.files.filter((path) => /(?:^|\/)(?:tsconfig|jsconfig|vite\.config|webpack\.config|rollup\.config|next\.config|jest\.config|eslint\.config|vitest\.config)/.test(relativePath(root, path)));
3140
- const allFiles = [...new Set([rootManifestPath, ...sourcePaths, ...documentPaths, ...configPaths].filter(existsSync5))].sort();
3248
+ const allFiles = [...new Set([rootManifestPath, ...sourcePaths, ...documentPaths, ...configPaths].filter(existsSync6))].sort();
3141
3249
  const entities = /* @__PURE__ */ new Map();
3142
3250
  const relations = /* @__PURE__ */ new Map();
3143
3251
  const addEntity = (entity) => {
@@ -3160,7 +3268,7 @@ var discoverRepository = (opts = {}) => {
3160
3268
  relations.set(relation.id, { ...existing, evidence: [...evidence2.values()] });
3161
3269
  };
3162
3270
  for (const pkg of packageResult.packages) {
3163
- const text = readFileSync3(pkg.manifestPath, "utf8");
3271
+ const text = readFileSync4(pkg.manifestPath, "utf8");
3164
3272
  addEntity({
3165
3273
  id: pkg.id,
3166
3274
  kind: "package",
@@ -3208,9 +3316,9 @@ var discoverRepository = (opts = {}) => {
3208
3316
  const path = relativePath(root, absPath);
3209
3317
  const pkg = packageForModule(packageResult.packages, absPath);
3210
3318
  const id = entityId("module", path);
3211
- const text = readFileSync3(absPath, "utf8");
3319
+ const text = readFileSync4(absPath, "utf8");
3212
3320
  const contentHash = fileContentHash(text);
3213
- modules.set(resolve4(absPath), { absPath, path, entityId: id, ...pkg ? { packageId: pkg.id } : {} });
3321
+ modules.set(resolve5(absPath), { absPath, path, entityId: id, ...pkg ? { packageId: pkg.id } : {} });
3214
3322
  modulesByPath.set(path, id);
3215
3323
  if (pkg) areaModules.push({ moduleId: id, path, packageId: pkg.id, packagePath: pkg.path });
3216
3324
  const priorModule = reuseModuleRelations ? prior?.modules.get(path) : void 0;
@@ -3333,7 +3441,7 @@ var discoverRepository = (opts = {}) => {
3333
3441
  for (const [path, absPath] of documentFiles) {
3334
3442
  let text;
3335
3443
  try {
3336
- text = readFileSync3(absPath, "utf8");
3444
+ text = readFileSync4(absPath, "utf8");
3337
3445
  } catch {
3338
3446
  unreadableDocuments.push(path);
3339
3447
  ledger.parsedFiles.push(path);
@@ -3452,7 +3560,7 @@ var discoverRepository = (opts = {}) => {
3452
3560
  });
3453
3561
  }
3454
3562
  for (const pkg of packageResult.packages) {
3455
- const text = readFileSync3(pkg.manifestPath, "utf8");
3563
+ const text = readFileSync4(pkg.manifestPath, "utf8");
3456
3564
  for (const dependency of dependencyEntries(pkg.manifest)) {
3457
3565
  const target2 = packageResult.packages.find((candidate) => candidate.name === dependency.name)?.id ?? entityId("external", dependency.name);
3458
3566
  if (!entities.has(target2)) addEntity({ id: target2, kind: "external", name: dependency.name, provenance: "observed", evidence: [lineEvidence("configuration", root, pkg.manifestPath, firstLineContaining(text, `"${dependency.name}"`))] });
@@ -3491,7 +3599,7 @@ var discoverRepository = (opts = {}) => {
3491
3599
  ledger.skippedFiles.push(module.path);
3492
3600
  continue;
3493
3601
  }
3494
- const text = readFileSync3(module.absPath, "utf8");
3602
+ const text = readFileSync4(module.absPath, "utf8");
3495
3603
  const sourceFile = ts2.createSourceFile(module.absPath, text, ts2.ScriptTarget.Latest, true, scriptKind(module.absPath));
3496
3604
  const runtimeWiringMethods = includeTestRuntimeWiring || !TEST_MODULE_PATTERN.test(module.path) ? configuredRuntimeWiringMethods : /* @__PURE__ */ new Set();
3497
3605
  const references = moduleReferences(root, module.absPath, sourceFile, runtimeWiringMethods);
@@ -3524,7 +3632,7 @@ var discoverRepository = (opts = {}) => {
3524
3632
  };
3525
3633
 
3526
3634
  // src/lib/bounded-text.ts
3527
- import { closeSync, fstatSync, openSync, readFileSync as readFileSync4 } from "fs";
3635
+ import { closeSync, fstatSync, openSync, readFileSync as readFileSync5 } from "fs";
3528
3636
  var MAX_DOCUMENT_BYTES = 4 * 1024 * 1024;
3529
3637
  var MAX_CORPUS_BYTES = 64 * 1024 * 1024;
3530
3638
  var readBoundedText = (path, budget, limits) => {
@@ -3541,7 +3649,7 @@ var readBoundedText = (path, budget, limits) => {
3541
3649
  throw new Error(`Documentation corpus exceeds the ${maxCorpusBytes} byte read budget.`);
3542
3650
  }
3543
3651
  budget.used += stat.size;
3544
- return readFileSync4(fd, "utf8");
3652
+ return readFileSync5(fd, "utf8");
3545
3653
  } finally {
3546
3654
  closeSync(fd);
3547
3655
  }
@@ -3731,8 +3839,8 @@ var slugFromPath = (relPath) => {
3731
3839
  };
3732
3840
 
3733
3841
  // src/lib/walk.ts
3734
- import { lstatSync as lstatSync2, readdirSync as readdirSync3, realpathSync as realpathSync3 } from "fs";
3735
- import { join as join6 } from "path";
3842
+ import { lstatSync as lstatSync2, readdirSync as readdirSync3, realpathSync as realpathSync4 } from "fs";
3843
+ import { join as join7 } from "path";
3736
3844
  var DEFAULT_SKIP = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", "coverage", ".doc-bridge"]);
3737
3845
  var DEFAULT_MAX_FILES2 = 1e4;
3738
3846
  var walkFiles = (root, opts) => {
@@ -3740,10 +3848,11 @@ var walkFiles = (root, opts) => {
3740
3848
  const skip = opts?.skipDirs ?? DEFAULT_SKIP;
3741
3849
  const out = [];
3742
3850
  const visited = /* @__PURE__ */ new Set();
3851
+ const ignored = opts?.respectIgnore === false ? void 0 : createIgnoreFilter(root);
3743
3852
  const visit2 = (dir) => {
3744
3853
  let canonicalDir;
3745
3854
  try {
3746
- canonicalDir = realpathSync3.native(dir);
3855
+ canonicalDir = realpathSync4.native(dir);
3747
3856
  } catch {
3748
3857
  return;
3749
3858
  }
@@ -3756,7 +3865,7 @@ var walkFiles = (root, opts) => {
3756
3865
  return;
3757
3866
  }
3758
3867
  for (const name of entries) {
3759
- const abs = join6(dir, name);
3868
+ const abs = join7(dir, name);
3760
3869
  let st;
3761
3870
  try {
3762
3871
  st = lstatSync2(abs);
@@ -3765,12 +3874,12 @@ var walkFiles = (root, opts) => {
3765
3874
  }
3766
3875
  if (st.isSymbolicLink()) continue;
3767
3876
  if (st.isDirectory()) {
3768
- if (skip.has(name)) continue;
3877
+ if (skip.has(name) || ignored?.isIgnored(abs, true)) continue;
3769
3878
  visit2(abs);
3770
3879
  continue;
3771
3880
  }
3772
3881
  if (!st.isFile()) continue;
3773
- if (extensions.some((ext) => name.endsWith(ext))) {
3882
+ if (extensions.some((ext) => name.endsWith(ext)) && !ignored?.isIgnored(abs, false)) {
3774
3883
  if (out.length >= (opts?.maxFiles ?? DEFAULT_MAX_FILES2)) {
3775
3884
  throw new Error(`Documentation corpus exceeds the ${opts?.maxFiles ?? DEFAULT_MAX_FILES2} file limit.`);
3776
3885
  }
@@ -4062,7 +4171,7 @@ var buildLookup = (config, packages, corpus, indexOutFile, humanDocs = {}, root
4062
4171
  };
4063
4172
 
4064
4173
  // src/version.ts
4065
- var PACKAGE_VERSION = "1.11.1";
4174
+ var PACKAGE_VERSION = "1.12.0";
4066
4175
 
4067
4176
  // src/index-builder/capabilities.ts
4068
4177
  var renderCapabilitiesJson = (config, index, paths) => {
@@ -4096,8 +4205,8 @@ var renderCapabilitiesJson = (config, index, paths) => {
4096
4205
  };
4097
4206
 
4098
4207
  // src/render/template-source.ts
4099
- import { readFileSync as readFileSync5 } from "fs";
4100
- import { resolve as resolve5 } from "path";
4208
+ import { readFileSync as readFileSync6 } from "fs";
4209
+ import { resolve as resolve6 } from "path";
4101
4210
 
4102
4211
  // src/render/engine.ts
4103
4212
  import {
@@ -4652,10 +4761,10 @@ var BUNDLED_TEMPLATES = {
4652
4761
  var resolveTemplateSource = (name, config, root) => {
4653
4762
  const override = config.render?.templates?.[name];
4654
4763
  if (!override) return { name, source: BUNDLED_TEMPLATES[name], origin: "bundled" };
4655
- const path = root ? resolve5(root, override) : resolve5(override);
4764
+ const path = root ? resolve6(root, override) : resolve6(override);
4656
4765
  let source;
4657
4766
  try {
4658
- source = readFileSync5(path, "utf8");
4767
+ source = readFileSync6(path, "utf8");
4659
4768
  } catch (error) {
4660
4769
  throw new Error(`render.templates["${name}"] points at ${toPosix(override)}, which could not be read: ${error instanceof Error ? error.message : String(error)}`);
4661
4770
  }
@@ -4674,8 +4783,8 @@ var compile = (template2) => {
4674
4783
  var renderNamedTemplate = (name, variables, config, root) => renderCompiledTemplate(compile(resolveTemplateSource(name, config, root)), variables);
4675
4784
 
4676
4785
  // src/index-builder/project-corpus.ts
4677
- import { basename as basename3, extname as extname3, relative as relative4, resolve as resolve6, sep as sep4 } from "path";
4678
- import { readFileSync as readFileSync6 } from "fs";
4786
+ import { basename as basename3, extname as extname3, relative as relative5, resolve as resolve7, sep as sep5 } from "path";
4787
+ import { readFileSync as readFileSync7 } from "fs";
4679
4788
  var CORPUS_PROJECTION_VERSION = 2;
4680
4789
  var PROJECTED_ENTRY_TYPES = ["document", "module"];
4681
4790
  var isProjectedEntry = (entry) => PROJECTED_ENTRY_TYPES.includes(entry.type);
@@ -4694,14 +4803,14 @@ var isInput = (path, name) => {
4694
4803
  return CONFIG_INPUT_PATTERN.test(path);
4695
4804
  };
4696
4805
  var repositoryInputs = (root, config) => {
4697
- const projectRoot = resolve6(root);
4806
+ const projectRoot = resolve7(root);
4698
4807
  const walk = safeWalkFiles(projectRoot, { extensions: INPUT_EXTENSIONS, ...safeWalkOptions(config) });
4699
4808
  const fingerprints = [];
4700
4809
  for (const absPath of walk.files) {
4701
- const path = toPosix(relative4(projectRoot, absPath).split(sep4).join("/"));
4810
+ const path = toPosix(relative5(projectRoot, absPath).split(sep5).join("/"));
4702
4811
  if (!isInput(path, basename3(absPath))) continue;
4703
4812
  try {
4704
- fingerprints.push([path, sha256NormalizedV1(readFileSync6(absPath, "utf8"))]);
4813
+ fingerprints.push([path, sha256NormalizedV1(readFileSync7(absPath, "utf8"))]);
4705
4814
  } catch {
4706
4815
  fingerprints.push([path, "unreadable"]);
4707
4816
  }
@@ -4746,15 +4855,15 @@ var llmsTxtVariables = (config, knowledge, projectName2) => {
4746
4855
  var renderLlmsTxt = (config, knowledge, projectName2, options = {}) => renderNamedTemplate("llms.txt", llmsTxtVariables(config, knowledge, projectName2), config, options.root);
4747
4856
 
4748
4857
  // src/index-builder/human-adapters/index.ts
4749
- import { realpathSync as realpathSync5 } from "fs";
4750
- import { resolve as resolve8, sep as sep6 } from "path";
4858
+ import { realpathSync as realpathSync6 } from "fs";
4859
+ import { resolve as resolve9, sep as sep7 } from "path";
4751
4860
 
4752
4861
  // src/index-builder/human-adapters/docusaurus.ts
4753
- import { existsSync as existsSync6 } from "fs";
4862
+ import { existsSync as existsSync7 } from "fs";
4754
4863
 
4755
4864
  // src/index-builder/human-adapters/core.ts
4756
- import { realpathSync as realpathSync4 } from "fs";
4757
- import { isAbsolute as isAbsolute3, relative as relative5, resolve as resolve7, sep as sep5 } from "path";
4865
+ import { realpathSync as realpathSync5 } from "fs";
4866
+ import { isAbsolute as isAbsolute4, relative as relative6, resolve as resolve8, sep as sep6 } from "path";
4758
4867
  var optionString = (options, keys) => {
4759
4868
  for (const key of keys) {
4760
4869
  const value = options?.[key];
@@ -4763,11 +4872,12 @@ var optionString = (options, keys) => {
4763
4872
  return void 0;
4764
4873
  };
4765
4874
  var parseFrontmatter2 = (raw) => {
4766
- if (!raw.startsWith("---\n")) return {};
4767
- const end = raw.indexOf("\n---", 4);
4875
+ const normalized = raw.includes("\r\n") ? raw.replace(/\r\n/g, "\n") : raw;
4876
+ if (!normalized.startsWith("---\n")) return {};
4877
+ const end = normalized.indexOf("\n---", 4);
4768
4878
  if (end === -1) return {};
4769
4879
  const out = {};
4770
- for (const line of raw.slice(4, end).split("\n")) {
4880
+ for (const line of normalized.slice(4, end).split("\n")) {
4771
4881
  const match = /^([A-Za-z0-9_-]+):\s*(.+?)\s*$/.exec(line);
4772
4882
  if (match?.[1] && match[2]) out[match[1]] = match[2].replace(/^['"]|['"]$/g, "");
4773
4883
  }
@@ -4785,15 +4895,15 @@ var humanUrl = (slug2, urlPrefix) => {
4785
4895
  };
4786
4896
  var scanMarkdownDocs = (root, humanRoot, options) => {
4787
4897
  const out = [];
4788
- const projectRoot = realpathSync4.native(resolve7(root));
4898
+ const projectRoot = realpathSync5.native(resolve8(root));
4789
4899
  const absRoot = containedProjectPath(root, humanRoot);
4790
4900
  if (!absRoot) return out;
4791
4901
  const budget = { used: 0 };
4792
4902
  for (const abs of walkFiles(absRoot, { extensions: [".md", ".mdx"] })) {
4793
- const canonical = realpathSync4.native(abs);
4794
- const fileRelative = relative5(projectRoot, canonical);
4795
- if (isAbsolute3(fileRelative) || fileRelative === ".." || fileRelative.startsWith(`..${sep5}`)) continue;
4796
- const relToHumanRoot = toPosix(abs.replace(`${toPosix(absRoot)}/`, ""));
4903
+ const canonical2 = realpathSync5.native(abs);
4904
+ const fileRelative = relative6(projectRoot, canonical2);
4905
+ if (isAbsolute4(fileRelative) || fileRelative === ".." || fileRelative.startsWith(`..${sep6}`)) continue;
4906
+ const relToHumanRoot = toPosix(abs).replace(`${toPosix(absRoot)}/`, "");
4797
4907
  const raw = readBoundedText(abs, budget);
4798
4908
  if (options?.includeRelPath && !options.includeRelPath(relToHumanRoot, raw)) continue;
4799
4909
  out.push({
@@ -4834,7 +4944,7 @@ var docusaurusRecordId = (relPath, raw) => {
4834
4944
  };
4835
4945
  var readSidebars = (sidebarsFile) => {
4836
4946
  if (!sidebarsFile) return { enabled: false, ids: /* @__PURE__ */ new Set(), autogenDirs: [] };
4837
- if (!existsSync6(sidebarsFile)) return { enabled: false, ids: /* @__PURE__ */ new Set(), autogenDirs: [] };
4947
+ if (!existsSync7(sidebarsFile)) return { enabled: false, ids: /* @__PURE__ */ new Set(), autogenDirs: [] };
4838
4948
  const raw = readBoundedText(sidebarsFile, { used: 0 }, { maxFileBytes: 1048576, maxCorpusBytes: 1048576 });
4839
4949
  const filter = { ids: /* @__PURE__ */ new Set(), autogenDirs: [] };
4840
4950
  const visit2 = (value) => {
@@ -4884,13 +4994,13 @@ var docusaurusAdapter = {
4884
4994
  };
4885
4995
 
4886
4996
  // src/index-builder/human-adapters/fumadocs.ts
4887
- import { existsSync as existsSync7, readFileSync as readFileSync7 } from "fs";
4888
- import { join as join7 } from "path";
4997
+ import { existsSync as existsSync8, readFileSync as readFileSync8 } from "fs";
4998
+ import { join as join8 } from "path";
4889
4999
  var readMetaPages = (dir) => {
4890
- const file = join7(dir, "meta.json");
4891
- if (!existsSync7(file)) return void 0;
5000
+ const file = join8(dir, "meta.json");
5001
+ if (!existsSync8(file)) return void 0;
4892
5002
  try {
4893
- const meta = JSON.parse(readFileSync7(file, "utf8"));
5003
+ const meta = JSON.parse(readFileSync8(file, "utf8"));
4894
5004
  return Array.isArray(meta.pages) ? meta.pages.filter((page) => typeof page === "string") : void 0;
4895
5005
  } catch {
4896
5006
  return void 0;
@@ -4905,7 +5015,7 @@ var isListedByMeta = (contentRoot, relPath) => {
4905
5015
  if (isDotFile(relPath)) return false;
4906
5016
  const parts = relPath.split("/");
4907
5017
  for (let i = 0; i < parts.length; i += 1) {
4908
- const dir = join7(contentRoot, ...parts.slice(0, i));
5018
+ const dir = join8(contentRoot, ...parts.slice(0, i));
4909
5019
  const pages = readMetaPages(dir);
4910
5020
  if (!pages?.length || pages.includes("...")) continue;
4911
5021
  const key = pageKey(parts[i] ?? "");
@@ -4918,7 +5028,7 @@ var fumadocsAdapter = {
4918
5028
  scan: ({ root, config }) => {
4919
5029
  const contentDir = optionString(config.options, ["contentDir", "root"]);
4920
5030
  if (!contentDir) return [];
4921
- const contentRoot = join7(root, contentDir);
5031
+ const contentRoot = join8(root, contentDir);
4922
5032
  const excludePrefixes = Array.isArray(config.options?.excludePrefixes) ? config.options.excludePrefixes.filter((v) => typeof v === "string") : typeof config.options?.excludePrefix === "string" ? [config.options.excludePrefix] : [];
4923
5033
  if (!excludePrefixes.includes("for-agents")) excludePrefixes.push("for-agents");
4924
5034
  return scanMarkdownDocs(root, contentDir, {
@@ -5062,21 +5172,21 @@ var humanConfigs = (config) => {
5062
5172
  };
5063
5173
  var canonicalPath = (path) => {
5064
5174
  try {
5065
- return realpathSync5.native(path);
5175
+ return realpathSync6.native(path);
5066
5176
  } catch {
5067
- return resolve8(path);
5177
+ return resolve9(path);
5068
5178
  }
5069
5179
  };
5070
5180
  var scanHumanDocRecords = (root, config) => {
5071
5181
  const out = [];
5072
5182
  const seen = /* @__PURE__ */ new Set();
5073
- const agentRoot = canonicalPath(resolve8(root, config.corpus.agent.root));
5183
+ const agentRoot = canonicalPath(resolve9(root, config.corpus.agent.root));
5074
5184
  for (const human of humanConfigs(config)) {
5075
5185
  const adapter = ADAPTERS.find((candidate) => candidate.plugin === human.plugin);
5076
5186
  if (!adapter) continue;
5077
5187
  for (const record of adapter.scan({ root, config: human })) {
5078
5188
  const recordPath = canonicalPath(record.path);
5079
- if (recordPath === agentRoot || recordPath.startsWith(`${agentRoot}${sep6}`) || record.path.includes("/for-agents/") || record.path.endsWith("/for-agents")) {
5189
+ if (recordPath === agentRoot || recordPath.startsWith(`${agentRoot}${sep7}`) || record.path.includes("/for-agents/") || record.path.endsWith("/for-agents")) {
5080
5190
  continue;
5081
5191
  }
5082
5192
  if (seen.has(record.id)) continue;
@@ -5089,8 +5199,8 @@ var scanHumanDocRecords = (root, config) => {
5089
5199
  var scanHumanDocs = (root, config) => Object.fromEntries(scanHumanDocRecords(root, config).map((doc) => [doc.id, doc.url]));
5090
5200
 
5091
5201
  // src/index-builder/plugins/nx.ts
5092
- import { existsSync as existsSync8, lstatSync as lstatSync3, readFileSync as readFileSync8, realpathSync as realpathSync6 } from "fs";
5093
- import { basename as basename4, dirname as dirname3, isAbsolute as isAbsolute4, relative as relative6, resolve as resolve9, sep as sep7 } from "path";
5202
+ import { existsSync as existsSync9, lstatSync as lstatSync3, readFileSync as readFileSync9, realpathSync as realpathSync7 } from "fs";
5203
+ import { basename as basename4, dirname as dirname4, isAbsolute as isAbsolute5, relative as relative7, resolve as resolve10, sep as sep8 } from "path";
5094
5204
  var NX_SCAN_SKIP = /* @__PURE__ */ new Set([
5095
5205
  "node_modules",
5096
5206
  ".git",
@@ -5103,22 +5213,22 @@ var NX_PROJECT_NAME = /^(?:@[A-Za-z0-9._-]+\/)?[A-Za-z0-9][A-Za-z0-9._-]*$/;
5103
5213
  var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
5104
5214
  var readJsonRecord = (path) => {
5105
5215
  try {
5106
- const parsed = JSON.parse(readFileSync8(path, "utf8"));
5216
+ const parsed = JSON.parse(readFileSync9(path, "utf8"));
5107
5217
  return isRecord2(parsed) ? parsed : void 0;
5108
5218
  } catch {
5109
5219
  return void 0;
5110
5220
  }
5111
5221
  };
5112
5222
  var safeProjectPath = (root, manifestDir, declaredRoot) => {
5113
- const candidate = typeof declaredRoot === "string" ? resolve9(root, declaredRoot) : manifestDir;
5114
- const rel = toPosix(relative6(root, candidate)) || ".";
5115
- if (isAbsolute4(rel) || rel === ".." || rel.startsWith("../")) return void 0;
5223
+ const candidate = typeof declaredRoot === "string" ? resolve10(root, declaredRoot) : manifestDir;
5224
+ const rel = toPosix(relative7(root, candidate)) || ".";
5225
+ if (isAbsolute5(rel) || rel === ".." || rel.startsWith("../")) return void 0;
5116
5226
  try {
5117
5227
  if (!lstatSync3(candidate).isDirectory()) return void 0;
5118
- const canonicalRoot = realpathSync6.native(root);
5119
- const canonicalCandidate = realpathSync6.native(candidate);
5120
- const canonicalRel = relative6(canonicalRoot, canonicalCandidate);
5121
- if (isAbsolute4(canonicalRel) || canonicalRel === ".." || canonicalRel.startsWith(`..${sep7}`)) {
5228
+ const canonicalRoot = realpathSync7.native(root);
5229
+ const canonicalCandidate = realpathSync7.native(candidate);
5230
+ const canonicalRel = relative7(canonicalRoot, canonicalCandidate);
5231
+ if (isAbsolute5(canonicalRel) || canonicalRel === ".." || canonicalRel.startsWith(`..${sep8}`)) {
5122
5232
  return void 0;
5123
5233
  }
5124
5234
  } catch {
@@ -5144,7 +5254,7 @@ var inferredChecks = (root, config, projectName2, targets) => {
5144
5254
  return checks.length ? checks : void 0;
5145
5255
  };
5146
5256
  var discoverNxProjects = (root, config) => {
5147
- if (!existsSync8(resolve9(root, "nx.json"))) return [];
5257
+ if (!existsSync9(resolve10(root, "nx.json"))) return [];
5148
5258
  const manifests = walkFiles(root, {
5149
5259
  extensions: ["project.json", "package.json"],
5150
5260
  skipDirs: NX_SCAN_SKIP,
@@ -5154,7 +5264,7 @@ var discoverNxProjects = (root, config) => {
5154
5264
  for (const manifest of manifests) {
5155
5265
  const json = readJsonRecord(manifest);
5156
5266
  if (!json) continue;
5157
- const manifestDir = dirname3(manifest);
5267
+ const manifestDir = dirname4(manifest);
5158
5268
  const manifestName = basename4(manifest);
5159
5269
  const isProjectJson = manifestName === "project.json";
5160
5270
  if (!isProjectJson && manifestName !== "package.json") continue;
@@ -5162,7 +5272,7 @@ var discoverNxProjects = (root, config) => {
5162
5272
  if (!isProjectJson && !isRecord2(nx)) continue;
5163
5273
  const path = safeProjectPath(root, manifestDir, isProjectJson ? json.root : void 0);
5164
5274
  if (!path) continue;
5165
- const projectPackage = isProjectJson ? readJsonRecord(resolve9(root, path, "package.json")) : void 0;
5275
+ const projectPackage = isProjectJson ? readJsonRecord(resolve10(root, path, "package.json")) : void 0;
5166
5276
  const projectName2 = typeof json.name === "string" ? json.name : typeof projectPackage?.name === "string" ? projectPackage.name : basename4(path === "." ? root : path);
5167
5277
  if (!NX_PROJECT_NAME.test(projectName2)) continue;
5168
5278
  const targets = /* @__PURE__ */ new Set();
@@ -5198,8 +5308,8 @@ var discoverNxProjects = (root, config) => {
5198
5308
  };
5199
5309
 
5200
5310
  // src/index-builder/plugins/pnpm-monorepo.ts
5201
- import { existsSync as existsSync9, readFileSync as readFileSync9 } from "fs";
5202
- import { basename as basename5, join as join8 } from "path";
5311
+ import { existsSync as existsSync10, readFileSync as readFileSync10 } from "fs";
5312
+ import { basename as basename5, join as join9 } from "path";
5203
5313
  var parsePnpmWorkspace = (yaml) => {
5204
5314
  const lines = yaml.split("\n");
5205
5315
  const patterns = [];
@@ -5221,10 +5331,10 @@ var parsePnpmWorkspace = (yaml) => {
5221
5331
  return patterns;
5222
5332
  };
5223
5333
  var readPackageJson = (dir) => {
5224
- const file = join8(dir, "package.json");
5225
- if (!existsSync9(file)) return null;
5334
+ const file = join9(dir, "package.json");
5335
+ if (!existsSync10(file)) return null;
5226
5336
  try {
5227
- return JSON.parse(readFileSync9(file, "utf8"));
5337
+ return JSON.parse(readFileSync10(file, "utf8"));
5228
5338
  } catch {
5229
5339
  return null;
5230
5340
  }
@@ -5233,9 +5343,9 @@ var discoverPnpmPackages = (root, config) => {
5233
5343
  const explicit = config.routing?.options?.packages;
5234
5344
  let patterns = explicit;
5235
5345
  if (!patterns?.length) {
5236
- const workspaceFile = join8(root, "pnpm-workspace.yaml");
5237
- if (existsSync9(workspaceFile)) {
5238
- patterns = parsePnpmWorkspace(readFileSync9(workspaceFile, "utf8"));
5346
+ const workspaceFile = join9(root, "pnpm-workspace.yaml");
5347
+ if (existsSync10(workspaceFile)) {
5348
+ patterns = parsePnpmWorkspace(readFileSync10(workspaceFile, "utf8"));
5239
5349
  }
5240
5350
  }
5241
5351
  if (!patterns?.length) return [];
@@ -5936,8 +6046,8 @@ var toKnowledgeEntry = (entry) => ({
5936
6046
  });
5937
6047
 
5938
6048
  // src/enrich/overlay.ts
5939
- import { existsSync as existsSync10, mkdirSync, readFileSync as readFileSync10, renameSync, writeFileSync } from "fs";
5940
- import { join as join9, resolve as resolve10 } from "path";
6049
+ import { existsSync as existsSync11, mkdirSync, readFileSync as readFileSync11, renameSync, writeFileSync } from "fs";
6050
+ import { join as join10, resolve as resolve11 } from "path";
5941
6051
 
5942
6052
  // src/schemas/enrichment.ts
5943
6053
  import { z as z6 } from "zod";
@@ -6434,14 +6544,14 @@ var EnrichmentProposalListSchema = z7.array(z7.unknown()).max(1024);
6434
6544
  // src/enrich/overlay.ts
6435
6545
  var ENRICHMENT_DIR = ".doc-bridge/enrich";
6436
6546
  var ENRICHMENT_OVERLAY_FILE = "overlay.json";
6437
- var enrichmentDir = (root) => join9(resolve10(root), ENRICHMENT_DIR);
6438
- var enrichmentOverlayPath = (root) => join9(enrichmentDir(root), ENRICHMENT_OVERLAY_FILE);
6439
- var enrichmentCacheDir = (root) => join9(enrichmentDir(root), "cache");
6547
+ var enrichmentDir = (root) => join10(resolve11(root), ENRICHMENT_DIR);
6548
+ var enrichmentOverlayPath = (root) => join10(enrichmentDir(root), ENRICHMENT_OVERLAY_FILE);
6549
+ var enrichmentCacheDir = (root) => join10(enrichmentDir(root), "cache");
6440
6550
  var readEnrichmentOverlay = (root) => {
6441
6551
  const path = enrichmentOverlayPath(root);
6442
- if (!existsSync10(path)) return void 0;
6552
+ if (!existsSync11(path)) return void 0;
6443
6553
  try {
6444
- const parsed = EnrichmentOverlayV1Schema.parse(JSON.parse(readFileSync10(path, "utf8")));
6554
+ const parsed = EnrichmentOverlayV1Schema.parse(JSON.parse(readFileSync11(path, "utf8")));
6445
6555
  return parsed.contentHash === enrichmentOverlayContentHash(parsed) ? parsed : void 0;
6446
6556
  } catch {
6447
6557
  return void 0;
@@ -6515,7 +6625,7 @@ var projectEnrichmentOverlay = (overlay, snapshot) => {
6515
6625
  const signals = /* @__PURE__ */ new Map();
6516
6626
  const aliases = /* @__PURE__ */ new Map();
6517
6627
  const summaries = /* @__PURE__ */ new Map();
6518
- const canonical = /* @__PURE__ */ new Map();
6628
+ const canonical2 = /* @__PURE__ */ new Map();
6519
6629
  const intents = [];
6520
6630
  const relations = [];
6521
6631
  const paths = new Map(snapshot.entities.map((entity) => [entity.id, entity.path]));
@@ -6540,7 +6650,7 @@ var projectEnrichmentOverlay = (overlay, snapshot) => {
6540
6650
  });
6541
6651
  break;
6542
6652
  case "mark-canonical":
6543
- canonical.set(proposal.entity, proposal.payload.scope);
6653
+ canonical2.set(proposal.entity, proposal.payload.scope);
6544
6654
  bump(proposal.entity, SIGNAL_CANONICAL);
6545
6655
  break;
6546
6656
  case "rank-hint":
@@ -6561,7 +6671,7 @@ var projectEnrichmentOverlay = (overlay, snapshot) => {
6561
6671
  ...signals.size ? { signals } : {},
6562
6672
  ...aliases.size ? { aliases } : {},
6563
6673
  ...summaries.size ? { summaries } : {},
6564
- ...canonical.size ? { canonical } : {},
6674
+ ...canonical2.size ? { canonical: canonical2 } : {},
6565
6675
  ...intents.length ? { intents } : {},
6566
6676
  ...relations.length ? { relations } : {}
6567
6677
  };
@@ -6588,7 +6698,7 @@ var assertObservedSurvive = (observed, enriched) => {
6588
6698
  var projectName = (root, config) => {
6589
6699
  if (config.project?.name) return config.project.name;
6590
6700
  try {
6591
- const pkg = JSON.parse(readFileSync11(join10(root, "package.json"), "utf8"));
6701
+ const pkg = JSON.parse(readFileSync12(join11(root, "package.json"), "utf8"));
6592
6702
  if (pkg.name) return pkg.name;
6593
6703
  } catch {
6594
6704
  }
@@ -6601,7 +6711,7 @@ var projectFromSnapshot = (root, config, given, lookup, curated, requested) => {
6601
6711
  for (const entity of observed.entities) {
6602
6712
  if (entity.kind !== "document" || !entity.path) continue;
6603
6713
  try {
6604
- contents.set(entity.path, readBoundedText(join10(root, entity.path), budget));
6714
+ contents.set(entity.path, readBoundedText(join11(root, entity.path), budget));
6605
6715
  } catch {
6606
6716
  }
6607
6717
  }
@@ -6624,7 +6734,7 @@ var projectFromSnapshot = (root, config, given, lookup, curated, requested) => {
6624
6734
  };
6625
6735
  var existingGeneratedAt = (indexPath, contentHash) => {
6626
6736
  try {
6627
- const index = JSON.parse(readFileSync11(indexPath, "utf8"));
6737
+ const index = JSON.parse(readFileSync12(indexPath, "utf8"));
6628
6738
  return index.contentHash === contentHash && typeof index.generatedAt === "string" ? index.generatedAt : void 0;
6629
6739
  } catch {
6630
6740
  return void 0;
@@ -6635,7 +6745,7 @@ var buildDocBridgeIndex = (opts) => {
6635
6745
  const config = opts.config;
6636
6746
  const write = opts.write ?? true;
6637
6747
  const outFile = config.index?.outFile ?? ".doc-bridge/index.json";
6638
- const indexPath = join10(root, outFile);
6748
+ const indexPath = join11(root, outFile);
6639
6749
  const corpus = scanAgentCorpus(root, config);
6640
6750
  const curated = corpus.map(({ absPath: _a, relPath: _r, frontmatter: _f, ...entry }) => entry);
6641
6751
  const retrieval = {
@@ -6685,7 +6795,7 @@ var buildDocBridgeIndex = (opts) => {
6685
6795
  );
6686
6796
  }
6687
6797
  if (write) {
6688
- mkdirSync2(dirname4(indexPath), { recursive: true });
6798
+ mkdirSync2(dirname5(indexPath), { recursive: true });
6689
6799
  writeFileSync2(indexPath, `${JSON.stringify(index, null, 2)}
6690
6800
  `, "utf8");
6691
6801
  }
@@ -6694,7 +6804,7 @@ var buildDocBridgeIndex = (opts) => {
6694
6804
  if (config.index?.llmsTxt?.enabled !== false) {
6695
6805
  const llmsOut = config.index?.llmsTxt?.outFile ?? "llms.txt";
6696
6806
  llmsTxtRelPath = toPosix(llmsOut);
6697
- llmsTxtPath = join10(root, llmsOut);
6807
+ llmsTxtPath = join11(root, llmsOut);
6698
6808
  if (write) {
6699
6809
  writeFileSync2(
6700
6810
  llmsTxtPath,
@@ -6706,9 +6816,9 @@ var buildDocBridgeIndex = (opts) => {
6706
6816
  let capabilitiesPath;
6707
6817
  if (config.index?.capabilities?.enabled !== false) {
6708
6818
  const capabilitiesOut = config.index?.capabilities?.outFile ?? ".doc-bridge/capabilities.json";
6709
- capabilitiesPath = join10(root, capabilitiesOut);
6819
+ capabilitiesPath = join11(root, capabilitiesOut);
6710
6820
  if (write) {
6711
- mkdirSync2(dirname4(capabilitiesPath), { recursive: true });
6821
+ mkdirSync2(dirname5(capabilitiesPath), { recursive: true });
6712
6822
  writeFileSync2(
6713
6823
  capabilitiesPath,
6714
6824
  renderCapabilitiesJson(config, index, {
@@ -6732,15 +6842,15 @@ var DOCUMENTATION_STANDARD_V1_ID = "documentation-standard-v1";
6732
6842
  var DOCUMENTATION_STANDARD_V1_STATUS = "stable";
6733
6843
  var MAX_TEXT_EVIDENCE_BYTES = 4 * 1024 * 1024;
6734
6844
  var safePath = (root, path) => {
6735
- const rootAbs = realpathSync7.native(resolve11(root));
6736
- const unresolved = resolve11(rootAbs, path);
6737
- const unresolvedRel = relative7(rootAbs, unresolved);
6738
- if (isAbsolute5(unresolvedRel) || unresolvedRel === ".." || unresolvedRel.startsWith(`..${sep8}`)) return void 0;
6739
- if (!existsSync11(unresolved)) return unresolved;
6845
+ const rootAbs = realpathSync8.native(resolve12(root));
6846
+ const unresolved = resolve12(rootAbs, path);
6847
+ const unresolvedRel = relative8(rootAbs, unresolved);
6848
+ if (isAbsolute6(unresolvedRel) || unresolvedRel === ".." || unresolvedRel.startsWith(`..${sep9}`)) return void 0;
6849
+ if (!existsSync12(unresolved)) return unresolved;
6740
6850
  try {
6741
- const abs = realpathSync7.native(unresolved);
6742
- const rel = relative7(rootAbs, abs);
6743
- return !isAbsolute5(rel) && rel !== ".." && !rel.startsWith(`..${sep8}`) ? abs : void 0;
6851
+ const abs = realpathSync8.native(unresolved);
6852
+ const rel = relative8(rootAbs, abs);
6853
+ return !isAbsolute6(rel) && rel !== ".." && !rel.startsWith(`..${sep9}`) ? abs : void 0;
6744
6854
  } catch {
6745
6855
  return void 0;
6746
6856
  }
@@ -6768,7 +6878,7 @@ var fileEvidence = (root, path, options) => {
6768
6878
  return {
6769
6879
  exists: true,
6770
6880
  content: "",
6771
- evidence: { path: toPosix(relative7(resolve11(root), abs)) || ".", detail: "File exists and is non-empty." }
6881
+ evidence: { path: toPosix(relative8(resolve12(root), abs)) || ".", detail: "File exists and is non-empty." }
6772
6882
  };
6773
6883
  }
6774
6884
  if (stat.size > MAX_TEXT_EVIDENCE_BYTES) {
@@ -6778,12 +6888,12 @@ var fileEvidence = (root, path, options) => {
6778
6888
  evidence: { path, detail: `Text evidence exceeds ${MAX_TEXT_EVIDENCE_BYTES} bytes.` }
6779
6889
  };
6780
6890
  }
6781
- const content = readFileSync12(fd, "utf8");
6891
+ const content = readFileSync13(fd, "utf8");
6782
6892
  return {
6783
6893
  exists: content.trim().length > 0,
6784
6894
  content,
6785
6895
  evidence: {
6786
- path: toPosix(relative7(resolve11(root), abs)) || ".",
6896
+ path: toPosix(relative8(resolve12(root), abs)) || ".",
6787
6897
  detail: content.trim().length > 0 ? "File exists and is non-empty." : "File is empty."
6788
6898
  }
6789
6899
  };
@@ -6825,7 +6935,7 @@ var humanDocsRule = (root, config) => {
6825
6935
  passed: docs.length > 0,
6826
6936
  message: docs.length > 0 ? `Found ${docs.length} human document(s).` : "No human documentation was discovered.",
6827
6937
  evidence: docs.slice(0, 10).map((doc) => ({
6828
- path: toPosix(relative7(resolve11(root), doc.path)),
6938
+ path: toPosix(relative8(resolve12(root), doc.path)),
6829
6939
  detail: `Human route: ${doc.url}`
6830
6940
  })),
6831
6941
  remediation: {
@@ -6836,10 +6946,10 @@ var humanDocsRule = (root, config) => {
6836
6946
  };
6837
6947
  var llmsRule = (root, config, options, generated) => {
6838
6948
  const llmsPath = config.index?.llmsTxt?.outFile ?? "llms.txt";
6839
- const llmsKey = safePath(root, llmsPath) ?? resolve11(root, llmsPath);
6949
+ const llmsKey = safePath(root, llmsPath) ?? resolve12(root, llmsPath);
6840
6950
  const rawSources = /* @__PURE__ */ new Map();
6841
6951
  for (const path of options.rawSources ?? []) {
6842
- const key = safePath(root, path) ?? resolve11(root, path);
6952
+ const key = safePath(root, path) ?? resolve12(root, path);
6843
6953
  if (key !== llmsKey && !rawSources.has(key)) rawSources.set(key, path);
6844
6954
  }
6845
6955
  const paths = [llmsPath, ...rawSources.values()];
@@ -6978,11 +7088,11 @@ var linksRule = (root, options) => {
6978
7088
  for (const link of links) {
6979
7089
  const sources = link.paths.map((path) => ({ path, file: fileEvidence(root, path) }));
6980
7090
  const matches2 = sources.filter(({ file }) => file.exists && file.content.includes(link.url));
6981
- const canonical = contract.urls.has(normalizedUrl(link.url));
6982
- if (matches2.length === 0 || !canonical) passed = false;
7091
+ const canonical2 = contract.urls.has(normalizedUrl(link.url));
7092
+ if (matches2.length === 0 || !canonical2) passed = false;
6983
7093
  evidence2.push({
6984
7094
  path: sources.map((source) => source.path).join(", "),
6985
- detail: matches2.length === 0 ? `Missing ${link.url}` : canonical ? `Found canonical ecosystem URL ${link.url}` : `Found ${link.url}, but it is absent from the canonical ecosystem manifest.`
7095
+ detail: matches2.length === 0 ? `Missing ${link.url}` : canonical2 ? `Found canonical ecosystem URL ${link.url}` : `Found ${link.url}, but it is absent from the canonical ecosystem manifest.`
6986
7096
  });
6987
7097
  }
6988
7098
  return {
@@ -7090,8 +7200,8 @@ var formatDocumentationStandardText = (report) => [
7090
7200
  ];
7091
7201
 
7092
7202
  // src/federation/llms.ts
7093
- import { existsSync as existsSync12, readFileSync as readFileSync13 } from "fs";
7094
- import { resolve as resolve12 } from "path";
7203
+ import { existsSync as existsSync13, readFileSync as readFileSync14 } from "fs";
7204
+ import { resolve as resolve13 } from "path";
7095
7205
 
7096
7206
  // src/retrieval/rank.ts
7097
7207
  var BM25_SCALE = 50;
@@ -7548,9 +7658,9 @@ var sourceText = async (root, source, fetchText) => {
7548
7658
  try {
7549
7659
  const remote = httpUrl(source);
7550
7660
  if (remote) return await fetchText(remote);
7551
- const path = resolve12(root, source);
7552
- if (!existsSync12(path)) return null;
7553
- return readFileSync13(path, "utf8");
7661
+ const path = resolve13(root, source);
7662
+ if (!existsSync13(path)) return null;
7663
+ return readFileSync14(path, "utf8");
7554
7664
  } catch {
7555
7665
  return null;
7556
7666
  }
@@ -7677,11 +7787,11 @@ var retrieveHybridChunks = async (root, config, index, query, options = {}) => {
7677
7787
  };
7678
7788
 
7679
7789
  // src/gates/run-gates.ts
7680
- import { readFileSync as readFileSync15 } from "fs";
7790
+ import { readFileSync as readFileSync16 } from "fs";
7681
7791
 
7682
7792
  // src/query/load-index.ts
7683
- import { existsSync as existsSync13, readFileSync as readFileSync14 } from "fs";
7684
- import { join as join11, resolve as resolve13 } from "path";
7793
+ import { existsSync as existsSync14, readFileSync as readFileSync15 } from "fs";
7794
+ import { join as join12, resolve as resolve14 } from "path";
7685
7795
 
7686
7796
  // src/schemas/agent-handoff.ts
7687
7797
  import { z as z9 } from "zod";
@@ -8004,11 +8114,11 @@ var IndexStaleError = class extends Error {
8004
8114
  actual;
8005
8115
  expected;
8006
8116
  };
8007
- var indexFilePath = (root, config) => join11(root, config.index?.outFile ?? ".doc-bridge/index.json");
8117
+ var indexFilePath = (root, config) => join12(root, config.index?.outFile ?? ".doc-bridge/index.json");
8008
8118
  var loadDocBridgeIndex = (root, config) => {
8009
8119
  const path = indexFilePath(root, config);
8010
- if (!existsSync13(path)) throw new IndexNotFoundError(path);
8011
- const raw = JSON.parse(readFileSync14(path, "utf8"));
8120
+ if (!existsSync14(path)) throw new IndexNotFoundError(path);
8121
+ const raw = JSON.parse(readFileSync15(path, "utf8"));
8012
8122
  return parseDocBridgeIndex(raw);
8013
8123
  };
8014
8124
  var loadFreshDocBridgeIndex = (root, config) => {
@@ -8028,7 +8138,7 @@ var loadFreshDocBridgeIndex = (root, config) => {
8028
8138
  };
8029
8139
 
8030
8140
  // src/discovery/reproducibility.ts
8031
- import { execFileSync as execFileSync2 } from "child_process";
8141
+ import { execFileSync as execFileSync3 } from "child_process";
8032
8142
  var NOT_CHECKED = (skipped) => ({
8033
8143
  checked: false,
8034
8144
  skipped,
@@ -8036,7 +8146,7 @@ var NOT_CHECKED = (skipped) => ({
8036
8146
  });
8037
8147
  var git = (root, args, options = {}) => {
8038
8148
  try {
8039
- return execFileSync2("git", args, {
8149
+ return execFileSync3("git", args, {
8040
8150
  cwd: root,
8041
8151
  encoding: "utf8",
8042
8152
  stdio: ["pipe", "pipe", "ignore"],
@@ -8115,7 +8225,7 @@ var runGate = (root, config, id) => {
8115
8225
  return {
8116
8226
  id,
8117
8227
  ok: false,
8118
- message: `${result.ignored.length} indexed path(s) are ignored by Git, so a clean checkout builds a different index. Add them to safety.exclude.`,
8228
+ message: `${result.ignored.length} indexed path(s) are ignored by Git, so a clean checkout builds a different index. Rebuild the index (scans skip ignored paths) or add them to safety.exclude.`,
8119
8229
  expected: "every indexed path is committed",
8120
8230
  actual: sample.join(", ")
8121
8231
  };
@@ -8174,7 +8284,7 @@ var runOkfTypeGate = (root, config) => {
8174
8284
  const required = config.corpus.agent.okf?.requireType ?? config.gates?.preset === "strict";
8175
8285
  if (!required) return { id: "okf-type", ok: true, message: "OKF type frontmatter not required" };
8176
8286
  const allowed = config.corpus.agent.okf?.allowedTypes;
8177
- const bad = scanAgentCorpus(root, config).filter((doc) => doc.path !== config.corpus.agent.index).map((doc) => ({ path: doc.path, type: frontmatterType(readFileSync15(doc.absPath, "utf8")) })).filter((doc) => !doc.type || allowed && !allowed.includes(doc.type));
8287
+ const bad = scanAgentCorpus(root, config).filter((doc) => doc.path !== config.corpus.agent.index).map((doc) => ({ path: doc.path, type: frontmatterType(readFileSync16(doc.absPath, "utf8")) })).filter((doc) => !doc.type || allowed && !allowed.includes(doc.type));
8178
8288
  if (bad.length) {
8179
8289
  return {
8180
8290
  id: "okf-type",
@@ -8248,7 +8358,7 @@ var runDocsStyleGate = (root, config) => {
8248
8358
  }
8249
8359
  const bad = scanAgentCorpus(root, config).filter((doc) => doc.path !== config.corpus.agent.index).map((doc) => ({
8250
8360
  path: doc.path,
8251
- missing: missingStyleRules(readFileSync15(doc.absPath, "utf8"), required)
8361
+ missing: missingStyleRules(readFileSync16(doc.absPath, "utf8"), required)
8252
8362
  })).filter((doc) => doc.missing.length > 0);
8253
8363
  if (bad.length) {
8254
8364
  return {
@@ -8318,11 +8428,11 @@ var resolvedOptions = (options) => {
8318
8428
  const config = RulesConfigSchema.parse(options.config ?? {});
8319
8429
  const mode = options.preset ?? config.mode ?? "default";
8320
8430
  const severity = { ...config.severity, ...options.severity };
8321
- const ignore = /* @__PURE__ */ new Set([...config.ignore ?? [], ...options.ignore ?? []]);
8431
+ const ignore2 = /* @__PURE__ */ new Set([...config.ignore ?? [], ...options.ignore ?? []]);
8322
8432
  return {
8323
8433
  mode,
8324
8434
  severity,
8325
- ignore,
8435
+ ignore: ignore2,
8326
8436
  criticalEntities: options.criticalEntities ?? config.criticalEntities ?? [],
8327
8437
  criticalPaths: options.criticalPaths ?? config.criticalPaths ?? [],
8328
8438
  warningThresholds: { ...config.warningThresholds, ...options.warningThresholds }
@@ -8414,7 +8524,7 @@ var parseRuleSeverity = (value) => {
8414
8524
  var MAX_RELATED = 3;
8415
8525
  var MAX_READ_BEFORE = 2;
8416
8526
  var MAX_RELATED_EVIDENCE = 3;
8417
- var dirname5 = (path) => path.split("/").slice(0, -1).join("/") || ".";
8527
+ var dirname6 = (path) => path.split("/").slice(0, -1).join("/") || ".";
8418
8528
  var isHttp = (value) => /^https?:\/\//.test(value);
8419
8529
  var bridgeFor = (config, id, humanDoc) => humanDoc ? { humanDoc: isHttp(humanDoc) ? "external" : "linked" } : config.corpus.human ? { humanDoc: "missing", action: "ak-docs bootstrap agent-docs", bootstrap: `docs/for-agents/human/${id}.md` } : void 0;
8420
8530
  var legacyHandoff = (index, id, config) => {
@@ -8550,7 +8660,7 @@ var handoffForEntity = (index, id, config, options = {}) => {
8550
8660
  const area = target2.graph.areaId ? byId.get(target2.graph.areaId) : void 0;
8551
8661
  const packageEntry = target2.graph.packageId ? byId.get(target2.graph.packageId) : target2.kind === "package" ? target2 : void 0;
8552
8662
  const explain = {};
8553
- const unit = target2.kind === "module" ? area ? { path: area.path, reason: `contained by area ${area.id}` } : packageEntry ? { path: packageEntry.path, reason: `contained by package ${packageEntry.id}` } : { path: dirname5(target2.path), reason: "the directory of the module; no area or package contains it" } : { path: ownership?.path ?? target2.path, reason: ownership ? `ownership ${ownership.id} path` : `the ${target2.kind} itself` };
8663
+ const unit = target2.kind === "module" ? area ? { path: area.path, reason: `contained by area ${area.id}` } : packageEntry ? { path: packageEntry.path, reason: `contained by package ${packageEntry.id}` } : { path: dirname6(target2.path), reason: "the directory of the module; no area or package contains it" } : { path: ownership?.path ?? target2.path, reason: ownership ? `ownership ${ownership.id} path` : `the ${target2.kind} itself` };
8554
8664
  explain.editRoots = [unit.reason];
8555
8665
  const documents = documentsFor(projection, byId, target2, ownership);
8556
8666
  const startHere = documents[0]?.path ?? config.corpus.agent.index ?? target2.path;
@@ -8745,7 +8855,7 @@ var runQuery = (index, config, req, options = {}) => {
8745
8855
  };
8746
8856
 
8747
8857
  // src/intelligence/adapter.ts
8748
- import { join as join12 } from "path";
8858
+ import { join as join13 } from "path";
8749
8859
 
8750
8860
  // src/intelligence/peers.ts
8751
8861
  var PeerMissingError = class extends Error {
@@ -8872,20 +8982,20 @@ var resolveIntelligenceRuntime = async (config) => {
8872
8982
  }
8873
8983
  return { adapter, embed, provider, ...model ? { model } : {} };
8874
8984
  };
8875
- var defaultVectorStorePath = (root) => join12(root, ".doc-bridge", "vectors");
8985
+ var defaultVectorStorePath = (root) => join13(root, ".doc-bridge", "vectors");
8876
8986
 
8877
8987
  // src/intelligence/rag.ts
8878
- import { readFileSync as readFileSync16 } from "fs";
8879
- import { join as join13 } from "path";
8988
+ import { readFileSync as readFileSync17 } from "fs";
8989
+ import { join as join14 } from "path";
8880
8990
  var loadDocuments = (root, index, sources) => {
8881
8991
  const includeAgent = sources.includes("agent") || sources.length === 0;
8882
8992
  const docs = [];
8883
8993
  if (includeAgent) {
8884
8994
  for (const entry of index.knowledge) {
8885
- const abs = join13(root, entry.path);
8995
+ const abs = join14(root, entry.path);
8886
8996
  let content = "";
8887
8997
  try {
8888
- content = readFileSync16(abs, "utf8");
8998
+ content = readFileSync17(abs, "utf8");
8889
8999
  } catch {
8890
9000
  content = [entry.title, entry.description].filter(Boolean).join("\n\n");
8891
9001
  }
@@ -8903,7 +9013,7 @@ var createDocBridgeRag = async (root, config, index) => {
8903
9013
  const { embed } = await resolveIntelligenceRuntime(config);
8904
9014
  const ragMod = await importPeer("@agentskit/rag");
8905
9015
  const memoryMod = await importPeer("@agentskit/memory");
8906
- const storePath = typeof config.intelligence?.retriever?.options?.storePath === "string" ? join13(root, config.intelligence.retriever.options.storePath) : defaultVectorStorePath(root);
9016
+ const storePath = typeof config.intelligence?.retriever?.options?.storePath === "string" ? join14(root, config.intelligence.retriever.options.storePath) : defaultVectorStorePath(root);
8907
9017
  const store = memoryMod.fileVectorMemory({ path: storePath });
8908
9018
  const rag = ragMod.createRAG({
8909
9019
  embed,
@@ -9038,15 +9148,15 @@ var startInkChat = async (root, config, index) => {
9038
9148
  };
9039
9149
 
9040
9150
  // src/memory/ingest.ts
9041
- import { existsSync as existsSync14, readFileSync as readFileSync17 } from "fs";
9042
- import { join as join14 } from "path";
9151
+ import { existsSync as existsSync15, readFileSync as readFileSync18 } from "fs";
9152
+ import { join as join15 } from "path";
9043
9153
  var memoryFact = (raw, id) => firstParagraph(raw) ?? firstHeading(raw) ?? id;
9044
9154
  var relativePath2 = (root, abs) => toPosix(abs).replace(`${toPosix(root)}/`, "");
9045
9155
  var ingestMarkdownDir = (root, dir, source, confidence) => {
9046
- if (!existsSync14(dir)) return [];
9047
- return walkFiles(dir, { extensions: [".md", ".mdc"] }).map((abs) => {
9156
+ if (!existsSync15(dir)) return [];
9157
+ return walkFiles(dir, { extensions: [".md", ".mdc"], respectIgnore: false }).map((abs) => {
9048
9158
  const rel = relativePath2(root, abs);
9049
- const raw = readFileSync17(abs, "utf8");
9159
+ const raw = readFileSync18(abs, "utf8");
9050
9160
  const id = slugFromPath(rel);
9051
9161
  return {
9052
9162
  schemaVersion: 1,
@@ -9061,10 +9171,10 @@ var ingestMarkdownDir = (root, dir, source, confidence) => {
9061
9171
  });
9062
9172
  };
9063
9173
  var ingestCursorRules = (root) => {
9064
- const dir = join14(root, ".cursor", "rules");
9174
+ const dir = join15(root, ".cursor", "rules");
9065
9175
  return ingestMarkdownDir(root, dir, "cursor", 0.6);
9066
9176
  };
9067
- var ingestAgentMemory = (root) => ingestMarkdownDir(root, join14(root, ".agent-memory"), "agent-memory", 0.7);
9177
+ var ingestAgentMemory = (root) => ingestMarkdownDir(root, join15(root, ".agent-memory"), "agent-memory", 0.7);
9068
9178
  var ingestMemoryCandidates = (root) => [
9069
9179
  ...ingestAgentMemory(root),
9070
9180
  ...ingestCursorRules(root)
@@ -9150,9 +9260,9 @@ var draftMemoryPromotion = (classifications) => {
9150
9260
  };
9151
9261
 
9152
9262
  // src/memory/github-pr.ts
9153
- import { execFileSync as execFileSync3, spawnSync } from "child_process";
9154
- import { existsSync as existsSync15, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
9155
- import { join as join15 } from "path";
9263
+ import { execFileSync as execFileSync4, spawnSync } from "child_process";
9264
+ import { existsSync as existsSync16, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
9265
+ import { join as join16 } from "path";
9156
9266
  var run = (cmd, args, cwd) => {
9157
9267
  const result = spawnSync(cmd, [...args], { cwd, encoding: "utf8" });
9158
9268
  const out = `${result.stdout ?? ""}${result.stderr ?? ""}`.trim();
@@ -9160,10 +9270,10 @@ var run = (cmd, args, cwd) => {
9160
9270
  };
9161
9271
  var hasGh = () => run("gh", ["--version"], process.cwd()).ok;
9162
9272
  var slug = () => (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
9163
- var defaultPromotionDraftPath = (root) => join15(root, ".doc-bridge", "drafts", `memory-promotion-${slug()}.md`);
9273
+ var defaultPromotionDraftPath = (root) => join16(root, ".doc-bridge", "drafts", `memory-promotion-${slug()}.md`);
9164
9274
  var writePromotionDraft = (root, draft, path) => {
9165
9275
  const draftPath = path ?? defaultPromotionDraftPath(root);
9166
- mkdirSync3(join15(root, ".doc-bridge", "drafts"), { recursive: true });
9276
+ mkdirSync3(join16(root, ".doc-bridge", "drafts"), { recursive: true });
9167
9277
  writeFileSync3(draftPath, `${draft.body}
9168
9278
  `, "utf8");
9169
9279
  return draftPath;
@@ -9199,7 +9309,7 @@ var promoteMemoryToGithubPr = (root, draft, options = {}) => {
9199
9309
  message: `Wrote draft to ${relDraft}. Run the printed git/gh commands to open a draft PR.`
9200
9310
  };
9201
9311
  }
9202
- if (!existsSync15(join15(root, ".git"))) {
9312
+ if (!existsSync16(join16(root, ".git"))) {
9203
9313
  return {
9204
9314
  ok: false,
9205
9315
  dryRun: false,
@@ -9277,7 +9387,7 @@ ${auth.out}`
9277
9387
  ];
9278
9388
  let prUrl = "";
9279
9389
  try {
9280
- prUrl = execFileSync3("gh", prArgs, { cwd: root, encoding: "utf8" }).trim();
9390
+ prUrl = execFileSync4("gh", prArgs, { cwd: root, encoding: "utf8" }).trim();
9281
9391
  } catch (error) {
9282
9392
  const message = error instanceof Error ? error.message : String(error);
9283
9393
  return {
@@ -9302,23 +9412,23 @@ ${auth.out}`
9302
9412
  };
9303
9413
 
9304
9414
  // src/index-builder/watch-index.ts
9305
- import { existsSync as existsSync16, watch } from "fs";
9306
- import { dirname as dirname6, resolve as resolve14 } from "path";
9415
+ import { existsSync as existsSync17, watch } from "fs";
9416
+ import { dirname as dirname7, resolve as resolve15 } from "path";
9307
9417
  var WATCH_PATTERN = /\.(md|mdx|json|ya?ml|mdc)$/i;
9308
9418
  var NX_MANIFEST_PATTERN = /(^|[/\\])(project|package)\.json$/i;
9309
9419
  var collectWatchRoots = (root, config, configPath) => {
9310
9420
  const roots = /* @__PURE__ */ new Set();
9311
- roots.add(resolve14(root, config.corpus.agent.root));
9421
+ roots.add(resolve15(root, config.corpus.agent.root));
9312
9422
  const humanSources = config.corpus.human ? Array.isArray(config.corpus.human) ? config.corpus.human : [config.corpus.human] : [];
9313
9423
  for (const source of humanSources) {
9314
9424
  const humanOpts = source.options ?? {};
9315
9425
  for (const key of ["contentDir", "docsDir", "root", "srcDir"]) {
9316
9426
  const value = humanOpts[key];
9317
- if (typeof value === "string" && value.length) roots.add(resolve14(root, value));
9427
+ if (typeof value === "string" && value.length) roots.add(resolve15(root, value));
9318
9428
  }
9319
9429
  }
9320
- if (configPath) roots.add(dirname6(resolve14(configPath)));
9321
- return [...roots].filter((dir) => existsSync16(dir));
9430
+ if (configPath) roots.add(dirname7(resolve15(configPath)));
9431
+ return [...roots].filter((dir) => existsSync17(dir));
9322
9432
  };
9323
9433
  var watchDocBridgeIndex = (opts) => {
9324
9434
  const debounceMs = opts.debounceMs ?? 350;
@@ -9359,15 +9469,15 @@ var watchDocBridgeIndex = (opts) => {
9359
9469
  rebuild();
9360
9470
  });
9361
9471
  }
9362
- const nxRoot = resolve14(opts.root);
9363
- if (opts.config.routing?.plugin === "nx" && existsSync16(nxRoot)) {
9472
+ const nxRoot = resolve15(opts.root);
9473
+ if (opts.config.routing?.plugin === "nx" && existsSync17(nxRoot)) {
9364
9474
  watch(nxRoot, { recursive: true }, (_event, filename) => {
9365
9475
  if (!filename || !NX_MANIFEST_PATTERN.test(filename)) return;
9366
9476
  rebuild();
9367
9477
  });
9368
9478
  }
9369
- const configDir = resolve14(opts.root);
9370
- if (existsSync16(configDir)) {
9479
+ const configDir = resolve15(opts.root);
9480
+ if (existsSync17(configDir)) {
9371
9481
  watch(configDir, (_event, filename) => {
9372
9482
  if (!filename || !/doc-bridge\.config/.test(filename)) return;
9373
9483
  rebuild();
@@ -9385,8 +9495,8 @@ var watchDocBridgeIndex = (opts) => {
9385
9495
  };
9386
9496
 
9387
9497
  // src/workflow/engine.ts
9388
- import { appendFileSync, existsSync as existsSync17, mkdirSync as mkdirSync4, readFileSync as readFileSync18, renameSync as renameSync2, rmSync, writeFileSync as writeFileSync4 } from "fs";
9389
- import { join as join16, relative as relative8, resolve as resolve15 } from "path";
9498
+ import { appendFileSync, existsSync as existsSync18, mkdirSync as mkdirSync4, readFileSync as readFileSync19, renameSync as renameSync2, rmSync, writeFileSync as writeFileSync4 } from "fs";
9499
+ import { join as join17, relative as relative9, resolve as resolve16 } from "path";
9390
9500
  var WORKFLOW_STAGES = ["collect", "normalize", "reconcile", "enrich", "evaluate", "report"];
9391
9501
  var OPTIONAL_WORKFLOW_STAGES = ["enrich"];
9392
9502
  var stageState = {
@@ -9397,7 +9507,7 @@ var stageState = {
9397
9507
  evaluate: "proposed",
9398
9508
  report: "delivered"
9399
9509
  };
9400
- var defaultStateDir = (root) => join16(root, ".doc-bridge", "workflow");
9510
+ var defaultStateDir = (root) => join17(root, ".doc-bridge", "workflow");
9401
9511
  var atomicWrite = (path, value) => {
9402
9512
  const temp = `${path}.tmp-${process.pid}-${Date.now()}`;
9403
9513
  writeFileSync4(temp, `${JSON.stringify(value, null, 2)}
@@ -9405,10 +9515,10 @@ var atomicWrite = (path, value) => {
9405
9515
  renameSync2(temp, path);
9406
9516
  };
9407
9517
  var writeManifest = (stateDir, run2) => {
9408
- atomicWrite(join16(stateDir, "manifest.json"), run2);
9518
+ atomicWrite(join17(stateDir, "manifest.json"), run2);
9409
9519
  };
9410
9520
  var appendTransition = (stateDir, transition2) => {
9411
- appendFileSync(join16(stateDir, "transitions.jsonl"), `${JSON.stringify(transition2)}
9521
+ appendFileSync(join17(stateDir, "transitions.jsonl"), `${JSON.stringify(transition2)}
9412
9522
  `, "utf8");
9413
9523
  };
9414
9524
  var transition = (run2, to, reason) => {
@@ -9439,8 +9549,8 @@ var transition = (run2, to, reason) => {
9439
9549
  };
9440
9550
  var runId = () => `${Date.now()}-${process.pid}`;
9441
9551
  var stageInputHash = (options, stage, input) => sha256NormalizedV1({ stage, input, sourceRevision: options.sourceRevision, configurationHash: options.configurationHash, pipelineVersion: options.pipelineVersion ?? "1.0.0", analyzerVersions: options.analyzerVersions ?? {}, toolVersion: options.toolVersion ?? "1.0.0" });
9442
- var stageArtifactPath = (stateDir, stage, inputHash) => join16(stateDir, "artifacts", `${stage}-${inputHash}.json`);
9443
- var readArtifact = (path) => JSON.parse(readFileSync18(path, "utf8"));
9552
+ var stageArtifactPath = (stateDir, stage, inputHash) => join17(stateDir, "artifacts", `${stage}-${inputHash}.json`);
9553
+ var readArtifact = (path) => JSON.parse(readFileSync19(path, "utf8"));
9444
9554
  var readVerifiedArtifact = (path, stage, step) => {
9445
9555
  const artifact2 = readArtifact(path);
9446
9556
  if (artifact2.type !== "workflow-step-artifact" || artifact2.stage !== stage || artifact2.inputHash !== step.inputHash) throw new Error(`Invalid workflow artifact for stage "${stage}".`);
@@ -9448,8 +9558,8 @@ var readVerifiedArtifact = (path, stage, step) => {
9448
9558
  return artifact2;
9449
9559
  };
9450
9560
  var stepArtifactPath = (stateDir, step) => {
9451
- const path = resolve15(stateDir, step.artifactRefs?.[0] ?? "");
9452
- const pathRelativeToState = relative8(stateDir, path);
9561
+ const path = resolve16(stateDir, step.artifactRefs?.[0] ?? "");
9562
+ const pathRelativeToState = relative9(stateDir, path);
9453
9563
  if (pathRelativeToState.startsWith("..") || pathRelativeToState.startsWith("/")) throw new Error(`Workflow artifact escapes state directory for stage "${step.name}".`);
9454
9564
  return path;
9455
9565
  };
@@ -9459,13 +9569,13 @@ var stepOutput = (stateDir, run2, stage) => {
9459
9569
  return readVerifiedArtifact(stepArtifactPath(stateDir, step), stage, step).value;
9460
9570
  };
9461
9571
  var acquireLock = (stateDir) => {
9462
- const lock = join16(stateDir, ".lock");
9572
+ const lock = join17(stateDir, ".lock");
9463
9573
  try {
9464
9574
  mkdirSync4(lock);
9465
9575
  } catch {
9466
- const ownerPath = join16(lock, "owner.json");
9576
+ const ownerPath = join17(lock, "owner.json");
9467
9577
  try {
9468
- const owner = JSON.parse(readFileSync18(ownerPath, "utf8"));
9578
+ const owner = JSON.parse(readFileSync19(ownerPath, "utf8"));
9469
9579
  if (typeof owner.pid === "number") process.kill(owner.pid, 0);
9470
9580
  throw new Error(`Workflow is already running (pid ${owner.pid ?? "unknown"}).`);
9471
9581
  } catch (error) {
@@ -9474,13 +9584,13 @@ var acquireLock = (stateDir) => {
9474
9584
  mkdirSync4(lock);
9475
9585
  }
9476
9586
  }
9477
- writeFileSync4(join16(lock, "owner.json"), JSON.stringify({ pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf8");
9587
+ writeFileSync4(join17(lock, "owner.json"), JSON.stringify({ pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf8");
9478
9588
  return () => rmSync(lock, { recursive: true, force: true });
9479
9589
  };
9480
9590
  var loadManifest = (stateDir) => {
9481
- const path = join16(stateDir, "manifest.json");
9482
- if (!existsSync17(path)) return void 0;
9483
- return WorkflowRunV1Schema.parse(JSON.parse(readFileSync18(path, "utf8")));
9591
+ const path = join17(stateDir, "manifest.json");
9592
+ if (!existsSync18(path)) return void 0;
9593
+ return WorkflowRunV1Schema.parse(JSON.parse(readFileSync19(path, "utf8")));
9484
9594
  };
9485
9595
  var baseRun = (options, stateDir, supersedes) => {
9486
9596
  const inputHash = sha256NormalizedV1({ sourceRevision: options.sourceRevision, configurationHash: options.configurationHash, pipelineVersion: options.pipelineVersion ?? "1.0.0", analyzerVersions: options.analyzerVersions ?? {}, toolVersion: options.toolVersion ?? "1.0.0" });
@@ -9489,7 +9599,7 @@ var baseRun = (options, stateDir, supersedes) => {
9489
9599
  schemaVersion: 1,
9490
9600
  contentHash: "0".repeat(64),
9491
9601
  contentHashAlgo: "sha256-normalized-v1",
9492
- project: { name: resolve15(options.root).split("/").pop() ?? "project", root: "." },
9602
+ project: { name: resolve16(options.root).split("/").pop() ?? "project", root: "." },
9493
9603
  sourceRevision: options.sourceRevision,
9494
9604
  sourceRevisionKind: "content",
9495
9605
  configurationHash: options.configurationHash,
@@ -9500,16 +9610,16 @@ var baseRun = (options, stateDir, supersedes) => {
9500
9610
  state: "created",
9501
9611
  steps: WORKFLOW_STAGES.map((name) => ({ name, status: "pending", inputHash })),
9502
9612
  transitions: [{ from: null, to: "created", at: (/* @__PURE__ */ new Date()).toISOString() }],
9503
- artifactRefs: [relative8(resolve15(options.root), stateDir), ...supersedes ? [`supersedes:${supersedes}`] : []]
9613
+ artifactRefs: [relative9(resolve16(options.root), stateDir), ...supersedes ? [`supersedes:${supersedes}`] : []]
9504
9614
  });
9505
9615
  };
9506
9616
  var withHash = (run2) => WorkflowRunV1Schema.parse({ ...run2, contentHash: contentHashForArtifactV1(run2) });
9507
9617
  var sameInputs = (run2, options) => run2.sourceRevision === options.sourceRevision && run2.configurationHash === options.configurationHash && run2.pipelineVersion === (options.pipelineVersion ?? "1.0.0") && sha256NormalizedV1(run2.analyzerVersions) === sha256NormalizedV1({ ...options.analyzerVersions ?? {}, workflow: options.toolVersion ?? "1.0.0" });
9508
9618
  var selectedStages = (stage) => stage && stage !== "all" ? [stage] : WORKFLOW_STAGES;
9509
9619
  var runWorkflow = (options) => {
9510
- const root = resolve15(options.root);
9511
- const stateDir = resolve15(root, options.stateDir ?? defaultStateDir(root));
9512
- mkdirSync4(join16(stateDir, "artifacts"), { recursive: true });
9620
+ const root = resolve16(options.root);
9621
+ const stateDir = resolve16(root, options.stateDir ?? defaultStateDir(root));
9622
+ mkdirSync4(join17(stateDir, "artifacts"), { recursive: true });
9513
9623
  const release = acquireLock(stateDir);
9514
9624
  try {
9515
9625
  let run2 = loadManifest(stateDir);
@@ -9548,8 +9658,8 @@ var runWorkflow = (options) => {
9548
9658
  const input = options.inputs?.[stage] ?? previousOutput;
9549
9659
  const inputHash = stageInputHash(options, stage, input);
9550
9660
  const existing = run2.steps.find((step) => step.name === stage);
9551
- const artifactPath = existing?.artifactRefs?.[0] && existing.inputHash === inputHash ? resolve15(stateDir, existing.artifactRefs[0]) : stageArtifactPath(stateDir, stage, inputHash);
9552
- if (existing?.status === "completed" && existing.inputHash === inputHash && existing.outputHash && existsSync17(artifactPath)) {
9661
+ const artifactPath = existing?.artifactRefs?.[0] && existing.inputHash === inputHash ? resolve16(stateDir, existing.artifactRefs[0]) : stageArtifactPath(stateDir, stage, inputHash);
9662
+ if (existing?.status === "completed" && existing.inputHash === inputHash && existing.outputHash && existsSync18(artifactPath)) {
9553
9663
  try {
9554
9664
  previousOutput = readVerifiedArtifact(artifactPath, stage, existing).value;
9555
9665
  } catch (error) {
@@ -9579,14 +9689,14 @@ var runWorkflow = (options) => {
9579
9689
  const value = handler({ root, stage, input, previousOutput });
9580
9690
  const outputHash = sha256NormalizedV1(value);
9581
9691
  const artifact2 = { type: "workflow-step-artifact", stage, inputHash, outputHash, value };
9582
- mkdirSync4(join16(stateDir, "artifacts"), { recursive: true });
9583
- if (existsSync17(artifactPath)) {
9692
+ mkdirSync4(join17(stateDir, "artifacts"), { recursive: true });
9693
+ if (existsSync18(artifactPath)) {
9584
9694
  const existingArtifact = readArtifact(artifactPath);
9585
9695
  if (existingArtifact.outputHash !== outputHash) throw new Error(`Immutable workflow artifact collision for stage "${stage}".`);
9586
9696
  } else {
9587
9697
  atomicWrite(artifactPath, artifact2);
9588
9698
  }
9589
- const ref = relative8(stateDir, artifactPath);
9699
+ const ref = relative9(stateDir, artifactPath);
9590
9700
  const completedStep = { name: stage, status: "completed", inputHash, outputHash, artifactRefs: [ref] };
9591
9701
  run2 = withHash({ ...run2, steps: run2.steps.map((step) => step.name === stage ? completedStep : step) });
9592
9702
  writeManifest(stateDir, run2);
@@ -9606,15 +9716,15 @@ var runWorkflow = (options) => {
9606
9716
  run2 = complete;
9607
9717
  }
9608
9718
  writeManifest(stateDir, run2);
9609
- if (run2.state === "delivered") atomicWrite(join16(stateDir, "last-known-good.json"), { runId: run2.runId, manifestHash: run2.contentHash, report: run2.steps.find((step) => step.name === "report")?.artifactRefs?.[0] });
9719
+ if (run2.state === "delivered") atomicWrite(join17(stateDir, "last-known-good.json"), { runId: run2.runId, manifestHash: run2.contentHash, report: run2.steps.find((step) => step.name === "report")?.artifactRefs?.[0] });
9610
9720
  }
9611
9721
  return { run: run2, stateDir, reusedStages };
9612
9722
  } finally {
9613
9723
  release();
9614
9724
  }
9615
9725
  };
9616
- var loadWorkflowManifest = (stateDir) => WorkflowRunV1Schema.parse(JSON.parse(readFileSync18(join16(resolve15(stateDir), "manifest.json"), "utf8")));
9617
- var loadWorkflowStepOutput = (stateDir, stage) => stepOutput(resolve15(stateDir), loadWorkflowManifest(stateDir), stage);
9726
+ var loadWorkflowManifest = (stateDir) => WorkflowRunV1Schema.parse(JSON.parse(readFileSync19(join17(resolve16(stateDir), "manifest.json"), "utf8")));
9727
+ var loadWorkflowStepOutput = (stateDir, stage) => stepOutput(resolve16(stateDir), loadWorkflowManifest(stateDir), stage);
9618
9728
 
9619
9729
  // src/doctor/badge.ts
9620
9730
  var doctorBadgeMetrics = (report) => {
@@ -9775,15 +9885,15 @@ var docBridgePatternPayload = () => ({
9775
9885
  });
9776
9886
 
9777
9887
  // src/cli/demo.ts
9778
- import { cpSync, existsSync as existsSync19, mkdtempSync, readFileSync as readFileSync20, rmSync as rmSync2 } from "fs";
9888
+ import { cpSync, existsSync as existsSync20, mkdtempSync, readFileSync as readFileSync21, rmSync as rmSync2 } from "fs";
9779
9889
  import { tmpdir } from "os";
9780
- import { dirname as dirname8, join as join18, resolve as resolve17 } from "path";
9890
+ import { dirname as dirname9, join as join19, resolve as resolve18 } from "path";
9781
9891
  import { fileURLToPath } from "url";
9782
9892
 
9783
9893
  // src/mcp/install.ts
9784
- import { existsSync as existsSync18, mkdirSync as mkdirSync5, readFileSync as readFileSync19, writeFileSync as writeFileSync5 } from "fs";
9894
+ import { existsSync as existsSync19, mkdirSync as mkdirSync5, readFileSync as readFileSync20, writeFileSync as writeFileSync5 } from "fs";
9785
9895
  import { homedir } from "os";
9786
- import { dirname as dirname7, join as join17, resolve as resolve16 } from "path";
9896
+ import { dirname as dirname8, join as join18, resolve as resolve17 } from "path";
9787
9897
  var SERVER_NAME = "ak-docs";
9788
9898
  var mcpServerEntry = (root) => ({
9789
9899
  command: "npx",
@@ -9791,26 +9901,26 @@ var mcpServerEntry = (root) => ({
9791
9901
  cwd: root
9792
9902
  });
9793
9903
  var readJson2 = (path) => {
9794
- if (!existsSync18(path)) return {};
9904
+ if (!existsSync19(path)) return {};
9795
9905
  try {
9796
- const parsed = JSON.parse(readFileSync19(path, "utf8"));
9906
+ const parsed = JSON.parse(readFileSync20(path, "utf8"));
9797
9907
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
9798
9908
  } catch {
9799
9909
  return {};
9800
9910
  }
9801
9911
  };
9802
9912
  var writeJson = (path, value) => {
9803
- mkdirSync5(dirname7(path), { recursive: true });
9913
+ mkdirSync5(dirname8(path), { recursive: true });
9804
9914
  writeFileSync5(path, `${JSON.stringify(value, null, 2)}
9805
9915
  `, "utf8");
9806
9916
  };
9807
9917
  var resolveTargetPath = (target2, root) => {
9808
- if (target2 === "cursor") return resolve16(root, ".cursor", "mcp.json");
9809
- return join17(homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
9918
+ if (target2 === "cursor") return resolve17(root, ".cursor", "mcp.json");
9919
+ return join18(homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
9810
9920
  };
9811
9921
  var installMcpConfig = (root, target2) => {
9812
9922
  const configPath = resolveTargetPath(target2, root);
9813
- const created = !existsSync18(configPath);
9923
+ const created = !existsSync19(configPath);
9814
9924
  const existing = readJson2(configPath);
9815
9925
  const servers = existing.mcpServers && typeof existing.mcpServers === "object" && !Array.isArray(existing.mcpServers) ? { ...existing.mcpServers } : {};
9816
9926
  servers[SERVER_NAME] = mcpServerEntry(root);
@@ -9835,12 +9945,12 @@ var installMcpConfig = (root, target2) => {
9835
9945
  var mcpSnippet = (root) => JSON.stringify({ mcpServers: { [SERVER_NAME]: mcpServerEntry(root) } }, null, 2);
9836
9946
 
9837
9947
  // src/cli/demo.ts
9838
- var packageRoot = resolve17(dirname8(fileURLToPath(import.meta.url)), "..", "..");
9948
+ var packageRoot = resolve18(dirname9(fileURLToPath(import.meta.url)), "..", "..");
9839
9949
  var fixturePath = (fixture) => {
9840
9950
  if (fixture === "monorepo") {
9841
- return join18(packageRoot, "examples", "demo-monorepo");
9951
+ return join19(packageRoot, "examples", "demo-monorepo");
9842
9952
  }
9843
- return join18(packageRoot, "examples", "demo-example");
9953
+ return join19(packageRoot, "examples", "demo-example");
9844
9954
  };
9845
9955
  var formatHandoffText = (handoff) => {
9846
9956
  const bridge = handoff.bridge?.humanDoc === "missing" ? `human guide: missing \u2192 ${handoff.bridge.action ?? "ak-docs bootstrap agent-docs"}` : handoff.humanDoc ? `human guide: ${handoff.humanDoc}` : "human guide: (none)";
@@ -9856,11 +9966,11 @@ var formatHandoffText = (handoff) => {
9856
9966
  var runDemo = (root, config, fixture = "example", options = {}) => {
9857
9967
  const targetPackage = fixture === "monorepo" ? "auth" : "example";
9858
9968
  const fixtureDir = fixturePath(fixture);
9859
- if (options.copyFixture && existsSync19(fixtureDir)) {
9969
+ if (options.copyFixture && existsSync20(fixtureDir)) {
9860
9970
  for (const rel of ["doc-bridge.config.json", "docs", "packages", "pnpm-workspace.yaml", "package.json"]) {
9861
- const src = join18(fixtureDir, rel);
9862
- if (!existsSync19(src)) continue;
9863
- const dest = join18(root, rel);
9971
+ const src = join19(fixtureDir, rel);
9972
+ if (!existsSync20(src)) continue;
9973
+ const dest = join19(root, rel);
9864
9974
  cpSync(src, dest, { recursive: true });
9865
9975
  }
9866
9976
  }
@@ -9915,14 +10025,14 @@ var formatDemoText = (result) => {
9915
10025
  return lines;
9916
10026
  };
9917
10027
  var withDemoWorkspace = (fixture, fn) => {
9918
- const dir = mkdtempSync(join18(tmpdir(), "ak-docs-demo-"));
10028
+ const dir = mkdtempSync(join19(tmpdir(), "ak-docs-demo-"));
9919
10029
  try {
9920
10030
  const fixtureDir = fixturePath(fixture);
9921
- if (!existsSync19(fixtureDir)) {
10031
+ if (!existsSync20(fixtureDir)) {
9922
10032
  throw new Error(`Demo fixture "${fixture}" not found at ${fixtureDir}`);
9923
10033
  }
9924
10034
  cpSync(fixtureDir, dir, { recursive: true });
9925
- const config = JSON.parse(readFileSync20(join18(dir, "doc-bridge.config.json"), "utf8"));
10035
+ const config = JSON.parse(readFileSync21(join19(dir, "doc-bridge.config.json"), "utf8"));
9926
10036
  return fn(dir, config);
9927
10037
  } finally {
9928
10038
  rmSync2(dir, { recursive: true, force: true });
@@ -9930,8 +10040,8 @@ var withDemoWorkspace = (fixture, fn) => {
9930
10040
  };
9931
10041
 
9932
10042
  // src/doctor/run-doctor.ts
9933
- import { existsSync as existsSync20, readFileSync as readFileSync21 } from "fs";
9934
- import { resolve as resolve18 } from "path";
10043
+ import { existsSync as existsSync21, readFileSync as readFileSync22 } from "fs";
10044
+ import { resolve as resolve19 } from "path";
9935
10045
 
9936
10046
  // src/bench/retrieval.ts
9937
10047
  import { z as z12 } from "zod";
@@ -10213,11 +10323,11 @@ var measureConnectivity = (index) => {
10213
10323
  };
10214
10324
  var measureBenchmark = (root, config, index) => {
10215
10325
  const suite = config.retrieval?.benchmark?.suite ?? DEFAULT_RETRIEVAL_SUITE;
10216
- const suitePath = resolve18(root, suite);
10217
- if (!existsSync20(suitePath)) return { status: "not-analyzed", suite, reason: `No retrieval suite at ${suite}` };
10326
+ const suitePath = resolve19(root, suite);
10327
+ if (!existsSync21(suitePath)) return { status: "not-analyzed", suite, reason: `No retrieval suite at ${suite}` };
10218
10328
  if (!index.projection) return { status: "not-analyzed", suite, reason: "The index carries no retrieval projection. Run: ak-docs index" };
10219
10329
  try {
10220
- const parsed = parseRetrievalSuite(JSON.parse(readFileSync21(suitePath, "utf8")));
10330
+ const parsed = parseRetrievalSuite(JSON.parse(readFileSync22(suitePath, "utf8")));
10221
10331
  const result = runRetrievalBench({ index, suite: parsed });
10222
10332
  return {
10223
10333
  status: "measured",
@@ -10465,8 +10575,8 @@ var formatDoctorText = (report) => {
10465
10575
  };
10466
10576
 
10467
10577
  // src/mcp/server.ts
10468
- import { mkdirSync as mkdirSync8, readFileSync as readFileSync25, realpathSync as realpathSync9, writeFileSync as writeFileSync9 } from "fs";
10469
- import { join as join22, relative as relative10, resolve as resolve22 } from "path";
10578
+ import { mkdirSync as mkdirSync8, readFileSync as readFileSync26, realpathSync as realpathSync10, writeFileSync as writeFileSync9 } from "fs";
10579
+ import { join as join23, relative as relative11, resolve as resolve23 } from "path";
10470
10580
  import { z as z14, ZodError } from "zod";
10471
10581
 
10472
10582
  // src/findings/report.ts
@@ -10884,14 +10994,14 @@ var formatKnowledgeLookupText = (response) => {
10884
10994
  };
10885
10995
 
10886
10996
  // src/fixes/proposals.ts
10887
- import { existsSync as existsSync21, readdirSync as readdirSync4, readFileSync as readFileSync22, realpathSync as realpathSync8, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync6 } from "fs";
10888
- import { basename as basename7, dirname as dirname9, extname as extname5, join as join19, relative as relative9, resolve as resolve19, sep as sep9 } from "path";
10997
+ import { existsSync as existsSync22, readdirSync as readdirSync4, readFileSync as readFileSync23, realpathSync as realpathSync9, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync6 } from "fs";
10998
+ import { basename as basename7, dirname as dirname10, extname as extname5, join as join20, relative as relative10, resolve as resolve20, sep as sep10 } from "path";
10889
10999
  var hash4 = (value) => sha256NormalizedV1(value);
10890
11000
  var artifactMetadata = (root, options) => ({
10891
11001
  schemaVersion: 1,
10892
11002
  contentHash: "0".repeat(64),
10893
11003
  contentHashAlgo: "sha256-normalized-v1",
10894
- project: { name: options.projectName ?? basename7(resolve19(root)), root: "." },
11004
+ project: { name: options.projectName ?? basename7(resolve20(root)), root: "." },
10895
11005
  sourceRevision: options.baseRevision,
10896
11006
  sourceRevisionKind: options.baseRevision.length === 40 ? "git" : "content",
10897
11007
  configurationHash: options.configurationHash,
@@ -10922,31 +11032,32 @@ var makeProposal = (root, options, changes, preconditions, postconditions) => {
10922
11032
  };
10923
11033
  return FixProposalV1Schema.parse({ ...draft, contentHash: contentHashForArtifactV1(draft) });
10924
11034
  };
10925
- var walkMarkdown = (root, directory = root) => readdirSync4(directory, { withFileTypes: true }).flatMap((entry) => {
11035
+ var walkMarkdown = (root, directory = root, ignored = createIgnoreFilter(root)) => readdirSync4(directory, { withFileTypes: true }).flatMap((entry) => {
10926
11036
  if (entry.name === ".git" || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build") return [];
10927
- const path = join19(directory, entry.name);
10928
- if (entry.isDirectory()) return walkMarkdown(root, path);
10929
- return entry.isFile() && [".md", ".mdx"].includes(extname5(entry.name).toLowerCase()) ? [relative9(root, path).split(sep9).join("/")] : [];
11037
+ const path = join20(directory, entry.name);
11038
+ if (ignored.isIgnored(path, entry.isDirectory())) return [];
11039
+ if (entry.isDirectory()) return walkMarkdown(root, path, ignored);
11040
+ return entry.isFile() && [".md", ".mdx"].includes(extname5(entry.name).toLowerCase()) ? [relative10(root, path).split(sep10).join("/")] : [];
10930
11041
  });
10931
11042
  var localLink = /(!?)\[([^\]]*)\]\(([^)\s]+)(?:\s+["'][^)]*["'])?\)/g;
10932
11043
  var sortJson = (value) => Array.isArray(value) ? value.map(sortJson) : value && typeof value === "object" ? Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => [key, sortJson(item)])) : value;
10933
11044
  var createMarkdownLinkFixProposal = (root, options) => {
10934
- const projectRoot = realpathSync8.native(resolve19(root));
11045
+ const projectRoot = realpathSync9.native(resolve20(root));
10935
11046
  const paths = walkMarkdown(projectRoot);
10936
11047
  const changes = [];
10937
11048
  for (const path of paths) {
10938
- const content = readFileSync22(join19(projectRoot, path), "utf8");
11049
+ const content = readFileSync23(join20(projectRoot, path), "utf8");
10939
11050
  let next = content;
10940
11051
  for (const match of content.matchAll(localLink)) {
10941
11052
  const target2 = match[3];
10942
11053
  if (!target2 || match[1] === "!" || /^(?:[a-z]+:|\/|#)/i.test(target2)) continue;
10943
11054
  const targetPath = target2.split("#")[0]?.split("?")[0];
10944
- if (!targetPath || existsSync21(resolve19(projectRoot, dirname9(path), targetPath))) continue;
11055
+ if (!targetPath || existsSync22(resolve20(projectRoot, dirname10(path), targetPath))) continue;
10945
11056
  const targetStem = basename7(targetPath, extname5(targetPath)).toLowerCase();
10946
11057
  const labelStem = (match[2] ?? "").trim().toLowerCase().replace(/[^a-z0-9]+/g, "");
10947
11058
  const candidates = paths.filter((candidate) => basename7(candidate, extname5(candidate)).toLowerCase() === targetStem || basename7(candidate, extname5(candidate)).toLowerCase().replace(/[^a-z0-9]+/g, "") === labelStem);
10948
11059
  if (candidates.length !== 1) continue;
10949
- let replacement = relative9(dirname9(path), candidates[0]).split(sep9).join("/");
11060
+ let replacement = relative10(dirname10(path), candidates[0]).split(sep10).join("/");
10950
11061
  if (target2.startsWith("./") && !replacement.startsWith(".")) replacement = `./${replacement}`;
10951
11062
  next = next.replace(match[0], match[0].replace(target2, replacement));
10952
11063
  }
@@ -10955,13 +11066,13 @@ var createMarkdownLinkFixProposal = (root, options) => {
10955
11066
  return changes.length ? makeProposal(projectRoot, options, changes, ["Each replacement has exactly one Markdown target."], ["All corrected local Markdown links resolve."]) : void 0;
10956
11067
  };
10957
11068
  var createArtifactNormalizationProposal = (root, artifactPath, options) => {
10958
- const projectRoot = realpathSync8.native(resolve19(root));
10959
- const path = artifactPath.split(sep9).join("/");
11069
+ const projectRoot = realpathSync9.native(resolve20(root));
11070
+ const path = artifactPath.split(sep10).join("/");
10960
11071
  const absolute = containedPath(projectRoot, path);
10961
11072
  if (!absolute) return void 0;
10962
11073
  let before;
10963
11074
  try {
10964
- before = readFileSync22(absolute, "utf8");
11075
+ before = readFileSync23(absolute, "utf8");
10965
11076
  } catch {
10966
11077
  return void 0;
10967
11078
  }
@@ -10972,7 +11083,7 @@ var createArtifactNormalizationProposal = (root, artifactPath, options) => {
10972
11083
  } catch {
10973
11084
  return void 0;
10974
11085
  }
10975
- return after === before ? void 0 : makeProposal(projectRoot, options, [{ path: relative9(projectRoot, absolute).split(sep9).join("/"), before, after }], ["The artifact contains valid JSON."], ["The artifact is valid canonical JSON with one trailing newline."]);
11086
+ return after === before ? void 0 : makeProposal(projectRoot, options, [{ path: relative10(projectRoot, absolute).split(sep10).join("/"), before, after }], ["The artifact contains valid JSON."], ["The artifact is valid canonical JSON with one trailing newline."]);
10976
11087
  };
10977
11088
  var approveFixProposal = (proposalInput, approvedBy, approvedAt = (/* @__PURE__ */ new Date()).toISOString()) => {
10978
11089
  const proposal = FixProposalV1Schema.parse(proposalInput);
@@ -10990,7 +11101,7 @@ var applyFixProposal = (root, proposalInput, options = {}) => {
10990
11101
  if (proposal.approval.proposalHash !== bindingHash(proposal)) throw new Error("Approval is not bound to the exact proposal content.");
10991
11102
  if (options.currentRevision && options.currentRevision !== proposal.baseRevision) throw new Error("The repository revision changed since this proposal was created.");
10992
11103
  if (!proposal.changes?.length) throw new Error("This proposal has no executable changes.");
10993
- const projectRoot = realpathSync8.native(resolve19(root));
11104
+ const projectRoot = realpathSync9.native(resolve20(root));
10994
11105
  const originals = /* @__PURE__ */ new Map();
10995
11106
  const affected = new Map(proposal.affectedFiles.map((file) => [file.path, file]));
10996
11107
  if (proposal.changes.some((change) => !affected.has(change.path) || affected.get(change.path)?.contentHash !== sha256NormalizedV1(change.before)) || affected.size !== proposal.changes.length) {
@@ -10998,29 +11109,29 @@ var applyFixProposal = (root, proposalInput, options = {}) => {
10998
11109
  }
10999
11110
  for (const file of proposal.affectedFiles) {
11000
11111
  const absolute = containedPath(projectRoot, file.path);
11001
- if (!absolute || !existsSync21(absolute)) throw new Error(`Affected file is unavailable or escapes the repository root: ${file.path}`);
11002
- const current = readFileSync22(absolute, "utf8");
11112
+ if (!absolute || !existsSync22(absolute)) throw new Error(`Affected file is unavailable or escapes the repository root: ${file.path}`);
11113
+ const current = readFileSync23(absolute, "utf8");
11003
11114
  if (sha256NormalizedV1(current) !== file.contentHash) throw new Error(`Affected file changed since proposal creation: ${file.path}`);
11004
11115
  originals.set(absolute, current);
11005
11116
  }
11006
11117
  try {
11007
11118
  for (const change of proposal.changes) {
11008
- const absolute = resolve19(projectRoot, change.path);
11119
+ const absolute = resolve20(projectRoot, change.path);
11009
11120
  writeFileSync6(`${absolute}.docbridge-${process.pid}.tmp`, change.after, "utf8");
11010
11121
  }
11011
11122
  for (const change of proposal.changes) {
11012
- const absolute = resolve19(projectRoot, change.path);
11123
+ const absolute = resolve20(projectRoot, change.path);
11013
11124
  renameSync3(`${absolute}.docbridge-${process.pid}.tmp`, absolute);
11014
11125
  }
11015
11126
  for (const change of proposal.changes) {
11016
- if (readFileSync22(resolve19(projectRoot, change.path), "utf8") !== change.after) throw new Error(`Postcondition failed for ${change.path}`);
11127
+ if (readFileSync23(resolve20(projectRoot, change.path), "utf8") !== change.after) throw new Error(`Postcondition failed for ${change.path}`);
11017
11128
  }
11018
11129
  options.verify?.(proposal.changes.map((change) => change.path));
11019
11130
  } catch (error) {
11020
11131
  for (const [absolute, content] of originals) writeFileSync6(absolute, content, "utf8");
11021
11132
  for (const change of proposal.changes) {
11022
- const temp = `${resolve19(projectRoot, change.path)}.docbridge-${process.pid}.tmp`;
11023
- if (existsSync21(temp)) unlinkSync(temp);
11133
+ const temp = `${resolve20(projectRoot, change.path)}.docbridge-${process.pid}.tmp`;
11134
+ if (existsSync22(temp)) unlinkSync(temp);
11024
11135
  }
11025
11136
  throw error;
11026
11137
  }
@@ -11029,9 +11140,9 @@ var applyFixProposal = (root, proposalInput, options = {}) => {
11029
11140
  };
11030
11141
 
11031
11142
  // src/agents/registry-adapter.ts
11032
- import { existsSync as existsSync22, readFileSync as readFileSync23, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6 } from "fs";
11143
+ import { existsSync as existsSync23, readFileSync as readFileSync24, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6 } from "fs";
11033
11144
  import { spawn } from "child_process";
11034
- import { join as join20, resolve as resolve20 } from "path";
11145
+ import { join as join21, resolve as resolve21 } from "path";
11035
11146
  import { pathToFileURL } from "url";
11036
11147
  import { z as z13 } from "zod";
11037
11148
  var DEFAULT_REGISTRY_AGENT_ID = "ecosystem-doc-bridge-corpus-scanner";
@@ -11066,7 +11177,7 @@ var validateGrounding = (proposal, snapshot, report, documentation) => {
11066
11177
  if (proposal.relatedDiagnosticIds.some((id) => !diagnosticIds.has(id))) throw new Error("Registry agent proposal references an unknown diagnostic.");
11067
11178
  if (proposal.evidence.some((item) => !evidenceKeys.has(evidenceKey2(item)))) throw new Error("Registry agent proposal contains evidence outside the supplied snapshot/report.");
11068
11179
  };
11069
- var runCli = (root, cli, context, timeoutMs, maxInputBytes, maxResponseBytes) => new Promise((resolve34, reject) => {
11180
+ var runCli = (root, cli, context, timeoutMs, maxInputBytes, maxResponseBytes) => new Promise((resolve35, reject) => {
11070
11181
  const v2 = "protocol" in context;
11071
11182
  const input = JSON.stringify(
11072
11183
  v2 ? { protocol: REGISTRY_AGENT_PROTOCOL_V2, response: 'Return exactly one JSON object { "proposals": [...] } on stdout. Do not emit markdown or logs on stdout.', context } : { protocol: "doc-bridge.registry-agent.v1", response: "Return exactly one AgentProposalV1 JSON object on stdout. Do not emit markdown or logs on stdout.", context }
@@ -11118,7 +11229,7 @@ var runCli = (root, cli, context, timeoutMs, maxInputBytes, maxResponseBytes) =>
11118
11229
  return;
11119
11230
  }
11120
11231
  try {
11121
- resolve34(JSON.parse(stdout));
11232
+ resolve35(JSON.parse(stdout));
11122
11233
  } catch (error) {
11123
11234
  reject(new Error(`Registry agent CLI must return one JSON object on stdout: ${error instanceof Error ? error.message : String(error)}`));
11124
11235
  }
@@ -11134,8 +11245,8 @@ var runCli = (root, cli, context, timeoutMs, maxInputBytes, maxResponseBytes) =>
11134
11245
  var loadRegistryAgentRunner = async (root, config) => {
11135
11246
  const metadata = loadRegistryAgentMetadata(root, config);
11136
11247
  const configured = registryConfig(config)?.runnerModule;
11137
- const modulePath = configured ? containedPath(root, configured) : containedPath(root, join20(metadata.root, "doc-bridge-adapter.js"));
11138
- if (!modulePath || !existsSync22(modulePath)) throw new Error(`Registry agent "${metadata.id}" has no local runner module. Configure intelligence.registry.runnerModule or add doc-bridge-adapter.js to the installed agent.`);
11248
+ const modulePath = configured ? containedPath(root, configured) : containedPath(root, join21(metadata.root, "doc-bridge-adapter.js"));
11249
+ if (!modulePath || !existsSync23(modulePath)) throw new Error(`Registry agent "${metadata.id}" has no local runner module. Configure intelligence.registry.runnerModule or add doc-bridge-adapter.js to the installed agent.`);
11139
11250
  const loaded = await import(pathToFileURL(modulePath).href);
11140
11251
  const runner = typeof loaded.run === "function" ? loaded.run : typeof loaded.default === "function" ? loaded.default : loaded.default && typeof loaded.default === "object" && "run" in loaded.default && typeof loaded.default.run === "function" ? loaded.default.run : void 0;
11141
11252
  if (!runner) throw new Error(`Registry agent runner at ${modulePath} must export a function or { run }. `);
@@ -11145,17 +11256,17 @@ var loadRegistryAgentMetadata = (root, config) => {
11145
11256
  const settings = registryConfig(config);
11146
11257
  const id = settings?.agentId ?? DEFAULT_REGISTRY_AGENT_ID;
11147
11258
  const agentRoot = settings?.agentRoot ?? "agents";
11148
- const agentPath = containedPath(root, join20(agentRoot, id));
11149
- if (!agentPath || !existsSync22(agentPath)) throw new Error(`AgentsKit Registry agent "${id}" is not installed at ${join20(agentRoot, id)}. Install it with: npx agentskit add ${id}`);
11150
- const metadataPath = [join20(agentPath, "agent.json"), join20(agentPath, "manifest.json")].find(existsSync22);
11259
+ const agentPath = containedPath(root, join21(agentRoot, id));
11260
+ if (!agentPath || !existsSync23(agentPath)) throw new Error(`AgentsKit Registry agent "${id}" is not installed at ${join21(agentRoot, id)}. Install it with: npx agentskit add ${id}`);
11261
+ const metadataPath = [join21(agentPath, "agent.json"), join21(agentPath, "manifest.json")].find(existsSync23);
11151
11262
  if (!metadataPath) throw new Error(`Registry agent "${id}" is installed but has no agent.json or manifest.json metadata.`);
11152
- const metadata = RegistryAgentMetadataSchema.parse(JSON.parse(readFileSync23(metadataPath, "utf8")));
11263
+ const metadata = RegistryAgentMetadataSchema.parse(JSON.parse(readFileSync24(metadataPath, "utf8")));
11153
11264
  if (metadata.id !== id) throw new Error(`Installed Registry agent metadata id "${metadata.id}" does not match configured id "${id}".`);
11154
11265
  return { ...metadata, root: agentPath };
11155
11266
  };
11156
11267
  var createRegistryAgentAdapter = (root, config, runner) => {
11157
11268
  if (!registryConfig(config)?.enabled) throw new Error("Registry agents are disabled. Set intelligence.registry.enabled: true to run an assisted workflow.");
11158
- const metadata = loadRegistryAgentMetadata(resolve20(root), config);
11269
+ const metadata = loadRegistryAgentMetadata(resolve21(root), config);
11159
11270
  const settings = registryConfig(config) ?? {};
11160
11271
  const timeoutMs = settings.timeoutMs ?? 12e4;
11161
11272
  const maxInputBytes = settings.maxInputBytes ?? 8e6;
@@ -11172,7 +11283,7 @@ var createRegistryAgentAdapter = (root, config, runner) => {
11172
11283
  try {
11173
11284
  let raw;
11174
11285
  if (settings.cli) {
11175
- raw = await runCli(resolve20(root), settings.cli, context, timeoutMs, maxInputBytes, maxResponseBytes);
11286
+ raw = await runCli(resolve21(root), settings.cli, context, timeoutMs, maxInputBytes, maxResponseBytes);
11176
11287
  } else {
11177
11288
  const localRunner = runner;
11178
11289
  const timeout = new Promise((_, reject) => {
@@ -11250,20 +11361,20 @@ var persistRegistryAgentProposal = (stateDir, proposal) => {
11250
11361
  AgentProposalV1Schema.parse(proposal);
11251
11362
  if (proposal.contentHash !== contentHashForArtifactV1(proposal)) throw new Error("Cannot persist a Registry agent proposal with an invalid contentHash.");
11252
11363
  const safeHash = contentHashForArtifactV1(proposal);
11253
- mkdirSync6(join20(resolve20(stateDir), "agents"), { recursive: true });
11254
- const path = join20(resolve20(stateDir), "agents", `${proposal.origin.id}-${safeHash}.json`);
11364
+ mkdirSync6(join21(resolve21(stateDir), "agents"), { recursive: true });
11365
+ const path = join21(resolve21(stateDir), "agents", `${proposal.origin.id}-${safeHash}.json`);
11255
11366
  writeFileSync7(path, `${JSON.stringify(proposal, null, 2)}
11256
11367
  `, "utf8");
11257
11368
  return path;
11258
11369
  };
11259
11370
 
11260
11371
  // src/enrich/approvals.ts
11261
- import { existsSync as existsSync23, mkdirSync as mkdirSync7, readFileSync as readFileSync24, readdirSync as readdirSync5, renameSync as renameSync4, writeFileSync as writeFileSync8 } from "fs";
11262
- import { join as join21, resolve as resolve21 } from "path";
11372
+ import { existsSync as existsSync24, mkdirSync as mkdirSync7, readFileSync as readFileSync25, readdirSync as readdirSync5, renameSync as renameSync4, writeFileSync as writeFileSync8 } from "fs";
11373
+ import { join as join22, resolve as resolve22 } from "path";
11263
11374
  var APPROVALS_DIR = ".doc-bridge/approvals";
11264
11375
  var ENRICHMENT_APPROVAL_GATE = "doc-bridge.enrichment";
11265
11376
  var FIX_APPROVAL_GATE = "doc-bridge.fix";
11266
- var approvalsDir = (root) => join21(resolve21(root), APPROVALS_DIR);
11377
+ var approvalsDir = (root) => join22(resolve22(root), APPROVALS_DIR);
11267
11378
  var safeId = (id) => {
11268
11379
  if (!/^[a-f0-9]{16,64}$/.test(id)) throw new Error(`Approval ids are content hashes; received "${id}".`);
11269
11380
  return id;
@@ -11271,7 +11382,7 @@ var safeId = (id) => {
11271
11382
  var enrichmentApprovalId = (proposalId, targetContentHash) => sha256NormalizedV1({ proposalId, targetContentHash });
11272
11383
  var fixApprovalId = (proposalId, proposalHash) => sha256NormalizedV1({ proposalId, proposalHash });
11273
11384
  var createFileApprovalStore = (dir) => {
11274
- const pathFor = (id) => join21(dir, `${safeId(id)}.json`);
11385
+ const pathFor = (id) => join22(dir, `${safeId(id)}.json`);
11275
11386
  const write = (approval) => {
11276
11387
  mkdirSync7(dir, { recursive: true });
11277
11388
  const path = pathFor(approval.id);
@@ -11282,9 +11393,9 @@ var createFileApprovalStore = (dir) => {
11282
11393
  };
11283
11394
  const read = (id) => {
11284
11395
  const path = pathFor(id);
11285
- if (!existsSync23(path)) return null;
11396
+ if (!existsSync24(path)) return null;
11286
11397
  try {
11287
- return JSON.parse(readFileSync24(path, "utf8"));
11398
+ return JSON.parse(readFileSync25(path, "utf8"));
11288
11399
  } catch {
11289
11400
  return null;
11290
11401
  }
@@ -11630,16 +11741,16 @@ var findDocPath = (index, args) => {
11630
11741
  return doc.path;
11631
11742
  };
11632
11743
  var resolveDocPath = (root, relPath) => {
11633
- const rootAbs = realpathSync9.native(root);
11634
- const unresolved = resolve22(rootAbs, relPath);
11635
- const unresolvedRel = relative10(rootAbs, unresolved);
11744
+ const rootAbs = realpathSync10.native(root);
11745
+ const unresolved = resolve23(rootAbs, relPath);
11746
+ const unresolvedRel = relative11(rootAbs, unresolved);
11636
11747
  if (unresolvedRel.startsWith("..")) throw new Error("doc.get path escapes project root");
11637
- const abs = realpathSync9.native(unresolved);
11638
- const rel = relative10(rootAbs, abs);
11748
+ const abs = realpathSync10.native(unresolved);
11749
+ const rel = relative11(rootAbs, abs);
11639
11750
  if (rel.startsWith("..")) throw new Error("doc.get path escapes project root");
11640
11751
  return abs;
11641
11752
  };
11642
- var workflowStateDir = (ctx) => resolve22(ctx.root, ctx.config.workflow?.stateDir ?? ".doc-bridge/workflow");
11753
+ var workflowStateDir = (ctx) => resolve23(ctx.root, ctx.config.workflow?.stateDir ?? ".doc-bridge/workflow");
11643
11754
  var workflowRun = (ctx) => loadWorkflowManifest(workflowStateDir(ctx));
11644
11755
  var ensureLatestRun = (ctx, runId2) => {
11645
11756
  const run2 = workflowRun(ctx);
@@ -11655,17 +11766,17 @@ var workflowReport = (ctx, runId2) => {
11655
11766
  ensureLatestRun(ctx, runId2);
11656
11767
  return parseReconciliationReport(loadWorkflowStepOutput(workflowStateDir(ctx), "reconcile"));
11657
11768
  };
11658
- var proposalPath = (ctx) => join22(ctx.root, ".doc-bridge", "proposal.json");
11769
+ var proposalPath = (ctx) => join23(ctx.root, ".doc-bridge", "proposal.json");
11659
11770
  var readSavedProposal = (ctx, input) => {
11660
11771
  if (input !== void 0) return FixProposalV1Schema.parse(input);
11661
11772
  try {
11662
- return FixProposalV1Schema.parse(JSON.parse(readFileSync25(proposalPath(ctx), "utf8")));
11773
+ return FixProposalV1Schema.parse(JSON.parse(readFileSync26(proposalPath(ctx), "utf8")));
11663
11774
  } catch {
11664
11775
  throw new Error(`No saved fix proposal at ${proposalPath(ctx)}.`);
11665
11776
  }
11666
11777
  };
11667
11778
  var saveProposal = (ctx, proposal) => {
11668
- mkdirSync8(join22(ctx.root, ".doc-bridge"), { recursive: true });
11779
+ mkdirSync8(join23(ctx.root, ".doc-bridge"), { recursive: true });
11669
11780
  writeFileSync9(proposalPath(ctx), `${JSON.stringify(proposal, null, 2)}
11670
11781
  `, "utf8");
11671
11782
  };
@@ -11728,7 +11839,7 @@ var handleMcpRequest = (ctx, request) => {
11728
11839
  }
11729
11840
  if (name === "doc.get") {
11730
11841
  const relPath = findDocPath(index(), parseToolArgs("doc.get", DocGetArgsSchema, args));
11731
- return textResult(readFileSync25(resolveDocPath(ctx.root, relPath), "utf8"));
11842
+ return textResult(readFileSync26(resolveDocPath(ctx.root, relPath), "utf8"));
11732
11843
  }
11733
11844
  if (name === "gate.status") return textResult(runGates(ctx.root, ctx.config));
11734
11845
  if (name === "retriever.query") {
@@ -12507,7 +12618,7 @@ var studyRetrievalSuite = (options) => {
12507
12618
  continue;
12508
12619
  }
12509
12620
  const targets = byRepository.get(task.repositoryId);
12510
- const resolve34 = (references, kind) => references.flatMap((item) => {
12621
+ const resolve35 = (references, kind) => references.flatMap((item) => {
12511
12622
  const resolved = targets?.[item];
12512
12623
  if (!resolved?.length) {
12513
12624
  unresolved.push({ taskId: task.id, repositoryId: task.repositoryId, reference: item, kind });
@@ -12516,7 +12627,7 @@ var studyRetrievalSuite = (options) => {
12516
12627
  return resolved;
12517
12628
  });
12518
12629
  const expectedTargets = [
12519
- .../* @__PURE__ */ new Set([...resolve34(task.expectedEntities ?? [], "entity"), ...resolve34(task.expectedDocuments ?? [], "document")])
12630
+ .../* @__PURE__ */ new Set([...resolve35(task.expectedEntities ?? [], "entity"), ...resolve35(task.expectedDocuments ?? [], "document")])
12520
12631
  ].sort();
12521
12632
  if (!expectedTargets.length) continue;
12522
12633
  const queries = taskRetrievalQueries(task);
@@ -13070,11 +13181,11 @@ var reconcileKnowledge = (observed, declared, options = {}) => {
13070
13181
  };
13071
13182
 
13072
13183
  // src/enrich/stage.ts
13073
- import { basename as basename8, resolve as resolve24 } from "path";
13184
+ import { basename as basename8, resolve as resolve25 } from "path";
13074
13185
 
13075
13186
  // src/enrich/cache.ts
13076
- import { existsSync as existsSync24, mkdirSync as mkdirSync9, readFileSync as readFileSync26, renameSync as renameSync5, writeFileSync as writeFileSync10 } from "fs";
13077
- import { join as join23 } from "path";
13187
+ import { existsSync as existsSync25, mkdirSync as mkdirSync9, readFileSync as readFileSync27, renameSync as renameSync5, writeFileSync as writeFileSync10 } from "fs";
13188
+ import { join as join24 } from "path";
13078
13189
  import { z as z19 } from "zod";
13079
13190
  var enrichmentCacheKey = (input) => sha256NormalizedV1({ task: input.task, agentId: input.agentId, agentVersion: input.agentVersion, promptVersion: input.promptVersion, packHash: input.packHash });
13080
13191
  var CacheEntrySchema = z19.object({
@@ -13089,14 +13200,14 @@ var CacheEntrySchema = z19.object({
13089
13200
  }).strict();
13090
13201
  var createEnrichmentCache = (root) => {
13091
13202
  const dir = enrichmentCacheDir(root);
13092
- const pathFor = (key) => join23(dir, `${key}.json`);
13203
+ const pathFor = (key) => join24(dir, `${key}.json`);
13093
13204
  return {
13094
13205
  read: (input) => {
13095
13206
  const key = enrichmentCacheKey(input);
13096
13207
  const path = pathFor(key);
13097
- if (!existsSync24(path)) return void 0;
13208
+ if (!existsSync25(path)) return void 0;
13098
13209
  try {
13099
- const entry = CacheEntrySchema.parse(JSON.parse(readFileSync26(path, "utf8")));
13210
+ const entry = CacheEntrySchema.parse(JSON.parse(readFileSync27(path, "utf8")));
13100
13211
  return entry.key === key && entry.packHash === input.packHash && entry.agentId === input.agentId ? entry.proposals : void 0;
13101
13212
  } catch {
13102
13213
  return void 0;
@@ -13117,8 +13228,8 @@ var createEnrichmentCache = (root) => {
13117
13228
  };
13118
13229
 
13119
13230
  // src/enrich/context-pack.ts
13120
- import { readFileSync as readFileSync27 } from "fs";
13121
- import { join as join24, resolve as resolve23 } from "path";
13231
+ import { readFileSync as readFileSync28 } from "fs";
13232
+ import { join as join25, resolve as resolve24 } from "path";
13122
13233
  var CONTEXT_PACK_VERSION = 1;
13123
13234
  var DEFAULT_PACK_BYTES = 64 * 1024;
13124
13235
  var MAX_PACK_NEIGHBOURS = 32;
@@ -13142,7 +13253,7 @@ var boundedMetadata = (metadata) => {
13142
13253
  var defaultReader = (root) => (path) => {
13143
13254
  if (!root) return void 0;
13144
13255
  try {
13145
- return readFileSync27(join24(resolve23(root), path), "utf8");
13256
+ return readFileSync28(join25(resolve24(root), path), "utf8");
13146
13257
  } catch {
13147
13258
  return void 0;
13148
13259
  }
@@ -13321,7 +13432,7 @@ var registryAgent = async (root, config) => {
13321
13432
  };
13322
13433
  return {
13323
13434
  call: async ({ role, task, packs }) => (await adapterFor(role.agentId)).enrich(task, packs, { role: role.role, promptVersion: role.promptVersion }),
13324
- version: (role) => loadRegistryAgentMetadata(resolve24(root), configWithAgent(config, role.agentId)).version
13435
+ version: (role) => loadRegistryAgentMetadata(resolve25(root), configWithAgent(config, role.agentId)).version
13325
13436
  };
13326
13437
  };
13327
13438
  var overlayBase = (options) => ({
@@ -13864,7 +13975,7 @@ const findingMatches=(finding)=>{const query=state.query.toLowerCase();return(!q
13864
13975
  const findingScope=(finding)=>data.view?.diagnosticGroup?.[finding.id]?.[0]||(()=>{const ids=[...(finding.entityIds||[])];(finding.relationIds||[]).forEach((id)=>{const relation=relationById.get(id);if(relation)ids.push(relation.from,relation.to)});return ids.map(groupFor).sort()[0]||"repository"})();
13865
13976
  const findingGroups=(findings)=>{const groups=new Map();findings.forEach((finding)=>{const scope=findingScope(finding),key=[scope,finding.code,finding.status,finding.severity].join("|"),group=groups.get(key)||{key,scope,code:finding.code,status:finding.status,severity:finding.severity,findings:[]};group.findings.push(finding);groups.set(key,group)});return[...groups.values()].sort((left,right)=>right.findings.length-left.findings.length||left.code.localeCompare(right.code)||left.key.localeCompare(right.key))};
13866
13977
  const renderFinding=(finding)=>"<article class=\"finding\" id=\""+esc("diagnostic-"+finding.id.replace(/[^A-Za-z0-9_-]+/g,"-"))+"\"><div class=\"finding-head\"><h3>"+esc(finding.code)+"</h3><span><span class=\"tag "+esc(finding.severity)+"\">"+esc(finding.severity)+"</span> <span class=\"tag\">"+esc(finding.status)+"</span></span></div><p>"+esc(finding.message)+"</p>"+(finding.evidence.length?"<ul>"+finding.evidence.slice(0,4).map((item)=>"<li>"+esc(item.path+(item.lineStart?":"+item.lineStart:"")+(item.context?" — "+item.context:""))+"</li>").join("")+"</ul>":"")+(finding.remediation?"<p><strong>Next check:</strong> "+esc(finding.remediation)+"</p>":"")+"</article>";
13867
- const renderFindings=()=>{let findings=data.diagnostics.filter(findingMatches);if(state.lens==="risks")findings=findings.filter((finding)=>finding.severity==="error"||finding.severity==="warn");if(state.lens==="evidence")findings=findings.filter((finding)=>finding.evidence.length);if(state.lens==="drift")findings=findings.filter((finding)=>finding.status!=="confirmed");const itemLabel=state.lens==="evidence"?"evidence checks":"findings",groups=findingGroups(findings),active=groups.find((group)=>group.key===state.findingGroup);if(!active){state.findingGroup=null;state.findingPage=0}syncHash();const selected=active||null,pageSize=40,pageCount=selected?Math.ceil(selected.findings.length/pageSize):0,page=Math.max(0,Math.min(state.findingPage,Math.max(0,pageCount-1))),start=page*pageSize;document.querySelector("#finding-count").textContent=findings.length+" "+itemLabel+" · "+groups.length+" groups";document.querySelector("#findings").innerHTML=findings.length?"<div class=\"finding-groups\">"+groups.map((group)=>"<article class=\"finding-group\"><div class=\"finding-head\"><h3>"+esc(group.code)+"</h3><span><span class=\"tag "+esc(group.severity)+"\">"+esc(group.severity)+"</span> <span class=\"tag\">"+esc(group.status)+"</span></span></div><p><strong>"+group.findings.length+"</strong> "+itemLabel+" · "+esc(groupById.get(group.scope)?.name||group.scope)+"</p><p>"+esc(group.findings[0].message)+"</p><button class=\"tab\" type=\"button\" data-finding-group=\""+esc(group.key)+"\" aria-expanded=\""+String(selected?.key===group.key)+"\">Inspect group</button></article>").join("")+"</div>"+(selected?"<div class=\"finding-detail\"><div class=\"finding-head\"><h3>"+esc(selected.code)+" · "+esc(groupById.get(selected.scope)?.name||selected.scope)+"</h3><span class=\"subtle\">"+selected.findings.length+" "+itemLabel+"</span></div>"+selected.findings.slice(start,start+pageSize).map(renderFinding).join("")+"<div class=\"finding-actions\"><button class=\"tab\" type=\"button\" data-finding-group=\""+esc(selected.key)+"\" data-finding-page=\""+(page-1)+"\" "+(page===0?"disabled":"")+">Previous</button><span class=\"subtle\">Showing "+(start+1)+"–"+Math.min(start+pageSize,selected.findings.length)+" of "+selected.findings.length+" · page "+(page+1)+"/"+pageCount+"</span><button class=\"tab\" type=\"button\" data-finding-group=\""+esc(selected.key)+"\" data-finding-page=\""+(page+1)+"\" "+(page+1>=pageCount?"disabled":"")+">Next</button></div></div>":""):"<p class=\"empty\">No "+itemLabel+" match the current lens and filters.</p>"};
13978
+ const renderFindings=()=>{let findings=data.diagnostics.filter(findingMatches);if(state.lens==="risks")findings=findings.filter((finding)=>finding.severity==="error"||finding.severity==="warn");if(state.lens==="evidence")findings=findings.filter((finding)=>finding.evidence.length);if(state.lens==="drift")findings=findings.filter((finding)=>finding.status!=="confirmed");const itemLabel=state.lens==="evidence"?"evidence checks":"findings",groups=findingGroups(findings),active=groups.find((group)=>group.key===state.findingGroup);if(!active){state.findingGroup=null;state.findingPage=0}syncHash();const selected=active||null,pageSize=40,pageCount=selected?Math.ceil(selected.findings.length/pageSize):0,page=Math.max(0,Math.min(state.findingPage,Math.max(0,pageCount-1))),start=page*pageSize;document.querySelector("#finding-count").textContent=findings.length+" "+itemLabel+" · "+groups.length+" groups";document.querySelector("#findings").innerHTML=findings.length?"<div class=\"finding-groups\">"+groups.map((group)=>"<article class=\"finding-group\"><div class=\"finding-head\"><h3>"+esc(group.code)+"</h3><span><span class=\"tag "+esc(group.severity)+"\">"+esc(group.severity)+"</span> <span class=\"tag\">"+esc(group.status)+"</span></span></div><p><strong>"+group.findings.length+"</strong> "+itemLabel+" · "+esc(groupById.get(group.scope)?.name||group.scope)+"</p><p>"+esc(group.findings[0].message)+"</p><button class=\"tab\" type=\"button\" data-finding-group=\""+esc(group.key)+"\" aria-expanded=\""+String(selected?.key===group.key)+"\">Inspect group</button></article>").join("")+"</div>"+(selected?"<div class=\"finding-detail\"><div class=\"finding-head\"><h3>"+esc(selected.code)+" · "+esc(groupById.get(selected.scope)?.name||selected.scope)+"</h3><span class=\"subtle\">"+selected.findings.length+" "+itemLabel+"</span></div>"+selected.findings.slice(start,start+pageSize).map(renderFinding).join("")+"<div class=\"finding-actions\"><button class=\"tab\" type=\"button\" data-finding-group=\""+esc(selected.key)+"\" data-finding-page=\""+(page - 1)+"\" "+(page===0?"disabled":"")+">Previous</button><span class=\"subtle\">Showing "+(start+1)+"–"+Math.min(start+pageSize,selected.findings.length)+" of "+selected.findings.length+" · page "+(page+1)+"/"+pageCount+"</span><button class=\"tab\" type=\"button\" data-finding-group=\""+esc(selected.key)+"\" data-finding-page=\""+(page+1)+"\" "+(page+1>=pageCount?"disabled":"")+">Next</button></div></div>":""):"<p class=\"empty\">No "+itemLabel+" match the current lens and filters.</p>"};
13868
13979
  const renderCoverage=()=>{document.querySelector("#coverage-list").innerHTML=(data.coverage||[]).map((entry)=>{const width=entry.status==="complete"?100:entry.status==="partial"?55:12;return"<div class=\"coverage-row\"><div><b>"+esc(entry.analyzer)+"</b><br><span class=\"subtle\">"+esc(entry.scope)+"</span></div><div class=\"bar\"><i class=\""+(entry.status==="complete"?"":entry.status==="partial"?"partial":"none")+"\" style=\"width:"+width+"%\"></i></div><div>"+esc(entry.status)+"</div></div>"}).join("")||"<p class=\"empty\">No coverage metadata.</p>"};
13869
13980
  const deferFindings=()=>{if(findingsLoaded())return;const actionable=data.actionableCount??data.diagnosticCount??0,confirmed=data.confirmedCount??0;document.querySelector("#finding-count").textContent=actionable+" actionable findings · "+confirmed+" confirmed checks available on demand";document.querySelector("#findings").innerHTML="<div class=\"empty\"><p>Findings stay out of the first paint so large repositories remain responsive. Confirmed checks are evidence, not issues.</p><button id=\"load-findings\" class=\"tab\" type=\"button\">Load findings</button></div>"};
13870
13981
  const scopePrompt=()=>{if((state.level==="module"||state.level==="file")&&!state.selected){document.querySelector("#map-note").textContent="Select an app or package to inspect this level.";document.querySelector("#graph").innerHTML="<text x=\"500\" y=\"270\" text-anchor=\"middle\" class=\"subtle\">Select an app or package to expand this view.</text>"}};
@@ -14099,8 +14210,8 @@ var formatBenchmarkText = (result) => [
14099
14210
  ].join("\n");
14100
14211
 
14101
14212
  // src/audit/documentation.ts
14102
- import { readFileSync as readFileSync28 } from "fs";
14103
- import { resolve as resolve25 } from "path";
14213
+ import { readFileSync as readFileSync29 } from "fs";
14214
+ import { resolve as resolve26 } from "path";
14104
14215
  import { minimatch as minimatch7 } from "minimatch";
14105
14216
 
14106
14217
  // src/render/data.ts
@@ -14508,7 +14619,7 @@ var auditDocumentation = (options) => {
14508
14619
  const generatedPaths = config.generatedPaths ?? [];
14509
14620
  const criticalPaths = config.criticalPaths ?? [];
14510
14621
  const requiredSections = config.requiredSections ?? [];
14511
- const documents = options.snapshot.entities.filter((entity) => entity.kind === "document" && entity.path).map((entity) => ({ path: normalizedPath2(entity.path), content: readFileSync28(resolve25(options.root, entity.path), "utf8") })).filter((document) => !matches(document.path, excluded)).sort((a, b) => a.path.localeCompare(b.path));
14622
+ const documents = options.snapshot.entities.filter((entity) => entity.kind === "document" && entity.path).map((entity) => ({ path: normalizedPath2(entity.path), content: readFileSync29(resolve26(options.root, entity.path), "utf8") })).filter((document) => !matches(document.path, excluded)).sort((a, b) => a.path.localeCompare(b.path));
14512
14623
  const findings = [];
14513
14624
  const generated = documents.filter((document) => matches(document.path, generatedPaths));
14514
14625
  const analyzed = documents.filter((document) => !matches(document.path, generatedPaths));
@@ -14730,8 +14841,8 @@ var formatDocumentationAuditText = (report) => [
14730
14841
  ];
14731
14842
 
14732
14843
  // src/render/render.ts
14733
- import { existsSync as existsSync25, mkdirSync as mkdirSync10, readFileSync as readFileSync29, writeFileSync as writeFileSync11 } from "fs";
14734
- import { dirname as dirname10, join as join25, relative as relative11, resolve as resolve26 } from "path";
14844
+ import { existsSync as existsSync26, mkdirSync as mkdirSync10, readFileSync as readFileSync30, writeFileSync as writeFileSync11 } from "fs";
14845
+ import { dirname as dirname11, join as join26, relative as relative12, resolve as resolve27 } from "path";
14735
14846
  var OPEN_PLACEHOLDER = "@@doc-bridge:generated-open@@";
14736
14847
  var CLOSE_PLACEHOLDER = "@@doc-bridge:generated-close@@";
14737
14848
  var REGION_VARIABLES = { open: OPEN_PLACEHOLDER, close: CLOSE_PLACEHOLDER };
@@ -14764,8 +14875,8 @@ var renderPage = (name, variables, config, root) => {
14764
14875
  const output = renderNamedTemplate(name, { ...variables, region: REGION_VARIABLES }, config, root);
14765
14876
  return RENDER_TEMPLATES[name].generatedRegion ? applyGeneratedRegions(output, name) : output;
14766
14877
  };
14767
- var readJson3 = (root, path) => JSON.parse(readFileSync29(resolve26(root, path), "utf8"));
14768
- var stateDirOf = (root, config) => resolve26(root, config.workflow?.stateDir ?? ".doc-bridge/workflow");
14878
+ var readJson3 = (root, path) => JSON.parse(readFileSync30(resolve27(root, path), "utf8"));
14879
+ var stateDirOf = (root, config) => resolve27(root, config.workflow?.stateDir ?? ".doc-bridge/workflow");
14769
14880
  var loadIndex = (options) => options.dataPath ? parseDocBridgeIndex(readJson3(options.root, options.dataPath)) : buildDocBridgeIndex({ root: options.root, config: options.config, write: false }).index;
14770
14881
  var loadReconciliation = (root, config) => {
14771
14882
  try {
@@ -14788,7 +14899,7 @@ var loadPreviousSnapshot = (options) => {
14788
14899
  };
14789
14900
  var DEFAULT_OVERLAY_PATH = ".doc-bridge/enrich/overlay.json";
14790
14901
  var loadOverlay = (options) => {
14791
- const path = options.dataPath ?? (existsSync25(resolve26(options.root, DEFAULT_OVERLAY_PATH)) ? DEFAULT_OVERLAY_PATH : void 0);
14902
+ const path = options.dataPath ?? (existsSync26(resolve27(options.root, DEFAULT_OVERLAY_PATH)) ? DEFAULT_OVERLAY_PATH : void 0);
14792
14903
  if (!path) return { overlay: void 0 };
14793
14904
  const value = readJson3(options.root, path);
14794
14905
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${path} is not an overlay object.`);
@@ -14839,20 +14950,20 @@ var writeRenderedPages = (result, target2, root) => {
14839
14950
  const single = result.pages.length === 1 && !RENDER_TEMPLATES[result.template].multiPage;
14840
14951
  const written = [];
14841
14952
  const write = (path, content) => {
14842
- mkdirSync10(dirname10(path), { recursive: true });
14953
+ mkdirSync10(dirname11(path), { recursive: true });
14843
14954
  writeFileSync11(path, content, "utf8");
14844
- return toPosix(relative11(root, path));
14955
+ return toPosix(relative12(root, path));
14845
14956
  };
14846
14957
  for (const page of result.pages) {
14847
14958
  if (!single) {
14848
- written.push(write(join25(target2, page.path), page.content));
14959
+ written.push(write(join26(target2, page.path), page.content));
14849
14960
  continue;
14850
14961
  }
14851
14962
  try {
14852
14963
  written.push(write(target2, page.content));
14853
14964
  } catch (error) {
14854
14965
  if (error.code !== "EISDIR") throw error;
14855
- written.push(write(join25(target2, page.path), page.content));
14966
+ written.push(write(join26(target2, page.path), page.content));
14856
14967
  }
14857
14968
  }
14858
14969
  return written;
@@ -14925,8 +15036,8 @@ Global flags:
14925
15036
  `;
14926
15037
 
14927
15038
  // src/parity/check.ts
14928
- import { existsSync as existsSync27, readFileSync as readFileSync31 } from "fs";
14929
- import { resolve as resolve28 } from "path";
15039
+ import { existsSync as existsSync28, readFileSync as readFileSync32 } from "fs";
15040
+ import { resolve as resolve29 } from "path";
14930
15041
  import { z as z23 } from "zod";
14931
15042
 
14932
15043
  // src/parity/claims.ts
@@ -15073,9 +15184,9 @@ var claimPattern = (claim, surface) => {
15073
15184
  var renderClaim = (claim, value, surface) => (surface === void 0 ? claim.template ?? "{value}" : templateFor(claim, surface)).replace("{value}", value);
15074
15185
 
15075
15186
  // src/parity/resolve.ts
15076
- import { existsSync as existsSync26, readFileSync as readFileSync30 } from "fs";
15077
- import { resolve as resolve27 } from "path";
15078
- var readJson4 = (path) => JSON.parse(readFileSync30(path, "utf8"));
15187
+ import { existsSync as existsSync27, readFileSync as readFileSync31 } from "fs";
15188
+ import { resolve as resolve28 } from "path";
15189
+ var readJson4 = (path) => JSON.parse(readFileSync31(path, "utf8"));
15079
15190
  var dotted = (value, field) => field.split(".").reduce((current, key) => {
15080
15191
  if (current === null || typeof current !== "object") return void 0;
15081
15192
  return current[key];
@@ -15127,20 +15238,20 @@ var resolveClaim = (claim, context) => {
15127
15238
  const evidence2 = claim.evidence;
15128
15239
  switch (evidence2.kind) {
15129
15240
  case "package-field": {
15130
- const path = resolve27(context.root, "package.json");
15131
- if (!existsSync26(path)) return { status: "not-analyzed", reason: "package.json is not present." };
15241
+ const path = resolve28(context.root, "package.json");
15242
+ if (!existsSync27(path)) return { status: "not-analyzed", reason: "package.json is not present." };
15132
15243
  const value = scalar2(dotted(readJson4(path), evidence2.field), void 0);
15133
15244
  return value === void 0 ? { status: "not-analyzed", reason: `package.json has no scalar field "${evidence2.field}".` } : { status: "resolved", value };
15134
15245
  }
15135
15246
  case "artifact-field": {
15136
- const path = resolve27(context.root, evidence2.path);
15137
- if (!existsSync26(path)) return { status: "not-analyzed", reason: `${evidence2.path} is not present.` };
15247
+ const path = resolve28(context.root, evidence2.path);
15248
+ if (!existsSync27(path)) return { status: "not-analyzed", reason: `${evidence2.path} is not present.` };
15138
15249
  const value = scalar2(dotted(readJson4(path), evidence2.field), evidence2.transform);
15139
15250
  return value === void 0 ? { status: "not-analyzed", reason: `${evidence2.path} has no scalar field "${evidence2.field}" that renders under ${evidence2.transform ?? "identity"}.` } : { status: "resolved", value };
15140
15251
  }
15141
15252
  case "artifact-sum": {
15142
- const path = resolve27(context.root, evidence2.path);
15143
- if (!existsSync26(path)) return { status: "not-analyzed", reason: `${evidence2.path} is not present.` };
15253
+ const path = resolve28(context.root, evidence2.path);
15254
+ if (!existsSync27(path)) return { status: "not-analyzed", reason: `${evidence2.path} is not present.` };
15144
15255
  const array = dotted(readJson4(path), evidence2.arrayField);
15145
15256
  if (!Array.isArray(array) || array.length === 0) {
15146
15257
  return { status: "not-analyzed", reason: `${evidence2.path} has no non-empty array at "${evidence2.arrayField}".` };
@@ -15249,8 +15360,8 @@ var occurrences = (claim, surface, content) => {
15249
15360
  var checkPublicParity = (options) => {
15250
15361
  const { registry } = options;
15251
15362
  const read = options.readSurface ?? ((path) => {
15252
- const absolute = resolve28(options.root, path);
15253
- return existsSync27(absolute) ? readFileSync31(absolute, "utf8") : void 0;
15363
+ const absolute = resolve29(options.root, path);
15364
+ return existsSync28(absolute) ? readFileSync32(absolute, "utf8") : void 0;
15254
15365
  });
15255
15366
  const surfaces2 = claimSurfaces(registry);
15256
15367
  const contents = new Map(surfaces2.map((surface) => [surface, read(surface)]));
@@ -15395,12 +15506,12 @@ var formatPublicParityText = (report) => [
15395
15506
  import { spawn as spawn2 } from "child_process";
15396
15507
  import { createHash as createHash3 } from "crypto";
15397
15508
  import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync12 } from "fs";
15398
- import { dirname as dirname11, resolve as resolve30 } from "path";
15509
+ import { dirname as dirname12, resolve as resolve31 } from "path";
15399
15510
  import { z as z25 } from "zod";
15400
15511
 
15401
15512
  // src/study/provider-cli.ts
15402
- import { accessSync, constants, existsSync as existsSync28, statSync as statSync3 } from "fs";
15403
- import { isAbsolute as isAbsolute6, resolve as resolve29 } from "path";
15513
+ import { accessSync, constants, existsSync as existsSync29, statSync as statSync3 } from "fs";
15514
+ import { isAbsolute as isAbsolute7, resolve as resolve30 } from "path";
15404
15515
  import { z as z24 } from "zod";
15405
15516
  var STUDY_PROVIDER_CLI_SCHEMA_VERSION = 1;
15406
15517
  var STUDY_PROVIDER_CLI_CONTENT_HASH_ALGO = "sha256-normalized-v1";
@@ -15470,9 +15581,9 @@ var calculateStudyCostUsd = (pricing2, usage2) => {
15470
15581
  return Number(((uncachedInputTokens * pricing2.inputPerMillionUsd + cachedInputTokens * pricing2.cachedInputPerMillionUsd + usage2.outputTokens * pricing2.outputPerMillionUsd) / 1e6).toFixed(8));
15471
15582
  };
15472
15583
  var validateStudyProviderCommand = (provider, cwd) => {
15473
- if (isAbsolute6(provider.command) || provider.command.includes("/")) {
15474
- const resolvedPath = isAbsolute6(provider.command) ? provider.command : resolve29(cwd, provider.command);
15475
- if (!existsSync28(resolvedPath) || !statSync3(resolvedPath).isFile()) throw new Error(`Provider CLI command is not executable at ${resolvedPath}.`);
15584
+ if (isAbsolute7(provider.command) || provider.command.includes("/")) {
15585
+ const resolvedPath = isAbsolute7(provider.command) ? provider.command : resolve30(cwd, provider.command);
15586
+ if (!existsSync29(resolvedPath) || !statSync3(resolvedPath).isFile()) throw new Error(`Provider CLI command is not executable at ${resolvedPath}.`);
15476
15587
  try {
15477
15588
  accessSync(resolvedPath, constants.X_OK);
15478
15589
  } catch {
@@ -15483,7 +15594,7 @@ var validateStudyProviderCommand = (provider, cwd) => {
15483
15594
  const pathEntries = (process.env.PATH ?? "").split(":").filter(Boolean);
15484
15595
  if (pathEntries.some((entry) => {
15485
15596
  try {
15486
- accessSync(resolve29(entry, provider.command), constants.X_OK);
15597
+ accessSync(resolve30(entry, provider.command), constants.X_OK);
15487
15598
  return true;
15488
15599
  } catch {
15489
15600
  return false;
@@ -15738,7 +15849,7 @@ var runAttempt = (request, sessionId) => new Promise((resolveAttempt) => {
15738
15849
  const maxRuntimeMs = request.maxRuntimeMs ?? request.plan.budget.maxRuntimeMs;
15739
15850
  const maxOutputBytes = request.maxOutputBytes ?? request.plan.budget.maxOutputBytes;
15740
15851
  const child = spawn2(request.command, [...request.args ?? []], {
15741
- cwd: resolve30(request.cwd),
15852
+ cwd: resolve31(request.cwd),
15742
15853
  shell: false,
15743
15854
  detached: true,
15744
15855
  env: { ...env, DOC_BRIDGE_STUDY_SESSION_ID: sessionId },
@@ -15866,10 +15977,10 @@ var runControlledCommand = async (request) => {
15866
15977
  };
15867
15978
  var persistControlledStudyLedger = (path, ledger) => {
15868
15979
  parseControlledStudyLedger(ledger);
15869
- mkdirSync11(dirname11(resolve30(path)), { recursive: true });
15870
- writeFileSync12(resolve30(path), `${JSON.stringify(ledger, null, 2)}
15980
+ mkdirSync11(dirname12(resolve31(path)), { recursive: true });
15981
+ writeFileSync12(resolve31(path), `${JSON.stringify(ledger, null, 2)}
15871
15982
  `, "utf8");
15872
- return resolve30(path);
15983
+ return resolve31(path);
15873
15984
  };
15874
15985
  var formatControlledStudyRunPlanText = (plan) => [
15875
15986
  `Run plan: ${plan.planVersion}`,
@@ -15882,8 +15993,8 @@ var formatControlledStudyRunPlanText = (plan) => [
15882
15993
  ];
15883
15994
 
15884
15995
  // src/study/execution.ts
15885
- import { existsSync as existsSync29, readFileSync as readFileSync32, statSync as statSync4 } from "fs";
15886
- import { resolve as resolve31 } from "path";
15996
+ import { existsSync as existsSync30, readFileSync as readFileSync33, statSync as statSync4 } from "fs";
15997
+ import { resolve as resolve32 } from "path";
15887
15998
  import { z as z26 } from "zod";
15888
15999
  var PROVIDER_RESPONSE_CONTRACT = "Return one JSON object matching the output schema. Required keys: taskOutcome, evidenceQuality, safetyOutcome, evidenceIds, clarificationRequests, reworkCount, and measurements. Each measurement is {name:string,value:number>=0}. Run every available acceptance check and report observed acceptanceChecksPassed, acceptanceChecksTotal, and acceptanceChecksExecuted; include firstEvidenceLatencyMs only when observed. Use canonical names when observed: tokensToFirstEvidence (tokens consumed before correct grounded evidence was in hand), registryAgentInputTokens, registryAgentOutputTokens, registryAgentCostUsd, registryAgentRuns (the enrichment agent of the assisted arm, reported apart from your own cost), searchHitRate, acceptanceChecksPassed, acceptanceChecksTotal, acceptanceChecksExecuted, entrypointEvidenceCount, ownershipEvidenceCount, architectureRelationCount, documentationClaimEvidenceCount, sourceComparisonEvidenceCount, verificationEvidenceCount, errorRate, documentationFindingCount, documentationExampleRate, documentationFreshnessRate, documentationCorrectnessRate, documentationCompletenessRate, documentationClarityRate, documentationMaintainabilityRate, timeToFirstEvidenceMs, analysisCostUsd, and agentCostUsd. Omit unknown values; never invent. Output no markdown, prose, logs, token counts, or extra keys; stdout must contain only the JSON object.";
15889
16000
  var STUDY_REPOSITORY_CONFIG_SCHEMA_VERSION = 1;
@@ -15917,8 +16028,8 @@ var emptyLedger2 = () => createControlledStudyLedger({
15917
16028
  observations: []
15918
16029
  });
15919
16030
  var loadLedger = (path) => {
15920
- if (!existsSync29(path)) return emptyLedger2();
15921
- return parseControlledStudyLedger(JSON.parse(readFileSync32(path, "utf8")));
16031
+ if (!existsSync30(path)) return emptyLedger2();
16032
+ return parseControlledStudyLedger(JSON.parse(readFileSync33(path, "utf8")));
15922
16033
  };
15923
16034
  var executionKey = (execution) => sha256NormalizedV1({
15924
16035
  taskId: execution.taskId,
@@ -15999,8 +16110,8 @@ var assertRunInputs = (options) => {
15999
16110
  throw new Error("Study repository config must contain exactly one root for every task-suite population id.");
16000
16111
  }
16001
16112
  for (const repository of options.repositories.repositories) {
16002
- const root = resolve31(repository.root);
16003
- if (!existsSync29(root) || !statSync4(root).isDirectory()) throw new Error(`Study repository ${repository.id} is not available at the configured root.`);
16113
+ const root = resolve32(repository.root);
16114
+ if (!existsSync30(root) || !statSync4(root).isDirectory()) throw new Error(`Study repository ${repository.id} is not available at the configured root.`);
16004
16115
  }
16005
16116
  const executions = selectTaskExecutions(options.suite, options.plan.sampling.sampleSize, options.plan.sampling);
16006
16117
  const assisted = assistedArmReadiness(options.plan, options.providers, options.suite);
@@ -16046,7 +16157,7 @@ var runControlledStudy = async (options) => {
16046
16157
  repositoryConfigHash: repositories.contentHash,
16047
16158
  assistedArm: { ...assisted, recorded: 0 }
16048
16159
  };
16049
- let ledger = loadLedger(resolve31(options.ledgerPath));
16160
+ let ledger = loadLedger(resolve32(options.ledgerPath));
16050
16161
  if (ledger.observations.some((observation) => observation.runId === plan.runId && observation.planHash !== plan.contentHash)) throw new Error(`Ledger already contains run ${plan.runId} with a different plan hash.`);
16051
16162
  let executed = 0;
16052
16163
  let skipped = 0;
@@ -16105,7 +16216,7 @@ var runControlledStudy = async (options) => {
16105
16216
  planned: executions.length,
16106
16217
  executed,
16107
16218
  skipped,
16108
- ledgerPath: resolve31(options.ledgerPath),
16219
+ ledgerPath: resolve32(options.ledgerPath),
16109
16220
  ledgerHash: ledger.contentHash,
16110
16221
  providerConfigHash: providers.contentHash,
16111
16222
  repositoryConfigHash: repositories.contentHash,
@@ -16129,7 +16240,7 @@ var formatControlledStudyRunText = (summary) => [
16129
16240
  import { spawn as spawn3 } from "child_process";
16130
16241
  import { createHash as createHash4 } from "crypto";
16131
16242
  import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync13 } from "fs";
16132
- import { dirname as dirname12, resolve as resolve32 } from "path";
16243
+ import { dirname as dirname13, resolve as resolve33 } from "path";
16133
16244
  import { z as z27 } from "zod";
16134
16245
  var STUDY_ADJUDICATION_METHOD = "independent-rubric-v1";
16135
16246
  var outcome2 = z27.enum(["success", "partial", "incorrect", "incomplete", "blocked"]);
@@ -16156,7 +16267,7 @@ var terminate = (child) => {
16156
16267
  var runAdjudicatorProcess = (config, cwd, input, maxRuntimeMs) => new Promise((resolveResult) => {
16157
16268
  const env = Object.fromEntries([.../* @__PURE__ */ new Set(["PATH", "HOME", "TMPDIR", ...config.envAllowlist])].flatMap((name) => process.env[name] === void 0 ? [] : [[name, process.env[name]]]));
16158
16269
  const started = Date.now();
16159
- const child = spawn3(config.command, [...config.args], { cwd: resolve32(cwd), shell: false, detached: true, env, stdio: ["pipe", "pipe", "pipe"] });
16270
+ const child = spawn3(config.command, [...config.args], { cwd: resolve33(cwd), shell: false, detached: true, env, stdio: ["pipe", "pipe", "pipe"] });
16160
16271
  let stdout = "";
16161
16272
  let stderrBytes = 0;
16162
16273
  let settled = false;
@@ -16294,10 +16405,10 @@ var independentlyAdjudicateStudyLedger = async (options) => {
16294
16405
  };
16295
16406
  var persistIndependentlyAdjudicatedLedger = (path, ledger) => {
16296
16407
  parseControlledStudyLedger(ledger);
16297
- mkdirSync12(dirname12(resolve32(path)), { recursive: true });
16298
- writeFileSync13(resolve32(path), `${JSON.stringify(ledger, null, 2)}
16408
+ mkdirSync12(dirname13(resolve33(path)), { recursive: true });
16409
+ writeFileSync13(resolve33(path), `${JSON.stringify(ledger, null, 2)}
16299
16410
  `, "utf8");
16300
- return resolve32(path);
16411
+ return resolve33(path);
16301
16412
  };
16302
16413
 
16303
16414
  // src/study/metrics.ts
@@ -17028,12 +17139,12 @@ var readIndexedDoc = (root, config, idOrPath) => {
17028
17139
  const index = loadFreshDocBridgeIndex(root, config);
17029
17140
  const entry = index.knowledge.find((doc) => doc.id === idOrPath || doc.path === idOrPath);
17030
17141
  if (!entry) throw new Error(`Unknown indexed doc "${idOrPath}". Try: search ${idOrPath}`);
17031
- const abs = resolve33(root, entry.path);
17032
- const rootAbs = resolve33(root);
17142
+ const abs = resolve34(root, entry.path);
17143
+ const rootAbs = resolve34(root);
17033
17144
  if (abs !== rootAbs && !abs.startsWith(`${rootAbs}/`)) {
17034
17145
  throw new Error(`Indexed doc escapes project root: ${entry.path}`);
17035
17146
  }
17036
- return readFileSync33(abs, "utf8");
17147
+ return readFileSync34(abs, "utf8");
17037
17148
  };
17038
17149
  var runAskRepl = async (root, config) => {
17039
17150
  const index = loadFreshDocBridgeIndex(root, config);
@@ -17137,7 +17248,7 @@ var scanWorkflow = (root, config) => {
17137
17248
  runWorkflow(workflowOptions(root, config, discovered.sourceRevision, "collect", { collect: () => discovered }, versions));
17138
17249
  return runWorkflow(workflowOptions(root, config, discovered.sourceRevision, "normalize", { normalize: ({ input }) => input }, versions));
17139
17250
  };
17140
- var documentationInputs = (root, snapshot) => snapshot.entities.filter((entity) => entity.kind === "document" && entity.path).map((entity) => ({ path: entity.path, content: readFileSync33(resolve33(root, entity.path), "utf8") }));
17251
+ var documentationInputs = (root, snapshot) => snapshot.entities.filter((entity) => entity.kind === "document" && entity.path).map((entity) => ({ path: entity.path, content: readFileSync34(resolve34(root, entity.path), "utf8") }));
17141
17252
  var ownershipOptions = (config) => {
17142
17253
  const ownership = Object.entries(config.routing?.options?.ownership ?? {}).map(([id, record]) => ({ id, path: record.path }));
17143
17254
  return ownership.length ? { ownership } : {};
@@ -17225,11 +17336,11 @@ var writeAtomicFile = (path, content) => {
17225
17336
  renameSync6(temporaryPath, path);
17226
17337
  };
17227
17338
  var writeReportArtifact = (htmlPath, artifact2) => {
17228
- mkdirSync13(dirname13(htmlPath), { recursive: true });
17339
+ mkdirSync13(dirname14(htmlPath), { recursive: true });
17229
17340
  if (artifact2.mode === "single-file") {
17230
17341
  writeAtomicFile(htmlPath, artifact2.indexHtml);
17231
17342
  const artifactDir2 = htmlPath.replace(/\.html?$/i, "");
17232
- if (existsSync30(artifactDir2)) rmSync3(artifactDir2, { recursive: true, force: true });
17343
+ if (existsSync31(artifactDir2)) rmSync3(artifactDir2, { recursive: true, force: true });
17233
17344
  return htmlPath;
17234
17345
  }
17235
17346
  const artifactDir = htmlPath.replace(/\.html?$/i, "");
@@ -17240,28 +17351,28 @@ var writeReportArtifact = (htmlPath, artifact2) => {
17240
17351
  rmSync3(backupDir, { recursive: true, force: true });
17241
17352
  mkdirSync13(temporaryDir, { recursive: true });
17242
17353
  for (const [file, content] of Object.entries(artifact2.files)) {
17243
- const filePath = resolve33(temporaryDir, file);
17244
- mkdirSync13(dirname13(filePath), { recursive: true });
17354
+ const filePath = resolve34(temporaryDir, file);
17355
+ mkdirSync13(dirname14(filePath), { recursive: true });
17245
17356
  writeFileSync14(filePath, content, "utf8");
17246
17357
  }
17247
- writeFileSync14(resolve33(temporaryDir, "manifest.json"), artifact2.manifest, "utf8");
17248
- const frameSource = `${relative12(dirname13(htmlPath), artifactDir)}/index.html`;
17358
+ writeFileSync14(resolve34(temporaryDir, "manifest.json"), artifact2.manifest, "utf8");
17359
+ const frameSource = `${relative13(dirname14(htmlPath), artifactDir)}/index.html`;
17249
17360
  const launcher = `<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Doc Bridge report</title></head><body style="margin:0"><iframe title="Doc Bridge report" src="${frameSource}" style="border:0;width:100vw;height:100vh"></iframe></body></html>`;
17250
17361
  writeFileSync14(launcherTemp, launcher, "utf8");
17251
17362
  try {
17252
- if (existsSync30(artifactDir)) renameSync6(artifactDir, backupDir);
17363
+ if (existsSync31(artifactDir)) renameSync6(artifactDir, backupDir);
17253
17364
  renameSync6(temporaryDir, artifactDir);
17254
17365
  renameSync6(launcherTemp, htmlPath);
17255
- if (existsSync30(backupDir)) rmSync3(backupDir, { recursive: true, force: true });
17366
+ if (existsSync31(backupDir)) rmSync3(backupDir, { recursive: true, force: true });
17256
17367
  } catch (error) {
17257
- if (existsSync30(backupDir)) {
17368
+ if (existsSync31(backupDir)) {
17258
17369
  const failedDir = `${artifactDir}.failed-${process.pid}`;
17259
- if (existsSync30(artifactDir)) renameSync6(artifactDir, failedDir);
17370
+ if (existsSync31(artifactDir)) renameSync6(artifactDir, failedDir);
17260
17371
  renameSync6(backupDir, artifactDir);
17261
- if (existsSync30(failedDir)) rmSync3(failedDir, { recursive: true, force: true });
17262
- } else if (existsSync30(artifactDir)) rmSync3(artifactDir, { recursive: true, force: true });
17263
- if (existsSync30(temporaryDir)) rmSync3(temporaryDir, { recursive: true, force: true });
17264
- if (existsSync30(launcherTemp)) rmSync3(launcherTemp, { force: true });
17372
+ if (existsSync31(failedDir)) rmSync3(failedDir, { recursive: true, force: true });
17373
+ } else if (existsSync31(artifactDir)) rmSync3(artifactDir, { recursive: true, force: true });
17374
+ if (existsSync31(temporaryDir)) rmSync3(temporaryDir, { recursive: true, force: true });
17375
+ if (existsSync31(launcherTemp)) rmSync3(launcherTemp, { force: true });
17265
17376
  throw error;
17266
17377
  }
17267
17378
  return artifactDir;
@@ -17325,8 +17436,8 @@ var finishWorkflowCommand = (command2, flags, argv, config, root, result, extra)
17325
17436
  const snapshot = config.intelligence?.registry?.enabled ? withAcceptedRelations(observed, readEnrichmentOverlay(root)) : observed;
17326
17437
  const report = parseReconciliationReport(loadWorkflowStepOutput(result.stateDir, "reconcile"));
17327
17438
  const outputPath = optionValues(argv, "--output")[0] ?? ".doc-bridge/report.html";
17328
- const htmlPath = resolve33(root, outputPath);
17329
- mkdirSync13(dirname13(htmlPath), { recursive: true });
17439
+ const htmlPath = resolve34(root, outputPath);
17440
+ mkdirSync13(dirname14(htmlPath), { recursive: true });
17330
17441
  const thresholdValue = optionValues(argv, "--report-threshold")[0];
17331
17442
  const thresholdBytes = thresholdValue === void 0 ? void 0 : Number(thresholdValue);
17332
17443
  if (thresholdBytes !== void 0 && (!Number.isSafeInteger(thresholdBytes) || thresholdBytes < 1)) throw new Error("--report-threshold must be a positive integer.");
@@ -17377,7 +17488,7 @@ var runBenchCommand = (flags, positional, configPath, argv) => {
17377
17488
  }
17378
17489
  try {
17379
17490
  const { config, root } = loadProject(configPath);
17380
- const suite = parseRetrievalSuite(JSON.parse(readFileSync33(resolve33(root, positional[2]), "utf8")));
17491
+ const suite = parseRetrievalSuite(JSON.parse(readFileSync34(resolve34(root, positional[2]), "utf8")));
17381
17492
  const limitOption = optionValues(argv, "--limit")[0];
17382
17493
  const limit = limitOption === void 0 ? void 0 : Number(limitOption);
17383
17494
  if (limit !== void 0 && (!Number.isInteger(limit) || limit <= 0)) {
@@ -17386,7 +17497,7 @@ var runBenchCommand = (flags, positional, configPath, argv) => {
17386
17497
  if (flags.has("--overlay")) {
17387
17498
  const overlay = readEnrichmentOverlay(root);
17388
17499
  if (!overlay) throw new Error("No enrichment overlay at .doc-bridge/enrich/overlay.json. Run: ak-docs enrich");
17389
- const stateDir = resolve33(root, config.workflow?.stateDir ?? ".doc-bridge/workflow");
17500
+ const stateDir = resolve34(root, config.workflow?.stateDir ?? ".doc-bridge/workflow");
17390
17501
  const snapshot = (() => {
17391
17502
  try {
17392
17503
  return parseDiscoverySnapshot(loadWorkflowStepOutput(stateDir, "normalize"));
@@ -17400,34 +17511,34 @@ var runBenchCommand = (flags, positional, configPath, argv) => {
17400
17511
  return delta2.regression ? 1 : 0;
17401
17512
  }
17402
17513
  const indexOption = optionValues(argv, "--index")[0];
17403
- const index = indexOption ? parseDocBridgeIndex(JSON.parse(readFileSync33(resolve33(root, indexOption), "utf8"))) : loadFreshDocBridgeIndex(root, config);
17514
+ const index = indexOption ? parseDocBridgeIndex(JSON.parse(readFileSync34(resolve34(root, indexOption), "utf8"))) : loadFreshDocBridgeIndex(root, config);
17404
17515
  const result = runRetrievalBench({
17405
17516
  index,
17406
17517
  suite,
17407
17518
  ...limit === void 0 ? {} : { limit }
17408
17519
  });
17409
17520
  const baselineOption = optionValues(argv, "--baseline")[0];
17410
- const baselinePath = baselineOption ? resolve33(root, baselineOption) : void 0;
17521
+ const baselinePath = baselineOption ? resolve34(root, baselineOption) : void 0;
17411
17522
  if (flags.has("--update-baseline")) {
17412
17523
  const approvedBy = optionValues(argv, "--by")[0];
17413
17524
  if (!baselinePath) throw new Error("--update-baseline requires --baseline <file>.");
17414
17525
  if (!approvedBy) throw new Error("--update-baseline requires --by <name>: a baseline is an approved figure, not a side effect of a run.");
17415
17526
  const reason = optionValues(argv, "--reason")[0];
17416
17527
  const baseline = createRetrievalBaseline({ result, approvedBy, ...reason ? { reason } : {} });
17417
- mkdirSync13(dirname13(baselinePath), { recursive: true });
17528
+ mkdirSync13(dirname14(baselinePath), { recursive: true });
17418
17529
  writeFileSync14(baselinePath, `${JSON.stringify(baseline, null, 2)}
17419
17530
  `, "utf8");
17420
17531
  if (wantsTextOutput(flags, config)) {
17421
- writeLines([...formatRetrievalBenchText(result), `Baseline written: ${relative12(root, baselinePath)} (approved by ${approvedBy})`]);
17532
+ writeLines([...formatRetrievalBenchText(result), `Baseline written: ${relative13(root, baselinePath)} (approved by ${approvedBy})`]);
17422
17533
  } else writeJson2({ ok: true, result, baseline, baselinePath });
17423
17534
  return 0;
17424
17535
  }
17425
- if (baselinePath && !existsSync30(baselinePath)) {
17536
+ if (baselinePath && !existsSync31(baselinePath)) {
17426
17537
  throw new Error(
17427
- `No baseline at ${relative12(root, baselinePath)}. Record the current figures with: ak-docs bench retrieval ${positional[2]} --baseline ${baselineOption} --update-baseline --by <name>`
17538
+ `No baseline at ${relative13(root, baselinePath)}. Record the current figures with: ak-docs bench retrieval ${positional[2]} --baseline ${baselineOption} --update-baseline --by <name>`
17428
17539
  );
17429
17540
  }
17430
- const comparison = baselinePath ? compareRetrievalBaseline(result, parseRetrievalBaseline(JSON.parse(readFileSync33(baselinePath, "utf8")))) : void 0;
17541
+ const comparison = baselinePath ? compareRetrievalBaseline(result, parseRetrievalBaseline(JSON.parse(readFileSync34(baselinePath, "utf8")))) : void 0;
17431
17542
  if (wantsTextOutput(flags, config)) {
17432
17543
  writeLines([...formatRetrievalBenchText(result), ...comparison ? formatRetrievalComparisonText(comparison) : []]);
17433
17544
  } else {
@@ -17480,7 +17591,7 @@ var runRenderCommand = (flags, positional, configPath, argv) => {
17480
17591
  }
17481
17592
  const result = renderArtifact({ root, config, template: name, ...dataPath ? { dataPath } : {} });
17482
17593
  if (outputPath) {
17483
- const written = writeRenderedPages(result, resolve33(root, outputPath), root);
17594
+ const written = writeRenderedPages(result, resolve34(root, outputPath), root);
17484
17595
  writeJson2({ ok: true, template: name, source: result.origin, written });
17485
17596
  return 0;
17486
17597
  }
@@ -17505,7 +17616,7 @@ var runRulesCommand = (argv, flags, positional, configPath) => {
17505
17616
  }
17506
17617
  try {
17507
17618
  const { config } = loadProject(configPath);
17508
- const report = parseReconciliationReport(JSON.parse(readFileSync33(resolve33(reportPath), "utf8")));
17619
+ const report = parseReconciliationReport(JSON.parse(readFileSync34(resolve34(reportPath), "utf8")));
17509
17620
  const presetValue = optionValues(argv, "--preset")[0];
17510
17621
  const preset = presetValue === void 0 ? void 0 : ["default", "recommended", "strict"].includes(presetValue) ? presetValue : (() => {
17511
17622
  throw new Error(`Invalid rules preset "${presetValue}".`);
@@ -17514,12 +17625,12 @@ var runRulesCommand = (argv, flags, positional, configPath) => {
17514
17625
  for (const [rule, level] of Object.entries(parseRuleAssignments(optionValues(argv, "--severity"), parseRuleSeverity))) {
17515
17626
  severity[parseRuleId(rule)] = level;
17516
17627
  }
17517
- const ignore = optionValues(argv, "--ignore").map(parseRuleId);
17628
+ const ignore2 = optionValues(argv, "--ignore").map(parseRuleId);
17518
17629
  const result = evaluateRules(report, {
17519
17630
  ...config.rules ? { config: config.rules } : {},
17520
17631
  ...preset ? { preset } : {},
17521
17632
  ...Object.keys(severity).length ? { severity } : {},
17522
- ...ignore.length ? { ignore } : {},
17633
+ ...ignore2.length ? { ignore: ignore2 } : {},
17523
17634
  ...optionValues(argv, "--critical-entity").length ? { criticalEntities: optionValues(argv, "--critical-entity") } : {},
17524
17635
  ...optionValues(argv, "--critical-path").length ? { criticalPaths: optionValues(argv, "--critical-path") } : {}
17525
17636
  });
@@ -17555,16 +17666,16 @@ var runFixCommand = async (argv, positional, configPath) => {
17555
17666
  }
17556
17667
  const outputPath = optionValues(argv, "--output")[0];
17557
17668
  if (outputPath) {
17558
- mkdirSync13(dirname13(resolve33(root, outputPath)), { recursive: true });
17559
- writeFileSync14(resolve33(root, outputPath), `${JSON.stringify(proposal2, null, 2)}
17669
+ mkdirSync13(dirname14(resolve34(root, outputPath)), { recursive: true });
17670
+ writeFileSync14(resolve34(root, outputPath), `${JSON.stringify(proposal2, null, 2)}
17560
17671
  `, "utf8");
17561
17672
  }
17562
- writeJson2({ ok: true, proposal: proposal2, ...outputPath ? { proposalPath: resolve33(root, outputPath) } : {} });
17673
+ writeJson2({ ok: true, proposal: proposal2, ...outputPath ? { proposalPath: resolve34(root, outputPath) } : {} });
17563
17674
  return 0;
17564
17675
  }
17565
17676
  if (!proposalPath2 || !["approve", "apply"].includes(action ?? "")) throw new Error("Usage: ak-docs fix propose links|normalize <artifact> [--output <file>] | fix approve|apply <proposal.json> [--by <name>]");
17566
- const file = resolve33(root, proposalPath2);
17567
- const proposal = JSON.parse(readFileSync33(file, "utf8"));
17677
+ const file = resolve34(root, proposalPath2);
17678
+ const proposal = JSON.parse(readFileSync34(file, "utf8"));
17568
17679
  const result = action === "approve" ? approveFixProposal(proposal, optionValues(argv, "--by")[0] ?? "human") : applyFixProposal(root, proposal, { currentRevision: sourceRevision2 });
17569
17680
  const recorded = action === "approve" && result.approval ? await recordApproval(root, { id: fixApprovalId(result.proposalId, result.approval.proposalHash), name: FIX_APPROVAL_GATE, payload: { proposalId: result.proposalId, proposalHash: result.approval.proposalHash }, decision: "approved", by: result.approval.approvedBy }) : void 0;
17570
17681
  writeFileSync14(file, `${JSON.stringify(result, null, 2)}
@@ -17592,7 +17703,7 @@ var runEnrichCommand = async (flags, positional, argv, configPath) => {
17592
17703
  const proposalId = positional[2];
17593
17704
  const by = optionValues(argv, "--by")[0];
17594
17705
  if (!proposalId || !by) throw new Error("Usage: ak-docs enrich approve|reject <proposalId> --by <name> [--reason <text>]");
17595
- const stateDir = resolve33(root, config.workflow?.stateDir ?? ".doc-bridge/workflow");
17706
+ const stateDir = resolve34(root, config.workflow?.stateDir ?? ".doc-bridge/workflow");
17596
17707
  const snapshot2 = (() => {
17597
17708
  try {
17598
17709
  return parseDiscoverySnapshot(loadWorkflowStepOutput(stateDir, "normalize"));
@@ -17618,7 +17729,7 @@ var runEnrichCommand = async (flags, positional, argv, configPath) => {
17618
17729
  config,
17619
17730
  snapshot,
17620
17731
  overlay: result.overlay,
17621
- suite: parseRetrievalSuite(JSON.parse(readFileSync33(resolve33(root, config.retrieval?.benchmark?.suite ?? DEFAULT_RETRIEVAL_SUITE), "utf8")))
17732
+ suite: parseRetrievalSuite(JSON.parse(readFileSync34(resolve34(root, config.retrieval?.benchmark?.suite ?? DEFAULT_RETRIEVAL_SUITE), "utf8")))
17622
17733
  }) : void 0;
17623
17734
  if (wantsTextOutput(flags, config)) writeLines([...formatEnrichmentText(result), ...delta2 ? formatOverlayRetrievalDeltaText(delta2) : []]);
17624
17735
  else writeJson2({
@@ -17652,7 +17763,7 @@ var runParityCommand = (flags, configPath, argv) => {
17652
17763
  try {
17653
17764
  const { config, root } = loadProject(configPath);
17654
17765
  const claimsPath = optionValues(argv, "--claims")[0] ?? DEFAULT_PUBLIC_CLAIMS;
17655
- const registry = parsePublicClaims(JSON.parse(readFileSync33(resolve33(root, claimsPath), "utf8")));
17766
+ const registry = parsePublicClaims(JSON.parse(readFileSync34(resolve34(root, claimsPath), "utf8")));
17656
17767
  const snapshot = discoverRepository({ root, config });
17657
17768
  const doctor = registry.claims.some((claim) => claim.evidence.kind === "doctor-metric") ? runDoctor(root, config) : void 0;
17658
17769
  const report = checkPublicParity({
@@ -17677,7 +17788,7 @@ var runParityCommand = (flags, configPath, argv) => {
17677
17788
  var runSuggestCommand = async (flags, configPath) => {
17678
17789
  try {
17679
17790
  const { config, root } = loadProject(configPath);
17680
- const stateDir = resolve33(root, config.workflow?.stateDir ?? ".doc-bridge/workflow");
17791
+ const stateDir = resolve34(root, config.workflow?.stateDir ?? ".doc-bridge/workflow");
17681
17792
  const snapshot = parseDiscoverySnapshot(loadWorkflowStepOutput(stateDir, "normalize"));
17682
17793
  const report = parseReconciliationReport(loadWorkflowStepOutput(stateDir, "reconcile"));
17683
17794
  const runner = config.intelligence?.registry?.cli ? void 0 : await loadRegistryAgentRunner(root, config);
@@ -17695,7 +17806,7 @@ var runSuggestCommand = async (flags, configPath) => {
17695
17806
  }
17696
17807
  };
17697
17808
  var writeIfMissing = (path, contents) => {
17698
- mkdirSync13(dirname13(path), { recursive: true });
17809
+ mkdirSync13(dirname14(path), { recursive: true });
17699
17810
  try {
17700
17811
  const fd = openSync3(path, "wx");
17701
17812
  try {
@@ -17809,7 +17920,7 @@ var scaffoldWorkspaceDocs = (root, config) => {
17809
17920
  const created = [];
17810
17921
  const skipped = [];
17811
17922
  for (const pkg of discoverPnpmPackages(root, config)) {
17812
- const path = resolve33(root, config.corpus.agent.root, "packages", `${pkg.id}.md`);
17923
+ const path = resolve34(root, config.corpus.agent.root, "packages", `${pkg.id}.md`);
17813
17924
  if (writeIfMissing(path, workspaceDocDraft(pkg.id, pkg.path))) created.push(path);
17814
17925
  else skipped.push(path);
17815
17926
  }
@@ -17819,11 +17930,11 @@ var bootstrapAgentDocs = (root, config) => {
17819
17930
  const created = [];
17820
17931
  const skipped = [];
17821
17932
  for (const doc of scanHumanDocRecords(root, config)) {
17822
- const raw = readFileSync33(doc.path, "utf8");
17933
+ const raw = readFileSync34(doc.path, "utf8");
17823
17934
  const body = raw.replace(/^---\n[\s\S]*?\n---\n?/, "");
17824
17935
  const title2 = firstHeading(body) ?? doc.id;
17825
17936
  const description = firstParagraph(body);
17826
- const draftPath = resolve33(root, config.corpus.agent.root, "human", `${doc.id}.md`);
17937
+ const draftPath = resolve34(root, config.corpus.agent.root, "human", `${doc.id}.md`);
17827
17938
  const draft = [
17828
17939
  "---",
17829
17940
  "type: knowledge",
@@ -17866,12 +17977,12 @@ var runStudyCommand = async (flags, positional, argv, configPath) => {
17866
17977
  if (action === "expectations") {
17867
17978
  const expectationsPath = optionValues(argv, "--expectations")[0];
17868
17979
  if (!expectationsPath) throw new Error("Study expectations require --expectations <expectations.json>.");
17869
- const suite = parseStudyTaskSuite(JSON.parse(readFileSync33(resolve33(inputPath), "utf8")));
17870
- const expectations = parseStudyExpectations(JSON.parse(readFileSync33(resolve33(expectationsPath), "utf8")));
17980
+ const suite = parseStudyTaskSuite(JSON.parse(readFileSync34(resolve34(inputPath), "utf8")));
17981
+ const expectations = parseStudyExpectations(JSON.parse(readFileSync34(resolve34(expectationsPath), "utf8")));
17871
17982
  const repositoryId = optionValues(argv, "--repository")[0];
17872
17983
  const indexOption = optionValues(argv, "--index")[0];
17873
17984
  const { config, root } = loadProject(configPath);
17874
- const index = indexOption ? parseDocBridgeIndex(JSON.parse(readFileSync33(resolve33(root, indexOption), "utf8"))) : loadFreshDocBridgeIndex(root, config);
17985
+ const index = indexOption ? parseDocBridgeIndex(JSON.parse(readFileSync34(resolve34(root, indexOption), "utf8"))) : loadFreshDocBridgeIndex(root, config);
17875
17986
  const check = checkStudyExpectations({ taskSuite: suite, expectations, index, ...repositoryId ? { repositoryId } : {} });
17876
17987
  if (flags.has("--text")) writeLines(formatStudyExpectationsText(check));
17877
17988
  else writeJson2({ ok: check.ok, expectations: check });
@@ -17884,11 +17995,11 @@ var runStudyCommand = async (flags, positional, argv, configPath) => {
17884
17995
  const ledgerPath = optionValues(argv, "--ledger")[0];
17885
17996
  if (!taskSuitePath || !providersPath || !repositoriesPath || !ledgerPath) throw new Error("Study run requires a task suite, --providers, --repositories, and --ledger.");
17886
17997
  const summary = await runControlledStudy({
17887
- plan: parseControlledStudyRunPlan(JSON.parse(readFileSync33(resolve33(inputPath), "utf8"))),
17888
- suite: parseStudyTaskSuite(JSON.parse(readFileSync33(resolve33(taskSuitePath), "utf8"))),
17889
- providers: parseStudyProviderCliConfig(JSON.parse(readFileSync33(resolve33(providersPath), "utf8"))),
17890
- repositories: parseStudyRepositoryConfig(JSON.parse(readFileSync33(resolve33(repositoriesPath), "utf8"))),
17891
- ledgerPath: resolve33(ledgerPath),
17998
+ plan: parseControlledStudyRunPlan(JSON.parse(readFileSync34(resolve34(inputPath), "utf8"))),
17999
+ suite: parseStudyTaskSuite(JSON.parse(readFileSync34(resolve34(taskSuitePath), "utf8"))),
18000
+ providers: parseStudyProviderCliConfig(JSON.parse(readFileSync34(resolve34(providersPath), "utf8"))),
18001
+ repositories: parseStudyRepositoryConfig(JSON.parse(readFileSync34(resolve34(repositoriesPath), "utf8"))),
18002
+ ledgerPath: resolve34(ledgerPath),
17892
18003
  ...optionValues(argv, "--round")[0] === void 0 ? {} : { round: optionValues(argv, "--round")[0] },
17893
18004
  ...flags.has("--dry-run") ? { dryRun: true } : {}
17894
18005
  });
@@ -17901,21 +18012,21 @@ var runStudyCommand = async (flags, positional, argv, configPath) => {
17901
18012
  const adjudicatorConfigPath = optionValues(argv, "--adjudicator")[0];
17902
18013
  const outputPath = optionValues(argv, "--output")[0];
17903
18014
  if (!taskSuitePath || !adjudicatorConfigPath || !outputPath) throw new Error("Study adjudication requires a task suite, --adjudicator with an adjudicator, and --output.");
17904
- const config = parseStudyProviderCliConfig(JSON.parse(readFileSync33(resolve33(adjudicatorConfigPath), "utf8")));
18015
+ const config = parseStudyProviderCliConfig(JSON.parse(readFileSync34(resolve34(adjudicatorConfigPath), "utf8")));
17905
18016
  if (!config.adjudicator) throw new Error("Study provider config must declare an adjudicator.");
17906
- const ledger = parseControlledStudyLedger(JSON.parse(readFileSync33(resolve33(inputPath), "utf8")));
17907
- const suite = parseStudyTaskSuite(JSON.parse(readFileSync33(resolve33(taskSuitePath), "utf8")));
18017
+ const ledger = parseControlledStudyLedger(JSON.parse(readFileSync34(resolve34(inputPath), "utf8")));
18018
+ const suite = parseStudyTaskSuite(JSON.parse(readFileSync34(resolve34(taskSuitePath), "utf8")));
17908
18019
  const limitValue = optionValues(argv, "--limit")[0];
17909
18020
  const limit = limitValue === void 0 ? void 0 : Number(limitValue);
17910
18021
  const offsetValue = optionValues(argv, "--offset")[0];
17911
18022
  const offset = offsetValue === void 0 ? void 0 : Number(offsetValue);
17912
18023
  const result = await independentlyAdjudicateStudyLedger({ ledger, taskSuite: suite, config: config.adjudicator, configurationHash: config.contentHash, cwd: process.cwd(), maxRuntimeMs: suite.maxRuntimeMsPerTask, ...optionValues(argv, "--run-id")[0] === void 0 ? {} : { runId: optionValues(argv, "--run-id")[0] }, ...offset === void 0 ? {} : { offset }, ...limit === void 0 ? {} : { limit } });
17913
18024
  persistIndependentlyAdjudicatedLedger(outputPath, result);
17914
- if (flags.has("--text")) writeLines([`Adjudicated observations: ${result.observations.length}`, `Ledger: ${resolve33(outputPath)}`, `Content hash: ${result.contentHash}`]);
18025
+ if (flags.has("--text")) writeLines([`Adjudicated observations: ${result.observations.length}`, `Ledger: ${resolve34(outputPath)}`, `Content hash: ${result.contentHash}`]);
17915
18026
  else writeJson2({ ok: true, ledger: result });
17916
18027
  return 0;
17917
18028
  }
17918
- const input = JSON.parse(readFileSync33(resolve33(inputPath), "utf8"));
18029
+ const input = JSON.parse(readFileSync34(resolve34(inputPath), "utf8"));
17919
18030
  if (action === "protocol") {
17920
18031
  const protocol = parseStudyProtocol(input);
17921
18032
  if (flags.has("--text")) writeLines(formatStudyProtocolText(protocol));
@@ -17973,7 +18084,7 @@ var runStudyCommand = async (flags, positional, argv, configPath) => {
17973
18084
  const registry = parseHistoricalEvidenceRegistry(input);
17974
18085
  const protocolPath = optionValues(argv, "--protocol")[0];
17975
18086
  if (protocolPath) {
17976
- const protocol = parseStudyProtocol(JSON.parse(readFileSync33(resolve33(protocolPath), "utf8")));
18087
+ const protocol = parseStudyProtocol(JSON.parse(readFileSync34(resolve34(protocolPath), "utf8")));
17977
18088
  validateHistoricalEvidenceRegistry(registry, protocol);
17978
18089
  }
17979
18090
  if (flags.has("--text")) writeLines(formatHistoricalEvidenceText(registry));
@@ -18017,8 +18128,8 @@ var runCli2 = (argv) => {
18017
18128
  return 1;
18018
18129
  }
18019
18130
  try {
18020
- const abs = resolve33(file);
18021
- const raw = readFileSync33(abs, "utf8");
18131
+ const abs = resolve34(file);
18132
+ const raw = readFileSync34(abs, "utf8");
18022
18133
  const handoff = parseAgentHandoff(JSON.parse(raw));
18023
18134
  writeJson2({ ok: true, handoff });
18024
18135
  return 0;
@@ -18060,8 +18171,8 @@ var runCli2 = (argv) => {
18060
18171
  return 1;
18061
18172
  }
18062
18173
  try {
18063
- const fixture = benchmarkFixture(JSON.parse(readFileSync33(resolve33(fixturePath2), "utf8")));
18064
- const observation = JSON.parse(readFileSync33(resolve33(observationPath), "utf8"));
18174
+ const fixture = benchmarkFixture(JSON.parse(readFileSync34(resolve34(fixturePath2), "utf8")));
18175
+ const observation = JSON.parse(readFileSync34(resolve34(observationPath), "utf8"));
18065
18176
  const result = measureBenchmark2(observation, fixture);
18066
18177
  if (flags.has("--text")) writeLines([formatBenchmarkText(result)]);
18067
18178
  else writeJson2(result);
@@ -18086,10 +18197,10 @@ var runCli2 = (argv) => {
18086
18197
  if (command2 === "init") {
18087
18198
  const root = process.cwd();
18088
18199
  const withDemo = flags.has("--demo") || !flags.has("--no-demo");
18089
- const configFile = resolve33(root, configPath ?? "doc-bridge.config.json");
18090
- const docsIndex = resolve33(root, "docs/for-agents/INDEX.md");
18091
- const exampleDoc = resolve33(root, "docs/for-agents/packages/example.md");
18092
- const agentsMd = resolve33(root, "AGENTS.md");
18200
+ const configFile = resolve34(root, configPath ?? "doc-bridge.config.json");
18201
+ const docsIndex = resolve34(root, "docs/for-agents/INDEX.md");
18202
+ const exampleDoc = resolve34(root, "docs/for-agents/packages/example.md");
18203
+ const agentsMd = resolve34(root, "AGENTS.md");
18093
18204
  const configWritten = writeIfMissing(configFile, initConfigContents(configFile, withDemo));
18094
18205
  const indexWritten = writeIfMissing(
18095
18206
  docsIndex,
@@ -18097,7 +18208,7 @@ var runCli2 = (argv) => {
18097
18208
  );
18098
18209
  const exampleWritten = withDemo ? writeIfMissing(exampleDoc, exampleAgentDoc) : false;
18099
18210
  const agentsWritten = writeIfMissing(agentsMd, agentsMdSnippet);
18100
- if (withDemo) writeIfMissing(resolve33(root, "src/.gitkeep"), "");
18211
+ if (withDemo) writeIfMissing(resolve34(root, "src/.gitkeep"), "");
18101
18212
  const scaffold = flags.has("--scaffold-workspaces") ? scaffoldWorkspaceDocs(root, loadProject(configFile).config) : void 0;
18102
18213
  writeJson2({
18103
18214
  ok: true,
@@ -18341,8 +18452,8 @@ var runCli2 = (argv) => {
18341
18452
  const { config, root } = loadProject(configPath);
18342
18453
  const report = runDoctor(root, config);
18343
18454
  if (flags.has("--write-badge")) {
18344
- const badgePath = resolve33(root, ".doc-bridge", "coverage-badge.json");
18345
- mkdirSync13(dirname13(badgePath), { recursive: true });
18455
+ const badgePath = resolve34(root, ".doc-bridge", "coverage-badge.json");
18456
+ mkdirSync13(dirname14(badgePath), { recursive: true });
18346
18457
  writeFileSync14(badgePath, `${formatDoctorBadgeJson(report.badge)}
18347
18458
  `, "utf8");
18348
18459
  }