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