@agentskit/doc-bridge 0.1.0-alpha.1 → 0.1.0-alpha.2

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 (61) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +1 -1
  3. package/dist/cli/program.js +283 -105
  4. package/dist/cli/program.js.map +1 -1
  5. package/dist/config/index.d.ts +1 -1
  6. package/dist/config/index.js +6 -3
  7. package/dist/config/index.js.map +1 -1
  8. package/dist/{index-CD_zmKXf.d.ts → index-CPUJbTbg.d.ts} +19 -10
  9. package/dist/index.d.ts +5 -4
  10. package/dist/index.js +278 -100
  11. package/dist/index.js.map +1 -1
  12. package/docs/DOGFOOD.md +92 -0
  13. package/package.json +27 -9
  14. package/scripts/prepare.mjs +44 -0
  15. package/src/cli/program.ts +933 -0
  16. package/src/config/defaults.ts +63 -0
  17. package/src/config/define-config.ts +6 -0
  18. package/src/config/index.ts +15 -0
  19. package/src/config/load-config.ts +138 -0
  20. package/src/config/schema.ts +294 -0
  21. package/src/federation/llms.ts +145 -0
  22. package/src/gates/run-gates.ts +274 -0
  23. package/src/index-builder/build-handoffs.ts +217 -0
  24. package/src/index-builder/build-index.ts +137 -0
  25. package/src/index-builder/capabilities.ts +37 -0
  26. package/src/index-builder/content-hash.ts +19 -0
  27. package/src/index-builder/human-adapters/core.ts +100 -0
  28. package/src/index-builder/human-adapters/docusaurus.ts +113 -0
  29. package/src/index-builder/human-adapters/fumadocs.ts +70 -0
  30. package/src/index-builder/human-adapters/index.ts +52 -0
  31. package/src/index-builder/human-adapters/plain-markdown.ts +10 -0
  32. package/src/index-builder/llms-txt.ts +19 -0
  33. package/src/index-builder/plugins/human-markdown.ts +7 -0
  34. package/src/index-builder/plugins/pnpm-monorepo.ts +72 -0
  35. package/src/index-builder/scan-corpus.ts +181 -0
  36. package/src/index.ts +120 -0
  37. package/src/intelligence/adapter.ts +90 -0
  38. package/src/intelligence/chat.ts +148 -0
  39. package/src/intelligence/peers.ts +59 -0
  40. package/src/intelligence/rag.ts +98 -0
  41. package/src/lib/glob-expand.ts +33 -0
  42. package/src/lib/markdown.ts +90 -0
  43. package/src/lib/package-manager.ts +104 -0
  44. package/src/lib/paths.ts +6 -0
  45. package/src/lib/walk.ts +45 -0
  46. package/src/mcp/server.ts +276 -0
  47. package/src/memory/ingest.ts +51 -0
  48. package/src/memory/pipeline.ts +119 -0
  49. package/src/query/load-index.ts +25 -0
  50. package/src/query/query.ts +142 -0
  51. package/src/query/search.ts +58 -0
  52. package/src/retriever/doc-bridge-retriever.ts +62 -0
  53. package/src/schemas/agent-handoff.ts +82 -0
  54. package/src/schemas/doc-bridge-index.ts +106 -0
  55. package/src/schemas/json-schemas.ts +156 -0
  56. package/src/schemas/memory-candidate.ts +37 -0
  57. package/src/shims/agentskit-peers.d.ts +80 -0
  58. package/src/validate.ts +67 -0
  59. package/src/version.ts +1 -0
  60. package/tsconfig.json +21 -0
  61. package/tsup.config.ts +15 -0
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ var applyConfigDefaults = (config) => {
10
10
  agent: {
11
11
  ...config.corpus.agent,
12
12
  index: agentIndex,
13
- include: config.corpus.agent.include ?? ["**/*.md"],
13
+ include: config.corpus.agent.include ?? ["**/*.{md,mdx}"],
14
14
  exclude: config.corpus.agent.exclude ?? [...DEFAULT_AGENT_EXCLUDE]
15
15
  }
16
16
  },
@@ -103,9 +103,11 @@ var OwnershipEntrySchema = z.object({
103
103
  humanDoc: z.string().min(1).max(512).optional()
104
104
  }).strict();
105
105
  var RoutingConfigSchema = z.object({
106
- plugin: z.enum(["pnpm-monorepo", "npm-workspaces", "yarn-workspaces", "custom"]).optional(),
106
+ plugin: z.enum(["pnpm-monorepo", "npm-workspaces", "yarn-workspaces", "pattern-files", "custom"]).optional(),
107
107
  options: z.object({
108
108
  packages: z.array(z.string().min(1).max(256)).max(128).optional(),
109
+ /** Infer ownership from corpus paths/frontmatter (default true). */
110
+ ownershipFromCorpus: z.boolean().optional(),
109
111
  ownership: z.record(z.string().min(1).max(256), OwnershipEntrySchema).optional(),
110
112
  intents: z.array(
111
113
  z.object({
@@ -125,7 +127,8 @@ var RoutingConfigSchema = z.object({
125
127
  }).strict().optional()
126
128
  }).strict();
127
129
  var GatesConfigSchema = z.object({
128
- preset: z.enum(["minimal", "standard", "strict"]).optional(),
130
+ /** minimal: freshness · standard: + human links · strict: + okf-type · playbook: freshness + okf soft style */
131
+ preset: z.enum(["minimal", "standard", "strict", "playbook"]).optional(),
129
132
  include: z.array(
130
133
  z.enum([
131
134
  "index-freshness",
@@ -695,16 +698,80 @@ ${zodIssues(result.error).map((i) => ` - ${i.path}: ${i.message}`).join("\n")}`
695
698
  };
696
699
 
697
700
  // src/index-builder/build-index.ts
698
- import { mkdirSync, readFileSync as readFileSync7, writeFileSync } from "fs";
699
- import { dirname as dirname3, join as join9 } from "path";
701
+ import { mkdirSync, readFileSync as readFileSync8, writeFileSync } from "fs";
702
+ import { dirname as dirname3, join as join10 } from "path";
700
703
 
701
704
  // src/lib/paths.ts
702
705
  import { resolve as resolve2 } from "path";
703
706
  var toPosix = (value) => value.split("\\").join("/");
704
707
 
708
+ // src/lib/package-manager.ts
709
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
710
+ import { join as join2 } from "path";
711
+ var detectPackageManager = (root) => {
712
+ if (existsSync2(join2(root, "pnpm-lock.yaml")) || existsSync2(join2(root, "pnpm-workspace.yaml"))) {
713
+ return "pnpm";
714
+ }
715
+ if (existsSync2(join2(root, "yarn.lock"))) return "yarn";
716
+ if (existsSync2(join2(root, "bun.lockb")) || existsSync2(join2(root, "bun.lock"))) return "bun";
717
+ if (existsSync2(join2(root, "package-lock.json"))) return "npm";
718
+ try {
719
+ const pkg = JSON.parse(readFileSync2(join2(root, "package.json"), "utf8"));
720
+ const pm = pkg.packageManager?.split("@")[0];
721
+ if (pm === "pnpm" || pm === "npm" || pm === "yarn" || pm === "bun") return pm;
722
+ } catch {
723
+ }
724
+ return "npm";
725
+ };
726
+ var defaultChecksForTarget = (root, opts) => {
727
+ const pm = detectPackageManager(root);
728
+ if (/\.mdx?$/.test(opts.packagePath) || opts.packagePath.includes("/pillars/")) {
729
+ try {
730
+ const pkg = JSON.parse(readFileSync2(join2(root, "package.json"), "utf8"));
731
+ const scripts = pkg.scripts ?? {};
732
+ if (scripts["check:okf-type"]) return ["pnpm run check:okf-type"];
733
+ if (scripts["docs:bridge:gate"]) return ["pnpm run docs:bridge:gate"];
734
+ if (scripts.test) return [pm === "pnpm" ? "pnpm test" : "npm test"];
735
+ } catch {
736
+ }
737
+ }
738
+ const isWorkspace = existsSync2(join2(root, "pnpm-workspace.yaml")) || existsSync2(join2(root, "lerna.json")) || Boolean(
739
+ (() => {
740
+ try {
741
+ const pkg = JSON.parse(readFileSync2(join2(root, "package.json"), "utf8"));
742
+ return Boolean(pkg.workspaces);
743
+ } catch {
744
+ return false;
745
+ }
746
+ })()
747
+ );
748
+ const filter = opts.packageName ?? (opts.packagePath.startsWith("packages/") || opts.packagePath.startsWith("apps/") ? opts.packageId : void 0);
749
+ if (pm === "pnpm") {
750
+ if (isWorkspace && filter) {
751
+ const base = [`pnpm --filter ${filter} test`];
752
+ if (opts.strict) base.push(`pnpm --filter ${filter} lint`);
753
+ return base;
754
+ }
755
+ return opts.strict ? ["pnpm test", "pnpm run lint"] : ["pnpm test"];
756
+ }
757
+ if (pm === "yarn") {
758
+ if (isWorkspace && filter) {
759
+ return opts.strict ? [`yarn workspace ${filter} test`, `yarn workspace ${filter} lint`] : [`yarn workspace ${filter} test`];
760
+ }
761
+ return opts.strict ? ["yarn test", "yarn lint"] : ["yarn test"];
762
+ }
763
+ if (pm === "bun") {
764
+ return opts.strict ? ["bun test", "bun run lint"] : ["bun test"];
765
+ }
766
+ if (isWorkspace && filter) {
767
+ return opts.strict ? [`npm test -w ${filter}`, `npm run lint -w ${filter}`] : [`npm test -w ${filter}`];
768
+ }
769
+ return opts.strict ? ["npm test", "npm run lint"] : ["npm test"];
770
+ };
771
+
705
772
  // src/index-builder/scan-corpus.ts
706
- import { readFileSync as readFileSync2 } from "fs";
707
- import { join as join3 } from "path";
773
+ import { readFileSync as readFileSync3 } from "fs";
774
+ import { join as join4 } from "path";
708
775
 
709
776
  // src/lib/markdown.ts
710
777
  var parseFrontmatter = (markdown) => {
@@ -780,7 +847,7 @@ var slugFromPath = (relPath) => {
780
847
 
781
848
  // src/lib/walk.ts
782
849
  import { readdirSync, statSync } from "fs";
783
- import { join as join2 } from "path";
850
+ import { join as join3 } from "path";
784
851
  var DEFAULT_SKIP = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", "coverage", ".doc-bridge"]);
785
852
  var walkFiles = (root, opts) => {
786
853
  const extensions = opts?.extensions ?? [".md"];
@@ -794,7 +861,7 @@ var walkFiles = (root, opts) => {
794
861
  return;
795
862
  }
796
863
  for (const name of entries) {
797
- const abs = join2(dir, name);
864
+ const abs = join3(dir, name);
798
865
  let st;
799
866
  try {
800
867
  st = statSync(abs);
@@ -818,13 +885,13 @@ var walkFiles = (root, opts) => {
818
885
 
819
886
  // src/index-builder/scan-corpus.ts
820
887
  var scanAgentCorpus = (root, config) => {
821
- const agentRoot = join3(root, config.corpus.agent.root);
888
+ const agentRoot = join4(root, config.corpus.agent.root);
822
889
  const files = walkFiles(agentRoot, { extensions: [".md", ".mdx"] });
823
890
  const corpusRelRoot = toPosix(config.corpus.agent.root);
824
891
  return files.map((abs) => {
825
892
  const relToCorpus = toPosix(abs.replace(`${toPosix(agentRoot)}/`, ""));
826
893
  const relPath = `${corpusRelRoot}/${relToCorpus}`;
827
- const raw = readFileSync2(abs, "utf8");
894
+ const raw = readFileSync3(abs, "utf8");
828
895
  const { data: frontmatter } = parseFrontmatter(raw);
829
896
  const id = frontmatterString(frontmatter, "id") ?? frontmatterString(frontmatter, "package") ?? slugFromPath(relToCorpus);
830
897
  const title = firstHeading(raw) ?? id;
@@ -842,16 +909,29 @@ var scanAgentCorpus = (root, config) => {
842
909
  });
843
910
  };
844
911
  var guessAgentDocForPackage = (corpus, packageId) => {
845
- const exact = corpus.find(
846
- (doc) => frontmatterString(doc.frontmatter, "package") === packageId || doc.relPath.endsWith(`/packages/${packageId}.md`) || doc.relPath.endsWith(`/${packageId}.md`) || doc.id === packageId
847
- );
848
- return exact?.path;
912
+ const candidates = [
913
+ (doc) => frontmatterString(doc.frontmatter, "package") === packageId,
914
+ (doc) => doc.id === packageId,
915
+ (doc) => doc.relPath.endsWith(`/packages/${packageId}.md`),
916
+ (doc) => doc.relPath.endsWith(`/packages/${packageId}.mdx`),
917
+ (doc) => doc.relPath.endsWith(`/packages/${packageId}/index.md`),
918
+ (doc) => doc.relPath.endsWith(`/packages/${packageId}/index.mdx`),
919
+ (doc) => doc.relPath.endsWith(`/${packageId}.md`),
920
+ (doc) => doc.relPath.endsWith(`/${packageId}.mdx`),
921
+ (doc) => doc.relPath.includes(`/packages/${packageId}/`)
922
+ ];
923
+ for (const match of candidates) {
924
+ const hit = corpus.find(match);
925
+ if (hit) return hit.path;
926
+ }
927
+ return void 0;
849
928
  };
850
929
  var ownershipFromFrontmatter = (corpus) => {
851
930
  const out = [];
852
931
  for (const doc of corpus) {
853
- const id = frontmatterString(doc.frontmatter, "package") ?? (frontmatterString(doc.frontmatter, "type") === "package" ? frontmatterString(doc.frontmatter, "id") ?? doc.id : void 0);
854
- const path = frontmatterString(doc.frontmatter, "editRoot") ?? frontmatterString(doc.frontmatter, "path");
932
+ const type = frontmatterString(doc.frontmatter, "type");
933
+ const id = frontmatterString(doc.frontmatter, "package") ?? (type === "package" || type === "module" || type === "pattern" ? frontmatterString(doc.frontmatter, "id") ?? doc.id : void 0);
934
+ const path = frontmatterString(doc.frontmatter, "editRoot") ?? frontmatterString(doc.frontmatter, "path") ?? (type === "package" || type === "module" ? `packages/${id}` : void 0);
855
935
  if (!id || !path) continue;
856
936
  const purpose = frontmatterString(doc.frontmatter, "purpose") ?? doc.description;
857
937
  const checks = frontmatterStringList(doc.frontmatter, "checks");
@@ -867,13 +947,55 @@ var ownershipFromFrontmatter = (corpus) => {
867
947
  }
868
948
  return out;
869
949
  };
950
+ var ownershipFromCorpus = (corpus) => {
951
+ const out = [];
952
+ const seen = /* @__PURE__ */ new Set();
953
+ for (const doc of corpus) {
954
+ if (frontmatterString(doc.frontmatter, "package") && frontmatterString(doc.frontmatter, "editRoot")) {
955
+ continue;
956
+ }
957
+ let id;
958
+ let path;
959
+ let purpose = frontmatterString(doc.frontmatter, "purpose") ?? doc.description;
960
+ const packagesFile = /(?:^|\/)packages\/([^/]+)\.(?:md|mdx)$/.exec(doc.relPath);
961
+ const packagesIndex = /(?:^|\/)packages\/([^/]+)\/index\.(?:md|mdx)$/.exec(doc.relPath);
962
+ const registryReadme = /(?:^|\/)registry\/([^/]+)\/README\.(?:md|mdx)$/i.exec(doc.relPath);
963
+ const patternFile = /(?:^|\/)pillars\/[^/]+\/([^/]+(?:-pattern)?)\.(?:md|mdx)$/.exec(doc.relPath);
964
+ const topLevelPkg = /(?:^|\/)for-agents\/([^/]+)\.(?:md|mdx)$/.exec(doc.relPath);
965
+ if (packagesFile?.[1] && packagesFile[1] !== "index") {
966
+ id = packagesFile[1];
967
+ path = `packages/${id}`;
968
+ } else if (packagesIndex?.[1]) {
969
+ id = packagesIndex[1];
970
+ path = `packages/${id}`;
971
+ } else if (registryReadme?.[1]) {
972
+ id = registryReadme[1];
973
+ path = `registry/${id}`;
974
+ } else if (patternFile?.[1] && patternFile[1] !== "index" && patternFile[1] !== "universal") {
975
+ id = patternFile[1];
976
+ path = doc.path;
977
+ purpose = purpose ?? `Playbook pattern: ${id}`;
978
+ } else if (topLevelPkg?.[1] && topLevelPkg[1] !== "index" && topLevelPkg[1] !== "INDEX") {
979
+ id = topLevelPkg[1];
980
+ path = `packages/${id}`;
981
+ }
982
+ if (!id || !path || seen.has(id)) continue;
983
+ seen.add(id);
984
+ const humanDoc = frontmatterString(doc.frontmatter, "humanDoc");
985
+ const checks = frontmatterStringList(doc.frontmatter, "checks");
986
+ out.push({
987
+ id,
988
+ path,
989
+ agentDoc: doc.path,
990
+ ...purpose ? { purpose } : {},
991
+ ...checks ? { checks } : {},
992
+ ...humanDoc ? { humanDoc } : {}
993
+ });
994
+ }
995
+ return out;
996
+ };
870
997
 
871
998
  // src/index-builder/build-handoffs.ts
872
- var defaultChecks = (config) => {
873
- const preset = config.gates?.preset ?? "minimal";
874
- if (preset === "strict" || preset === "standard") return ["npm test", "npm run lint"];
875
- return ["npm test"];
876
- };
877
999
  var collectPackages = (config, discovered, corpus) => {
878
1000
  const byId = /* @__PURE__ */ new Map();
879
1001
  for (const [id, entry] of Object.entries(config.routing?.options?.ownership ?? {})) {
@@ -891,7 +1013,11 @@ var collectPackages = (config, discovered, corpus) => {
891
1013
  ...pkg.name ? { name: pkg.name } : existing.name ? { name: existing.name } : {}
892
1014
  });
893
1015
  }
894
- for (const seed of ownershipFromFrontmatter(corpus)) {
1016
+ const seeds = [
1017
+ ...ownershipFromFrontmatter(corpus),
1018
+ ...config.routing?.options?.ownershipFromCorpus === false ? [] : ownershipFromCorpus(corpus)
1019
+ ];
1020
+ for (const seed of seeds) {
895
1021
  const existing = byId.get(seed.id);
896
1022
  if (!existing) {
897
1023
  byId.set(seed.id, { id: seed.id, path: seed.path });
@@ -903,22 +1029,51 @@ var collectPackages = (config, discovered, corpus) => {
903
1029
  }
904
1030
  return [...byId.values()].sort((a, b) => a.id.localeCompare(b.id));
905
1031
  };
906
- var buildLookup = (config, packages, corpus, indexOutFile, humanDocs = {}) => {
1032
+ var resolveHumanDoc = (packageId, override, fmHuman, humanDocs = {}) => {
1033
+ if (override) return override;
1034
+ if (fmHuman) return fmHuman;
1035
+ if (humanDocs[packageId]) return humanDocs[packageId];
1036
+ const aliases = [
1037
+ packageId,
1038
+ packageId.replace(/^@[^/]+\//, ""),
1039
+ packageId.replace(/^os-/, ""),
1040
+ packageId.replace(/-pattern$/, "")
1041
+ ];
1042
+ for (const alias of aliases) {
1043
+ if (humanDocs[alias]) return humanDocs[alias];
1044
+ }
1045
+ return void 0;
1046
+ };
1047
+ var buildLookup = (config, packages, corpus, indexOutFile, humanDocs = {}, root = process.cwd()) => {
907
1048
  const ownership = {};
908
1049
  const handoffs = {};
909
- const checks = defaultChecks(config);
910
- const fmSeeds = new Map(ownershipFromFrontmatter(corpus).map((seed) => [seed.id, seed]));
1050
+ const strict = (config.gates?.preset ?? "minimal") !== "minimal";
1051
+ const fmSeeds = new Map(
1052
+ [...ownershipFromFrontmatter(corpus), ...ownershipFromCorpus(corpus)].map((seed) => [
1053
+ seed.id,
1054
+ seed
1055
+ ])
1056
+ );
911
1057
  for (const pkg of packages) {
912
1058
  const override = config.routing?.options?.ownership?.[pkg.id];
913
1059
  const fm = fmSeeds.get(pkg.id);
914
1060
  const agentDoc = override?.agentDoc ?? fm?.agentDoc ?? guessAgentDocForPackage(corpus, pkg.id) ?? config.corpus.agent.index;
915
1061
  const startHere = agentDoc ?? "";
916
1062
  const purpose = override?.purpose ?? fm?.purpose;
917
- const humanDoc = override?.humanDoc ?? fm?.humanDoc ?? humanDocs[pkg.id];
1063
+ const path = override?.path ?? fm?.path ?? pkg.path;
1064
+ const checks = [
1065
+ ...override?.checks ?? fm?.checks ?? defaultChecksForTarget(root, {
1066
+ packageId: pkg.id,
1067
+ packagePath: path,
1068
+ ...pkg.name ? { packageName: pkg.name } : {},
1069
+ strict
1070
+ })
1071
+ ];
1072
+ const humanDoc = resolveHumanDoc(pkg.id, override?.humanDoc, fm?.humanDoc, humanDocs);
918
1073
  const record = {
919
1074
  id: pkg.id,
920
- path: override?.path ?? fm?.path ?? pkg.path,
921
- checks: [...override?.checks ?? fm?.checks ?? checks],
1075
+ path,
1076
+ checks,
922
1077
  ...override?.group ? { group: override.group } : {},
923
1078
  ...override?.layer ? { layer: override.layer } : {},
924
1079
  ...purpose ? { purpose } : {},
@@ -972,7 +1127,7 @@ var buildLookup = (config, packages, corpus, indexOutFile, humanDocs = {}) => {
972
1127
  };
973
1128
 
974
1129
  // src/version.ts
975
- var PACKAGE_VERSION = "0.1.0-alpha.1";
1130
+ var PACKAGE_VERSION = "0.1.0-alpha.2";
976
1131
 
977
1132
  // src/index-builder/capabilities.ts
978
1133
  var renderCapabilitiesJson = (config, index, paths) => {
@@ -1041,13 +1196,13 @@ ${lines.join("\n")}
1041
1196
  };
1042
1197
 
1043
1198
  // src/index-builder/human-adapters/docusaurus.ts
1044
- import { existsSync as existsSync2, readFileSync as readFileSync4 } from "fs";
1045
- import { join as join5 } from "path";
1199
+ import { existsSync as existsSync3, readFileSync as readFileSync5 } from "fs";
1200
+ import { join as join6 } from "path";
1046
1201
  import vm2 from "vm";
1047
1202
 
1048
1203
  // src/index-builder/human-adapters/core.ts
1049
- import { readFileSync as readFileSync3 } from "fs";
1050
- import { join as join4 } from "path";
1204
+ import { readFileSync as readFileSync4 } from "fs";
1205
+ import { join as join5 } from "path";
1051
1206
  var optionString = (options, keys) => {
1052
1207
  for (const key of keys) {
1053
1208
  const value = options?.[key];
@@ -1078,10 +1233,10 @@ var humanUrl = (slug, urlPrefix) => {
1078
1233
  };
1079
1234
  var scanMarkdownDocs = (root, humanRoot, options) => {
1080
1235
  const out = [];
1081
- const absRoot = join4(root, humanRoot);
1236
+ const absRoot = join5(root, humanRoot);
1082
1237
  for (const abs of walkFiles(absRoot, { extensions: [".md", ".mdx"] })) {
1083
1238
  const relToHumanRoot = toPosix(abs.replace(`${toPosix(absRoot)}/`, ""));
1084
- const raw = readFileSync3(abs, "utf8");
1239
+ const raw = readFileSync4(abs, "utf8");
1085
1240
  if (options?.includeRelPath && !options.includeRelPath(relToHumanRoot, raw)) continue;
1086
1241
  out.push({
1087
1242
  id: options?.idForDoc?.(relToHumanRoot, raw) ?? docId(relToHumanRoot, raw),
@@ -1120,8 +1275,8 @@ var docusaurusRecordId = (relPath, raw) => {
1120
1275
  return frontmatter.package ?? frontmatter.module ?? docusaurusSidebarId(relPath, raw);
1121
1276
  };
1122
1277
  var sidebarsValue = (file) => {
1123
- if (!existsSync2(file)) return void 0;
1124
- const raw = readFileSync4(file, "utf8").replace(/import\s+type\s+[\s\S]*?;?\n/g, "").replace(/:\s*[A-Za-z0-9_.$<>{}\[\],\s]+(?=\s*=)/g, "").replace(/\s+satisfies\s+[A-Za-z0-9_.$<>{}\[\],\s]+(?=\s*(?:;|\n|$))/g, "").replace(/export\s+default/, "module.exports =");
1278
+ if (!existsSync3(file)) return void 0;
1279
+ const raw = readFileSync5(file, "utf8").replace(/import\s+type\s+[\s\S]*?;?\n/g, "").replace(/:\s*[A-Za-z0-9_.$<>{}\[\],\s]+(?=\s*=)/g, "").replace(/\s+satisfies\s+[A-Za-z0-9_.$<>{}\[\],\s]+(?=\s*(?:;|\n|$))/g, "").replace(/export\s+default/, "module.exports =");
1125
1280
  const sandbox = { module: { exports: {} }, exports: {} };
1126
1281
  vm2.runInNewContext(raw, sandbox, { timeout: 250 });
1127
1282
  return sandbox.module.exports;
@@ -1151,7 +1306,7 @@ var visitSidebar = (value, filter) => {
1151
1306
  };
1152
1307
  var readSidebars = (root, sidebarsFile) => {
1153
1308
  if (!sidebarsFile) return { enabled: false, ids: /* @__PURE__ */ new Set(), autogenDirs: [] };
1154
- const value = sidebarsValue(join5(root, sidebarsFile));
1309
+ const value = sidebarsValue(join6(root, sidebarsFile));
1155
1310
  const filter = { ids: /* @__PURE__ */ new Set(), autogenDirs: [] };
1156
1311
  visitSidebar(value, filter);
1157
1312
  return { enabled: true, ...filter };
@@ -1180,13 +1335,13 @@ var docusaurusAdapter = {
1180
1335
  };
1181
1336
 
1182
1337
  // src/index-builder/human-adapters/fumadocs.ts
1183
- import { existsSync as existsSync3, readFileSync as readFileSync5 } from "fs";
1184
- import { join as join6 } from "path";
1338
+ import { existsSync as existsSync4, readFileSync as readFileSync6 } from "fs";
1339
+ import { join as join7 } from "path";
1185
1340
  var readMetaPages = (dir) => {
1186
- const file = join6(dir, "meta.json");
1187
- if (!existsSync3(file)) return void 0;
1341
+ const file = join7(dir, "meta.json");
1342
+ if (!existsSync4(file)) return void 0;
1188
1343
  try {
1189
- const meta = JSON.parse(readFileSync5(file, "utf8"));
1344
+ const meta = JSON.parse(readFileSync6(file, "utf8"));
1190
1345
  return Array.isArray(meta.pages) ? meta.pages.filter((page) => typeof page === "string") : void 0;
1191
1346
  } catch {
1192
1347
  return void 0;
@@ -1201,7 +1356,7 @@ var isListedByMeta = (contentRoot, relPath) => {
1201
1356
  if (isDotFile(relPath)) return false;
1202
1357
  const parts = relPath.split("/");
1203
1358
  for (let i = 0; i < parts.length; i += 1) {
1204
- const dir = join6(contentRoot, ...parts.slice(0, i));
1359
+ const dir = join7(contentRoot, ...parts.slice(0, i));
1205
1360
  const pages = readMetaPages(dir);
1206
1361
  if (!pages?.length || pages.includes("...")) continue;
1207
1362
  const key = pageKey(parts[i] ?? "");
@@ -1214,9 +1369,16 @@ var fumadocsAdapter = {
1214
1369
  scan: ({ root, config }) => {
1215
1370
  const contentDir = optionString(config.options, ["contentDir", "root"]);
1216
1371
  if (!contentDir) return [];
1217
- const contentRoot = join6(root, contentDir);
1372
+ const contentRoot = join7(root, contentDir);
1373
+ const excludePrefixes = Array.isArray(config.options?.excludePrefixes) ? config.options.excludePrefixes.filter((v) => typeof v === "string") : typeof config.options?.excludePrefix === "string" ? [config.options.excludePrefix] : [];
1374
+ if (!excludePrefixes.includes("for-agents")) excludePrefixes.push("for-agents");
1218
1375
  return scanMarkdownDocs(root, contentDir, {
1219
- includeRelPath: (relPath) => isListedByMeta(contentRoot, relPath),
1376
+ includeRelPath: (relPath) => {
1377
+ if (excludePrefixes.some((prefix) => relPath === prefix || relPath.startsWith(`${prefix}/`))) {
1378
+ return false;
1379
+ }
1380
+ return isListedByMeta(contentRoot, relPath);
1381
+ },
1220
1382
  urlPrefix: config.options?.urlPrefix,
1221
1383
  stripGroups: true
1222
1384
  });
@@ -1227,7 +1389,7 @@ var fumadocsAdapter = {
1227
1389
  var plainMarkdownAdapter = {
1228
1390
  plugin: "plain-markdown",
1229
1391
  scan: ({ root, config }) => {
1230
- const humanRoot = optionString(config.options, ["root"]) ?? "docs";
1392
+ const humanRoot = optionString(config.options, ["contentDir", "root", "docsDir"]) ?? "docs";
1231
1393
  return scanMarkdownDocs(root, humanRoot, { urlPrefix: config.options?.urlPrefix });
1232
1394
  }
1233
1395
  };
@@ -1246,10 +1408,14 @@ var humanConfigs = (config) => {
1246
1408
  var scanHumanDocRecords = (root, config) => {
1247
1409
  const out = [];
1248
1410
  const seen = /* @__PURE__ */ new Set();
1411
+ const agentRoot = config.corpus.agent.root.replace(/\/$/, "");
1249
1412
  for (const human of humanConfigs(config)) {
1250
1413
  const adapter = ADAPTERS.find((candidate) => candidate.plugin === human.plugin);
1251
1414
  if (!adapter) continue;
1252
1415
  for (const record of adapter.scan({ root, config: human })) {
1416
+ if (record.path === agentRoot || record.path.startsWith(`${agentRoot}/`) || record.path.includes("/for-agents/") || record.path.endsWith("/for-agents")) {
1417
+ continue;
1418
+ }
1253
1419
  if (seen.has(record.id)) continue;
1254
1420
  seen.add(record.id);
1255
1421
  out.push(record);
@@ -1260,26 +1426,26 @@ var scanHumanDocRecords = (root, config) => {
1260
1426
  var scanHumanDocs = (root, config) => Object.fromEntries(scanHumanDocRecords(root, config).map((doc) => [doc.id, doc.url]));
1261
1427
 
1262
1428
  // src/index-builder/plugins/pnpm-monorepo.ts
1263
- import { existsSync as existsSync5, readFileSync as readFileSync6 } from "fs";
1264
- import { basename as basename2, join as join8 } from "path";
1429
+ import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
1430
+ import { basename as basename2, join as join9 } from "path";
1265
1431
 
1266
1432
  // src/lib/glob-expand.ts
1267
- import { existsSync as existsSync4, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
1268
- import { join as join7 } from "path";
1433
+ import { existsSync as existsSync5, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
1434
+ import { join as join8 } from "path";
1269
1435
  var expandWorkspaceGlobs = (root, patterns) => {
1270
1436
  const dirs = /* @__PURE__ */ new Set();
1271
1437
  for (const pattern of patterns) {
1272
1438
  const normalized = toPosix(pattern).replace(/\/$/, "");
1273
1439
  if (!normalized.includes("*")) {
1274
- const abs = join7(root, normalized);
1275
- if (existsSync4(abs)) dirs.add(toPosix(abs));
1440
+ const abs = join8(root, normalized);
1441
+ if (existsSync5(abs)) dirs.add(toPosix(abs));
1276
1442
  continue;
1277
1443
  }
1278
1444
  const star = normalized.indexOf("*");
1279
- const base = join7(root, normalized.slice(0, star).replace(/\/$/, ""));
1280
- if (!existsSync4(base)) continue;
1445
+ const base = join8(root, normalized.slice(0, star).replace(/\/$/, ""));
1446
+ if (!existsSync5(base)) continue;
1281
1447
  for (const name of readdirSync2(base)) {
1282
- const abs = join7(base, name);
1448
+ const abs = join8(base, name);
1283
1449
  try {
1284
1450
  if (statSync2(abs).isDirectory()) dirs.add(toPosix(abs));
1285
1451
  } catch {
@@ -1311,10 +1477,10 @@ var parsePnpmWorkspace = (yaml) => {
1311
1477
  return patterns;
1312
1478
  };
1313
1479
  var readPackageJson = (dir) => {
1314
- const file = join8(dir, "package.json");
1315
- if (!existsSync5(file)) return null;
1480
+ const file = join9(dir, "package.json");
1481
+ if (!existsSync6(file)) return null;
1316
1482
  try {
1317
- return JSON.parse(readFileSync6(file, "utf8"));
1483
+ return JSON.parse(readFileSync7(file, "utf8"));
1318
1484
  } catch {
1319
1485
  return null;
1320
1486
  }
@@ -1323,9 +1489,9 @@ var discoverPnpmPackages = (root, config) => {
1323
1489
  const explicit = config.routing?.options?.packages;
1324
1490
  let patterns = explicit;
1325
1491
  if (!patterns?.length) {
1326
- const workspaceFile = join8(root, "pnpm-workspace.yaml");
1327
- if (existsSync5(workspaceFile)) {
1328
- patterns = parsePnpmWorkspace(readFileSync6(workspaceFile, "utf8"));
1492
+ const workspaceFile = join9(root, "pnpm-workspace.yaml");
1493
+ if (existsSync6(workspaceFile)) {
1494
+ patterns = parsePnpmWorkspace(readFileSync7(workspaceFile, "utf8"));
1329
1495
  }
1330
1496
  }
1331
1497
  if (!patterns?.length) return [];
@@ -1346,7 +1512,7 @@ var discoverPnpmPackages = (root, config) => {
1346
1512
  var projectName = (root, config) => {
1347
1513
  if (config.project?.name) return config.project.name;
1348
1514
  try {
1349
- const pkg = JSON.parse(readFileSync7(join9(root, "package.json"), "utf8"));
1515
+ const pkg = JSON.parse(readFileSync8(join10(root, "package.json"), "utf8"));
1350
1516
  if (pkg.name) return pkg.name;
1351
1517
  } catch {
1352
1518
  }
@@ -1354,7 +1520,7 @@ var projectName = (root, config) => {
1354
1520
  };
1355
1521
  var existingGeneratedAt = (indexPath, contentHash) => {
1356
1522
  try {
1357
- const index = JSON.parse(readFileSync7(indexPath, "utf8"));
1523
+ const index = JSON.parse(readFileSync8(indexPath, "utf8"));
1358
1524
  return index.contentHash === contentHash && typeof index.generatedAt === "string" ? index.generatedAt : void 0;
1359
1525
  } catch {
1360
1526
  return void 0;
@@ -1365,14 +1531,14 @@ var buildDocBridgeIndex = (opts) => {
1365
1531
  const config = opts.config;
1366
1532
  const write = opts.write ?? true;
1367
1533
  const outFile = config.index?.outFile ?? ".doc-bridge/index.json";
1368
- const indexPath = join9(root, outFile);
1534
+ const indexPath = join10(root, outFile);
1369
1535
  const corpus = scanAgentCorpus(root, config);
1370
1536
  const knowledge = corpus.map(({ absPath: _a, relPath: _r, frontmatter: _f, ...entry }) => entry);
1371
1537
  const shouldDiscover = config.routing?.plugin === "pnpm-monorepo" || Boolean(config.routing?.options?.packages?.length) || config.routing?.plugin === "npm-workspaces" || config.routing?.plugin === "yarn-workspaces";
1372
1538
  const discovered = shouldDiscover ? discoverPnpmPackages(root, config) : [];
1373
1539
  const packages = collectPackages(config, discovered, corpus);
1374
1540
  const humanDocs = scanHumanDocs(root, config);
1375
- const { lookup, handoffs } = buildLookup(config, packages, corpus, outFile, humanDocs);
1541
+ const { lookup, handoffs } = buildLookup(config, packages, corpus, outFile, humanDocs, root);
1376
1542
  const hashPayload = {
1377
1543
  schemaVersion: 1,
1378
1544
  knowledge,
@@ -1400,7 +1566,7 @@ var buildDocBridgeIndex = (opts) => {
1400
1566
  if (config.index?.llmsTxt?.enabled !== false) {
1401
1567
  const llmsOut = config.index?.llmsTxt?.outFile ?? "llms.txt";
1402
1568
  llmsTxtRelPath = toPosix(llmsOut);
1403
- llmsTxtPath = join9(root, llmsOut);
1569
+ llmsTxtPath = join10(root, llmsOut);
1404
1570
  if (write) {
1405
1571
  writeFileSync(
1406
1572
  llmsTxtPath,
@@ -1412,7 +1578,7 @@ var buildDocBridgeIndex = (opts) => {
1412
1578
  let capabilitiesPath;
1413
1579
  if (config.index?.capabilities?.enabled !== false) {
1414
1580
  const capabilitiesOut = config.index?.capabilities?.outFile ?? ".doc-bridge/capabilities.json";
1415
- capabilitiesPath = join9(root, capabilitiesOut);
1581
+ capabilitiesPath = join10(root, capabilitiesOut);
1416
1582
  if (write) {
1417
1583
  mkdirSync(dirname3(capabilitiesPath), { recursive: true });
1418
1584
  writeFileSync(
@@ -1434,11 +1600,11 @@ var buildDocBridgeIndex = (opts) => {
1434
1600
  };
1435
1601
 
1436
1602
  // src/gates/run-gates.ts
1437
- import { readFileSync as readFileSync9 } from "fs";
1603
+ import { readFileSync as readFileSync10 } from "fs";
1438
1604
 
1439
1605
  // src/query/load-index.ts
1440
- import { existsSync as existsSync6, readFileSync as readFileSync8 } from "fs";
1441
- import { join as join10, resolve as resolve3 } from "path";
1606
+ import { existsSync as existsSync7, readFileSync as readFileSync9 } from "fs";
1607
+ import { join as join11, resolve as resolve3 } from "path";
1442
1608
  var IndexNotFoundError = class extends Error {
1443
1609
  constructor(path) {
1444
1610
  super(`Missing index at ${path}. Run: ak-docs index`);
@@ -1447,11 +1613,11 @@ var IndexNotFoundError = class extends Error {
1447
1613
  }
1448
1614
  path;
1449
1615
  };
1450
- var indexFilePath = (root, config) => join10(root, config.index?.outFile ?? ".doc-bridge/index.json");
1616
+ var indexFilePath = (root, config) => join11(root, config.index?.outFile ?? ".doc-bridge/index.json");
1451
1617
  var loadDocBridgeIndex = (root, config) => {
1452
1618
  const path = indexFilePath(root, config);
1453
- if (!existsSync6(path)) throw new IndexNotFoundError(path);
1454
- const raw = JSON.parse(readFileSync8(path, "utf8"));
1619
+ if (!existsSync7(path)) throw new IndexNotFoundError(path);
1620
+ const raw = JSON.parse(readFileSync9(path, "utf8"));
1455
1621
  return parseDocBridgeIndex(raw);
1456
1622
  };
1457
1623
  var resolveRoot = (cwd) => resolve3(cwd ?? process.cwd());
@@ -1516,7 +1682,7 @@ var runOkfTypeGate = (root, config) => {
1516
1682
  const required = config.corpus.agent.okf?.requireType ?? config.gates?.preset === "strict";
1517
1683
  if (!required) return { id: "okf-type", ok: true, message: "OKF type frontmatter not required" };
1518
1684
  const allowed = config.corpus.agent.okf?.allowedTypes;
1519
- const bad = scanAgentCorpus(root, config).filter((doc) => doc.path !== config.corpus.agent.index).map((doc) => ({ path: doc.path, type: frontmatterType(readFileSync9(doc.absPath, "utf8")) })).filter((doc) => !doc.type || allowed && !allowed.includes(doc.type));
1685
+ const bad = scanAgentCorpus(root, config).filter((doc) => doc.path !== config.corpus.agent.index).map((doc) => ({ path: doc.path, type: frontmatterType(readFileSync10(doc.absPath, "utf8")) })).filter((doc) => !doc.type || allowed && !allowed.includes(doc.type));
1520
1686
  if (bad.length) {
1521
1687
  return {
1522
1688
  id: "okf-type",
@@ -1537,13 +1703,22 @@ var DOCS_STYLE_RULES = {
1537
1703
  "examples",
1538
1704
  "no-stale-wording"
1539
1705
  ],
1540
- "playbook-okf": ["title", "purpose", "owner-source", "no-stale-wording"]
1706
+ /** Full playbook OKF style (strict). */
1707
+ "playbook-okf": ["title", "purpose", "owner-source", "no-stale-wording"],
1708
+ /** Soft profile for large existing OKF corpora (title + no stale placeholders). */
1709
+ "playbook-okf-soft": ["title", "no-stale-wording"],
1710
+ "title-only": ["title"]
1541
1711
  };
1542
1712
  var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1543
1713
  var docsStyleOptions = (config) => {
1544
1714
  const raw = config.gates?.options?.["docs-style"];
1545
- if (!isRecord(raw)) return { profile: "playbook-okf", required: DOCS_STYLE_RULES["playbook-okf"] };
1546
- const profile = raw.profile === "google-dev-docs" || raw.profile === "playbook-okf" || raw.profile === "custom" ? raw.profile : "playbook-okf";
1715
+ if (!isRecord(raw)) {
1716
+ if (config.gates?.preset === "playbook") {
1717
+ return { profile: "playbook-okf-soft", required: DOCS_STYLE_RULES["playbook-okf-soft"] };
1718
+ }
1719
+ return { profile: "playbook-okf", required: DOCS_STYLE_RULES["playbook-okf"] };
1720
+ }
1721
+ const profile = raw.profile === "google-dev-docs" || raw.profile === "playbook-okf" || raw.profile === "playbook-okf-soft" || raw.profile === "title-only" || raw.profile === "custom" ? raw.profile : "playbook-okf";
1547
1722
  const customRequired = Array.isArray(raw.required) ? raw.required.filter(
1548
1723
  (rule) => [
1549
1724
  "title",
@@ -1581,7 +1756,7 @@ var runDocsStyleGate = (root, config) => {
1581
1756
  }
1582
1757
  const bad = scanAgentCorpus(root, config).filter((doc) => doc.path !== config.corpus.agent.index).map((doc) => ({
1583
1758
  path: doc.path,
1584
- missing: missingStyleRules(readFileSync9(doc.absPath, "utf8"), required)
1759
+ missing: missingStyleRules(readFileSync10(doc.absPath, "utf8"), required)
1585
1760
  })).filter((doc) => doc.missing.length > 0);
1586
1761
  if (bad.length) {
1587
1762
  return {
@@ -1605,7 +1780,10 @@ var runGates = (root, config, ids) => {
1605
1780
  var resolveGateIds = (config) => {
1606
1781
  const preset = config.gates?.preset ?? "minimal";
1607
1782
  const ids = new Set(
1608
- preset === "minimal" ? ["index-freshness"] : preset === "strict" ? ["index-freshness", "human-guide-links", "okf-type"] : ["index-freshness", "human-guide-links"]
1783
+ preset === "minimal" ? ["index-freshness"] : preset === "strict" ? ["index-freshness", "human-guide-links", "okf-type", "docs-style"] : preset === "playbook" ? (
1784
+ // okf-type only — docs-style soft is opt-in via include (large corpora vary)
1785
+ ["index-freshness", "okf-type"]
1786
+ ) : ["index-freshness", "human-guide-links"]
1609
1787
  );
1610
1788
  for (const id of config.gates?.include ?? []) {
1611
1789
  if (SUPPORTED_GATES.includes(id)) ids.add(id);
@@ -1617,7 +1795,7 @@ var resolveGateIds = (config) => {
1617
1795
  };
1618
1796
 
1619
1797
  // src/mcp/server.ts
1620
- import { readFileSync as readFileSync11, realpathSync } from "fs";
1798
+ import { readFileSync as readFileSync12, realpathSync } from "fs";
1621
1799
  import { relative, resolve as resolve4 } from "path";
1622
1800
  import { z as z5, ZodError } from "zod";
1623
1801
 
@@ -1689,15 +1867,15 @@ var createDocBridgeRetriever = (index, options = {}) => ({
1689
1867
  });
1690
1868
 
1691
1869
  // src/memory/ingest.ts
1692
- import { existsSync as existsSync7, readFileSync as readFileSync10 } from "fs";
1693
- import { join as join11 } from "path";
1870
+ import { existsSync as existsSync8, readFileSync as readFileSync11 } from "fs";
1871
+ import { join as join12 } from "path";
1694
1872
  var memoryFact = (raw, id) => firstParagraph(raw) ?? firstHeading(raw) ?? id;
1695
1873
  var relativePath = (root, abs) => toPosix(abs).replace(`${toPosix(root)}/`, "");
1696
1874
  var ingestMarkdownDir = (root, dir, source, confidence) => {
1697
- if (!existsSync7(dir)) return [];
1875
+ if (!existsSync8(dir)) return [];
1698
1876
  return walkFiles(dir, { extensions: [".md", ".mdc"] }).map((abs) => {
1699
1877
  const rel = relativePath(root, abs);
1700
- const raw = readFileSync10(abs, "utf8");
1878
+ const raw = readFileSync11(abs, "utf8");
1701
1879
  const id = slugFromPath(rel);
1702
1880
  return {
1703
1881
  schemaVersion: 1,
@@ -1712,10 +1890,10 @@ var ingestMarkdownDir = (root, dir, source, confidence) => {
1712
1890
  });
1713
1891
  };
1714
1892
  var ingestCursorRules = (root) => {
1715
- const dir = join11(root, ".cursor", "rules");
1893
+ const dir = join12(root, ".cursor", "rules");
1716
1894
  return ingestMarkdownDir(root, dir, "cursor", 0.6);
1717
1895
  };
1718
- var ingestAgentMemory = (root) => ingestMarkdownDir(root, join11(root, ".agent-memory"), "agent-memory", 0.7);
1896
+ var ingestAgentMemory = (root) => ingestMarkdownDir(root, join12(root, ".agent-memory"), "agent-memory", 0.7);
1719
1897
  var ingestMemoryCandidates = (root) => [
1720
1898
  ...ingestAgentMemory(root),
1721
1899
  ...ingestCursorRules(root)
@@ -2020,7 +2198,7 @@ var handleMcpRequest = (ctx, request) => {
2020
2198
  return {
2021
2199
  protocolVersion: "2024-11-05",
2022
2200
  capabilities: { tools: {} },
2023
- serverInfo: { name: "ak-docs", version: "0.1.0-alpha.1" }
2201
+ serverInfo: { name: "ak-docs", version: PACKAGE_VERSION }
2024
2202
  };
2025
2203
  }
2026
2204
  if (request.method === "tools/list") return { tools: MCP_TOOLS };
@@ -2045,7 +2223,7 @@ var handleMcpRequest = (ctx, request) => {
2045
2223
  }
2046
2224
  if (name === "doc.get") {
2047
2225
  const relPath = findDocPath(index(), parseToolArgs("doc.get", DocGetArgsSchema, args));
2048
- return textResult(readFileSync11(resolveDocPath(ctx.root, relPath), "utf8"));
2226
+ return textResult(readFileSync12(resolveDocPath(ctx.root, relPath), "utf8"));
2049
2227
  }
2050
2228
  if (name === "gate.status") return textResult(runGates(ctx.root, ctx.config));
2051
2229
  if (name === "retriever.query") {
@@ -2123,7 +2301,7 @@ var startMcpStdioServer = (ctx) => {
2123
2301
  };
2124
2302
 
2125
2303
  // src/federation/llms.ts
2126
- import { existsSync as existsSync8, readFileSync as readFileSync12 } from "fs";
2304
+ import { existsSync as existsSync9, readFileSync as readFileSync13 } from "fs";
2127
2305
  import { resolve as resolve5 } from "path";
2128
2306
  var tokenize2 = (value) => value.toLowerCase().split(/[^a-z0-9]+/).filter((token) => token.length >= 2);
2129
2307
  var scoreText = (query, text) => {
@@ -2139,8 +2317,8 @@ var defaultFetchText = async (url) => {
2139
2317
  var sourceText = async (root, source, fetchText) => {
2140
2318
  if (/^https?:\/\//.test(source)) return fetchText(source);
2141
2319
  const path = resolve5(root, source);
2142
- if (!existsSync8(path)) throw new Error(`Federation source not found: ${source}`);
2143
- return readFileSync12(path, "utf8");
2320
+ if (!existsSync9(path)) throw new Error(`Federation source not found: ${source}`);
2321
+ return readFileSync13(path, "utf8");
2144
2322
  };
2145
2323
  var sameOrigin = (base, target) => {
2146
2324
  if (!/^https?:\/\//.test(base) || !/^https?:\/\//.test(target)) return true;
@@ -2216,11 +2394,11 @@ var retrieveHybridChunks = async (root, config, index, query, options = {}) => {
2216
2394
  };
2217
2395
 
2218
2396
  // src/intelligence/rag.ts
2219
- import { readFileSync as readFileSync13 } from "fs";
2220
- import { join as join13 } from "path";
2397
+ import { readFileSync as readFileSync14 } from "fs";
2398
+ import { join as join14 } from "path";
2221
2399
 
2222
2400
  // src/intelligence/adapter.ts
2223
- import { join as join12 } from "path";
2401
+ import { join as join13 } from "path";
2224
2402
 
2225
2403
  // src/intelligence/peers.ts
2226
2404
  var PeerMissingError = class extends Error {
@@ -2335,7 +2513,7 @@ var resolveIntelligenceRuntime = async (config) => {
2335
2513
  }
2336
2514
  return { adapter, embed, provider, ...model ? { model } : {} };
2337
2515
  };
2338
- var defaultVectorStorePath = (root) => join12(root, ".doc-bridge", "vectors");
2516
+ var defaultVectorStorePath = (root) => join13(root, ".doc-bridge", "vectors");
2339
2517
 
2340
2518
  // src/intelligence/rag.ts
2341
2519
  var loadDocuments = (root, index, sources) => {
@@ -2343,10 +2521,10 @@ var loadDocuments = (root, index, sources) => {
2343
2521
  const docs = [];
2344
2522
  if (includeAgent) {
2345
2523
  for (const entry of index.knowledge) {
2346
- const abs = join13(root, entry.path);
2524
+ const abs = join14(root, entry.path);
2347
2525
  let content = "";
2348
2526
  try {
2349
- content = readFileSync13(abs, "utf8");
2527
+ content = readFileSync14(abs, "utf8");
2350
2528
  } catch {
2351
2529
  content = [entry.title, entry.description].filter(Boolean).join("\n\n");
2352
2530
  }
@@ -2364,7 +2542,7 @@ var createDocBridgeRag = async (root, config, index) => {
2364
2542
  const { embed } = await resolveIntelligenceRuntime(config);
2365
2543
  const ragMod = await importPeer("@agentskit/rag");
2366
2544
  const memoryMod = await importPeer("@agentskit/memory");
2367
- const storePath = typeof config.intelligence?.retriever?.options?.storePath === "string" ? join13(root, config.intelligence.retriever.options.storePath) : defaultVectorStorePath(root);
2545
+ const storePath = typeof config.intelligence?.retriever?.options?.storePath === "string" ? join14(root, config.intelligence.retriever.options.storePath) : defaultVectorStorePath(root);
2368
2546
  const store = memoryMod.fileVectorMemory({ path: storePath });
2369
2547
  const rag = ragMod.createRAG({
2370
2548
  embed,