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