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