@agentskit/doc-bridge 1.11.1 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -1
- package/README.md +3 -2
- package/action.yml +1 -1
- package/dist/cli/program.js +582 -471
- package/dist/cli/program.js.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.js +500 -389
- package/dist/index.js.map +1 -1
- package/docs/DESIGN.md +71 -0
- package/docs/MARKETPLACE-ECOSYSTEM-PLAN.md +1 -1
- package/docs/PRD-enterprise-hardening.md +5 -5
- package/docs/PRD-knowledge-retrieval-and-enrichment.md +1 -1
- package/docs/knowledge-engine-runbook.md +1 -1
- package/docs/loop-workflow.md +15 -15
- package/docs/spec/config-v1.md +29 -7
- package/docs/spec/documentation-standard-v1.md +5 -0
- package/docs/spec/mcp-knowledge-tools-v1.md +1 -1
- package/docs/validation-cycle-plan.md +13 -13
- package/ecosystem-claims.json +17 -17
- package/ecosystem-upstream.json +2 -2
- package/ecosystem.json +300 -147
- package/mcpb/manifest.json +1 -1
- package/package.json +2 -1
- package/skills/doc-bridge-handoff/SKILL.md +1 -1
- package/skills/doc-bridge-handoff/scripts/resolve-handoff.mjs +1 -1
- package/src/conformance/ecosystem-contract.ts +10 -26
- package/src/discovery/repository.ts +7 -1
- package/src/findings/report.ts +1 -1
- package/src/fixes/proposals.ts +4 -2
- package/src/gates/run-gates.ts +1 -1
- package/src/index-builder/human-adapters/core.ts +10 -4
- package/src/lib/ignore-filter.ts +151 -0
- package/src/lib/walk.ts +10 -2
- package/src/memory/ingest.ts +1 -1
- package/src/report/html.ts +1 -1
- package/src/safety/repository.ts +9 -0
- package/src/version.ts +1 -1
- package/docs/DOGFOOD-ROUND2.md +0 -147
- package/docs/DOGFOOD-ROUND3.md +0 -79
- package/docs/DOGFOOD-V1.md +0 -89
- package/docs/DOGFOOD.md +0 -97
package/dist/index.js
CHANGED
|
@@ -1716,8 +1716,8 @@ ${zodIssues(result.error).map((i) => ` - ${i.path}: ${i.message}`).join("\n")}`
|
|
|
1716
1716
|
};
|
|
1717
1717
|
|
|
1718
1718
|
// src/index-builder/build-index.ts
|
|
1719
|
-
import { mkdirSync as mkdirSync2, readFileSync as
|
|
1720
|
-
import { dirname as
|
|
1719
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync12, writeFileSync as writeFileSync2 } from "fs";
|
|
1720
|
+
import { dirname as dirname5, join as join11 } from "path";
|
|
1721
1721
|
|
|
1722
1722
|
// src/discovery/documentation.ts
|
|
1723
1723
|
import { parseDocument } from "yaml";
|
|
@@ -1831,8 +1831,8 @@ var nodeStart = (node) => {
|
|
|
1831
1831
|
var conventionalPackageReference = (path, agentRoot) => {
|
|
1832
1832
|
const prefix = `${agentRoot.replace(/\/$/, "")}/`;
|
|
1833
1833
|
if (!path.startsWith(prefix)) return void 0;
|
|
1834
|
-
const
|
|
1835
|
-
const [scope, file] =
|
|
1834
|
+
const relative13 = path.slice(prefix.length);
|
|
1835
|
+
const [scope, file] = relative13.split("/");
|
|
1836
1836
|
if (scope !== "packages" && scope !== "apps" || !file) return void 0;
|
|
1837
1837
|
return file.replace(/\.mdx?$/, "");
|
|
1838
1838
|
};
|
|
@@ -2145,9 +2145,9 @@ var applyDocumentationDeclarations = (snapshot, documents, options = {}) => {
|
|
|
2145
2145
|
};
|
|
2146
2146
|
|
|
2147
2147
|
// src/discovery/repository.ts
|
|
2148
|
-
import { execFileSync } from "child_process";
|
|
2149
|
-
import { existsSync as
|
|
2150
|
-
import { basename as basename2, dirname as
|
|
2148
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
2149
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
|
|
2150
|
+
import { basename as basename2, dirname as dirname3, extname as extname2, join as join6, relative as relative4, resolve as resolve5, sep as sep4 } from "path";
|
|
2151
2151
|
import * as ts2 from "typescript";
|
|
2152
2152
|
|
|
2153
2153
|
// src/lib/glob-expand.ts
|
|
@@ -2163,9 +2163,9 @@ var containedProjectPath = (root, path) => {
|
|
|
2163
2163
|
const unresolved = resolve2(projectRoot, path);
|
|
2164
2164
|
const unresolvedRelative = relative(projectRoot, unresolved);
|
|
2165
2165
|
if (isAbsolute(unresolvedRelative) || unresolvedRelative === ".." || unresolvedRelative.startsWith(`..${sep}`)) return void 0;
|
|
2166
|
-
const
|
|
2167
|
-
const canonicalRelative = relative(projectRoot,
|
|
2168
|
-
return isAbsolute(canonicalRelative) || canonicalRelative === ".." || canonicalRelative.startsWith(`..${sep}`) ? void 0 :
|
|
2166
|
+
const canonical2 = existsSync2(unresolved) ? realpathSync.native(unresolved) : unresolved;
|
|
2167
|
+
const canonicalRelative = relative(projectRoot, canonical2);
|
|
2168
|
+
return isAbsolute(canonicalRelative) || canonicalRelative === ".." || canonicalRelative.startsWith(`..${sep}`) ? void 0 : canonical2;
|
|
2169
2169
|
};
|
|
2170
2170
|
|
|
2171
2171
|
// src/lib/glob-expand.ts
|
|
@@ -2257,25 +2257,140 @@ var defaultChecksForTarget = (root, opts) => {
|
|
|
2257
2257
|
};
|
|
2258
2258
|
|
|
2259
2259
|
// src/safety/repository.ts
|
|
2260
|
-
import { lstatSync, readdirSync as readdirSync2, realpathSync as
|
|
2261
|
-
import { isAbsolute as
|
|
2260
|
+
import { lstatSync, readdirSync as readdirSync2, realpathSync as realpathSync3, statSync as statSync2 } from "fs";
|
|
2261
|
+
import { isAbsolute as isAbsolute3, relative as relative3, resolve as resolve4, sep as sep3 } from "path";
|
|
2262
2262
|
import { minimatch } from "minimatch";
|
|
2263
|
+
|
|
2264
|
+
// src/lib/ignore-filter.ts
|
|
2265
|
+
import { execFileSync } from "child_process";
|
|
2266
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, realpathSync as realpathSync2 } from "fs";
|
|
2267
|
+
import { dirname as dirname2, isAbsolute as isAbsolute2, join as join4, relative as relative2, resolve as resolve3, sep as sep2 } from "path";
|
|
2268
|
+
import ignore from "ignore";
|
|
2269
|
+
var toPosix2 = (value) => value.split(sep2).join("/");
|
|
2270
|
+
var canonical = (path) => {
|
|
2271
|
+
try {
|
|
2272
|
+
return realpathSync2.native(resolve3(path));
|
|
2273
|
+
} catch {
|
|
2274
|
+
return resolve3(path);
|
|
2275
|
+
}
|
|
2276
|
+
};
|
|
2277
|
+
var below = (root, candidate) => {
|
|
2278
|
+
const rel = relative2(root, candidate);
|
|
2279
|
+
if (rel === "") return "";
|
|
2280
|
+
if (isAbsolute2(rel) || rel === ".." || rel.startsWith(`..${sep2}`)) return void 0;
|
|
2281
|
+
return toPosix2(rel);
|
|
2282
|
+
};
|
|
2283
|
+
var gitVisibleFiles = (root) => {
|
|
2284
|
+
try {
|
|
2285
|
+
const inside = execFileSync("git", ["rev-parse", "--is-inside-work-tree"], {
|
|
2286
|
+
cwd: root,
|
|
2287
|
+
encoding: "utf8",
|
|
2288
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
2289
|
+
}).trim();
|
|
2290
|
+
if (inside !== "true") return void 0;
|
|
2291
|
+
const output = execFileSync("git", ["ls-files", "-z", "--cached", "--others", "--exclude-standard", "--", "."], {
|
|
2292
|
+
cwd: root,
|
|
2293
|
+
encoding: "utf8",
|
|
2294
|
+
maxBuffer: 256 * 1024 * 1024,
|
|
2295
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
2296
|
+
});
|
|
2297
|
+
return output.split("\0").filter(Boolean);
|
|
2298
|
+
} catch {
|
|
2299
|
+
return void 0;
|
|
2300
|
+
}
|
|
2301
|
+
};
|
|
2302
|
+
var gitFilter = (root, canonicalRoot, visible) => {
|
|
2303
|
+
const files = new Set(visible.filter((path) => !path.endsWith("/")));
|
|
2304
|
+
const directories = /* @__PURE__ */ new Set([""]);
|
|
2305
|
+
for (const file of visible) {
|
|
2306
|
+
let parent = file;
|
|
2307
|
+
for (; ; ) {
|
|
2308
|
+
const slash = parent.lastIndexOf("/");
|
|
2309
|
+
if (slash === -1) break;
|
|
2310
|
+
parent = parent.slice(0, slash);
|
|
2311
|
+
if (directories.has(parent)) break;
|
|
2312
|
+
directories.add(parent);
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
return {
|
|
2316
|
+
mode: "git",
|
|
2317
|
+
isIgnored: (absolutePath, isDirectory) => {
|
|
2318
|
+
const rel = below(root, resolve3(absolutePath)) ?? below(canonicalRoot, canonical(absolutePath));
|
|
2319
|
+
if (rel === void 0) return false;
|
|
2320
|
+
return isDirectory ? !directories.has(rel) : !files.has(rel);
|
|
2321
|
+
}
|
|
2322
|
+
};
|
|
2323
|
+
};
|
|
2324
|
+
var gitignoreFilter = (root) => {
|
|
2325
|
+
const rules = /* @__PURE__ */ new Map();
|
|
2326
|
+
const rulesFor = (directory) => {
|
|
2327
|
+
if (rules.has(directory)) return rules.get(directory);
|
|
2328
|
+
const file = join4(directory, ".gitignore");
|
|
2329
|
+
let matcher;
|
|
2330
|
+
if (existsSync5(file)) {
|
|
2331
|
+
try {
|
|
2332
|
+
matcher = ignore().add(readFileSync3(file, "utf8"));
|
|
2333
|
+
} catch {
|
|
2334
|
+
matcher = void 0;
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
rules.set(directory, matcher);
|
|
2338
|
+
return matcher;
|
|
2339
|
+
};
|
|
2340
|
+
const ignoredCache = /* @__PURE__ */ new Map();
|
|
2341
|
+
const isIgnored = (absolutePath, isDirectory) => {
|
|
2342
|
+
const target2 = resolve3(absolutePath);
|
|
2343
|
+
const rel = below(root, target2);
|
|
2344
|
+
if (rel === void 0 || rel === "") return false;
|
|
2345
|
+
const key = `${isDirectory ? "d" : "f"}:${rel}`;
|
|
2346
|
+
const cached = ignoredCache.get(key);
|
|
2347
|
+
if (cached !== void 0) return cached;
|
|
2348
|
+
const parent = dirname2(target2);
|
|
2349
|
+
let result = parent !== root && below(root, parent) !== void 0 ? isIgnored(parent, true) : false;
|
|
2350
|
+
if (!result) {
|
|
2351
|
+
let decided;
|
|
2352
|
+
let directory = root;
|
|
2353
|
+
const segments = below(root, parent)?.split("/").filter(Boolean) ?? [];
|
|
2354
|
+
for (let index = 0; index <= segments.length; index += 1) {
|
|
2355
|
+
if (index > 0) directory = join4(directory, segments[index - 1]);
|
|
2356
|
+
const matcher = rulesFor(directory);
|
|
2357
|
+
if (!matcher) continue;
|
|
2358
|
+
const local = toPosix2(relative2(directory, target2)) + (isDirectory ? "/" : "");
|
|
2359
|
+
const verdict = matcher.test(local);
|
|
2360
|
+
if (verdict.ignored) decided = true;
|
|
2361
|
+
else if (verdict.unignored) decided = false;
|
|
2362
|
+
}
|
|
2363
|
+
result = decided ?? false;
|
|
2364
|
+
}
|
|
2365
|
+
ignoredCache.set(key, result);
|
|
2366
|
+
return result;
|
|
2367
|
+
};
|
|
2368
|
+
return { mode: "gitignore", isIgnored };
|
|
2369
|
+
};
|
|
2370
|
+
var createIgnoreFilter = (root) => {
|
|
2371
|
+
const base = resolve3(root);
|
|
2372
|
+
const canonicalRoot = canonical(root);
|
|
2373
|
+
const visible = gitVisibleFiles(canonicalRoot);
|
|
2374
|
+
return visible ? gitFilter(base, canonicalRoot, visible) : gitignoreFilter(base);
|
|
2375
|
+
};
|
|
2376
|
+
|
|
2377
|
+
// src/safety/repository.ts
|
|
2263
2378
|
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"];
|
|
2264
2379
|
var containedPath = (root, candidate) => {
|
|
2265
|
-
const projectRoot =
|
|
2266
|
-
const unresolved =
|
|
2267
|
-
const unresolvedRelative =
|
|
2268
|
-
if (
|
|
2380
|
+
const projectRoot = realpathSync3.native(resolve4(root));
|
|
2381
|
+
const unresolved = resolve4(projectRoot, candidate);
|
|
2382
|
+
const unresolvedRelative = relative3(projectRoot, unresolved);
|
|
2383
|
+
if (isAbsolute3(unresolvedRelative) || unresolvedRelative === ".." || unresolvedRelative.startsWith(`..${sep3}`)) return void 0;
|
|
2269
2384
|
try {
|
|
2270
|
-
const
|
|
2271
|
-
const canonicalRelative =
|
|
2272
|
-
return
|
|
2385
|
+
const canonical2 = realpathSync3.native(unresolved);
|
|
2386
|
+
const canonicalRelative = relative3(projectRoot, canonical2);
|
|
2387
|
+
return isAbsolute3(canonicalRelative) || canonicalRelative === ".." || canonicalRelative.startsWith(`..${sep3}`) ? void 0 : canonical2;
|
|
2273
2388
|
} catch {
|
|
2274
2389
|
return unresolved;
|
|
2275
2390
|
}
|
|
2276
2391
|
};
|
|
2277
2392
|
var safeWalkFiles = (root, options = {}) => {
|
|
2278
|
-
const projectRoot =
|
|
2393
|
+
const projectRoot = resolve4(root);
|
|
2279
2394
|
const extensions = options.extensions ?? [];
|
|
2280
2395
|
const excludes = options.exclude ?? DEFAULT_SAFETY_EXCLUDES;
|
|
2281
2396
|
const files = [];
|
|
@@ -2283,6 +2398,7 @@ var safeWalkFiles = (root, options = {}) => {
|
|
|
2283
2398
|
let reason;
|
|
2284
2399
|
const started = Date.now();
|
|
2285
2400
|
const matchesExclude = (path) => excludes.some((pattern) => minimatch(path, pattern, { dot: true }));
|
|
2401
|
+
const ignored = options.respectIgnore === false ? void 0 : createIgnoreFilter(projectRoot);
|
|
2286
2402
|
const visit2 = (directory) => {
|
|
2287
2403
|
if (reason) return;
|
|
2288
2404
|
if (options.maxTimeMs !== void 0 && Date.now() - started >= options.maxTimeMs) {
|
|
@@ -2300,8 +2416,8 @@ var safeWalkFiles = (root, options = {}) => {
|
|
|
2300
2416
|
return;
|
|
2301
2417
|
}
|
|
2302
2418
|
for (const name of entries.sort()) {
|
|
2303
|
-
const absolute =
|
|
2304
|
-
const relativePath3 =
|
|
2419
|
+
const absolute = resolve4(directory, name);
|
|
2420
|
+
const relativePath3 = relative3(projectRoot, absolute).split(sep3).join("/");
|
|
2305
2421
|
if (matchesExclude(relativePath3) || name === ".git") continue;
|
|
2306
2422
|
let stats;
|
|
2307
2423
|
try {
|
|
@@ -2310,6 +2426,7 @@ var safeWalkFiles = (root, options = {}) => {
|
|
|
2310
2426
|
continue;
|
|
2311
2427
|
}
|
|
2312
2428
|
if (stats.isSymbolicLink()) continue;
|
|
2429
|
+
if (ignored?.isIgnored(absolute, stats.isDirectory())) continue;
|
|
2313
2430
|
if (stats.isDirectory()) {
|
|
2314
2431
|
visit2(absolute);
|
|
2315
2432
|
if (reason) return;
|
|
@@ -2546,11 +2663,11 @@ var relativeToPackage = (modulePath, packagePath) => {
|
|
|
2546
2663
|
const prefix = `${packagePath}/`;
|
|
2547
2664
|
return modulePath.startsWith(prefix) ? modulePath.slice(prefix.length) : void 0;
|
|
2548
2665
|
};
|
|
2549
|
-
var
|
|
2666
|
+
var join5 = (...parts) => parts.filter(Boolean).join("/");
|
|
2550
2667
|
var conventionalAreaPath = (module, depth = DEFAULT_AREA_DEPTH, roots = DEFAULT_AREA_ROOTS) => {
|
|
2551
|
-
const
|
|
2552
|
-
if (
|
|
2553
|
-
const segments =
|
|
2668
|
+
const relative13 = relativeToPackage(normalize(module.path), normalize(module.packagePath));
|
|
2669
|
+
if (relative13 === void 0) return void 0;
|
|
2670
|
+
const segments = relative13.split("/");
|
|
2554
2671
|
segments.pop();
|
|
2555
2672
|
if (!segments.length) return void 0;
|
|
2556
2673
|
const rootPrefix = [];
|
|
@@ -2562,7 +2679,7 @@ var conventionalAreaPath = (module, depth = DEFAULT_AREA_DEPTH, roots = DEFAULT_
|
|
|
2562
2679
|
const taken = rest.slice(0, Math.max(1, depth));
|
|
2563
2680
|
if (!taken.length) return void 0;
|
|
2564
2681
|
const packagePath = normalize(module.packagePath);
|
|
2565
|
-
return
|
|
2682
|
+
return join5(packagePath === "." ? "" : packagePath, ...rootPrefix, ...taken);
|
|
2566
2683
|
};
|
|
2567
2684
|
var encloses = (candidate, path) => path === candidate || path.startsWith(`${candidate}/`);
|
|
2568
2685
|
var deriveAreas = (options) => {
|
|
@@ -3246,13 +3363,13 @@ var MAX_MARKDOWN_NOTES = 32;
|
|
|
3246
3363
|
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3247
3364
|
var readJson = (path) => {
|
|
3248
3365
|
try {
|
|
3249
|
-
const value = JSON.parse(
|
|
3366
|
+
const value = JSON.parse(readFileSync4(path, "utf8"));
|
|
3250
3367
|
return isRecord(value) ? { value } : { error: "JSON root is not an object" };
|
|
3251
3368
|
} catch (error) {
|
|
3252
3369
|
return { error: error instanceof Error ? error.message : String(error) };
|
|
3253
3370
|
}
|
|
3254
3371
|
};
|
|
3255
|
-
var relativePath = (root, path) => toPosix(
|
|
3372
|
+
var relativePath = (root, path) => toPosix(relative4(root, path)) || ".";
|
|
3256
3373
|
var lineEvidence = (source, root, path, lineStart, lineEnd) => ({
|
|
3257
3374
|
source,
|
|
3258
3375
|
path: relativePath(root, path),
|
|
@@ -3270,11 +3387,11 @@ var workspacePatterns = (root, rootManifest) => {
|
|
|
3270
3387
|
if (isRecord(fromPackageJson) && Array.isArray(fromPackageJson.packages)) {
|
|
3271
3388
|
return fromPackageJson.packages.filter((value) => typeof value === "string");
|
|
3272
3389
|
}
|
|
3273
|
-
const workspacePath =
|
|
3274
|
-
if (!
|
|
3390
|
+
const workspacePath = join6(root, "pnpm-workspace.yaml");
|
|
3391
|
+
if (!existsSync6(workspacePath)) return [];
|
|
3275
3392
|
const patterns = [];
|
|
3276
3393
|
let inPackages = false;
|
|
3277
|
-
for (const line of
|
|
3394
|
+
for (const line of readFileSync4(workspacePath, "utf8").split(/\r?\n/)) {
|
|
3278
3395
|
const trimmed = line.trim();
|
|
3279
3396
|
if (trimmed === "packages:") {
|
|
3280
3397
|
inPackages = true;
|
|
@@ -3292,7 +3409,7 @@ var workspacePatterns = (root, rootManifest) => {
|
|
|
3292
3409
|
var discoverPackages = (root, rootManifest, config) => {
|
|
3293
3410
|
const packages = [];
|
|
3294
3411
|
const coverage = [];
|
|
3295
|
-
const rootManifestPath =
|
|
3412
|
+
const rootManifestPath = join6(root, "package.json");
|
|
3296
3413
|
if (rootManifest) {
|
|
3297
3414
|
const name = packageName(rootManifest, "");
|
|
3298
3415
|
packages.push({
|
|
@@ -3312,8 +3429,8 @@ var discoverPackages = (root, rootManifest, config) => {
|
|
|
3312
3429
|
}
|
|
3313
3430
|
const dirs = expandWorkspaceGlobs(root, patterns);
|
|
3314
3431
|
for (const absPath of dirs) {
|
|
3315
|
-
const manifestPath =
|
|
3316
|
-
if (!
|
|
3432
|
+
const manifestPath = join6(absPath, "package.json");
|
|
3433
|
+
if (!existsSync6(manifestPath)) continue;
|
|
3317
3434
|
const parsed = readJson(manifestPath);
|
|
3318
3435
|
if (!parsed.value) {
|
|
3319
3436
|
coverage.push({ status: "partial", reason: `${relativePath(root, manifestPath)}: ${parsed.error ?? "invalid package.json"}` });
|
|
@@ -3323,7 +3440,7 @@ var discoverPackages = (root, rootManifest, config) => {
|
|
|
3323
3440
|
const name = packageName(parsed.value, path);
|
|
3324
3441
|
const id = entityId("package", name ?? path);
|
|
3325
3442
|
const duplicate = packages.find((pkg) => pkg.id === id);
|
|
3326
|
-
if (duplicate && duplicate.absPath !== absPath) {
|
|
3443
|
+
if (duplicate && toPosix(duplicate.absPath) !== toPosix(absPath)) {
|
|
3327
3444
|
throw new Error(`Package identity collision for "${id}": "${duplicate.path}" and "${path}".`);
|
|
3328
3445
|
}
|
|
3329
3446
|
if (!duplicate) packages.push({ id, ...name ? { name } : {}, path, absPath, manifestPath, manifest: parsed.value });
|
|
@@ -3331,13 +3448,13 @@ var discoverPackages = (root, rootManifest, config) => {
|
|
|
3331
3448
|
coverage.push({ status: "complete" });
|
|
3332
3449
|
return { packages: packages.sort((a, b) => a.id.localeCompare(b.id)), coverage };
|
|
3333
3450
|
};
|
|
3334
|
-
var packageForModule = (packages, absPath) => [...packages].filter((pkg) => absPath === pkg.absPath || absPath.startsWith(`${pkg.absPath}${
|
|
3451
|
+
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];
|
|
3335
3452
|
var readCompilerOptions = (root) => {
|
|
3336
3453
|
const configPath = ts2.findConfigFile(root, ts2.sys.fileExists, "tsconfig.json");
|
|
3337
3454
|
if (!configPath) return { options: {} };
|
|
3338
3455
|
const parsed = ts2.readConfigFile(configPath, ts2.sys.readFile);
|
|
3339
3456
|
if (parsed.error) return { options: {}, error: ts2.flattenDiagnosticMessageText(parsed.error.messageText, "\n") };
|
|
3340
|
-
const config = ts2.parseJsonConfigFileContent(parsed.config, ts2.sys,
|
|
3457
|
+
const config = ts2.parseJsonConfigFileContent(parsed.config, ts2.sys, dirname3(configPath));
|
|
3341
3458
|
if (config.errors.length) {
|
|
3342
3459
|
return {
|
|
3343
3460
|
options: config.options,
|
|
@@ -3468,17 +3585,17 @@ var moduleReferences = (root, path, sourceFile, runtimeWiringMethods) => {
|
|
|
3468
3585
|
};
|
|
3469
3586
|
};
|
|
3470
3587
|
var resolveRelativeModule = (specifier, containingFile, modulePaths) => {
|
|
3471
|
-
const base =
|
|
3588
|
+
const base = resolve5(dirname3(containingFile), specifier);
|
|
3472
3589
|
const extension = extname2(base);
|
|
3473
3590
|
const extensionlessBase = extension ? base.slice(0, -extension.length) : base;
|
|
3474
3591
|
const candidates = [
|
|
3475
3592
|
base,
|
|
3476
3593
|
...SOURCE_EXTENSIONS.map((extension2) => `${base}${extension2}`),
|
|
3477
|
-
...SOURCE_EXTENSIONS.map((extension2) =>
|
|
3594
|
+
...SOURCE_EXTENSIONS.map((extension2) => join6(base, `index${extension2}`)),
|
|
3478
3595
|
...SOURCE_EXTENSIONS.map((extension2) => `${extensionlessBase}${extension2}`),
|
|
3479
|
-
...SOURCE_EXTENSIONS.map((extension2) =>
|
|
3596
|
+
...SOURCE_EXTENSIONS.map((extension2) => join6(extensionlessBase, `index${extension2}`))
|
|
3480
3597
|
];
|
|
3481
|
-
return candidates.map((candidate) => modulePaths.get(
|
|
3598
|
+
return candidates.map((candidate) => modulePaths.get(resolve5(candidate))).find(Boolean);
|
|
3482
3599
|
};
|
|
3483
3600
|
var resolveReference = (reference8, containingFile, modules, packages, compilerOptions) => {
|
|
3484
3601
|
if (reference8.specifier.startsWith(".") || reference8.specifier.startsWith("/")) {
|
|
@@ -3488,7 +3605,7 @@ var resolveReference = (reference8, containingFile, modules, packages, compilerO
|
|
|
3488
3605
|
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];
|
|
3489
3606
|
if (packageTarget) return { targetId: packageTarget.id };
|
|
3490
3607
|
const resolved = ts2.resolveModuleName(reference8.specifier, containingFile, compilerOptions, ts2.sys).resolvedModule?.resolvedFileName;
|
|
3491
|
-
const resolvedTarget = resolved ? modules.get(
|
|
3608
|
+
const resolvedTarget = resolved ? modules.get(resolve5(resolved)) : void 0;
|
|
3492
3609
|
if (resolvedTarget) return { targetId: resolvedTarget.entityId };
|
|
3493
3610
|
return { targetId: entityId("external", reference8.specifier) };
|
|
3494
3611
|
};
|
|
@@ -3505,26 +3622,26 @@ var sourceRevision = (root, files) => {
|
|
|
3505
3622
|
value: sha256NormalizedV1(
|
|
3506
3623
|
files.map((path) => ({
|
|
3507
3624
|
path: relativePath(root, path),
|
|
3508
|
-
contentHash: sha256NormalizedV1(
|
|
3625
|
+
contentHash: sha256NormalizedV1(readFileSync4(path, "utf8"))
|
|
3509
3626
|
}))
|
|
3510
3627
|
),
|
|
3511
3628
|
kind: "content"
|
|
3512
3629
|
});
|
|
3513
3630
|
try {
|
|
3514
|
-
const status =
|
|
3631
|
+
const status = execFileSync2("git", ["status", "--porcelain", "--untracked-files=all"], {
|
|
3515
3632
|
cwd: root,
|
|
3516
3633
|
encoding: "utf8",
|
|
3517
3634
|
stdio: ["ignore", "pipe", "ignore"]
|
|
3518
3635
|
}).trim();
|
|
3519
3636
|
if (status) return contentRevision();
|
|
3520
|
-
const value =
|
|
3637
|
+
const value = execFileSync2("git", ["rev-parse", "HEAD"], { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
3521
3638
|
if (value) return { value, kind: "git" };
|
|
3522
3639
|
} catch {
|
|
3523
3640
|
}
|
|
3524
3641
|
return contentRevision();
|
|
3525
3642
|
};
|
|
3526
3643
|
var hasPackageManagerMetadata = (root, rootManifest) => Boolean(
|
|
3527
|
-
rootManifest?.packageManager ||
|
|
3644
|
+
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"))
|
|
3528
3645
|
);
|
|
3529
3646
|
var PIPELINE_VERSION = "1.5.0";
|
|
3530
3647
|
var ANALYZER_VERSIONS = { repository: "1.3.0", "js-ts": "1.3.5", markdown: MARKDOWN_ANALYZER_VERSION, graph: GRAPH_ANALYZER_VERSION };
|
|
@@ -3549,12 +3666,12 @@ var artifact = (root, config, files, entities, relations, coverage) => {
|
|
|
3549
3666
|
return DiscoverySnapshotV1Schema.parse({ ...base, contentHash: contentHashForArtifactV1(base) });
|
|
3550
3667
|
};
|
|
3551
3668
|
var discoverRepository = (opts = {}) => {
|
|
3552
|
-
const root =
|
|
3669
|
+
const root = resolve5(opts.root ?? process.cwd());
|
|
3553
3670
|
const safeOptions = safeWalkOptions(opts.config, {
|
|
3554
3671
|
maxFiles: opts.maxFiles ?? opts.config?.safety?.maxFiles ?? DEFAULT_MAX_FILES,
|
|
3555
3672
|
...opts.maxBytes !== void 0 ? { maxBytes: opts.maxBytes } : {}
|
|
3556
3673
|
});
|
|
3557
|
-
const rootManifestPath =
|
|
3674
|
+
const rootManifestPath = join6(root, "package.json");
|
|
3558
3675
|
const rootManifest = readJson(rootManifestPath).value;
|
|
3559
3676
|
const packageResult = discoverPackages(root, rootManifest, opts.config);
|
|
3560
3677
|
const sourceWalk = safeWalkFiles(root, { extensions: SOURCE_EXTENSIONS, ...safeOptions });
|
|
@@ -3563,7 +3680,7 @@ var discoverRepository = (opts = {}) => {
|
|
|
3563
3680
|
const sourcePaths = sourceWalk.files;
|
|
3564
3681
|
const documentPaths = documentWalk.files;
|
|
3565
3682
|
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)));
|
|
3566
|
-
const allFiles = [...new Set([rootManifestPath, ...sourcePaths, ...documentPaths, ...configPaths].filter(
|
|
3683
|
+
const allFiles = [...new Set([rootManifestPath, ...sourcePaths, ...documentPaths, ...configPaths].filter(existsSync6))].sort();
|
|
3567
3684
|
const entities = /* @__PURE__ */ new Map();
|
|
3568
3685
|
const relations = /* @__PURE__ */ new Map();
|
|
3569
3686
|
const addEntity = (entity) => {
|
|
@@ -3586,7 +3703,7 @@ var discoverRepository = (opts = {}) => {
|
|
|
3586
3703
|
relations.set(relation.id, { ...existing, evidence: [...evidence2.values()] });
|
|
3587
3704
|
};
|
|
3588
3705
|
for (const pkg of packageResult.packages) {
|
|
3589
|
-
const text =
|
|
3706
|
+
const text = readFileSync4(pkg.manifestPath, "utf8");
|
|
3590
3707
|
addEntity({
|
|
3591
3708
|
id: pkg.id,
|
|
3592
3709
|
kind: "package",
|
|
@@ -3634,9 +3751,9 @@ var discoverRepository = (opts = {}) => {
|
|
|
3634
3751
|
const path = relativePath(root, absPath);
|
|
3635
3752
|
const pkg = packageForModule(packageResult.packages, absPath);
|
|
3636
3753
|
const id = entityId("module", path);
|
|
3637
|
-
const text =
|
|
3754
|
+
const text = readFileSync4(absPath, "utf8");
|
|
3638
3755
|
const contentHash = fileContentHash(text);
|
|
3639
|
-
modules.set(
|
|
3756
|
+
modules.set(resolve5(absPath), { absPath, path, entityId: id, ...pkg ? { packageId: pkg.id } : {} });
|
|
3640
3757
|
modulesByPath.set(path, id);
|
|
3641
3758
|
if (pkg) areaModules.push({ moduleId: id, path, packageId: pkg.id, packagePath: pkg.path });
|
|
3642
3759
|
const priorModule = reuseModuleRelations ? prior?.modules.get(path) : void 0;
|
|
@@ -3759,7 +3876,7 @@ var discoverRepository = (opts = {}) => {
|
|
|
3759
3876
|
for (const [path, absPath] of documentFiles) {
|
|
3760
3877
|
let text;
|
|
3761
3878
|
try {
|
|
3762
|
-
text =
|
|
3879
|
+
text = readFileSync4(absPath, "utf8");
|
|
3763
3880
|
} catch {
|
|
3764
3881
|
unreadableDocuments.push(path);
|
|
3765
3882
|
ledger.parsedFiles.push(path);
|
|
@@ -3878,7 +3995,7 @@ var discoverRepository = (opts = {}) => {
|
|
|
3878
3995
|
});
|
|
3879
3996
|
}
|
|
3880
3997
|
for (const pkg of packageResult.packages) {
|
|
3881
|
-
const text =
|
|
3998
|
+
const text = readFileSync4(pkg.manifestPath, "utf8");
|
|
3882
3999
|
for (const dependency of dependencyEntries(pkg.manifest)) {
|
|
3883
4000
|
const target2 = packageResult.packages.find((candidate) => candidate.name === dependency.name)?.id ?? entityId("external", dependency.name);
|
|
3884
4001
|
if (!entities.has(target2)) addEntity({ id: target2, kind: "external", name: dependency.name, provenance: "observed", evidence: [lineEvidence("configuration", root, pkg.manifestPath, firstLineContaining(text, `"${dependency.name}"`))] });
|
|
@@ -3917,7 +4034,7 @@ var discoverRepository = (opts = {}) => {
|
|
|
3917
4034
|
ledger.skippedFiles.push(module.path);
|
|
3918
4035
|
continue;
|
|
3919
4036
|
}
|
|
3920
|
-
const text =
|
|
4037
|
+
const text = readFileSync4(module.absPath, "utf8");
|
|
3921
4038
|
const sourceFile = ts2.createSourceFile(module.absPath, text, ts2.ScriptTarget.Latest, true, scriptKind(module.absPath));
|
|
3922
4039
|
const runtimeWiringMethods = includeTestRuntimeWiring || !TEST_MODULE_PATTERN.test(module.path) ? configuredRuntimeWiringMethods : /* @__PURE__ */ new Set();
|
|
3923
4040
|
const references = moduleReferences(root, module.absPath, sourceFile, runtimeWiringMethods);
|
|
@@ -3950,7 +4067,7 @@ var discoverRepository = (opts = {}) => {
|
|
|
3950
4067
|
};
|
|
3951
4068
|
|
|
3952
4069
|
// src/lib/bounded-text.ts
|
|
3953
|
-
import { closeSync, fstatSync, openSync, readFileSync as
|
|
4070
|
+
import { closeSync, fstatSync, openSync, readFileSync as readFileSync5 } from "fs";
|
|
3954
4071
|
var MAX_DOCUMENT_BYTES = 4 * 1024 * 1024;
|
|
3955
4072
|
var MAX_CORPUS_BYTES = 64 * 1024 * 1024;
|
|
3956
4073
|
var readBoundedText = (path, budget, limits) => {
|
|
@@ -3967,7 +4084,7 @@ var readBoundedText = (path, budget, limits) => {
|
|
|
3967
4084
|
throw new Error(`Documentation corpus exceeds the ${maxCorpusBytes} byte read budget.`);
|
|
3968
4085
|
}
|
|
3969
4086
|
budget.used += stat.size;
|
|
3970
|
-
return
|
|
4087
|
+
return readFileSync5(fd, "utf8");
|
|
3971
4088
|
} finally {
|
|
3972
4089
|
closeSync(fd);
|
|
3973
4090
|
}
|
|
@@ -4069,8 +4186,8 @@ var slugFromPath = (relPath) => {
|
|
|
4069
4186
|
};
|
|
4070
4187
|
|
|
4071
4188
|
// src/lib/walk.ts
|
|
4072
|
-
import { lstatSync as lstatSync2, readdirSync as readdirSync3, realpathSync as
|
|
4073
|
-
import { join as
|
|
4189
|
+
import { lstatSync as lstatSync2, readdirSync as readdirSync3, realpathSync as realpathSync4 } from "fs";
|
|
4190
|
+
import { join as join7 } from "path";
|
|
4074
4191
|
var DEFAULT_SKIP = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", "coverage", ".doc-bridge"]);
|
|
4075
4192
|
var DEFAULT_MAX_FILES2 = 1e4;
|
|
4076
4193
|
var walkFiles = (root, opts) => {
|
|
@@ -4078,10 +4195,11 @@ var walkFiles = (root, opts) => {
|
|
|
4078
4195
|
const skip = opts?.skipDirs ?? DEFAULT_SKIP;
|
|
4079
4196
|
const out = [];
|
|
4080
4197
|
const visited = /* @__PURE__ */ new Set();
|
|
4198
|
+
const ignored = opts?.respectIgnore === false ? void 0 : createIgnoreFilter(root);
|
|
4081
4199
|
const visit2 = (dir) => {
|
|
4082
4200
|
let canonicalDir;
|
|
4083
4201
|
try {
|
|
4084
|
-
canonicalDir =
|
|
4202
|
+
canonicalDir = realpathSync4.native(dir);
|
|
4085
4203
|
} catch {
|
|
4086
4204
|
return;
|
|
4087
4205
|
}
|
|
@@ -4094,7 +4212,7 @@ var walkFiles = (root, opts) => {
|
|
|
4094
4212
|
return;
|
|
4095
4213
|
}
|
|
4096
4214
|
for (const name of entries) {
|
|
4097
|
-
const abs =
|
|
4215
|
+
const abs = join7(dir, name);
|
|
4098
4216
|
let st;
|
|
4099
4217
|
try {
|
|
4100
4218
|
st = lstatSync2(abs);
|
|
@@ -4103,12 +4221,12 @@ var walkFiles = (root, opts) => {
|
|
|
4103
4221
|
}
|
|
4104
4222
|
if (st.isSymbolicLink()) continue;
|
|
4105
4223
|
if (st.isDirectory()) {
|
|
4106
|
-
if (skip.has(name)) continue;
|
|
4224
|
+
if (skip.has(name) || ignored?.isIgnored(abs, true)) continue;
|
|
4107
4225
|
visit2(abs);
|
|
4108
4226
|
continue;
|
|
4109
4227
|
}
|
|
4110
4228
|
if (!st.isFile()) continue;
|
|
4111
|
-
if (extensions.some((ext) => name.endsWith(ext))) {
|
|
4229
|
+
if (extensions.some((ext) => name.endsWith(ext)) && !ignored?.isIgnored(abs, false)) {
|
|
4112
4230
|
if (out.length >= (opts?.maxFiles ?? DEFAULT_MAX_FILES2)) {
|
|
4113
4231
|
throw new Error(`Documentation corpus exceeds the ${opts?.maxFiles ?? DEFAULT_MAX_FILES2} file limit.`);
|
|
4114
4232
|
}
|
|
@@ -4400,7 +4518,7 @@ var buildLookup = (config, packages, corpus, indexOutFile, humanDocs = {}, root
|
|
|
4400
4518
|
};
|
|
4401
4519
|
|
|
4402
4520
|
// src/version.ts
|
|
4403
|
-
var PACKAGE_VERSION = "1.
|
|
4521
|
+
var PACKAGE_VERSION = "1.12.0";
|
|
4404
4522
|
|
|
4405
4523
|
// src/index-builder/capabilities.ts
|
|
4406
4524
|
var renderCapabilitiesJson = (config, index, paths) => {
|
|
@@ -4434,8 +4552,8 @@ var renderCapabilitiesJson = (config, index, paths) => {
|
|
|
4434
4552
|
};
|
|
4435
4553
|
|
|
4436
4554
|
// src/render/template-source.ts
|
|
4437
|
-
import { readFileSync as
|
|
4438
|
-
import { resolve as
|
|
4555
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
4556
|
+
import { resolve as resolve6 } from "path";
|
|
4439
4557
|
|
|
4440
4558
|
// src/render/engine.ts
|
|
4441
4559
|
import {
|
|
@@ -4992,10 +5110,10 @@ var BUNDLED_TEMPLATES = {
|
|
|
4992
5110
|
var resolveTemplateSource = (name, config, root) => {
|
|
4993
5111
|
const override = config.render?.templates?.[name];
|
|
4994
5112
|
if (!override) return { name, source: BUNDLED_TEMPLATES[name], origin: "bundled" };
|
|
4995
|
-
const path = root ?
|
|
5113
|
+
const path = root ? resolve6(root, override) : resolve6(override);
|
|
4996
5114
|
let source;
|
|
4997
5115
|
try {
|
|
4998
|
-
source =
|
|
5116
|
+
source = readFileSync6(path, "utf8");
|
|
4999
5117
|
} catch (error) {
|
|
5000
5118
|
throw new Error(`render.templates["${name}"] points at ${toPosix(override)}, which could not be read: ${error instanceof Error ? error.message : String(error)}`);
|
|
5001
5119
|
}
|
|
@@ -5014,8 +5132,8 @@ var compile = (template2) => {
|
|
|
5014
5132
|
var renderNamedTemplate = (name, variables, config, root) => renderCompiledTemplate(compile(resolveTemplateSource(name, config, root)), variables);
|
|
5015
5133
|
|
|
5016
5134
|
// src/index-builder/project-corpus.ts
|
|
5017
|
-
import { basename as basename3, extname as extname3, relative as
|
|
5018
|
-
import { readFileSync as
|
|
5135
|
+
import { basename as basename3, extname as extname3, relative as relative5, resolve as resolve7, sep as sep5 } from "path";
|
|
5136
|
+
import { readFileSync as readFileSync7 } from "fs";
|
|
5019
5137
|
var CORPUS_PROJECTION_VERSION = 2;
|
|
5020
5138
|
var PROJECTED_ENTRY_TYPES = ["document", "module"];
|
|
5021
5139
|
var isProjectedEntry = (entry) => PROJECTED_ENTRY_TYPES.includes(entry.type);
|
|
@@ -5034,14 +5152,14 @@ var isInput = (path, name) => {
|
|
|
5034
5152
|
return CONFIG_INPUT_PATTERN.test(path);
|
|
5035
5153
|
};
|
|
5036
5154
|
var repositoryInputs = (root, config) => {
|
|
5037
|
-
const projectRoot =
|
|
5155
|
+
const projectRoot = resolve7(root);
|
|
5038
5156
|
const walk = safeWalkFiles(projectRoot, { extensions: INPUT_EXTENSIONS, ...safeWalkOptions(config) });
|
|
5039
5157
|
const fingerprints = [];
|
|
5040
5158
|
for (const absPath of walk.files) {
|
|
5041
|
-
const path = toPosix(
|
|
5159
|
+
const path = toPosix(relative5(projectRoot, absPath).split(sep5).join("/"));
|
|
5042
5160
|
if (!isInput(path, basename3(absPath))) continue;
|
|
5043
5161
|
try {
|
|
5044
|
-
fingerprints.push([path, sha256NormalizedV1(
|
|
5162
|
+
fingerprints.push([path, sha256NormalizedV1(readFileSync7(absPath, "utf8"))]);
|
|
5045
5163
|
} catch {
|
|
5046
5164
|
fingerprints.push([path, "unreadable"]);
|
|
5047
5165
|
}
|
|
@@ -5086,15 +5204,15 @@ var llmsTxtVariables = (config, knowledge, projectName2) => {
|
|
|
5086
5204
|
var renderLlmsTxt = (config, knowledge, projectName2, options = {}) => renderNamedTemplate("llms.txt", llmsTxtVariables(config, knowledge, projectName2), config, options.root);
|
|
5087
5205
|
|
|
5088
5206
|
// src/index-builder/human-adapters/index.ts
|
|
5089
|
-
import { realpathSync as
|
|
5090
|
-
import { resolve as
|
|
5207
|
+
import { realpathSync as realpathSync6 } from "fs";
|
|
5208
|
+
import { resolve as resolve9, sep as sep7 } from "path";
|
|
5091
5209
|
|
|
5092
5210
|
// src/index-builder/human-adapters/docusaurus.ts
|
|
5093
|
-
import { existsSync as
|
|
5211
|
+
import { existsSync as existsSync7 } from "fs";
|
|
5094
5212
|
|
|
5095
5213
|
// src/index-builder/human-adapters/core.ts
|
|
5096
|
-
import { realpathSync as
|
|
5097
|
-
import { isAbsolute as
|
|
5214
|
+
import { realpathSync as realpathSync5 } from "fs";
|
|
5215
|
+
import { isAbsolute as isAbsolute4, relative as relative6, resolve as resolve8, sep as sep6 } from "path";
|
|
5098
5216
|
var optionString = (options, keys) => {
|
|
5099
5217
|
for (const key of keys) {
|
|
5100
5218
|
const value = options?.[key];
|
|
@@ -5103,11 +5221,12 @@ var optionString = (options, keys) => {
|
|
|
5103
5221
|
return void 0;
|
|
5104
5222
|
};
|
|
5105
5223
|
var parseFrontmatter2 = (raw) => {
|
|
5106
|
-
|
|
5107
|
-
|
|
5224
|
+
const normalized = raw.includes("\r\n") ? raw.replace(/\r\n/g, "\n") : raw;
|
|
5225
|
+
if (!normalized.startsWith("---\n")) return {};
|
|
5226
|
+
const end = normalized.indexOf("\n---", 4);
|
|
5108
5227
|
if (end === -1) return {};
|
|
5109
5228
|
const out = {};
|
|
5110
|
-
for (const line of
|
|
5229
|
+
for (const line of normalized.slice(4, end).split("\n")) {
|
|
5111
5230
|
const match = /^([A-Za-z0-9_-]+):\s*(.+?)\s*$/.exec(line);
|
|
5112
5231
|
if (match?.[1] && match[2]) out[match[1]] = match[2].replace(/^['"]|['"]$/g, "");
|
|
5113
5232
|
}
|
|
@@ -5125,15 +5244,15 @@ var humanUrl = (slug2, urlPrefix) => {
|
|
|
5125
5244
|
};
|
|
5126
5245
|
var scanMarkdownDocs = (root, humanRoot, options) => {
|
|
5127
5246
|
const out = [];
|
|
5128
|
-
const projectRoot =
|
|
5247
|
+
const projectRoot = realpathSync5.native(resolve8(root));
|
|
5129
5248
|
const absRoot = containedProjectPath(root, humanRoot);
|
|
5130
5249
|
if (!absRoot) return out;
|
|
5131
5250
|
const budget = { used: 0 };
|
|
5132
5251
|
for (const abs of walkFiles(absRoot, { extensions: [".md", ".mdx"] })) {
|
|
5133
|
-
const
|
|
5134
|
-
const fileRelative =
|
|
5135
|
-
if (
|
|
5136
|
-
const relToHumanRoot = toPosix(abs.replace(`${toPosix(absRoot)}/`, "")
|
|
5252
|
+
const canonical2 = realpathSync5.native(abs);
|
|
5253
|
+
const fileRelative = relative6(projectRoot, canonical2);
|
|
5254
|
+
if (isAbsolute4(fileRelative) || fileRelative === ".." || fileRelative.startsWith(`..${sep6}`)) continue;
|
|
5255
|
+
const relToHumanRoot = toPosix(abs).replace(`${toPosix(absRoot)}/`, "");
|
|
5137
5256
|
const raw = readBoundedText(abs, budget);
|
|
5138
5257
|
if (options?.includeRelPath && !options.includeRelPath(relToHumanRoot, raw)) continue;
|
|
5139
5258
|
out.push({
|
|
@@ -5174,7 +5293,7 @@ var docusaurusRecordId = (relPath, raw) => {
|
|
|
5174
5293
|
};
|
|
5175
5294
|
var readSidebars = (sidebarsFile) => {
|
|
5176
5295
|
if (!sidebarsFile) return { enabled: false, ids: /* @__PURE__ */ new Set(), autogenDirs: [] };
|
|
5177
|
-
if (!
|
|
5296
|
+
if (!existsSync7(sidebarsFile)) return { enabled: false, ids: /* @__PURE__ */ new Set(), autogenDirs: [] };
|
|
5178
5297
|
const raw = readBoundedText(sidebarsFile, { used: 0 }, { maxFileBytes: 1048576, maxCorpusBytes: 1048576 });
|
|
5179
5298
|
const filter = { ids: /* @__PURE__ */ new Set(), autogenDirs: [] };
|
|
5180
5299
|
const visit2 = (value) => {
|
|
@@ -5224,13 +5343,13 @@ var docusaurusAdapter = {
|
|
|
5224
5343
|
};
|
|
5225
5344
|
|
|
5226
5345
|
// src/index-builder/human-adapters/fumadocs.ts
|
|
5227
|
-
import { existsSync as
|
|
5228
|
-
import { join as
|
|
5346
|
+
import { existsSync as existsSync8, readFileSync as readFileSync8 } from "fs";
|
|
5347
|
+
import { join as join8 } from "path";
|
|
5229
5348
|
var readMetaPages = (dir) => {
|
|
5230
|
-
const file =
|
|
5231
|
-
if (!
|
|
5349
|
+
const file = join8(dir, "meta.json");
|
|
5350
|
+
if (!existsSync8(file)) return void 0;
|
|
5232
5351
|
try {
|
|
5233
|
-
const meta = JSON.parse(
|
|
5352
|
+
const meta = JSON.parse(readFileSync8(file, "utf8"));
|
|
5234
5353
|
return Array.isArray(meta.pages) ? meta.pages.filter((page) => typeof page === "string") : void 0;
|
|
5235
5354
|
} catch {
|
|
5236
5355
|
return void 0;
|
|
@@ -5245,7 +5364,7 @@ var isListedByMeta = (contentRoot, relPath) => {
|
|
|
5245
5364
|
if (isDotFile(relPath)) return false;
|
|
5246
5365
|
const parts = relPath.split("/");
|
|
5247
5366
|
for (let i = 0; i < parts.length; i += 1) {
|
|
5248
|
-
const dir =
|
|
5367
|
+
const dir = join8(contentRoot, ...parts.slice(0, i));
|
|
5249
5368
|
const pages = readMetaPages(dir);
|
|
5250
5369
|
if (!pages?.length || pages.includes("...")) continue;
|
|
5251
5370
|
const key = pageKey(parts[i] ?? "");
|
|
@@ -5258,7 +5377,7 @@ var fumadocsAdapter = {
|
|
|
5258
5377
|
scan: ({ root, config }) => {
|
|
5259
5378
|
const contentDir = optionString(config.options, ["contentDir", "root"]);
|
|
5260
5379
|
if (!contentDir) return [];
|
|
5261
|
-
const contentRoot =
|
|
5380
|
+
const contentRoot = join8(root, contentDir);
|
|
5262
5381
|
const excludePrefixes = Array.isArray(config.options?.excludePrefixes) ? config.options.excludePrefixes.filter((v) => typeof v === "string") : typeof config.options?.excludePrefix === "string" ? [config.options.excludePrefix] : [];
|
|
5263
5382
|
if (!excludePrefixes.includes("for-agents")) excludePrefixes.push("for-agents");
|
|
5264
5383
|
return scanMarkdownDocs(root, contentDir, {
|
|
@@ -5402,21 +5521,21 @@ var humanConfigs = (config) => {
|
|
|
5402
5521
|
};
|
|
5403
5522
|
var canonicalPath = (path) => {
|
|
5404
5523
|
try {
|
|
5405
|
-
return
|
|
5524
|
+
return realpathSync6.native(path);
|
|
5406
5525
|
} catch {
|
|
5407
|
-
return
|
|
5526
|
+
return resolve9(path);
|
|
5408
5527
|
}
|
|
5409
5528
|
};
|
|
5410
5529
|
var scanHumanDocRecords = (root, config) => {
|
|
5411
5530
|
const out = [];
|
|
5412
5531
|
const seen = /* @__PURE__ */ new Set();
|
|
5413
|
-
const agentRoot = canonicalPath(
|
|
5532
|
+
const agentRoot = canonicalPath(resolve9(root, config.corpus.agent.root));
|
|
5414
5533
|
for (const human of humanConfigs(config)) {
|
|
5415
5534
|
const adapter = ADAPTERS.find((candidate) => candidate.plugin === human.plugin);
|
|
5416
5535
|
if (!adapter) continue;
|
|
5417
5536
|
for (const record of adapter.scan({ root, config: human })) {
|
|
5418
5537
|
const recordPath = canonicalPath(record.path);
|
|
5419
|
-
if (recordPath === agentRoot || recordPath.startsWith(`${agentRoot}${
|
|
5538
|
+
if (recordPath === agentRoot || recordPath.startsWith(`${agentRoot}${sep7}`) || record.path.includes("/for-agents/") || record.path.endsWith("/for-agents")) {
|
|
5420
5539
|
continue;
|
|
5421
5540
|
}
|
|
5422
5541
|
if (seen.has(record.id)) continue;
|
|
@@ -5429,8 +5548,8 @@ var scanHumanDocRecords = (root, config) => {
|
|
|
5429
5548
|
var scanHumanDocs = (root, config) => Object.fromEntries(scanHumanDocRecords(root, config).map((doc) => [doc.id, doc.url]));
|
|
5430
5549
|
|
|
5431
5550
|
// src/index-builder/plugins/nx.ts
|
|
5432
|
-
import { existsSync as
|
|
5433
|
-
import { basename as basename4, dirname as
|
|
5551
|
+
import { existsSync as existsSync9, lstatSync as lstatSync3, readFileSync as readFileSync9, realpathSync as realpathSync7 } from "fs";
|
|
5552
|
+
import { basename as basename4, dirname as dirname4, isAbsolute as isAbsolute5, relative as relative7, resolve as resolve10, sep as sep8 } from "path";
|
|
5434
5553
|
var NX_SCAN_SKIP = /* @__PURE__ */ new Set([
|
|
5435
5554
|
"node_modules",
|
|
5436
5555
|
".git",
|
|
@@ -5443,22 +5562,22 @@ var NX_PROJECT_NAME = /^(?:@[A-Za-z0-9._-]+\/)?[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
|
5443
5562
|
var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5444
5563
|
var readJsonRecord = (path) => {
|
|
5445
5564
|
try {
|
|
5446
|
-
const parsed = JSON.parse(
|
|
5565
|
+
const parsed = JSON.parse(readFileSync9(path, "utf8"));
|
|
5447
5566
|
return isRecord2(parsed) ? parsed : void 0;
|
|
5448
5567
|
} catch {
|
|
5449
5568
|
return void 0;
|
|
5450
5569
|
}
|
|
5451
5570
|
};
|
|
5452
5571
|
var safeProjectPath = (root, manifestDir, declaredRoot) => {
|
|
5453
|
-
const candidate = typeof declaredRoot === "string" ?
|
|
5454
|
-
const rel = toPosix(
|
|
5455
|
-
if (
|
|
5572
|
+
const candidate = typeof declaredRoot === "string" ? resolve10(root, declaredRoot) : manifestDir;
|
|
5573
|
+
const rel = toPosix(relative7(root, candidate)) || ".";
|
|
5574
|
+
if (isAbsolute5(rel) || rel === ".." || rel.startsWith("../")) return void 0;
|
|
5456
5575
|
try {
|
|
5457
5576
|
if (!lstatSync3(candidate).isDirectory()) return void 0;
|
|
5458
|
-
const canonicalRoot =
|
|
5459
|
-
const canonicalCandidate =
|
|
5460
|
-
const canonicalRel =
|
|
5461
|
-
if (
|
|
5577
|
+
const canonicalRoot = realpathSync7.native(root);
|
|
5578
|
+
const canonicalCandidate = realpathSync7.native(candidate);
|
|
5579
|
+
const canonicalRel = relative7(canonicalRoot, canonicalCandidate);
|
|
5580
|
+
if (isAbsolute5(canonicalRel) || canonicalRel === ".." || canonicalRel.startsWith(`..${sep8}`)) {
|
|
5462
5581
|
return void 0;
|
|
5463
5582
|
}
|
|
5464
5583
|
} catch {
|
|
@@ -5484,7 +5603,7 @@ var inferredChecks = (root, config, projectName2, targets) => {
|
|
|
5484
5603
|
return checks.length ? checks : void 0;
|
|
5485
5604
|
};
|
|
5486
5605
|
var discoverNxProjects = (root, config) => {
|
|
5487
|
-
if (!
|
|
5606
|
+
if (!existsSync9(resolve10(root, "nx.json"))) return [];
|
|
5488
5607
|
const manifests = walkFiles(root, {
|
|
5489
5608
|
extensions: ["project.json", "package.json"],
|
|
5490
5609
|
skipDirs: NX_SCAN_SKIP,
|
|
@@ -5494,7 +5613,7 @@ var discoverNxProjects = (root, config) => {
|
|
|
5494
5613
|
for (const manifest of manifests) {
|
|
5495
5614
|
const json = readJsonRecord(manifest);
|
|
5496
5615
|
if (!json) continue;
|
|
5497
|
-
const manifestDir =
|
|
5616
|
+
const manifestDir = dirname4(manifest);
|
|
5498
5617
|
const manifestName = basename4(manifest);
|
|
5499
5618
|
const isProjectJson = manifestName === "project.json";
|
|
5500
5619
|
if (!isProjectJson && manifestName !== "package.json") continue;
|
|
@@ -5502,7 +5621,7 @@ var discoverNxProjects = (root, config) => {
|
|
|
5502
5621
|
if (!isProjectJson && !isRecord2(nx)) continue;
|
|
5503
5622
|
const path = safeProjectPath(root, manifestDir, isProjectJson ? json.root : void 0);
|
|
5504
5623
|
if (!path) continue;
|
|
5505
|
-
const projectPackage = isProjectJson ? readJsonRecord(
|
|
5624
|
+
const projectPackage = isProjectJson ? readJsonRecord(resolve10(root, path, "package.json")) : void 0;
|
|
5506
5625
|
const projectName2 = typeof json.name === "string" ? json.name : typeof projectPackage?.name === "string" ? projectPackage.name : basename4(path === "." ? root : path);
|
|
5507
5626
|
if (!NX_PROJECT_NAME.test(projectName2)) continue;
|
|
5508
5627
|
const targets = /* @__PURE__ */ new Set();
|
|
@@ -5538,8 +5657,8 @@ var discoverNxProjects = (root, config) => {
|
|
|
5538
5657
|
};
|
|
5539
5658
|
|
|
5540
5659
|
// src/index-builder/plugins/pnpm-monorepo.ts
|
|
5541
|
-
import { existsSync as
|
|
5542
|
-
import { basename as basename5, join as
|
|
5660
|
+
import { existsSync as existsSync10, readFileSync as readFileSync10 } from "fs";
|
|
5661
|
+
import { basename as basename5, join as join9 } from "path";
|
|
5543
5662
|
var parsePnpmWorkspace = (yaml) => {
|
|
5544
5663
|
const lines = yaml.split("\n");
|
|
5545
5664
|
const patterns = [];
|
|
@@ -5561,10 +5680,10 @@ var parsePnpmWorkspace = (yaml) => {
|
|
|
5561
5680
|
return patterns;
|
|
5562
5681
|
};
|
|
5563
5682
|
var readPackageJson = (dir) => {
|
|
5564
|
-
const file =
|
|
5565
|
-
if (!
|
|
5683
|
+
const file = join9(dir, "package.json");
|
|
5684
|
+
if (!existsSync10(file)) return null;
|
|
5566
5685
|
try {
|
|
5567
|
-
return JSON.parse(
|
|
5686
|
+
return JSON.parse(readFileSync10(file, "utf8"));
|
|
5568
5687
|
} catch {
|
|
5569
5688
|
return null;
|
|
5570
5689
|
}
|
|
@@ -5573,9 +5692,9 @@ var discoverPnpmPackages = (root, config) => {
|
|
|
5573
5692
|
const explicit = config.routing?.options?.packages;
|
|
5574
5693
|
let patterns = explicit;
|
|
5575
5694
|
if (!patterns?.length) {
|
|
5576
|
-
const workspaceFile =
|
|
5577
|
-
if (
|
|
5578
|
-
patterns = parsePnpmWorkspace(
|
|
5695
|
+
const workspaceFile = join9(root, "pnpm-workspace.yaml");
|
|
5696
|
+
if (existsSync10(workspaceFile)) {
|
|
5697
|
+
patterns = parsePnpmWorkspace(readFileSync10(workspaceFile, "utf8"));
|
|
5579
5698
|
}
|
|
5580
5699
|
}
|
|
5581
5700
|
if (!patterns?.length) return [];
|
|
@@ -6276,8 +6395,8 @@ var toKnowledgeEntry = (entry) => ({
|
|
|
6276
6395
|
});
|
|
6277
6396
|
|
|
6278
6397
|
// src/enrich/overlay.ts
|
|
6279
|
-
import { existsSync as
|
|
6280
|
-
import { join as
|
|
6398
|
+
import { existsSync as existsSync11, mkdirSync, readFileSync as readFileSync11, renameSync, writeFileSync } from "fs";
|
|
6399
|
+
import { join as join10, resolve as resolve11 } from "path";
|
|
6281
6400
|
|
|
6282
6401
|
// src/schemas/enrichment.ts
|
|
6283
6402
|
import { z as z9 } from "zod";
|
|
@@ -6785,14 +6904,14 @@ var EnrichmentProposalListSchema = z10.array(z10.unknown()).max(1024);
|
|
|
6785
6904
|
// src/enrich/overlay.ts
|
|
6786
6905
|
var ENRICHMENT_DIR = ".doc-bridge/enrich";
|
|
6787
6906
|
var ENRICHMENT_OVERLAY_FILE = "overlay.json";
|
|
6788
|
-
var enrichmentDir = (root) =>
|
|
6789
|
-
var enrichmentOverlayPath = (root) =>
|
|
6790
|
-
var enrichmentCacheDir = (root) =>
|
|
6907
|
+
var enrichmentDir = (root) => join10(resolve11(root), ENRICHMENT_DIR);
|
|
6908
|
+
var enrichmentOverlayPath = (root) => join10(enrichmentDir(root), ENRICHMENT_OVERLAY_FILE);
|
|
6909
|
+
var enrichmentCacheDir = (root) => join10(enrichmentDir(root), "cache");
|
|
6791
6910
|
var readEnrichmentOverlay = (root) => {
|
|
6792
6911
|
const path = enrichmentOverlayPath(root);
|
|
6793
|
-
if (!
|
|
6912
|
+
if (!existsSync11(path)) return void 0;
|
|
6794
6913
|
try {
|
|
6795
|
-
const parsed = EnrichmentOverlayV1Schema.parse(JSON.parse(
|
|
6914
|
+
const parsed = EnrichmentOverlayV1Schema.parse(JSON.parse(readFileSync11(path, "utf8")));
|
|
6796
6915
|
return parsed.contentHash === enrichmentOverlayContentHash(parsed) ? parsed : void 0;
|
|
6797
6916
|
} catch {
|
|
6798
6917
|
return void 0;
|
|
@@ -6870,7 +6989,7 @@ var projectEnrichmentOverlay = (overlay, snapshot) => {
|
|
|
6870
6989
|
const signals = /* @__PURE__ */ new Map();
|
|
6871
6990
|
const aliases = /* @__PURE__ */ new Map();
|
|
6872
6991
|
const summaries = /* @__PURE__ */ new Map();
|
|
6873
|
-
const
|
|
6992
|
+
const canonical2 = /* @__PURE__ */ new Map();
|
|
6874
6993
|
const intents = [];
|
|
6875
6994
|
const relations = [];
|
|
6876
6995
|
const paths = new Map(snapshot.entities.map((entity) => [entity.id, entity.path]));
|
|
@@ -6895,7 +7014,7 @@ var projectEnrichmentOverlay = (overlay, snapshot) => {
|
|
|
6895
7014
|
});
|
|
6896
7015
|
break;
|
|
6897
7016
|
case "mark-canonical":
|
|
6898
|
-
|
|
7017
|
+
canonical2.set(proposal.entity, proposal.payload.scope);
|
|
6899
7018
|
bump(proposal.entity, SIGNAL_CANONICAL);
|
|
6900
7019
|
break;
|
|
6901
7020
|
case "rank-hint":
|
|
@@ -6916,7 +7035,7 @@ var projectEnrichmentOverlay = (overlay, snapshot) => {
|
|
|
6916
7035
|
...signals.size ? { signals } : {},
|
|
6917
7036
|
...aliases.size ? { aliases } : {},
|
|
6918
7037
|
...summaries.size ? { summaries } : {},
|
|
6919
|
-
...
|
|
7038
|
+
...canonical2.size ? { canonical: canonical2 } : {},
|
|
6920
7039
|
...intents.length ? { intents } : {},
|
|
6921
7040
|
...relations.length ? { relations } : {}
|
|
6922
7041
|
};
|
|
@@ -6944,7 +7063,7 @@ var enrichmentFindings = (overlay) => overlay.accepted.filter((entry) => ENRICHM
|
|
|
6944
7063
|
var projectName = (root, config) => {
|
|
6945
7064
|
if (config.project?.name) return config.project.name;
|
|
6946
7065
|
try {
|
|
6947
|
-
const pkg = JSON.parse(
|
|
7066
|
+
const pkg = JSON.parse(readFileSync12(join11(root, "package.json"), "utf8"));
|
|
6948
7067
|
if (pkg.name) return pkg.name;
|
|
6949
7068
|
} catch {
|
|
6950
7069
|
}
|
|
@@ -6957,7 +7076,7 @@ var projectFromSnapshot = (root, config, given, lookup, curated, requested) => {
|
|
|
6957
7076
|
for (const entity of observed.entities) {
|
|
6958
7077
|
if (entity.kind !== "document" || !entity.path) continue;
|
|
6959
7078
|
try {
|
|
6960
|
-
contents.set(entity.path, readBoundedText(
|
|
7079
|
+
contents.set(entity.path, readBoundedText(join11(root, entity.path), budget));
|
|
6961
7080
|
} catch {
|
|
6962
7081
|
}
|
|
6963
7082
|
}
|
|
@@ -6980,7 +7099,7 @@ var projectFromSnapshot = (root, config, given, lookup, curated, requested) => {
|
|
|
6980
7099
|
};
|
|
6981
7100
|
var existingGeneratedAt = (indexPath, contentHash) => {
|
|
6982
7101
|
try {
|
|
6983
|
-
const index = JSON.parse(
|
|
7102
|
+
const index = JSON.parse(readFileSync12(indexPath, "utf8"));
|
|
6984
7103
|
return index.contentHash === contentHash && typeof index.generatedAt === "string" ? index.generatedAt : void 0;
|
|
6985
7104
|
} catch {
|
|
6986
7105
|
return void 0;
|
|
@@ -6991,7 +7110,7 @@ var buildDocBridgeIndex = (opts) => {
|
|
|
6991
7110
|
const config = opts.config;
|
|
6992
7111
|
const write = opts.write ?? true;
|
|
6993
7112
|
const outFile = config.index?.outFile ?? ".doc-bridge/index.json";
|
|
6994
|
-
const indexPath =
|
|
7113
|
+
const indexPath = join11(root, outFile);
|
|
6995
7114
|
const corpus = scanAgentCorpus(root, config);
|
|
6996
7115
|
const curated = corpus.map(({ absPath: _a, relPath: _r, frontmatter: _f, ...entry }) => entry);
|
|
6997
7116
|
const retrieval = {
|
|
@@ -7041,7 +7160,7 @@ var buildDocBridgeIndex = (opts) => {
|
|
|
7041
7160
|
);
|
|
7042
7161
|
}
|
|
7043
7162
|
if (write) {
|
|
7044
|
-
mkdirSync2(
|
|
7163
|
+
mkdirSync2(dirname5(indexPath), { recursive: true });
|
|
7045
7164
|
writeFileSync2(indexPath, `${JSON.stringify(index, null, 2)}
|
|
7046
7165
|
`, "utf8");
|
|
7047
7166
|
}
|
|
@@ -7050,7 +7169,7 @@ var buildDocBridgeIndex = (opts) => {
|
|
|
7050
7169
|
if (config.index?.llmsTxt?.enabled !== false) {
|
|
7051
7170
|
const llmsOut = config.index?.llmsTxt?.outFile ?? "llms.txt";
|
|
7052
7171
|
llmsTxtRelPath = toPosix(llmsOut);
|
|
7053
|
-
llmsTxtPath =
|
|
7172
|
+
llmsTxtPath = join11(root, llmsOut);
|
|
7054
7173
|
if (write) {
|
|
7055
7174
|
writeFileSync2(
|
|
7056
7175
|
llmsTxtPath,
|
|
@@ -7062,9 +7181,9 @@ var buildDocBridgeIndex = (opts) => {
|
|
|
7062
7181
|
let capabilitiesPath;
|
|
7063
7182
|
if (config.index?.capabilities?.enabled !== false) {
|
|
7064
7183
|
const capabilitiesOut = config.index?.capabilities?.outFile ?? ".doc-bridge/capabilities.json";
|
|
7065
|
-
capabilitiesPath =
|
|
7184
|
+
capabilitiesPath = join11(root, capabilitiesOut);
|
|
7066
7185
|
if (write) {
|
|
7067
|
-
mkdirSync2(
|
|
7186
|
+
mkdirSync2(dirname5(capabilitiesPath), { recursive: true });
|
|
7068
7187
|
writeFileSync2(
|
|
7069
7188
|
capabilitiesPath,
|
|
7070
7189
|
renderCapabilitiesJson(config, index, {
|
|
@@ -7084,7 +7203,7 @@ var buildDocBridgeIndex = (opts) => {
|
|
|
7084
7203
|
};
|
|
7085
7204
|
|
|
7086
7205
|
// src/discovery/reproducibility.ts
|
|
7087
|
-
import { execFileSync as
|
|
7206
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
7088
7207
|
var NOT_CHECKED = (skipped) => ({
|
|
7089
7208
|
checked: false,
|
|
7090
7209
|
skipped,
|
|
@@ -7092,7 +7211,7 @@ var NOT_CHECKED = (skipped) => ({
|
|
|
7092
7211
|
});
|
|
7093
7212
|
var git = (root, args, options = {}) => {
|
|
7094
7213
|
try {
|
|
7095
|
-
return
|
|
7214
|
+
return execFileSync3("git", args, {
|
|
7096
7215
|
cwd: root,
|
|
7097
7216
|
encoding: "utf8",
|
|
7098
7217
|
stdio: ["pipe", "pipe", "ignore"],
|
|
@@ -7441,9 +7560,9 @@ var createDocBridgeGraphMemory = (snapshot, overlay = {}) => {
|
|
|
7441
7560
|
};
|
|
7442
7561
|
|
|
7443
7562
|
// src/agents/registry-adapter.ts
|
|
7444
|
-
import { existsSync as
|
|
7563
|
+
import { existsSync as existsSync12, readFileSync as readFileSync13, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
|
|
7445
7564
|
import { spawn } from "child_process";
|
|
7446
|
-
import { join as
|
|
7565
|
+
import { join as join12, resolve as resolve12 } from "path";
|
|
7447
7566
|
import { pathToFileURL } from "url";
|
|
7448
7567
|
import { z as z11 } from "zod";
|
|
7449
7568
|
var DEFAULT_REGISTRY_AGENT_ID = "ecosystem-doc-bridge-corpus-scanner";
|
|
@@ -7478,7 +7597,7 @@ var validateGrounding = (proposal, snapshot, report, documentation) => {
|
|
|
7478
7597
|
if (proposal.relatedDiagnosticIds.some((id) => !diagnosticIds.has(id))) throw new Error("Registry agent proposal references an unknown diagnostic.");
|
|
7479
7598
|
if (proposal.evidence.some((item) => !evidenceKeys.has(evidenceKey2(item)))) throw new Error("Registry agent proposal contains evidence outside the supplied snapshot/report.");
|
|
7480
7599
|
};
|
|
7481
|
-
var runCli = (root, cli, context, timeoutMs, maxInputBytes, maxResponseBytes) => new Promise((
|
|
7600
|
+
var runCli = (root, cli, context, timeoutMs, maxInputBytes, maxResponseBytes) => new Promise((resolve33, reject) => {
|
|
7482
7601
|
const v2 = "protocol" in context;
|
|
7483
7602
|
const input = JSON.stringify(
|
|
7484
7603
|
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 }
|
|
@@ -7530,7 +7649,7 @@ var runCli = (root, cli, context, timeoutMs, maxInputBytes, maxResponseBytes) =>
|
|
|
7530
7649
|
return;
|
|
7531
7650
|
}
|
|
7532
7651
|
try {
|
|
7533
|
-
|
|
7652
|
+
resolve33(JSON.parse(stdout));
|
|
7534
7653
|
} catch (error) {
|
|
7535
7654
|
reject(new Error(`Registry agent CLI must return one JSON object on stdout: ${error instanceof Error ? error.message : String(error)}`));
|
|
7536
7655
|
}
|
|
@@ -7546,8 +7665,8 @@ var runCli = (root, cli, context, timeoutMs, maxInputBytes, maxResponseBytes) =>
|
|
|
7546
7665
|
var loadRegistryAgentRunner = async (root, config) => {
|
|
7547
7666
|
const metadata = loadRegistryAgentMetadata(root, config);
|
|
7548
7667
|
const configured = registryConfig(config)?.runnerModule;
|
|
7549
|
-
const modulePath = configured ? containedPath(root, configured) : containedPath(root,
|
|
7550
|
-
if (!modulePath || !
|
|
7668
|
+
const modulePath = configured ? containedPath(root, configured) : containedPath(root, join12(metadata.root, "doc-bridge-adapter.js"));
|
|
7669
|
+
if (!modulePath || !existsSync12(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.`);
|
|
7551
7670
|
const loaded = await import(pathToFileURL(modulePath).href);
|
|
7552
7671
|
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;
|
|
7553
7672
|
if (!runner) throw new Error(`Registry agent runner at ${modulePath} must export a function or { run }. `);
|
|
@@ -7557,17 +7676,17 @@ var loadRegistryAgentMetadata = (root, config) => {
|
|
|
7557
7676
|
const settings = registryConfig(config);
|
|
7558
7677
|
const id = settings?.agentId ?? DEFAULT_REGISTRY_AGENT_ID;
|
|
7559
7678
|
const agentRoot = settings?.agentRoot ?? "agents";
|
|
7560
|
-
const agentPath = containedPath(root,
|
|
7561
|
-
if (!agentPath || !
|
|
7562
|
-
const metadataPath = [
|
|
7679
|
+
const agentPath = containedPath(root, join12(agentRoot, id));
|
|
7680
|
+
if (!agentPath || !existsSync12(agentPath)) throw new Error(`AgentsKit Registry agent "${id}" is not installed at ${join12(agentRoot, id)}. Install it with: npx agentskit add ${id}`);
|
|
7681
|
+
const metadataPath = [join12(agentPath, "agent.json"), join12(agentPath, "manifest.json")].find(existsSync12);
|
|
7563
7682
|
if (!metadataPath) throw new Error(`Registry agent "${id}" is installed but has no agent.json or manifest.json metadata.`);
|
|
7564
|
-
const metadata = RegistryAgentMetadataSchema.parse(JSON.parse(
|
|
7683
|
+
const metadata = RegistryAgentMetadataSchema.parse(JSON.parse(readFileSync13(metadataPath, "utf8")));
|
|
7565
7684
|
if (metadata.id !== id) throw new Error(`Installed Registry agent metadata id "${metadata.id}" does not match configured id "${id}".`);
|
|
7566
7685
|
return { ...metadata, root: agentPath };
|
|
7567
7686
|
};
|
|
7568
7687
|
var createRegistryAgentAdapter = (root, config, runner) => {
|
|
7569
7688
|
if (!registryConfig(config)?.enabled) throw new Error("Registry agents are disabled. Set intelligence.registry.enabled: true to run an assisted workflow.");
|
|
7570
|
-
const metadata = loadRegistryAgentMetadata(
|
|
7689
|
+
const metadata = loadRegistryAgentMetadata(resolve12(root), config);
|
|
7571
7690
|
const settings = registryConfig(config) ?? {};
|
|
7572
7691
|
const timeoutMs = settings.timeoutMs ?? 12e4;
|
|
7573
7692
|
const maxInputBytes = settings.maxInputBytes ?? 8e6;
|
|
@@ -7584,7 +7703,7 @@ var createRegistryAgentAdapter = (root, config, runner) => {
|
|
|
7584
7703
|
try {
|
|
7585
7704
|
let raw;
|
|
7586
7705
|
if (settings.cli) {
|
|
7587
|
-
raw = await runCli(
|
|
7706
|
+
raw = await runCli(resolve12(root), settings.cli, context, timeoutMs, maxInputBytes, maxResponseBytes);
|
|
7588
7707
|
} else {
|
|
7589
7708
|
const localRunner = runner;
|
|
7590
7709
|
const timeout = new Promise((_, reject) => {
|
|
@@ -7662,8 +7781,8 @@ var persistRegistryAgentProposal = (stateDir, proposal) => {
|
|
|
7662
7781
|
AgentProposalV1Schema.parse(proposal);
|
|
7663
7782
|
if (proposal.contentHash !== contentHashForArtifactV1(proposal)) throw new Error("Cannot persist a Registry agent proposal with an invalid contentHash.");
|
|
7664
7783
|
const safeHash = contentHashForArtifactV1(proposal);
|
|
7665
|
-
mkdirSync3(
|
|
7666
|
-
const path =
|
|
7784
|
+
mkdirSync3(join12(resolve12(stateDir), "agents"), { recursive: true });
|
|
7785
|
+
const path = join12(resolve12(stateDir), "agents", `${proposal.origin.id}-${safeHash}.json`);
|
|
7667
7786
|
writeFileSync3(path, `${JSON.stringify(proposal, null, 2)}
|
|
7668
7787
|
`, "utf8");
|
|
7669
7788
|
return path;
|
|
@@ -8040,15 +8159,15 @@ var reconcileKnowledge = (observed, declared, options = {}) => {
|
|
|
8040
8159
|
};
|
|
8041
8160
|
|
|
8042
8161
|
// src/audit/documentation.ts
|
|
8043
|
-
import { readFileSync as
|
|
8044
|
-
import { resolve as
|
|
8162
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
8163
|
+
import { resolve as resolve13 } from "path";
|
|
8045
8164
|
import { minimatch as minimatch6 } from "minimatch";
|
|
8046
8165
|
|
|
8047
8166
|
// src/query/handoff.ts
|
|
8048
8167
|
var MAX_RELATED = 3;
|
|
8049
8168
|
var MAX_READ_BEFORE = 2;
|
|
8050
8169
|
var MAX_RELATED_EVIDENCE = 3;
|
|
8051
|
-
var
|
|
8170
|
+
var dirname6 = (path) => path.split("/").slice(0, -1).join("/") || ".";
|
|
8052
8171
|
var isHttp = (value) => /^https?:\/\//.test(value);
|
|
8053
8172
|
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;
|
|
8054
8173
|
var legacyHandoff = (index, id, config) => {
|
|
@@ -8184,7 +8303,7 @@ var handoffForEntity = (index, id, config, options = {}) => {
|
|
|
8184
8303
|
const area = target2.graph.areaId ? byId.get(target2.graph.areaId) : void 0;
|
|
8185
8304
|
const packageEntry = target2.graph.packageId ? byId.get(target2.graph.packageId) : target2.kind === "package" ? target2 : void 0;
|
|
8186
8305
|
const explain = {};
|
|
8187
|
-
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:
|
|
8306
|
+
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` };
|
|
8188
8307
|
explain.editRoots = [unit.reason];
|
|
8189
8308
|
const documents = documentsFor(projection, byId, target2, ownership);
|
|
8190
8309
|
const startHere = documents[0]?.path ?? config.corpus.agent.index ?? target2.path;
|
|
@@ -8652,7 +8771,7 @@ var auditDocumentation = (options) => {
|
|
|
8652
8771
|
const generatedPaths = config.generatedPaths ?? [];
|
|
8653
8772
|
const criticalPaths = config.criticalPaths ?? [];
|
|
8654
8773
|
const requiredSections = config.requiredSections ?? [];
|
|
8655
|
-
const documents = options.snapshot.entities.filter((entity) => entity.kind === "document" && entity.path).map((entity) => ({ path: normalizedPath2(entity.path), content:
|
|
8774
|
+
const documents = options.snapshot.entities.filter((entity) => entity.kind === "document" && entity.path).map((entity) => ({ path: normalizedPath2(entity.path), content: readFileSync14(resolve13(options.root, entity.path), "utf8") })).filter((document) => !matches(document.path, excluded)).sort((a, b) => a.path.localeCompare(b.path));
|
|
8656
8775
|
const findings = [];
|
|
8657
8776
|
const generated = documents.filter((document) => matches(document.path, generatedPaths));
|
|
8658
8777
|
const analyzed = documents.filter((document) => !matches(document.path, generatedPaths));
|
|
@@ -9220,7 +9339,7 @@ const findingMatches=(finding)=>{const query=state.query.toLowerCase();return(!q
|
|
|
9220
9339
|
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"})();
|
|
9221
9340
|
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))};
|
|
9222
9341
|
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>";
|
|
9223
|
-
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>"};
|
|
9342
|
+
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>"};
|
|
9224
9343
|
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>"};
|
|
9225
9344
|
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>"};
|
|
9226
9345
|
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>"}};
|
|
@@ -9389,14 +9508,14 @@ var renderOfflineReportArtifact = (input, options = {}) => {
|
|
|
9389
9508
|
};
|
|
9390
9509
|
|
|
9391
9510
|
// src/fixes/proposals.ts
|
|
9392
|
-
import { existsSync as
|
|
9393
|
-
import { basename as basename7, dirname as
|
|
9511
|
+
import { existsSync as existsSync13, readdirSync as readdirSync4, readFileSync as readFileSync15, realpathSync as realpathSync8, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync4 } from "fs";
|
|
9512
|
+
import { basename as basename7, dirname as dirname7, extname as extname5, join as join13, relative as relative8, resolve as resolve14, sep as sep9 } from "path";
|
|
9394
9513
|
var hash4 = (value) => sha256NormalizedV1(value);
|
|
9395
9514
|
var artifactMetadata = (root, options) => ({
|
|
9396
9515
|
schemaVersion: 1,
|
|
9397
9516
|
contentHash: "0".repeat(64),
|
|
9398
9517
|
contentHashAlgo: "sha256-normalized-v1",
|
|
9399
|
-
project: { name: options.projectName ?? basename7(
|
|
9518
|
+
project: { name: options.projectName ?? basename7(resolve14(root)), root: "." },
|
|
9400
9519
|
sourceRevision: options.baseRevision,
|
|
9401
9520
|
sourceRevisionKind: options.baseRevision.length === 40 ? "git" : "content",
|
|
9402
9521
|
configurationHash: options.configurationHash,
|
|
@@ -9427,31 +9546,32 @@ var makeProposal = (root, options, changes, preconditions, postconditions) => {
|
|
|
9427
9546
|
};
|
|
9428
9547
|
return FixProposalV1Schema.parse({ ...draft, contentHash: contentHashForArtifactV1(draft) });
|
|
9429
9548
|
};
|
|
9430
|
-
var walkMarkdown = (root, directory = root) => readdirSync4(directory, { withFileTypes: true }).flatMap((entry) => {
|
|
9549
|
+
var walkMarkdown = (root, directory = root, ignored = createIgnoreFilter(root)) => readdirSync4(directory, { withFileTypes: true }).flatMap((entry) => {
|
|
9431
9550
|
if (entry.name === ".git" || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build") return [];
|
|
9432
|
-
const path =
|
|
9433
|
-
if (entry.isDirectory()) return
|
|
9434
|
-
|
|
9551
|
+
const path = join13(directory, entry.name);
|
|
9552
|
+
if (ignored.isIgnored(path, entry.isDirectory())) return [];
|
|
9553
|
+
if (entry.isDirectory()) return walkMarkdown(root, path, ignored);
|
|
9554
|
+
return entry.isFile() && [".md", ".mdx"].includes(extname5(entry.name).toLowerCase()) ? [relative8(root, path).split(sep9).join("/")] : [];
|
|
9435
9555
|
});
|
|
9436
9556
|
var localLink = /(!?)\[([^\]]*)\]\(([^)\s]+)(?:\s+["'][^)]*["'])?\)/g;
|
|
9437
9557
|
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;
|
|
9438
9558
|
var createMarkdownLinkFixProposal = (root, options) => {
|
|
9439
|
-
const projectRoot =
|
|
9559
|
+
const projectRoot = realpathSync8.native(resolve14(root));
|
|
9440
9560
|
const paths = walkMarkdown(projectRoot);
|
|
9441
9561
|
const changes = [];
|
|
9442
9562
|
for (const path of paths) {
|
|
9443
|
-
const content =
|
|
9563
|
+
const content = readFileSync15(join13(projectRoot, path), "utf8");
|
|
9444
9564
|
let next = content;
|
|
9445
9565
|
for (const match of content.matchAll(localLink)) {
|
|
9446
9566
|
const target2 = match[3];
|
|
9447
9567
|
if (!target2 || match[1] === "!" || /^(?:[a-z]+:|\/|#)/i.test(target2)) continue;
|
|
9448
9568
|
const targetPath = target2.split("#")[0]?.split("?")[0];
|
|
9449
|
-
if (!targetPath ||
|
|
9569
|
+
if (!targetPath || existsSync13(resolve14(projectRoot, dirname7(path), targetPath))) continue;
|
|
9450
9570
|
const targetStem = basename7(targetPath, extname5(targetPath)).toLowerCase();
|
|
9451
9571
|
const labelStem = (match[2] ?? "").trim().toLowerCase().replace(/[^a-z0-9]+/g, "");
|
|
9452
9572
|
const candidates = paths.filter((candidate) => basename7(candidate, extname5(candidate)).toLowerCase() === targetStem || basename7(candidate, extname5(candidate)).toLowerCase().replace(/[^a-z0-9]+/g, "") === labelStem);
|
|
9453
9573
|
if (candidates.length !== 1) continue;
|
|
9454
|
-
let replacement =
|
|
9574
|
+
let replacement = relative8(dirname7(path), candidates[0]).split(sep9).join("/");
|
|
9455
9575
|
if (target2.startsWith("./") && !replacement.startsWith(".")) replacement = `./${replacement}`;
|
|
9456
9576
|
next = next.replace(match[0], match[0].replace(target2, replacement));
|
|
9457
9577
|
}
|
|
@@ -9460,13 +9580,13 @@ var createMarkdownLinkFixProposal = (root, options) => {
|
|
|
9460
9580
|
return changes.length ? makeProposal(projectRoot, options, changes, ["Each replacement has exactly one Markdown target."], ["All corrected local Markdown links resolve."]) : void 0;
|
|
9461
9581
|
};
|
|
9462
9582
|
var createArtifactNormalizationProposal = (root, artifactPath, options) => {
|
|
9463
|
-
const projectRoot =
|
|
9464
|
-
const path = artifactPath.split(
|
|
9583
|
+
const projectRoot = realpathSync8.native(resolve14(root));
|
|
9584
|
+
const path = artifactPath.split(sep9).join("/");
|
|
9465
9585
|
const absolute = containedPath(projectRoot, path);
|
|
9466
9586
|
if (!absolute) return void 0;
|
|
9467
9587
|
let before;
|
|
9468
9588
|
try {
|
|
9469
|
-
before =
|
|
9589
|
+
before = readFileSync15(absolute, "utf8");
|
|
9470
9590
|
} catch {
|
|
9471
9591
|
return void 0;
|
|
9472
9592
|
}
|
|
@@ -9477,7 +9597,7 @@ var createArtifactNormalizationProposal = (root, artifactPath, options) => {
|
|
|
9477
9597
|
} catch {
|
|
9478
9598
|
return void 0;
|
|
9479
9599
|
}
|
|
9480
|
-
return after === before ? void 0 : makeProposal(projectRoot, options, [{ path:
|
|
9600
|
+
return after === before ? void 0 : makeProposal(projectRoot, options, [{ path: relative8(projectRoot, absolute).split(sep9).join("/"), before, after }], ["The artifact contains valid JSON."], ["The artifact is valid canonical JSON with one trailing newline."]);
|
|
9481
9601
|
};
|
|
9482
9602
|
var approveFixProposal = (proposalInput, approvedBy, approvedAt = (/* @__PURE__ */ new Date()).toISOString()) => {
|
|
9483
9603
|
const proposal = FixProposalV1Schema.parse(proposalInput);
|
|
@@ -9495,7 +9615,7 @@ var applyFixProposal = (root, proposalInput, options = {}) => {
|
|
|
9495
9615
|
if (proposal.approval.proposalHash !== bindingHash(proposal)) throw new Error("Approval is not bound to the exact proposal content.");
|
|
9496
9616
|
if (options.currentRevision && options.currentRevision !== proposal.baseRevision) throw new Error("The repository revision changed since this proposal was created.");
|
|
9497
9617
|
if (!proposal.changes?.length) throw new Error("This proposal has no executable changes.");
|
|
9498
|
-
const projectRoot =
|
|
9618
|
+
const projectRoot = realpathSync8.native(resolve14(root));
|
|
9499
9619
|
const originals = /* @__PURE__ */ new Map();
|
|
9500
9620
|
const affected = new Map(proposal.affectedFiles.map((file) => [file.path, file]));
|
|
9501
9621
|
if (proposal.changes.some((change) => !affected.has(change.path) || affected.get(change.path)?.contentHash !== sha256NormalizedV1(change.before)) || affected.size !== proposal.changes.length) {
|
|
@@ -9503,29 +9623,29 @@ var applyFixProposal = (root, proposalInput, options = {}) => {
|
|
|
9503
9623
|
}
|
|
9504
9624
|
for (const file of proposal.affectedFiles) {
|
|
9505
9625
|
const absolute = containedPath(projectRoot, file.path);
|
|
9506
|
-
if (!absolute || !
|
|
9507
|
-
const current =
|
|
9626
|
+
if (!absolute || !existsSync13(absolute)) throw new Error(`Affected file is unavailable or escapes the repository root: ${file.path}`);
|
|
9627
|
+
const current = readFileSync15(absolute, "utf8");
|
|
9508
9628
|
if (sha256NormalizedV1(current) !== file.contentHash) throw new Error(`Affected file changed since proposal creation: ${file.path}`);
|
|
9509
9629
|
originals.set(absolute, current);
|
|
9510
9630
|
}
|
|
9511
9631
|
try {
|
|
9512
9632
|
for (const change of proposal.changes) {
|
|
9513
|
-
const absolute =
|
|
9633
|
+
const absolute = resolve14(projectRoot, change.path);
|
|
9514
9634
|
writeFileSync4(`${absolute}.docbridge-${process.pid}.tmp`, change.after, "utf8");
|
|
9515
9635
|
}
|
|
9516
9636
|
for (const change of proposal.changes) {
|
|
9517
|
-
const absolute =
|
|
9637
|
+
const absolute = resolve14(projectRoot, change.path);
|
|
9518
9638
|
renameSync2(`${absolute}.docbridge-${process.pid}.tmp`, absolute);
|
|
9519
9639
|
}
|
|
9520
9640
|
for (const change of proposal.changes) {
|
|
9521
|
-
if (
|
|
9641
|
+
if (readFileSync15(resolve14(projectRoot, change.path), "utf8") !== change.after) throw new Error(`Postcondition failed for ${change.path}`);
|
|
9522
9642
|
}
|
|
9523
9643
|
options.verify?.(proposal.changes.map((change) => change.path));
|
|
9524
9644
|
} catch (error) {
|
|
9525
9645
|
for (const [absolute, content] of originals) writeFileSync4(absolute, content, "utf8");
|
|
9526
9646
|
for (const change of proposal.changes) {
|
|
9527
|
-
const temp = `${
|
|
9528
|
-
if (
|
|
9647
|
+
const temp = `${resolve14(projectRoot, change.path)}.docbridge-${process.pid}.tmp`;
|
|
9648
|
+
if (existsSync13(temp)) unlinkSync(temp);
|
|
9529
9649
|
}
|
|
9530
9650
|
throw error;
|
|
9531
9651
|
}
|
|
@@ -9534,8 +9654,8 @@ var applyFixProposal = (root, proposalInput, options = {}) => {
|
|
|
9534
9654
|
};
|
|
9535
9655
|
|
|
9536
9656
|
// src/workflow/engine.ts
|
|
9537
|
-
import { appendFileSync, existsSync as
|
|
9538
|
-
import { join as
|
|
9657
|
+
import { appendFileSync, existsSync as existsSync14, mkdirSync as mkdirSync4, readFileSync as readFileSync16, renameSync as renameSync3, rmSync, writeFileSync as writeFileSync5 } from "fs";
|
|
9658
|
+
import { join as join14, relative as relative9, resolve as resolve15 } from "path";
|
|
9539
9659
|
var WORKFLOW_STAGES = ["collect", "normalize", "reconcile", "enrich", "evaluate", "report"];
|
|
9540
9660
|
var OPTIONAL_WORKFLOW_STAGES = ["enrich"];
|
|
9541
9661
|
var stageState = {
|
|
@@ -9546,7 +9666,7 @@ var stageState = {
|
|
|
9546
9666
|
evaluate: "proposed",
|
|
9547
9667
|
report: "delivered"
|
|
9548
9668
|
};
|
|
9549
|
-
var defaultStateDir = (root) =>
|
|
9669
|
+
var defaultStateDir = (root) => join14(root, ".doc-bridge", "workflow");
|
|
9550
9670
|
var atomicWrite = (path, value) => {
|
|
9551
9671
|
const temp = `${path}.tmp-${process.pid}-${Date.now()}`;
|
|
9552
9672
|
writeFileSync5(temp, `${JSON.stringify(value, null, 2)}
|
|
@@ -9554,10 +9674,10 @@ var atomicWrite = (path, value) => {
|
|
|
9554
9674
|
renameSync3(temp, path);
|
|
9555
9675
|
};
|
|
9556
9676
|
var writeManifest = (stateDir, run2) => {
|
|
9557
|
-
atomicWrite(
|
|
9677
|
+
atomicWrite(join14(stateDir, "manifest.json"), run2);
|
|
9558
9678
|
};
|
|
9559
9679
|
var appendTransition = (stateDir, transition2) => {
|
|
9560
|
-
appendFileSync(
|
|
9680
|
+
appendFileSync(join14(stateDir, "transitions.jsonl"), `${JSON.stringify(transition2)}
|
|
9561
9681
|
`, "utf8");
|
|
9562
9682
|
};
|
|
9563
9683
|
var transition = (run2, to, reason) => {
|
|
@@ -9588,8 +9708,8 @@ var transition = (run2, to, reason) => {
|
|
|
9588
9708
|
};
|
|
9589
9709
|
var runId = () => `${Date.now()}-${process.pid}`;
|
|
9590
9710
|
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" });
|
|
9591
|
-
var stageArtifactPath = (stateDir, stage, inputHash) =>
|
|
9592
|
-
var readArtifact = (path) => JSON.parse(
|
|
9711
|
+
var stageArtifactPath = (stateDir, stage, inputHash) => join14(stateDir, "artifacts", `${stage}-${inputHash}.json`);
|
|
9712
|
+
var readArtifact = (path) => JSON.parse(readFileSync16(path, "utf8"));
|
|
9593
9713
|
var readVerifiedArtifact = (path, stage, step) => {
|
|
9594
9714
|
const artifact2 = readArtifact(path);
|
|
9595
9715
|
if (artifact2.type !== "workflow-step-artifact" || artifact2.stage !== stage || artifact2.inputHash !== step.inputHash) throw new Error(`Invalid workflow artifact for stage "${stage}".`);
|
|
@@ -9597,8 +9717,8 @@ var readVerifiedArtifact = (path, stage, step) => {
|
|
|
9597
9717
|
return artifact2;
|
|
9598
9718
|
};
|
|
9599
9719
|
var stepArtifactPath = (stateDir, step) => {
|
|
9600
|
-
const path =
|
|
9601
|
-
const pathRelativeToState =
|
|
9720
|
+
const path = resolve15(stateDir, step.artifactRefs?.[0] ?? "");
|
|
9721
|
+
const pathRelativeToState = relative9(stateDir, path);
|
|
9602
9722
|
if (pathRelativeToState.startsWith("..") || pathRelativeToState.startsWith("/")) throw new Error(`Workflow artifact escapes state directory for stage "${step.name}".`);
|
|
9603
9723
|
return path;
|
|
9604
9724
|
};
|
|
@@ -9608,13 +9728,13 @@ var stepOutput = (stateDir, run2, stage) => {
|
|
|
9608
9728
|
return readVerifiedArtifact(stepArtifactPath(stateDir, step), stage, step).value;
|
|
9609
9729
|
};
|
|
9610
9730
|
var acquireLock = (stateDir) => {
|
|
9611
|
-
const lock =
|
|
9731
|
+
const lock = join14(stateDir, ".lock");
|
|
9612
9732
|
try {
|
|
9613
9733
|
mkdirSync4(lock);
|
|
9614
9734
|
} catch {
|
|
9615
|
-
const ownerPath =
|
|
9735
|
+
const ownerPath = join14(lock, "owner.json");
|
|
9616
9736
|
try {
|
|
9617
|
-
const owner = JSON.parse(
|
|
9737
|
+
const owner = JSON.parse(readFileSync16(ownerPath, "utf8"));
|
|
9618
9738
|
if (typeof owner.pid === "number") process.kill(owner.pid, 0);
|
|
9619
9739
|
throw new Error(`Workflow is already running (pid ${owner.pid ?? "unknown"}).`);
|
|
9620
9740
|
} catch (error) {
|
|
@@ -9623,13 +9743,13 @@ var acquireLock = (stateDir) => {
|
|
|
9623
9743
|
mkdirSync4(lock);
|
|
9624
9744
|
}
|
|
9625
9745
|
}
|
|
9626
|
-
writeFileSync5(
|
|
9746
|
+
writeFileSync5(join14(lock, "owner.json"), JSON.stringify({ pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf8");
|
|
9627
9747
|
return () => rmSync(lock, { recursive: true, force: true });
|
|
9628
9748
|
};
|
|
9629
9749
|
var loadManifest = (stateDir) => {
|
|
9630
|
-
const path =
|
|
9631
|
-
if (!
|
|
9632
|
-
return WorkflowRunV1Schema.parse(JSON.parse(
|
|
9750
|
+
const path = join14(stateDir, "manifest.json");
|
|
9751
|
+
if (!existsSync14(path)) return void 0;
|
|
9752
|
+
return WorkflowRunV1Schema.parse(JSON.parse(readFileSync16(path, "utf8")));
|
|
9633
9753
|
};
|
|
9634
9754
|
var baseRun = (options, stateDir, supersedes) => {
|
|
9635
9755
|
const inputHash = sha256NormalizedV1({ sourceRevision: options.sourceRevision, configurationHash: options.configurationHash, pipelineVersion: options.pipelineVersion ?? "1.0.0", analyzerVersions: options.analyzerVersions ?? {}, toolVersion: options.toolVersion ?? "1.0.0" });
|
|
@@ -9638,7 +9758,7 @@ var baseRun = (options, stateDir, supersedes) => {
|
|
|
9638
9758
|
schemaVersion: 1,
|
|
9639
9759
|
contentHash: "0".repeat(64),
|
|
9640
9760
|
contentHashAlgo: "sha256-normalized-v1",
|
|
9641
|
-
project: { name:
|
|
9761
|
+
project: { name: resolve15(options.root).split("/").pop() ?? "project", root: "." },
|
|
9642
9762
|
sourceRevision: options.sourceRevision,
|
|
9643
9763
|
sourceRevisionKind: "content",
|
|
9644
9764
|
configurationHash: options.configurationHash,
|
|
@@ -9649,16 +9769,16 @@ var baseRun = (options, stateDir, supersedes) => {
|
|
|
9649
9769
|
state: "created",
|
|
9650
9770
|
steps: WORKFLOW_STAGES.map((name) => ({ name, status: "pending", inputHash })),
|
|
9651
9771
|
transitions: [{ from: null, to: "created", at: (/* @__PURE__ */ new Date()).toISOString() }],
|
|
9652
|
-
artifactRefs: [
|
|
9772
|
+
artifactRefs: [relative9(resolve15(options.root), stateDir), ...supersedes ? [`supersedes:${supersedes}`] : []]
|
|
9653
9773
|
});
|
|
9654
9774
|
};
|
|
9655
9775
|
var withHash = (run2) => WorkflowRunV1Schema.parse({ ...run2, contentHash: contentHashForArtifactV1(run2) });
|
|
9656
9776
|
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" });
|
|
9657
9777
|
var selectedStages = (stage) => stage && stage !== "all" ? [stage] : WORKFLOW_STAGES;
|
|
9658
9778
|
var runWorkflow = (options) => {
|
|
9659
|
-
const root =
|
|
9660
|
-
const stateDir =
|
|
9661
|
-
mkdirSync4(
|
|
9779
|
+
const root = resolve15(options.root);
|
|
9780
|
+
const stateDir = resolve15(root, options.stateDir ?? defaultStateDir(root));
|
|
9781
|
+
mkdirSync4(join14(stateDir, "artifacts"), { recursive: true });
|
|
9662
9782
|
const release = acquireLock(stateDir);
|
|
9663
9783
|
try {
|
|
9664
9784
|
let run2 = loadManifest(stateDir);
|
|
@@ -9697,8 +9817,8 @@ var runWorkflow = (options) => {
|
|
|
9697
9817
|
const input = options.inputs?.[stage] ?? previousOutput;
|
|
9698
9818
|
const inputHash = stageInputHash(options, stage, input);
|
|
9699
9819
|
const existing = run2.steps.find((step) => step.name === stage);
|
|
9700
|
-
const artifactPath = existing?.artifactRefs?.[0] && existing.inputHash === inputHash ?
|
|
9701
|
-
if (existing?.status === "completed" && existing.inputHash === inputHash && existing.outputHash &&
|
|
9820
|
+
const artifactPath = existing?.artifactRefs?.[0] && existing.inputHash === inputHash ? resolve15(stateDir, existing.artifactRefs[0]) : stageArtifactPath(stateDir, stage, inputHash);
|
|
9821
|
+
if (existing?.status === "completed" && existing.inputHash === inputHash && existing.outputHash && existsSync14(artifactPath)) {
|
|
9702
9822
|
try {
|
|
9703
9823
|
previousOutput = readVerifiedArtifact(artifactPath, stage, existing).value;
|
|
9704
9824
|
} catch (error) {
|
|
@@ -9728,14 +9848,14 @@ var runWorkflow = (options) => {
|
|
|
9728
9848
|
const value = handler({ root, stage, input, previousOutput });
|
|
9729
9849
|
const outputHash = sha256NormalizedV1(value);
|
|
9730
9850
|
const artifact2 = { type: "workflow-step-artifact", stage, inputHash, outputHash, value };
|
|
9731
|
-
mkdirSync4(
|
|
9732
|
-
if (
|
|
9851
|
+
mkdirSync4(join14(stateDir, "artifacts"), { recursive: true });
|
|
9852
|
+
if (existsSync14(artifactPath)) {
|
|
9733
9853
|
const existingArtifact = readArtifact(artifactPath);
|
|
9734
9854
|
if (existingArtifact.outputHash !== outputHash) throw new Error(`Immutable workflow artifact collision for stage "${stage}".`);
|
|
9735
9855
|
} else {
|
|
9736
9856
|
atomicWrite(artifactPath, artifact2);
|
|
9737
9857
|
}
|
|
9738
|
-
const ref =
|
|
9858
|
+
const ref = relative9(stateDir, artifactPath);
|
|
9739
9859
|
const completedStep = { name: stage, status: "completed", inputHash, outputHash, artifactRefs: [ref] };
|
|
9740
9860
|
run2 = withHash({ ...run2, steps: run2.steps.map((step) => step.name === stage ? completedStep : step) });
|
|
9741
9861
|
writeManifest(stateDir, run2);
|
|
@@ -9755,15 +9875,15 @@ var runWorkflow = (options) => {
|
|
|
9755
9875
|
run2 = complete;
|
|
9756
9876
|
}
|
|
9757
9877
|
writeManifest(stateDir, run2);
|
|
9758
|
-
if (run2.state === "delivered") atomicWrite(
|
|
9878
|
+
if (run2.state === "delivered") atomicWrite(join14(stateDir, "last-known-good.json"), { runId: run2.runId, manifestHash: run2.contentHash, report: run2.steps.find((step) => step.name === "report")?.artifactRefs?.[0] });
|
|
9759
9879
|
}
|
|
9760
9880
|
return { run: run2, stateDir, reusedStages };
|
|
9761
9881
|
} finally {
|
|
9762
9882
|
release();
|
|
9763
9883
|
}
|
|
9764
9884
|
};
|
|
9765
|
-
var loadWorkflowManifest = (stateDir) => WorkflowRunV1Schema.parse(JSON.parse(
|
|
9766
|
-
var loadWorkflowStepOutput = (stateDir, stage) => stepOutput(
|
|
9885
|
+
var loadWorkflowManifest = (stateDir) => WorkflowRunV1Schema.parse(JSON.parse(readFileSync16(join14(resolve15(stateDir), "manifest.json"), "utf8")));
|
|
9886
|
+
var loadWorkflowStepOutput = (stateDir, stage) => stepOutput(resolve15(stateDir), loadWorkflowManifest(stateDir), stage);
|
|
9767
9887
|
|
|
9768
9888
|
// src/study/metrics.ts
|
|
9769
9889
|
import { z as z13 } from "zod";
|
|
@@ -10367,11 +10487,11 @@ var resolvedOptions = (options) => {
|
|
|
10367
10487
|
const config = RulesConfigSchema.parse(options.config ?? {});
|
|
10368
10488
|
const mode = options.preset ?? config.mode ?? "default";
|
|
10369
10489
|
const severity = { ...config.severity, ...options.severity };
|
|
10370
|
-
const
|
|
10490
|
+
const ignore2 = /* @__PURE__ */ new Set([...config.ignore ?? [], ...options.ignore ?? []]);
|
|
10371
10491
|
return {
|
|
10372
10492
|
mode,
|
|
10373
10493
|
severity,
|
|
10374
|
-
ignore,
|
|
10494
|
+
ignore: ignore2,
|
|
10375
10495
|
criticalEntities: options.criticalEntities ?? config.criticalEntities ?? [],
|
|
10376
10496
|
criticalPaths: options.criticalPaths ?? config.criticalPaths ?? [],
|
|
10377
10497
|
warningThresholds: { ...config.warningThresholds, ...options.warningThresholds }
|
|
@@ -10486,11 +10606,11 @@ function formatEcosystemLlmsSection(options) {
|
|
|
10486
10606
|
}
|
|
10487
10607
|
|
|
10488
10608
|
// src/gates/run-gates.ts
|
|
10489
|
-
import { readFileSync as
|
|
10609
|
+
import { readFileSync as readFileSync19 } from "fs";
|
|
10490
10610
|
|
|
10491
10611
|
// src/conformance/documentation-standard-v1.ts
|
|
10492
|
-
import { closeSync as closeSync2, existsSync as
|
|
10493
|
-
import { isAbsolute as
|
|
10612
|
+
import { closeSync as closeSync2, existsSync as existsSync15, fstatSync as fstatSync2, openSync as openSync2, readFileSync as readFileSync17, realpathSync as realpathSync9 } from "fs";
|
|
10613
|
+
import { isAbsolute as isAbsolute6, relative as relative10, resolve as resolve16, sep as sep10 } from "path";
|
|
10494
10614
|
|
|
10495
10615
|
// src/conformance/ecosystem-contract.ts
|
|
10496
10616
|
import { z as z15 } from "zod";
|
|
@@ -10540,10 +10660,9 @@ var ManifestSchema = z15.object({
|
|
|
10540
10660
|
schemaVersion: z15.literal(2),
|
|
10541
10661
|
parentBrand: z15.object({ id: NonEmptyStringSchema, name: NonEmptyStringSchema }).passthrough(),
|
|
10542
10662
|
products: z15.array(ProductSchema).min(1),
|
|
10543
|
-
//
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
}),
|
|
10663
|
+
// Deprecated compatibility shim: when present, every entry projects one products[] record.
|
|
10664
|
+
// Membership is whatever the canonical manifest lists; no product is required by name.
|
|
10665
|
+
properties: z15.array(LegacyPropertySchema).optional(),
|
|
10547
10666
|
builder: z15.object({ id: NonEmptyStringSchema, name: NonEmptyStringSchema, url: HttpsUrlSchema }).passthrough().optional()
|
|
10548
10667
|
}).passthrough();
|
|
10549
10668
|
var EvidenceSchema2 = z15.discriminatedUnion("type", [
|
|
@@ -10577,16 +10696,6 @@ var ClaimsSchema = z15.object({
|
|
|
10577
10696
|
manifestSchemaVersion: z15.literal(2),
|
|
10578
10697
|
products: z15.array(ClaimProductSchema)
|
|
10579
10698
|
}).passthrough();
|
|
10580
|
-
var LEGACY_FOUR_PRODUCT_IDS = ["agentskit", "akos", "playbook", "registry"];
|
|
10581
|
-
var FULL_SEVEN_PRODUCT_IDS = [
|
|
10582
|
-
"agentskit",
|
|
10583
|
-
"registry",
|
|
10584
|
-
"agentskit-chat",
|
|
10585
|
-
"playbook",
|
|
10586
|
-
"doc-bridge",
|
|
10587
|
-
"code-review",
|
|
10588
|
-
"akos"
|
|
10589
|
-
];
|
|
10590
10699
|
var parseCanonicalEcosystemContract = (manifestInput, claimsInput) => {
|
|
10591
10700
|
const manifest = ManifestSchema.parse(manifestInput);
|
|
10592
10701
|
const claims = ClaimsSchema.parse(claimsInput);
|
|
@@ -10612,12 +10721,14 @@ var parseCanonicalEcosystemContract = (manifestInput, claimsInput) => {
|
|
|
10612
10721
|
if (!products.has(nextId)) throw new Error(`Product ${product.id} references unknown product ${nextId}.`);
|
|
10613
10722
|
}
|
|
10614
10723
|
}
|
|
10615
|
-
const propertyIds =
|
|
10616
|
-
for (const [index,
|
|
10617
|
-
const
|
|
10724
|
+
const propertyIds = /* @__PURE__ */ new Set();
|
|
10725
|
+
for (const [index, legacy] of (manifest.properties ?? []).entries()) {
|
|
10726
|
+
const id = legacy.id;
|
|
10618
10727
|
const product = products.get(id);
|
|
10619
|
-
if (
|
|
10620
|
-
|
|
10728
|
+
if (propertyIds.has(id)) throw new Error(`Legacy property ${id} is listed more than once.`);
|
|
10729
|
+
propertyIds.add(id);
|
|
10730
|
+
if (!product || !product.surfaces.home) {
|
|
10731
|
+
throw new Error(`Legacy property ${index} (${id}) must project a manifest product with a home surface.`);
|
|
10621
10732
|
}
|
|
10622
10733
|
const expected = {
|
|
10623
10734
|
name: product.name,
|
|
@@ -10672,15 +10783,15 @@ var DOCUMENTATION_STANDARD_V1_ID = "documentation-standard-v1";
|
|
|
10672
10783
|
var DOCUMENTATION_STANDARD_V1_STATUS = "stable";
|
|
10673
10784
|
var MAX_TEXT_EVIDENCE_BYTES = 4 * 1024 * 1024;
|
|
10674
10785
|
var safePath = (root, path) => {
|
|
10675
|
-
const rootAbs =
|
|
10676
|
-
const unresolved =
|
|
10677
|
-
const unresolvedRel =
|
|
10678
|
-
if (
|
|
10679
|
-
if (!
|
|
10786
|
+
const rootAbs = realpathSync9.native(resolve16(root));
|
|
10787
|
+
const unresolved = resolve16(rootAbs, path);
|
|
10788
|
+
const unresolvedRel = relative10(rootAbs, unresolved);
|
|
10789
|
+
if (isAbsolute6(unresolvedRel) || unresolvedRel === ".." || unresolvedRel.startsWith(`..${sep10}`)) return void 0;
|
|
10790
|
+
if (!existsSync15(unresolved)) return unresolved;
|
|
10680
10791
|
try {
|
|
10681
|
-
const abs =
|
|
10682
|
-
const rel =
|
|
10683
|
-
return !
|
|
10792
|
+
const abs = realpathSync9.native(unresolved);
|
|
10793
|
+
const rel = relative10(rootAbs, abs);
|
|
10794
|
+
return !isAbsolute6(rel) && rel !== ".." && !rel.startsWith(`..${sep10}`) ? abs : void 0;
|
|
10684
10795
|
} catch {
|
|
10685
10796
|
return void 0;
|
|
10686
10797
|
}
|
|
@@ -10708,7 +10819,7 @@ var fileEvidence = (root, path, options) => {
|
|
|
10708
10819
|
return {
|
|
10709
10820
|
exists: true,
|
|
10710
10821
|
content: "",
|
|
10711
|
-
evidence: { path: toPosix(
|
|
10822
|
+
evidence: { path: toPosix(relative10(resolve16(root), abs)) || ".", detail: "File exists and is non-empty." }
|
|
10712
10823
|
};
|
|
10713
10824
|
}
|
|
10714
10825
|
if (stat.size > MAX_TEXT_EVIDENCE_BYTES) {
|
|
@@ -10718,12 +10829,12 @@ var fileEvidence = (root, path, options) => {
|
|
|
10718
10829
|
evidence: { path, detail: `Text evidence exceeds ${MAX_TEXT_EVIDENCE_BYTES} bytes.` }
|
|
10719
10830
|
};
|
|
10720
10831
|
}
|
|
10721
|
-
const content =
|
|
10832
|
+
const content = readFileSync17(fd, "utf8");
|
|
10722
10833
|
return {
|
|
10723
10834
|
exists: content.trim().length > 0,
|
|
10724
10835
|
content,
|
|
10725
10836
|
evidence: {
|
|
10726
|
-
path: toPosix(
|
|
10837
|
+
path: toPosix(relative10(resolve16(root), abs)) || ".",
|
|
10727
10838
|
detail: content.trim().length > 0 ? "File exists and is non-empty." : "File is empty."
|
|
10728
10839
|
}
|
|
10729
10840
|
};
|
|
@@ -10765,7 +10876,7 @@ var humanDocsRule = (root, config) => {
|
|
|
10765
10876
|
passed: docs.length > 0,
|
|
10766
10877
|
message: docs.length > 0 ? `Found ${docs.length} human document(s).` : "No human documentation was discovered.",
|
|
10767
10878
|
evidence: docs.slice(0, 10).map((doc) => ({
|
|
10768
|
-
path: toPosix(
|
|
10879
|
+
path: toPosix(relative10(resolve16(root), doc.path)),
|
|
10769
10880
|
detail: `Human route: ${doc.url}`
|
|
10770
10881
|
})),
|
|
10771
10882
|
remediation: {
|
|
@@ -10776,10 +10887,10 @@ var humanDocsRule = (root, config) => {
|
|
|
10776
10887
|
};
|
|
10777
10888
|
var llmsRule = (root, config, options, generated) => {
|
|
10778
10889
|
const llmsPath = config.index?.llmsTxt?.outFile ?? "llms.txt";
|
|
10779
|
-
const llmsKey = safePath(root, llmsPath) ??
|
|
10890
|
+
const llmsKey = safePath(root, llmsPath) ?? resolve16(root, llmsPath);
|
|
10780
10891
|
const rawSources = /* @__PURE__ */ new Map();
|
|
10781
10892
|
for (const path of options.rawSources ?? []) {
|
|
10782
|
-
const key = safePath(root, path) ??
|
|
10893
|
+
const key = safePath(root, path) ?? resolve16(root, path);
|
|
10783
10894
|
if (key !== llmsKey && !rawSources.has(key)) rawSources.set(key, path);
|
|
10784
10895
|
}
|
|
10785
10896
|
const paths = [llmsPath, ...rawSources.values()];
|
|
@@ -10918,11 +11029,11 @@ var linksRule = (root, options) => {
|
|
|
10918
11029
|
for (const link of links) {
|
|
10919
11030
|
const sources = link.paths.map((path) => ({ path, file: fileEvidence(root, path) }));
|
|
10920
11031
|
const matches2 = sources.filter(({ file }) => file.exists && file.content.includes(link.url));
|
|
10921
|
-
const
|
|
10922
|
-
if (matches2.length === 0 || !
|
|
11032
|
+
const canonical2 = contract.urls.has(normalizedUrl(link.url));
|
|
11033
|
+
if (matches2.length === 0 || !canonical2) passed = false;
|
|
10923
11034
|
evidence2.push({
|
|
10924
11035
|
path: sources.map((source) => source.path).join(", "),
|
|
10925
|
-
detail: matches2.length === 0 ? `Missing ${link.url}` :
|
|
11036
|
+
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.`
|
|
10926
11037
|
});
|
|
10927
11038
|
}
|
|
10928
11039
|
return {
|
|
@@ -11030,8 +11141,8 @@ var formatDocumentationStandardText = (report) => [
|
|
|
11030
11141
|
];
|
|
11031
11142
|
|
|
11032
11143
|
// src/query/load-index.ts
|
|
11033
|
-
import { existsSync as
|
|
11034
|
-
import { join as
|
|
11144
|
+
import { existsSync as existsSync16, readFileSync as readFileSync18 } from "fs";
|
|
11145
|
+
import { join as join15, resolve as resolve17 } from "path";
|
|
11035
11146
|
var IndexNotFoundError = class extends Error {
|
|
11036
11147
|
constructor(path) {
|
|
11037
11148
|
super(`Missing index at ${path}. Run: ak-docs index`);
|
|
@@ -11052,11 +11163,11 @@ var IndexStaleError = class extends Error {
|
|
|
11052
11163
|
actual;
|
|
11053
11164
|
expected;
|
|
11054
11165
|
};
|
|
11055
|
-
var indexFilePath = (root, config) =>
|
|
11166
|
+
var indexFilePath = (root, config) => join15(root, config.index?.outFile ?? ".doc-bridge/index.json");
|
|
11056
11167
|
var loadDocBridgeIndex = (root, config) => {
|
|
11057
11168
|
const path = indexFilePath(root, config);
|
|
11058
|
-
if (!
|
|
11059
|
-
const raw = JSON.parse(
|
|
11169
|
+
if (!existsSync16(path)) throw new IndexNotFoundError(path);
|
|
11170
|
+
const raw = JSON.parse(readFileSync18(path, "utf8"));
|
|
11060
11171
|
return parseDocBridgeIndex(raw);
|
|
11061
11172
|
};
|
|
11062
11173
|
var loadFreshDocBridgeIndex = (root, config) => {
|
|
@@ -11074,7 +11185,7 @@ var loadFreshDocBridgeIndex = (root, config) => {
|
|
|
11074
11185
|
}
|
|
11075
11186
|
return index;
|
|
11076
11187
|
};
|
|
11077
|
-
var resolveRoot = (cwd) =>
|
|
11188
|
+
var resolveRoot = (cwd) => resolve17(cwd ?? process.cwd());
|
|
11078
11189
|
|
|
11079
11190
|
// src/gates/run-gates.ts
|
|
11080
11191
|
var RESERVED_GATE_IDS = /* @__PURE__ */ new Set(["link-rot", "routing-currency", "bootstrap-size"]);
|
|
@@ -11120,7 +11231,7 @@ var runGate = (root, config, id) => {
|
|
|
11120
11231
|
return {
|
|
11121
11232
|
id,
|
|
11122
11233
|
ok: false,
|
|
11123
|
-
message: `${result.ignored.length} indexed path(s) are ignored by Git, so a clean checkout builds a different index.
|
|
11234
|
+
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.`,
|
|
11124
11235
|
expected: "every indexed path is committed",
|
|
11125
11236
|
actual: sample.join(", ")
|
|
11126
11237
|
};
|
|
@@ -11179,7 +11290,7 @@ var runOkfTypeGate = (root, config) => {
|
|
|
11179
11290
|
const required = config.corpus.agent.okf?.requireType ?? config.gates?.preset === "strict";
|
|
11180
11291
|
if (!required) return { id: "okf-type", ok: true, message: "OKF type frontmatter not required" };
|
|
11181
11292
|
const allowed = config.corpus.agent.okf?.allowedTypes;
|
|
11182
|
-
const bad = scanAgentCorpus(root, config).filter((doc) => doc.path !== config.corpus.agent.index).map((doc) => ({ path: doc.path, type: frontmatterType(
|
|
11293
|
+
const bad = scanAgentCorpus(root, config).filter((doc) => doc.path !== config.corpus.agent.index).map((doc) => ({ path: doc.path, type: frontmatterType(readFileSync19(doc.absPath, "utf8")) })).filter((doc) => !doc.type || allowed && !allowed.includes(doc.type));
|
|
11183
11294
|
if (bad.length) {
|
|
11184
11295
|
return {
|
|
11185
11296
|
id: "okf-type",
|
|
@@ -11253,7 +11364,7 @@ var runDocsStyleGate = (root, config) => {
|
|
|
11253
11364
|
}
|
|
11254
11365
|
const bad = scanAgentCorpus(root, config).filter((doc) => doc.path !== config.corpus.agent.index).map((doc) => ({
|
|
11255
11366
|
path: doc.path,
|
|
11256
|
-
missing: missingStyleRules(
|
|
11367
|
+
missing: missingStyleRules(readFileSync19(doc.absPath, "utf8"), required)
|
|
11257
11368
|
})).filter((doc) => doc.missing.length > 0);
|
|
11258
11369
|
if (bad.length) {
|
|
11259
11370
|
return {
|
|
@@ -11298,8 +11409,8 @@ var resolveGateIds = (config) => {
|
|
|
11298
11409
|
};
|
|
11299
11410
|
|
|
11300
11411
|
// src/mcp/server.ts
|
|
11301
|
-
import { mkdirSync as mkdirSync6, readFileSync as
|
|
11302
|
-
import { join as
|
|
11412
|
+
import { mkdirSync as mkdirSync6, readFileSync as readFileSync22, realpathSync as realpathSync10, writeFileSync as writeFileSync7 } from "fs";
|
|
11413
|
+
import { join as join18, relative as relative11, resolve as resolve19 } from "path";
|
|
11303
11414
|
import { z as z16, ZodError } from "zod";
|
|
11304
11415
|
|
|
11305
11416
|
// src/query/search.ts
|
|
@@ -11570,15 +11681,15 @@ ${document.source ? `Source: ${document.source}
|
|
|
11570
11681
|
` : ""}${document.content}`).join("\n\n");
|
|
11571
11682
|
|
|
11572
11683
|
// src/memory/ingest.ts
|
|
11573
|
-
import { existsSync as
|
|
11574
|
-
import { join as
|
|
11684
|
+
import { existsSync as existsSync17, readFileSync as readFileSync20 } from "fs";
|
|
11685
|
+
import { join as join16 } from "path";
|
|
11575
11686
|
var memoryFact = (raw, id) => firstParagraph(raw) ?? firstHeading(raw) ?? id;
|
|
11576
11687
|
var relativePath2 = (root, abs) => toPosix(abs).replace(`${toPosix(root)}/`, "");
|
|
11577
11688
|
var ingestMarkdownDir = (root, dir, source, confidence) => {
|
|
11578
|
-
if (!
|
|
11579
|
-
return walkFiles(dir, { extensions: [".md", ".mdc"] }).map((abs) => {
|
|
11689
|
+
if (!existsSync17(dir)) return [];
|
|
11690
|
+
return walkFiles(dir, { extensions: [".md", ".mdc"], respectIgnore: false }).map((abs) => {
|
|
11580
11691
|
const rel = relativePath2(root, abs);
|
|
11581
|
-
const raw =
|
|
11692
|
+
const raw = readFileSync20(abs, "utf8");
|
|
11582
11693
|
const id = slugFromPath(rel);
|
|
11583
11694
|
return {
|
|
11584
11695
|
schemaVersion: 1,
|
|
@@ -11593,10 +11704,10 @@ var ingestMarkdownDir = (root, dir, source, confidence) => {
|
|
|
11593
11704
|
});
|
|
11594
11705
|
};
|
|
11595
11706
|
var ingestCursorRules = (root) => {
|
|
11596
|
-
const dir =
|
|
11707
|
+
const dir = join16(root, ".cursor", "rules");
|
|
11597
11708
|
return ingestMarkdownDir(root, dir, "cursor", 0.6);
|
|
11598
11709
|
};
|
|
11599
|
-
var ingestAgentMemory = (root) => ingestMarkdownDir(root,
|
|
11710
|
+
var ingestAgentMemory = (root) => ingestMarkdownDir(root, join16(root, ".agent-memory"), "agent-memory", 0.7);
|
|
11600
11711
|
var ingestMemoryCandidates = (root) => [
|
|
11601
11712
|
...ingestAgentMemory(root),
|
|
11602
11713
|
...ingestCursorRules(root)
|
|
@@ -12234,8 +12345,8 @@ var formatKnowledgeLookupText = (response) => {
|
|
|
12234
12345
|
};
|
|
12235
12346
|
|
|
12236
12347
|
// src/enrich/approvals.ts
|
|
12237
|
-
import { existsSync as
|
|
12238
|
-
import { join as
|
|
12348
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync5, readFileSync as readFileSync21, readdirSync as readdirSync5, renameSync as renameSync4, writeFileSync as writeFileSync6 } from "fs";
|
|
12349
|
+
import { join as join17, resolve as resolve18 } from "path";
|
|
12239
12350
|
|
|
12240
12351
|
// src/intelligence/peers.ts
|
|
12241
12352
|
var PeerMissingError = class extends Error {
|
|
@@ -12287,7 +12398,7 @@ var layer1InstallHint = () => LAYER1_INSTALL;
|
|
|
12287
12398
|
var APPROVALS_DIR = ".doc-bridge/approvals";
|
|
12288
12399
|
var ENRICHMENT_APPROVAL_GATE = "doc-bridge.enrichment";
|
|
12289
12400
|
var FIX_APPROVAL_GATE = "doc-bridge.fix";
|
|
12290
|
-
var approvalsDir = (root) =>
|
|
12401
|
+
var approvalsDir = (root) => join17(resolve18(root), APPROVALS_DIR);
|
|
12291
12402
|
var safeId = (id) => {
|
|
12292
12403
|
if (!/^[a-f0-9]{16,64}$/.test(id)) throw new Error(`Approval ids are content hashes; received "${id}".`);
|
|
12293
12404
|
return id;
|
|
@@ -12295,7 +12406,7 @@ var safeId = (id) => {
|
|
|
12295
12406
|
var enrichmentApprovalId = (proposalId, targetContentHash) => sha256NormalizedV1({ proposalId, targetContentHash });
|
|
12296
12407
|
var fixApprovalId = (proposalId, proposalHash) => sha256NormalizedV1({ proposalId, proposalHash });
|
|
12297
12408
|
var createFileApprovalStore = (dir) => {
|
|
12298
|
-
const pathFor = (id) =>
|
|
12409
|
+
const pathFor = (id) => join17(dir, `${safeId(id)}.json`);
|
|
12299
12410
|
const write = (approval) => {
|
|
12300
12411
|
mkdirSync5(dir, { recursive: true });
|
|
12301
12412
|
const path = pathFor(approval.id);
|
|
@@ -12306,9 +12417,9 @@ var createFileApprovalStore = (dir) => {
|
|
|
12306
12417
|
};
|
|
12307
12418
|
const read = (id) => {
|
|
12308
12419
|
const path = pathFor(id);
|
|
12309
|
-
if (!
|
|
12420
|
+
if (!existsSync18(path)) return null;
|
|
12310
12421
|
try {
|
|
12311
|
-
return JSON.parse(
|
|
12422
|
+
return JSON.parse(readFileSync21(path, "utf8"));
|
|
12312
12423
|
} catch {
|
|
12313
12424
|
return null;
|
|
12314
12425
|
}
|
|
@@ -12330,10 +12441,10 @@ var createFileApprovalStore = (dir) => {
|
|
|
12330
12441
|
};
|
|
12331
12442
|
};
|
|
12332
12443
|
var listApprovals = (dir) => {
|
|
12333
|
-
if (!
|
|
12444
|
+
if (!existsSync18(dir)) return [];
|
|
12334
12445
|
return readdirSync5(dir).filter((name) => /^[a-f0-9]{16,64}\.json$/.test(name)).sort().flatMap((name) => {
|
|
12335
12446
|
try {
|
|
12336
|
-
return [JSON.parse(
|
|
12447
|
+
return [JSON.parse(readFileSync21(join17(dir, name), "utf8"))];
|
|
12337
12448
|
} catch {
|
|
12338
12449
|
return [];
|
|
12339
12450
|
}
|
|
@@ -12664,16 +12775,16 @@ var findDocPath = (index, args) => {
|
|
|
12664
12775
|
return doc.path;
|
|
12665
12776
|
};
|
|
12666
12777
|
var resolveDocPath = (root, relPath) => {
|
|
12667
|
-
const rootAbs =
|
|
12668
|
-
const unresolved =
|
|
12669
|
-
const unresolvedRel =
|
|
12778
|
+
const rootAbs = realpathSync10.native(root);
|
|
12779
|
+
const unresolved = resolve19(rootAbs, relPath);
|
|
12780
|
+
const unresolvedRel = relative11(rootAbs, unresolved);
|
|
12670
12781
|
if (unresolvedRel.startsWith("..")) throw new Error("doc.get path escapes project root");
|
|
12671
|
-
const abs =
|
|
12672
|
-
const rel =
|
|
12782
|
+
const abs = realpathSync10.native(unresolved);
|
|
12783
|
+
const rel = relative11(rootAbs, abs);
|
|
12673
12784
|
if (rel.startsWith("..")) throw new Error("doc.get path escapes project root");
|
|
12674
12785
|
return abs;
|
|
12675
12786
|
};
|
|
12676
|
-
var workflowStateDir = (ctx) =>
|
|
12787
|
+
var workflowStateDir = (ctx) => resolve19(ctx.root, ctx.config.workflow?.stateDir ?? ".doc-bridge/workflow");
|
|
12677
12788
|
var workflowRun = (ctx) => loadWorkflowManifest(workflowStateDir(ctx));
|
|
12678
12789
|
var ensureLatestRun = (ctx, runId2) => {
|
|
12679
12790
|
const run2 = workflowRun(ctx);
|
|
@@ -12689,17 +12800,17 @@ var workflowReport = (ctx, runId2) => {
|
|
|
12689
12800
|
ensureLatestRun(ctx, runId2);
|
|
12690
12801
|
return parseReconciliationReport(loadWorkflowStepOutput(workflowStateDir(ctx), "reconcile"));
|
|
12691
12802
|
};
|
|
12692
|
-
var proposalPath = (ctx) =>
|
|
12803
|
+
var proposalPath = (ctx) => join18(ctx.root, ".doc-bridge", "proposal.json");
|
|
12693
12804
|
var readSavedProposal = (ctx, input) => {
|
|
12694
12805
|
if (input !== void 0) return FixProposalV1Schema.parse(input);
|
|
12695
12806
|
try {
|
|
12696
|
-
return FixProposalV1Schema.parse(JSON.parse(
|
|
12807
|
+
return FixProposalV1Schema.parse(JSON.parse(readFileSync22(proposalPath(ctx), "utf8")));
|
|
12697
12808
|
} catch {
|
|
12698
12809
|
throw new Error(`No saved fix proposal at ${proposalPath(ctx)}.`);
|
|
12699
12810
|
}
|
|
12700
12811
|
};
|
|
12701
12812
|
var saveProposal = (ctx, proposal) => {
|
|
12702
|
-
mkdirSync6(
|
|
12813
|
+
mkdirSync6(join18(ctx.root, ".doc-bridge"), { recursive: true });
|
|
12703
12814
|
writeFileSync7(proposalPath(ctx), `${JSON.stringify(proposal, null, 2)}
|
|
12704
12815
|
`, "utf8");
|
|
12705
12816
|
};
|
|
@@ -12762,7 +12873,7 @@ var handleMcpRequest = (ctx, request) => {
|
|
|
12762
12873
|
}
|
|
12763
12874
|
if (name === "doc.get") {
|
|
12764
12875
|
const relPath = findDocPath(index(), parseToolArgs("doc.get", DocGetArgsSchema, args));
|
|
12765
|
-
return textResult(
|
|
12876
|
+
return textResult(readFileSync22(resolveDocPath(ctx.root, relPath), "utf8"));
|
|
12766
12877
|
}
|
|
12767
12878
|
if (name === "gate.status") return textResult(runGates(ctx.root, ctx.config));
|
|
12768
12879
|
if (name === "retriever.query") {
|
|
@@ -12951,9 +13062,9 @@ var startMcpStdioServer = (ctx) => {
|
|
|
12951
13062
|
};
|
|
12952
13063
|
|
|
12953
13064
|
// src/mcp/install.ts
|
|
12954
|
-
import { existsSync as
|
|
13065
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync7, readFileSync as readFileSync23, writeFileSync as writeFileSync8 } from "fs";
|
|
12955
13066
|
import { homedir } from "os";
|
|
12956
|
-
import { dirname as
|
|
13067
|
+
import { dirname as dirname8, join as join19, resolve as resolve20 } from "path";
|
|
12957
13068
|
var SERVER_NAME = "ak-docs";
|
|
12958
13069
|
var mcpServerEntry = (root) => ({
|
|
12959
13070
|
command: "npx",
|
|
@@ -12961,26 +13072,26 @@ var mcpServerEntry = (root) => ({
|
|
|
12961
13072
|
cwd: root
|
|
12962
13073
|
});
|
|
12963
13074
|
var readJson2 = (path) => {
|
|
12964
|
-
if (!
|
|
13075
|
+
if (!existsSync19(path)) return {};
|
|
12965
13076
|
try {
|
|
12966
|
-
const parsed = JSON.parse(
|
|
13077
|
+
const parsed = JSON.parse(readFileSync23(path, "utf8"));
|
|
12967
13078
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
12968
13079
|
} catch {
|
|
12969
13080
|
return {};
|
|
12970
13081
|
}
|
|
12971
13082
|
};
|
|
12972
13083
|
var writeJson = (path, value) => {
|
|
12973
|
-
mkdirSync7(
|
|
13084
|
+
mkdirSync7(dirname8(path), { recursive: true });
|
|
12974
13085
|
writeFileSync8(path, `${JSON.stringify(value, null, 2)}
|
|
12975
13086
|
`, "utf8");
|
|
12976
13087
|
};
|
|
12977
13088
|
var resolveTargetPath = (target2, root) => {
|
|
12978
|
-
if (target2 === "cursor") return
|
|
12979
|
-
return
|
|
13089
|
+
if (target2 === "cursor") return resolve20(root, ".cursor", "mcp.json");
|
|
13090
|
+
return join19(homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
12980
13091
|
};
|
|
12981
13092
|
var installMcpConfig = (root, target2) => {
|
|
12982
13093
|
const configPath = resolveTargetPath(target2, root);
|
|
12983
|
-
const created = !
|
|
13094
|
+
const created = !existsSync19(configPath);
|
|
12984
13095
|
const existing = readJson2(configPath);
|
|
12985
13096
|
const servers = existing.mcpServers && typeof existing.mcpServers === "object" && !Array.isArray(existing.mcpServers) ? { ...existing.mcpServers } : {};
|
|
12986
13097
|
servers[SERVER_NAME] = mcpServerEntry(root);
|
|
@@ -13005,8 +13116,8 @@ var installMcpConfig = (root, target2) => {
|
|
|
13005
13116
|
var mcpSnippet = (root) => JSON.stringify({ mcpServers: { [SERVER_NAME]: mcpServerEntry(root) } }, null, 2);
|
|
13006
13117
|
|
|
13007
13118
|
// src/doctor/run-doctor.ts
|
|
13008
|
-
import { existsSync as
|
|
13009
|
-
import { resolve as
|
|
13119
|
+
import { existsSync as existsSync20, readFileSync as readFileSync24 } from "fs";
|
|
13120
|
+
import { resolve as resolve21 } from "path";
|
|
13010
13121
|
|
|
13011
13122
|
// src/bench/retrieval.ts
|
|
13012
13123
|
import { z as z17 } from "zod";
|
|
@@ -13333,11 +13444,11 @@ var measureConnectivity = (index) => {
|
|
|
13333
13444
|
};
|
|
13334
13445
|
var measureBenchmark = (root, config, index) => {
|
|
13335
13446
|
const suite = config.retrieval?.benchmark?.suite ?? DEFAULT_RETRIEVAL_SUITE;
|
|
13336
|
-
const suitePath =
|
|
13337
|
-
if (!
|
|
13447
|
+
const suitePath = resolve21(root, suite);
|
|
13448
|
+
if (!existsSync20(suitePath)) return { status: "not-analyzed", suite, reason: `No retrieval suite at ${suite}` };
|
|
13338
13449
|
if (!index.projection) return { status: "not-analyzed", suite, reason: "The index carries no retrieval projection. Run: ak-docs index" };
|
|
13339
13450
|
try {
|
|
13340
|
-
const parsed = parseRetrievalSuite(JSON.parse(
|
|
13451
|
+
const parsed = parseRetrievalSuite(JSON.parse(readFileSync24(suitePath, "utf8")));
|
|
13341
13452
|
const result = runRetrievalBench({ index, suite: parsed });
|
|
13342
13453
|
return {
|
|
13343
13454
|
status: "measured",
|
|
@@ -13585,23 +13696,23 @@ var formatDoctorText = (report) => {
|
|
|
13585
13696
|
};
|
|
13586
13697
|
|
|
13587
13698
|
// src/index-builder/watch-index.ts
|
|
13588
|
-
import { existsSync as
|
|
13589
|
-
import { dirname as
|
|
13699
|
+
import { existsSync as existsSync21, watch } from "fs";
|
|
13700
|
+
import { dirname as dirname9, resolve as resolve22 } from "path";
|
|
13590
13701
|
var WATCH_PATTERN = /\.(md|mdx|json|ya?ml|mdc)$/i;
|
|
13591
13702
|
var NX_MANIFEST_PATTERN = /(^|[/\\])(project|package)\.json$/i;
|
|
13592
13703
|
var collectWatchRoots = (root, config, configPath) => {
|
|
13593
13704
|
const roots = /* @__PURE__ */ new Set();
|
|
13594
|
-
roots.add(
|
|
13705
|
+
roots.add(resolve22(root, config.corpus.agent.root));
|
|
13595
13706
|
const humanSources = config.corpus.human ? Array.isArray(config.corpus.human) ? config.corpus.human : [config.corpus.human] : [];
|
|
13596
13707
|
for (const source of humanSources) {
|
|
13597
13708
|
const humanOpts = source.options ?? {};
|
|
13598
13709
|
for (const key of ["contentDir", "docsDir", "root", "srcDir"]) {
|
|
13599
13710
|
const value = humanOpts[key];
|
|
13600
|
-
if (typeof value === "string" && value.length) roots.add(
|
|
13711
|
+
if (typeof value === "string" && value.length) roots.add(resolve22(root, value));
|
|
13601
13712
|
}
|
|
13602
13713
|
}
|
|
13603
|
-
if (configPath) roots.add(
|
|
13604
|
-
return [...roots].filter((dir) =>
|
|
13714
|
+
if (configPath) roots.add(dirname9(resolve22(configPath)));
|
|
13715
|
+
return [...roots].filter((dir) => existsSync21(dir));
|
|
13605
13716
|
};
|
|
13606
13717
|
var watchDocBridgeIndex = (opts) => {
|
|
13607
13718
|
const debounceMs = opts.debounceMs ?? 350;
|
|
@@ -13642,15 +13753,15 @@ var watchDocBridgeIndex = (opts) => {
|
|
|
13642
13753
|
rebuild();
|
|
13643
13754
|
});
|
|
13644
13755
|
}
|
|
13645
|
-
const nxRoot =
|
|
13646
|
-
if (opts.config.routing?.plugin === "nx" &&
|
|
13756
|
+
const nxRoot = resolve22(opts.root);
|
|
13757
|
+
if (opts.config.routing?.plugin === "nx" && existsSync21(nxRoot)) {
|
|
13647
13758
|
watch(nxRoot, { recursive: true }, (_event, filename) => {
|
|
13648
13759
|
if (!filename || !NX_MANIFEST_PATTERN.test(filename)) return;
|
|
13649
13760
|
rebuild();
|
|
13650
13761
|
});
|
|
13651
13762
|
}
|
|
13652
|
-
const configDir =
|
|
13653
|
-
if (
|
|
13763
|
+
const configDir = resolve22(opts.root);
|
|
13764
|
+
if (existsSync21(configDir)) {
|
|
13654
13765
|
watch(configDir, (_event, filename) => {
|
|
13655
13766
|
if (!filename || !/doc-bridge\.config/.test(filename)) return;
|
|
13656
13767
|
rebuild();
|
|
@@ -13717,9 +13828,9 @@ var evaluateQualityScorecard = (input) => {
|
|
|
13717
13828
|
};
|
|
13718
13829
|
|
|
13719
13830
|
// src/memory/github-pr.ts
|
|
13720
|
-
import { execFileSync as
|
|
13721
|
-
import { existsSync as
|
|
13722
|
-
import { join as
|
|
13831
|
+
import { execFileSync as execFileSync4, spawnSync } from "child_process";
|
|
13832
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9 } from "fs";
|
|
13833
|
+
import { join as join20 } from "path";
|
|
13723
13834
|
var run = (cmd, args, cwd) => {
|
|
13724
13835
|
const result = spawnSync(cmd, [...args], { cwd, encoding: "utf8" });
|
|
13725
13836
|
const out = `${result.stdout ?? ""}${result.stderr ?? ""}`.trim();
|
|
@@ -13727,10 +13838,10 @@ var run = (cmd, args, cwd) => {
|
|
|
13727
13838
|
};
|
|
13728
13839
|
var hasGh = () => run("gh", ["--version"], process.cwd()).ok;
|
|
13729
13840
|
var slug = () => (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
13730
|
-
var defaultPromotionDraftPath = (root) =>
|
|
13841
|
+
var defaultPromotionDraftPath = (root) => join20(root, ".doc-bridge", "drafts", `memory-promotion-${slug()}.md`);
|
|
13731
13842
|
var writePromotionDraft = (root, draft, path) => {
|
|
13732
13843
|
const draftPath = path ?? defaultPromotionDraftPath(root);
|
|
13733
|
-
mkdirSync8(
|
|
13844
|
+
mkdirSync8(join20(root, ".doc-bridge", "drafts"), { recursive: true });
|
|
13734
13845
|
writeFileSync9(draftPath, `${draft.body}
|
|
13735
13846
|
`, "utf8");
|
|
13736
13847
|
return draftPath;
|
|
@@ -13766,7 +13877,7 @@ var promoteMemoryToGithubPr = (root, draft, options = {}) => {
|
|
|
13766
13877
|
message: `Wrote draft to ${relDraft}. Run the printed git/gh commands to open a draft PR.`
|
|
13767
13878
|
};
|
|
13768
13879
|
}
|
|
13769
|
-
if (!
|
|
13880
|
+
if (!existsSync22(join20(root, ".git"))) {
|
|
13770
13881
|
return {
|
|
13771
13882
|
ok: false,
|
|
13772
13883
|
dryRun: false,
|
|
@@ -13844,7 +13955,7 @@ ${auth.out}`
|
|
|
13844
13955
|
];
|
|
13845
13956
|
let prUrl = "";
|
|
13846
13957
|
try {
|
|
13847
|
-
prUrl =
|
|
13958
|
+
prUrl = execFileSync4("gh", prArgs, { cwd: root, encoding: "utf8" }).trim();
|
|
13848
13959
|
} catch (error) {
|
|
13849
13960
|
const message = error instanceof Error ? error.message : String(error);
|
|
13850
13961
|
return {
|
|
@@ -14634,12 +14745,12 @@ var formatStudyTaskSuiteText = (suite) => [
|
|
|
14634
14745
|
import { spawn as spawn2 } from "child_process";
|
|
14635
14746
|
import { createHash as createHash3 } from "crypto";
|
|
14636
14747
|
import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync10 } from "fs";
|
|
14637
|
-
import { dirname as
|
|
14748
|
+
import { dirname as dirname10, resolve as resolve24 } from "path";
|
|
14638
14749
|
import { z as z24 } from "zod";
|
|
14639
14750
|
|
|
14640
14751
|
// src/study/provider-cli.ts
|
|
14641
|
-
import { accessSync, constants, existsSync as
|
|
14642
|
-
import { isAbsolute as
|
|
14752
|
+
import { accessSync, constants, existsSync as existsSync23, statSync as statSync3 } from "fs";
|
|
14753
|
+
import { isAbsolute as isAbsolute7, resolve as resolve23 } from "path";
|
|
14643
14754
|
import { z as z23 } from "zod";
|
|
14644
14755
|
var STUDY_PROVIDER_CLI_SCHEMA_VERSION = 1;
|
|
14645
14756
|
var STUDY_PROVIDER_CLI_CONTENT_HASH_ALGO = "sha256-normalized-v1";
|
|
@@ -14714,9 +14825,9 @@ var calculateStudyCostUsd = (pricing2, usage) => {
|
|
|
14714
14825
|
return Number(((uncachedInputTokens * pricing2.inputPerMillionUsd + cachedInputTokens * pricing2.cachedInputPerMillionUsd + usage.outputTokens * pricing2.outputPerMillionUsd) / 1e6).toFixed(8));
|
|
14715
14826
|
};
|
|
14716
14827
|
var validateStudyProviderCommand = (provider, cwd) => {
|
|
14717
|
-
if (
|
|
14718
|
-
const resolvedPath =
|
|
14719
|
-
if (!
|
|
14828
|
+
if (isAbsolute7(provider.command) || provider.command.includes("/")) {
|
|
14829
|
+
const resolvedPath = isAbsolute7(provider.command) ? provider.command : resolve23(cwd, provider.command);
|
|
14830
|
+
if (!existsSync23(resolvedPath) || !statSync3(resolvedPath).isFile()) throw new Error(`Provider CLI command is not executable at ${resolvedPath}.`);
|
|
14720
14831
|
try {
|
|
14721
14832
|
accessSync(resolvedPath, constants.X_OK);
|
|
14722
14833
|
} catch {
|
|
@@ -14727,7 +14838,7 @@ var validateStudyProviderCommand = (provider, cwd) => {
|
|
|
14727
14838
|
const pathEntries = (process.env.PATH ?? "").split(":").filter(Boolean);
|
|
14728
14839
|
if (pathEntries.some((entry) => {
|
|
14729
14840
|
try {
|
|
14730
|
-
accessSync(
|
|
14841
|
+
accessSync(resolve23(entry, provider.command), constants.X_OK);
|
|
14731
14842
|
return true;
|
|
14732
14843
|
} catch {
|
|
14733
14844
|
return false;
|
|
@@ -14994,7 +15105,7 @@ var runAttempt = (request, sessionId) => new Promise((resolveAttempt) => {
|
|
|
14994
15105
|
const maxRuntimeMs = request.maxRuntimeMs ?? request.plan.budget.maxRuntimeMs;
|
|
14995
15106
|
const maxOutputBytes = request.maxOutputBytes ?? request.plan.budget.maxOutputBytes;
|
|
14996
15107
|
const child = spawn2(request.command, [...request.args ?? []], {
|
|
14997
|
-
cwd:
|
|
15108
|
+
cwd: resolve24(request.cwd),
|
|
14998
15109
|
shell: false,
|
|
14999
15110
|
detached: true,
|
|
15000
15111
|
env: { ...env, DOC_BRIDGE_STUDY_SESSION_ID: sessionId },
|
|
@@ -15122,10 +15233,10 @@ var runControlledCommand = async (request) => {
|
|
|
15122
15233
|
};
|
|
15123
15234
|
var persistControlledStudyLedger = (path, ledger) => {
|
|
15124
15235
|
parseControlledStudyLedger(ledger);
|
|
15125
|
-
mkdirSync9(
|
|
15126
|
-
writeFileSync10(
|
|
15236
|
+
mkdirSync9(dirname10(resolve24(path)), { recursive: true });
|
|
15237
|
+
writeFileSync10(resolve24(path), `${JSON.stringify(ledger, null, 2)}
|
|
15127
15238
|
`, "utf8");
|
|
15128
|
-
return
|
|
15239
|
+
return resolve24(path);
|
|
15129
15240
|
};
|
|
15130
15241
|
var formatControlledStudyRunPlanText = (plan) => [
|
|
15131
15242
|
`Run plan: ${plan.planVersion}`,
|
|
@@ -15141,7 +15252,7 @@ var formatControlledStudyRunPlanText = (plan) => [
|
|
|
15141
15252
|
import { spawn as spawn3 } from "child_process";
|
|
15142
15253
|
import { createHash as createHash4 } from "crypto";
|
|
15143
15254
|
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync11 } from "fs";
|
|
15144
|
-
import { dirname as
|
|
15255
|
+
import { dirname as dirname11, resolve as resolve25 } from "path";
|
|
15145
15256
|
import { z as z25 } from "zod";
|
|
15146
15257
|
var STUDY_ADJUDICATION_METHOD = "independent-rubric-v1";
|
|
15147
15258
|
var outcome2 = z25.enum(["success", "partial", "incorrect", "incomplete", "blocked"]);
|
|
@@ -15168,7 +15279,7 @@ var terminate = (child) => {
|
|
|
15168
15279
|
var runAdjudicatorProcess = (config, cwd, input, maxRuntimeMs) => new Promise((resolveResult) => {
|
|
15169
15280
|
const env = Object.fromEntries([.../* @__PURE__ */ new Set(["PATH", "HOME", "TMPDIR", ...config.envAllowlist])].flatMap((name) => process.env[name] === void 0 ? [] : [[name, process.env[name]]]));
|
|
15170
15281
|
const started = Date.now();
|
|
15171
|
-
const child = spawn3(config.command, [...config.args], { cwd:
|
|
15282
|
+
const child = spawn3(config.command, [...config.args], { cwd: resolve25(cwd), shell: false, detached: true, env, stdio: ["pipe", "pipe", "pipe"] });
|
|
15172
15283
|
let stdout = "";
|
|
15173
15284
|
let stderrBytes = 0;
|
|
15174
15285
|
let settled = false;
|
|
@@ -15306,10 +15417,10 @@ var independentlyAdjudicateStudyLedger = async (options) => {
|
|
|
15306
15417
|
};
|
|
15307
15418
|
var persistIndependentlyAdjudicatedLedger = (path, ledger) => {
|
|
15308
15419
|
parseControlledStudyLedger(ledger);
|
|
15309
|
-
mkdirSync10(
|
|
15310
|
-
writeFileSync11(
|
|
15420
|
+
mkdirSync10(dirname11(resolve25(path)), { recursive: true });
|
|
15421
|
+
writeFileSync11(resolve25(path), `${JSON.stringify(ledger, null, 2)}
|
|
15311
15422
|
`, "utf8");
|
|
15312
|
-
return
|
|
15423
|
+
return resolve25(path);
|
|
15313
15424
|
};
|
|
15314
15425
|
var adjudicatedLedgerInputHash = (task, observation) => createHash4("sha256").update(adjudicatorInput(task, observation)).digest("hex");
|
|
15315
15426
|
|
|
@@ -15351,8 +15462,8 @@ var measureProviderToolTelemetry = (events) => {
|
|
|
15351
15462
|
};
|
|
15352
15463
|
|
|
15353
15464
|
// src/study/execution.ts
|
|
15354
|
-
import { existsSync as
|
|
15355
|
-
import { resolve as
|
|
15465
|
+
import { existsSync as existsSync24, readFileSync as readFileSync25, statSync as statSync4 } from "fs";
|
|
15466
|
+
import { resolve as resolve26 } from "path";
|
|
15356
15467
|
import { z as z26 } from "zod";
|
|
15357
15468
|
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.";
|
|
15358
15469
|
var STUDY_REPOSITORY_CONFIG_SCHEMA_VERSION = 1;
|
|
@@ -15391,8 +15502,8 @@ var emptyLedger2 = () => createControlledStudyLedger({
|
|
|
15391
15502
|
observations: []
|
|
15392
15503
|
});
|
|
15393
15504
|
var loadLedger = (path) => {
|
|
15394
|
-
if (!
|
|
15395
|
-
return parseControlledStudyLedger(JSON.parse(
|
|
15505
|
+
if (!existsSync24(path)) return emptyLedger2();
|
|
15506
|
+
return parseControlledStudyLedger(JSON.parse(readFileSync25(path, "utf8")));
|
|
15396
15507
|
};
|
|
15397
15508
|
var executionKey = (execution) => sha256NormalizedV1({
|
|
15398
15509
|
taskId: execution.taskId,
|
|
@@ -15473,8 +15584,8 @@ var assertRunInputs = (options) => {
|
|
|
15473
15584
|
throw new Error("Study repository config must contain exactly one root for every task-suite population id.");
|
|
15474
15585
|
}
|
|
15475
15586
|
for (const repository of options.repositories.repositories) {
|
|
15476
|
-
const root =
|
|
15477
|
-
if (!
|
|
15587
|
+
const root = resolve26(repository.root);
|
|
15588
|
+
if (!existsSync24(root) || !statSync4(root).isDirectory()) throw new Error(`Study repository ${repository.id} is not available at the configured root.`);
|
|
15478
15589
|
}
|
|
15479
15590
|
const executions = selectTaskExecutions(options.suite, options.plan.sampling.sampleSize, options.plan.sampling);
|
|
15480
15591
|
const assisted = assistedArmReadiness(options.plan, options.providers, options.suite);
|
|
@@ -15520,7 +15631,7 @@ var runControlledStudy = async (options) => {
|
|
|
15520
15631
|
repositoryConfigHash: repositories.contentHash,
|
|
15521
15632
|
assistedArm: { ...assisted, recorded: 0 }
|
|
15522
15633
|
};
|
|
15523
|
-
let ledger = loadLedger(
|
|
15634
|
+
let ledger = loadLedger(resolve26(options.ledgerPath));
|
|
15524
15635
|
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.`);
|
|
15525
15636
|
let executed = 0;
|
|
15526
15637
|
let skipped = 0;
|
|
@@ -15579,7 +15690,7 @@ var runControlledStudy = async (options) => {
|
|
|
15579
15690
|
planned: executions.length,
|
|
15580
15691
|
executed,
|
|
15581
15692
|
skipped,
|
|
15582
|
-
ledgerPath:
|
|
15693
|
+
ledgerPath: resolve26(options.ledgerPath),
|
|
15583
15694
|
ledgerHash: ledger.contentHash,
|
|
15584
15695
|
providerConfigHash: providers.contentHash,
|
|
15585
15696
|
repositoryConfigHash: repositories.contentHash,
|
|
@@ -15600,8 +15711,8 @@ var formatControlledStudyRunText = (summary) => [
|
|
|
15600
15711
|
];
|
|
15601
15712
|
|
|
15602
15713
|
// src/federation/llms.ts
|
|
15603
|
-
import { existsSync as
|
|
15604
|
-
import { resolve as
|
|
15714
|
+
import { existsSync as existsSync25, readFileSync as readFileSync26 } from "fs";
|
|
15715
|
+
import { resolve as resolve27 } from "path";
|
|
15605
15716
|
var scoreText = (query, text) => {
|
|
15606
15717
|
const hay = text.toLowerCase();
|
|
15607
15718
|
return tokenizeSearchText(query).reduce((score, token) => score + (hasSearchToken(hay, token) ? token.length : 0), 0);
|
|
@@ -15626,9 +15737,9 @@ var sourceText = async (root, source, fetchText) => {
|
|
|
15626
15737
|
try {
|
|
15627
15738
|
const remote = httpUrl(source);
|
|
15628
15739
|
if (remote) return await fetchText(remote);
|
|
15629
|
-
const path =
|
|
15630
|
-
if (!
|
|
15631
|
-
return
|
|
15740
|
+
const path = resolve27(root, source);
|
|
15741
|
+
if (!existsSync25(path)) return null;
|
|
15742
|
+
return readFileSync26(path, "utf8");
|
|
15632
15743
|
} catch {
|
|
15633
15744
|
return null;
|
|
15634
15745
|
}
|
|
@@ -15755,11 +15866,11 @@ var retrieveHybridChunks = async (root, config, index, query, options = {}) => {
|
|
|
15755
15866
|
};
|
|
15756
15867
|
|
|
15757
15868
|
// src/intelligence/rag.ts
|
|
15758
|
-
import { readFileSync as
|
|
15759
|
-
import { join as
|
|
15869
|
+
import { readFileSync as readFileSync27 } from "fs";
|
|
15870
|
+
import { join as join22 } from "path";
|
|
15760
15871
|
|
|
15761
15872
|
// src/intelligence/adapter.ts
|
|
15762
|
-
import { join as
|
|
15873
|
+
import { join as join21 } from "path";
|
|
15763
15874
|
var readEnv = (name) => {
|
|
15764
15875
|
if (!name) return void 0;
|
|
15765
15876
|
const value = process.env[name];
|
|
@@ -15838,7 +15949,7 @@ var resolveIntelligenceRuntime = async (config) => {
|
|
|
15838
15949
|
}
|
|
15839
15950
|
return { adapter, embed, provider, ...model ? { model } : {} };
|
|
15840
15951
|
};
|
|
15841
|
-
var defaultVectorStorePath = (root) =>
|
|
15952
|
+
var defaultVectorStorePath = (root) => join21(root, ".doc-bridge", "vectors");
|
|
15842
15953
|
|
|
15843
15954
|
// src/intelligence/rag.ts
|
|
15844
15955
|
var loadDocuments = (root, index, sources) => {
|
|
@@ -15846,10 +15957,10 @@ var loadDocuments = (root, index, sources) => {
|
|
|
15846
15957
|
const docs = [];
|
|
15847
15958
|
if (includeAgent) {
|
|
15848
15959
|
for (const entry of index.knowledge) {
|
|
15849
|
-
const abs =
|
|
15960
|
+
const abs = join22(root, entry.path);
|
|
15850
15961
|
let content = "";
|
|
15851
15962
|
try {
|
|
15852
|
-
content =
|
|
15963
|
+
content = readFileSync27(abs, "utf8");
|
|
15853
15964
|
} catch {
|
|
15854
15965
|
content = [entry.title, entry.description].filter(Boolean).join("\n\n");
|
|
15855
15966
|
}
|
|
@@ -15867,7 +15978,7 @@ var createDocBridgeRag = async (root, config, index) => {
|
|
|
15867
15978
|
const { embed } = await resolveIntelligenceRuntime(config);
|
|
15868
15979
|
const ragMod = await importPeer("@agentskit/rag");
|
|
15869
15980
|
const memoryMod = await importPeer("@agentskit/memory");
|
|
15870
|
-
const storePath = typeof config.intelligence?.retriever?.options?.storePath === "string" ?
|
|
15981
|
+
const storePath = typeof config.intelligence?.retriever?.options?.storePath === "string" ? join22(root, config.intelligence.retriever.options.storePath) : defaultVectorStorePath(root);
|
|
15871
15982
|
const store = memoryMod.fileVectorMemory({ path: storePath });
|
|
15872
15983
|
const rag = ragMod.createRAG({
|
|
15873
15984
|
embed,
|
|
@@ -16122,8 +16233,8 @@ var docBridgePatternPayload = () => ({
|
|
|
16122
16233
|
});
|
|
16123
16234
|
|
|
16124
16235
|
// src/render/render.ts
|
|
16125
|
-
import { existsSync as
|
|
16126
|
-
import { dirname as
|
|
16236
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync11, readFileSync as readFileSync28, writeFileSync as writeFileSync12 } from "fs";
|
|
16237
|
+
import { dirname as dirname12, join as join23, relative as relative12, resolve as resolve28 } from "path";
|
|
16127
16238
|
var OPEN_PLACEHOLDER = "@@doc-bridge:generated-open@@";
|
|
16128
16239
|
var CLOSE_PLACEHOLDER = "@@doc-bridge:generated-close@@";
|
|
16129
16240
|
var REGION_VARIABLES = { open: OPEN_PLACEHOLDER, close: CLOSE_PLACEHOLDER };
|
|
@@ -16156,8 +16267,8 @@ var renderPage = (name, variables, config, root) => {
|
|
|
16156
16267
|
const output = renderNamedTemplate(name, { ...variables, region: REGION_VARIABLES }, config, root);
|
|
16157
16268
|
return RENDER_TEMPLATES[name].generatedRegion ? applyGeneratedRegions(output, name) : output;
|
|
16158
16269
|
};
|
|
16159
|
-
var readJson3 = (root, path) => JSON.parse(
|
|
16160
|
-
var stateDirOf = (root, config) =>
|
|
16270
|
+
var readJson3 = (root, path) => JSON.parse(readFileSync28(resolve28(root, path), "utf8"));
|
|
16271
|
+
var stateDirOf = (root, config) => resolve28(root, config.workflow?.stateDir ?? ".doc-bridge/workflow");
|
|
16161
16272
|
var loadIndex = (options) => options.dataPath ? parseDocBridgeIndex(readJson3(options.root, options.dataPath)) : buildDocBridgeIndex({ root: options.root, config: options.config, write: false }).index;
|
|
16162
16273
|
var loadReconciliation = (root, config) => {
|
|
16163
16274
|
try {
|
|
@@ -16180,7 +16291,7 @@ var loadPreviousSnapshot = (options) => {
|
|
|
16180
16291
|
};
|
|
16181
16292
|
var DEFAULT_OVERLAY_PATH = ".doc-bridge/enrich/overlay.json";
|
|
16182
16293
|
var loadOverlay = (options) => {
|
|
16183
|
-
const path = options.dataPath ?? (
|
|
16294
|
+
const path = options.dataPath ?? (existsSync26(resolve28(options.root, DEFAULT_OVERLAY_PATH)) ? DEFAULT_OVERLAY_PATH : void 0);
|
|
16184
16295
|
if (!path) return { overlay: void 0 };
|
|
16185
16296
|
const value = readJson3(options.root, path);
|
|
16186
16297
|
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${path} is not an overlay object.`);
|
|
@@ -16231,28 +16342,28 @@ var writeRenderedPages = (result, target2, root) => {
|
|
|
16231
16342
|
const single = result.pages.length === 1 && !RENDER_TEMPLATES[result.template].multiPage;
|
|
16232
16343
|
const written = [];
|
|
16233
16344
|
const write = (path, content) => {
|
|
16234
|
-
mkdirSync11(
|
|
16345
|
+
mkdirSync11(dirname12(path), { recursive: true });
|
|
16235
16346
|
writeFileSync12(path, content, "utf8");
|
|
16236
|
-
return toPosix(
|
|
16347
|
+
return toPosix(relative12(root, path));
|
|
16237
16348
|
};
|
|
16238
16349
|
for (const page of result.pages) {
|
|
16239
16350
|
if (!single) {
|
|
16240
|
-
written.push(write(
|
|
16351
|
+
written.push(write(join23(target2, page.path), page.content));
|
|
16241
16352
|
continue;
|
|
16242
16353
|
}
|
|
16243
16354
|
try {
|
|
16244
16355
|
written.push(write(target2, page.content));
|
|
16245
16356
|
} catch (error) {
|
|
16246
16357
|
if (error.code !== "EISDIR") throw error;
|
|
16247
|
-
written.push(write(
|
|
16358
|
+
written.push(write(join23(target2, page.path), page.content));
|
|
16248
16359
|
}
|
|
16249
16360
|
}
|
|
16250
16361
|
return written;
|
|
16251
16362
|
};
|
|
16252
16363
|
|
|
16253
16364
|
// src/enrich/context-pack.ts
|
|
16254
|
-
import { readFileSync as
|
|
16255
|
-
import { join as
|
|
16365
|
+
import { readFileSync as readFileSync29 } from "fs";
|
|
16366
|
+
import { join as join24, resolve as resolve29 } from "path";
|
|
16256
16367
|
var CONTEXT_PACK_VERSION = 1;
|
|
16257
16368
|
var DEFAULT_PACK_BYTES = 64 * 1024;
|
|
16258
16369
|
var MAX_PACK_NEIGHBOURS = 32;
|
|
@@ -16276,7 +16387,7 @@ var boundedMetadata = (metadata) => {
|
|
|
16276
16387
|
var defaultReader = (root) => (path) => {
|
|
16277
16388
|
if (!root) return void 0;
|
|
16278
16389
|
try {
|
|
16279
|
-
return
|
|
16390
|
+
return readFileSync29(join24(resolve29(root), path), "utf8");
|
|
16280
16391
|
} catch {
|
|
16281
16392
|
return void 0;
|
|
16282
16393
|
}
|
|
@@ -16400,8 +16511,8 @@ var batchContextPacks = (packs) => {
|
|
|
16400
16511
|
};
|
|
16401
16512
|
|
|
16402
16513
|
// src/enrich/cache.ts
|
|
16403
|
-
import { existsSync as
|
|
16404
|
-
import { join as
|
|
16514
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync12, readFileSync as readFileSync30, renameSync as renameSync5, writeFileSync as writeFileSync13 } from "fs";
|
|
16515
|
+
import { join as join25 } from "path";
|
|
16405
16516
|
import { z as z27 } from "zod";
|
|
16406
16517
|
var enrichmentCacheKey = (input) => sha256NormalizedV1({ task: input.task, agentId: input.agentId, agentVersion: input.agentVersion, promptVersion: input.promptVersion, packHash: input.packHash });
|
|
16407
16518
|
var CacheEntrySchema = z27.object({
|
|
@@ -16416,14 +16527,14 @@ var CacheEntrySchema = z27.object({
|
|
|
16416
16527
|
}).strict();
|
|
16417
16528
|
var createEnrichmentCache = (root) => {
|
|
16418
16529
|
const dir = enrichmentCacheDir(root);
|
|
16419
|
-
const pathFor = (key) =>
|
|
16530
|
+
const pathFor = (key) => join25(dir, `${key}.json`);
|
|
16420
16531
|
return {
|
|
16421
16532
|
read: (input) => {
|
|
16422
16533
|
const key = enrichmentCacheKey(input);
|
|
16423
16534
|
const path = pathFor(key);
|
|
16424
|
-
if (!
|
|
16535
|
+
if (!existsSync27(path)) return void 0;
|
|
16425
16536
|
try {
|
|
16426
|
-
const entry = CacheEntrySchema.parse(JSON.parse(
|
|
16537
|
+
const entry = CacheEntrySchema.parse(JSON.parse(readFileSync30(path, "utf8")));
|
|
16427
16538
|
return entry.key === key && entry.packHash === input.packHash && entry.agentId === input.agentId ? entry.proposals : void 0;
|
|
16428
16539
|
} catch {
|
|
16429
16540
|
return void 0;
|
|
@@ -16455,7 +16566,7 @@ var createMemoryEnrichmentCache = () => {
|
|
|
16455
16566
|
};
|
|
16456
16567
|
|
|
16457
16568
|
// src/enrich/stage.ts
|
|
16458
|
-
import { basename as basename8, resolve as
|
|
16569
|
+
import { basename as basename8, resolve as resolve30 } from "path";
|
|
16459
16570
|
|
|
16460
16571
|
// src/enrich/stats.ts
|
|
16461
16572
|
var inventedReferenceCount = (rejected) => rejected.filter((entry) => INVENTED_RELATION_REASONS.includes(entry.reason)).length;
|
|
@@ -16552,7 +16663,7 @@ var registryAgent = async (root, config) => {
|
|
|
16552
16663
|
};
|
|
16553
16664
|
return {
|
|
16554
16665
|
call: async ({ role, task, packs }) => (await adapterFor(role.agentId)).enrich(task, packs, { role: role.role, promptVersion: role.promptVersion }),
|
|
16555
|
-
version: (role) => loadRegistryAgentMetadata(
|
|
16666
|
+
version: (role) => loadRegistryAgentMetadata(resolve30(root), configWithAgent(config, role.agentId)).version
|
|
16556
16667
|
};
|
|
16557
16668
|
};
|
|
16558
16669
|
var overlayBase = (options) => ({
|
|
@@ -16870,7 +16981,7 @@ var studyRetrievalSuite = (options) => {
|
|
|
16870
16981
|
continue;
|
|
16871
16982
|
}
|
|
16872
16983
|
const targets = byRepository.get(task.repositoryId);
|
|
16873
|
-
const
|
|
16984
|
+
const resolve33 = (references, kind) => references.flatMap((item) => {
|
|
16874
16985
|
const resolved = targets?.[item];
|
|
16875
16986
|
if (!resolved?.length) {
|
|
16876
16987
|
unresolved.push({ taskId: task.id, repositoryId: task.repositoryId, reference: item, kind });
|
|
@@ -16879,7 +16990,7 @@ var studyRetrievalSuite = (options) => {
|
|
|
16879
16990
|
return resolved;
|
|
16880
16991
|
});
|
|
16881
16992
|
const expectedTargets = [
|
|
16882
|
-
.../* @__PURE__ */ new Set([...
|
|
16993
|
+
.../* @__PURE__ */ new Set([...resolve33(task.expectedEntities ?? [], "entity"), ...resolve33(task.expectedDocuments ?? [], "document")])
|
|
16883
16994
|
].sort();
|
|
16884
16995
|
if (!expectedTargets.length) continue;
|
|
16885
16996
|
const queries = taskRetrievalQueries(task);
|
|
@@ -17089,8 +17200,8 @@ var claimPattern = (claim, surface) => {
|
|
|
17089
17200
|
var renderClaim = (claim, value, surface) => (surface === void 0 ? claim.template ?? "{value}" : templateFor(claim, surface)).replace("{value}", value);
|
|
17090
17201
|
|
|
17091
17202
|
// src/parity/resolve.ts
|
|
17092
|
-
import { existsSync as
|
|
17093
|
-
import { resolve as
|
|
17203
|
+
import { existsSync as existsSync28, readFileSync as readFileSync31 } from "fs";
|
|
17204
|
+
import { resolve as resolve31 } from "path";
|
|
17094
17205
|
|
|
17095
17206
|
// src/cli/usage.ts
|
|
17096
17207
|
var CLI_COMMAND_USAGE = `ak-docs \u2014 human\u2194agent documentation bridge (@agentskit/doc-bridge)
|
|
@@ -17159,7 +17270,7 @@ Global flags:
|
|
|
17159
17270
|
`;
|
|
17160
17271
|
|
|
17161
17272
|
// src/parity/resolve.ts
|
|
17162
|
-
var readJson4 = (path) => JSON.parse(
|
|
17273
|
+
var readJson4 = (path) => JSON.parse(readFileSync31(path, "utf8"));
|
|
17163
17274
|
var dotted = (value, field) => field.split(".").reduce((current, key) => {
|
|
17164
17275
|
if (current === null || typeof current !== "object") return void 0;
|
|
17165
17276
|
return current[key];
|
|
@@ -17211,20 +17322,20 @@ var resolveClaim = (claim, context) => {
|
|
|
17211
17322
|
const evidence2 = claim.evidence;
|
|
17212
17323
|
switch (evidence2.kind) {
|
|
17213
17324
|
case "package-field": {
|
|
17214
|
-
const path =
|
|
17215
|
-
if (!
|
|
17325
|
+
const path = resolve31(context.root, "package.json");
|
|
17326
|
+
if (!existsSync28(path)) return { status: "not-analyzed", reason: "package.json is not present." };
|
|
17216
17327
|
const value = scalar2(dotted(readJson4(path), evidence2.field), void 0);
|
|
17217
17328
|
return value === void 0 ? { status: "not-analyzed", reason: `package.json has no scalar field "${evidence2.field}".` } : { status: "resolved", value };
|
|
17218
17329
|
}
|
|
17219
17330
|
case "artifact-field": {
|
|
17220
|
-
const path =
|
|
17221
|
-
if (!
|
|
17331
|
+
const path = resolve31(context.root, evidence2.path);
|
|
17332
|
+
if (!existsSync28(path)) return { status: "not-analyzed", reason: `${evidence2.path} is not present.` };
|
|
17222
17333
|
const value = scalar2(dotted(readJson4(path), evidence2.field), evidence2.transform);
|
|
17223
17334
|
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 };
|
|
17224
17335
|
}
|
|
17225
17336
|
case "artifact-sum": {
|
|
17226
|
-
const path =
|
|
17227
|
-
if (!
|
|
17337
|
+
const path = resolve31(context.root, evidence2.path);
|
|
17338
|
+
if (!existsSync28(path)) return { status: "not-analyzed", reason: `${evidence2.path} is not present.` };
|
|
17228
17339
|
const array = dotted(readJson4(path), evidence2.arrayField);
|
|
17229
17340
|
if (!Array.isArray(array) || array.length === 0) {
|
|
17230
17341
|
return { status: "not-analyzed", reason: `${evidence2.path} has no non-empty array at "${evidence2.arrayField}".` };
|
|
@@ -17259,8 +17370,8 @@ var resolveClaim = (claim, context) => {
|
|
|
17259
17370
|
};
|
|
17260
17371
|
|
|
17261
17372
|
// src/parity/check.ts
|
|
17262
|
-
import { existsSync as
|
|
17263
|
-
import { resolve as
|
|
17373
|
+
import { existsSync as existsSync29, readFileSync as readFileSync32 } from "fs";
|
|
17374
|
+
import { resolve as resolve32 } from "path";
|
|
17264
17375
|
import { z as z30 } from "zod";
|
|
17265
17376
|
var PUBLIC_PARITY_SCHEMA_VERSION = 1;
|
|
17266
17377
|
var PARITY_EXCERPT_LIMIT = 160;
|
|
@@ -17336,8 +17447,8 @@ var occurrences = (claim, surface, content) => {
|
|
|
17336
17447
|
var checkPublicParity = (options) => {
|
|
17337
17448
|
const { registry } = options;
|
|
17338
17449
|
const read = options.readSurface ?? ((path) => {
|
|
17339
|
-
const absolute =
|
|
17340
|
-
return
|
|
17450
|
+
const absolute = resolve32(options.root, path);
|
|
17451
|
+
return existsSync29(absolute) ? readFileSync32(absolute, "utf8") : void 0;
|
|
17341
17452
|
});
|
|
17342
17453
|
const surfaces2 = claimSurfaces(registry);
|
|
17343
17454
|
const contents = new Map(surfaces2.map((surface) => [surface, read(surface)]));
|