@agentskit/doc-bridge 1.10.0 → 1.11.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 +59 -0
- package/action.yml +1 -1
- package/dist/cli/program.js +125 -9
- package/dist/cli/program.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -1
- package/dist/{index-7wYGbllW.d.ts → index-CimDq6_e.d.ts} +2 -0
- package/dist/index.d.ts +69 -7
- package/dist/index.js +113 -7
- package/dist/index.js.map +1 -1
- package/docs/spec/config-v1.md +23 -1
- package/mcpb/manifest.json +1 -1
- package/package.json +2 -2
- package/skills/doc-bridge-handoff/scripts/resolve-handoff.mjs +1 -1
- package/src/cli/program.ts +23 -2
- package/src/config/schema.ts +2 -0
- package/src/discovery/reproducibility.ts +109 -0
- package/src/doctor/run-doctor.ts +24 -0
- package/src/gates/run-gates.ts +44 -0
- package/src/index.ts +6 -0
- package/src/retrieval/project.ts +33 -6
- package/src/schemas/retrieval-index.ts +6 -1
- package/src/version.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -161,6 +161,7 @@ var GatesConfigSchema = z.object({
|
|
|
161
161
|
include: z.array(
|
|
162
162
|
z.enum([
|
|
163
163
|
"index-freshness",
|
|
164
|
+
"index-reproducible",
|
|
164
165
|
"human-guide-links",
|
|
165
166
|
"link-rot",
|
|
166
167
|
"okf-type",
|
|
@@ -173,6 +174,7 @@ var GatesConfigSchema = z.object({
|
|
|
173
174
|
exclude: z.array(
|
|
174
175
|
z.enum([
|
|
175
176
|
"index-freshness",
|
|
177
|
+
"index-reproducible",
|
|
176
178
|
"human-guide-links",
|
|
177
179
|
"link-rot",
|
|
178
180
|
"okf-type",
|
|
@@ -1331,8 +1333,13 @@ var RetrievalIndexV1Schema = z5.object({
|
|
|
1331
1333
|
schemaVersion: z5.literal(RETRIEVAL_INDEX_SCHEMA_VERSION),
|
|
1332
1334
|
contentHash: hash2,
|
|
1333
1335
|
contentHashAlgo: z5.literal("sha256-normalized-v1"),
|
|
1334
|
-
/**
|
|
1336
|
+
/**
|
|
1337
|
+
* Which snapshot this was projected from. Provenance, not a seal input: it carries the
|
|
1338
|
+
* snapshot's `sourceRevision`, and the projection is a function of what the snapshot observed
|
|
1339
|
+
* rather than of the revision it was observed at.
|
|
1340
|
+
*/
|
|
1335
1341
|
snapshotHash: hash2,
|
|
1342
|
+
/** The inputs the projection is a function of. Same hashes, same projection. */
|
|
1336
1343
|
overlayHash: hash2,
|
|
1337
1344
|
configurationHash: hash2,
|
|
1338
1345
|
lexiconVersion: z5.number().int().nonnegative().max(1e3),
|
|
@@ -4393,7 +4400,7 @@ var buildLookup = (config, packages, corpus, indexOutFile, humanDocs = {}, root
|
|
|
4393
4400
|
};
|
|
4394
4401
|
|
|
4395
4402
|
// src/version.ts
|
|
4396
|
-
var PACKAGE_VERSION = "1.
|
|
4403
|
+
var PACKAGE_VERSION = "1.11.0";
|
|
4397
4404
|
|
|
4398
4405
|
// src/index-builder/capabilities.ts
|
|
4399
4406
|
var renderCapabilitiesJson = (config, index, paths) => {
|
|
@@ -5973,7 +5980,7 @@ var resolveSearchParams = (configured) => ({
|
|
|
5973
5980
|
});
|
|
5974
5981
|
|
|
5975
5982
|
// src/retrieval/project.ts
|
|
5976
|
-
var RETRIEVAL_PROJECTION_VERSION =
|
|
5983
|
+
var RETRIEVAL_PROJECTION_VERSION = 2;
|
|
5977
5984
|
var DOCUMENT_BODY_LIMIT = 4e3;
|
|
5978
5985
|
var MAX_EDGES = 64;
|
|
5979
5986
|
var MAX_ALIASES = 32;
|
|
@@ -5981,6 +5988,12 @@ var MAX_TAGS = 32;
|
|
|
5981
5988
|
var MAX_SYMBOLS = 256;
|
|
5982
5989
|
var MAX_SUMMARY = 400;
|
|
5983
5990
|
var EMPTY_OVERLAY_HASH = sha256NormalizedV1({ accepted: [] });
|
|
5991
|
+
var snapshotObservationHash = (snapshot) => sha256NormalizedV1({
|
|
5992
|
+
pipelineVersion: snapshot.pipelineVersion,
|
|
5993
|
+
analyzerVersions: snapshot.analyzerVersions,
|
|
5994
|
+
entities: snapshot.entities,
|
|
5995
|
+
relations: snapshot.relations
|
|
5996
|
+
});
|
|
5984
5997
|
var CONFIDENCE_RANK = { observed: 0, declared: 1, fuzzy: 2, proposed: 3 };
|
|
5985
5998
|
var weakerConfidence = (a, b) => CONFIDENCE_RANK[a] >= CONFIDENCE_RANK[b] ? a : b;
|
|
5986
5999
|
var relationConfidence = (relation) => relation.metadata?.confidence === "fuzzy" ? "fuzzy" : relation.provenance;
|
|
@@ -6241,7 +6254,7 @@ var projectRetrievalIndex = (options) => {
|
|
|
6241
6254
|
};
|
|
6242
6255
|
const contentHash = sha256NormalizedV1({
|
|
6243
6256
|
projectionVersion: RETRIEVAL_PROJECTION_VERSION,
|
|
6244
|
-
|
|
6257
|
+
observationHash: snapshotObservationHash(snapshot),
|
|
6245
6258
|
overlayHash: base.overlayHash,
|
|
6246
6259
|
configurationHash: base.configurationHash,
|
|
6247
6260
|
lexiconVersion: base.lexiconVersion,
|
|
@@ -7070,6 +7083,50 @@ var buildDocBridgeIndex = (opts) => {
|
|
|
7070
7083
|
};
|
|
7071
7084
|
};
|
|
7072
7085
|
|
|
7086
|
+
// src/discovery/reproducibility.ts
|
|
7087
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
7088
|
+
var NOT_CHECKED = (skipped) => ({
|
|
7089
|
+
checked: false,
|
|
7090
|
+
skipped,
|
|
7091
|
+
ignored: []
|
|
7092
|
+
});
|
|
7093
|
+
var git = (root, args, options = {}) => {
|
|
7094
|
+
try {
|
|
7095
|
+
return execFileSync2("git", args, {
|
|
7096
|
+
cwd: root,
|
|
7097
|
+
encoding: "utf8",
|
|
7098
|
+
stdio: ["pipe", "pipe", "ignore"],
|
|
7099
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
7100
|
+
...options.input === void 0 ? {} : { input: options.input }
|
|
7101
|
+
});
|
|
7102
|
+
} catch (error) {
|
|
7103
|
+
const status = error.status;
|
|
7104
|
+
if (options.allowExit1 && status === 1) return error.stdout ?? "";
|
|
7105
|
+
return void 0;
|
|
7106
|
+
}
|
|
7107
|
+
};
|
|
7108
|
+
var checkIndexReproducibility = (root, indexPath, paths) => {
|
|
7109
|
+
if (git(root, ["rev-parse", "--is-inside-work-tree"]) === void 0) return NOT_CHECKED("no-git");
|
|
7110
|
+
if (git(root, ["ls-files", "--error-unmatch", "--", indexPath]) === void 0) {
|
|
7111
|
+
return NOT_CHECKED("index-untracked");
|
|
7112
|
+
}
|
|
7113
|
+
if (paths.length === 0) return { checked: true, ignored: [] };
|
|
7114
|
+
const unique3 = [...new Set(paths)].sort();
|
|
7115
|
+
const output = git(root, ["check-ignore", "--verbose", "-z", "--stdin"], {
|
|
7116
|
+
input: `${unique3.join("\0")}\0`,
|
|
7117
|
+
allowExit1: true
|
|
7118
|
+
});
|
|
7119
|
+
if (output === void 0) return NOT_CHECKED("no-git");
|
|
7120
|
+
const fields = output.split("\0");
|
|
7121
|
+
const ignored = [];
|
|
7122
|
+
for (let index = 0; index + 3 < fields.length; index += 4) {
|
|
7123
|
+
const [source, line, pattern, path] = [fields[index], fields[index + 1], fields[index + 2], fields[index + 3]];
|
|
7124
|
+
if (!path) continue;
|
|
7125
|
+
ignored.push({ path, rule: `${source ?? "?"}:${line ?? "?"}:${pattern ?? "?"}` });
|
|
7126
|
+
}
|
|
7127
|
+
return { checked: true, ignored: ignored.sort((left, right) => left.path.localeCompare(right.path)) };
|
|
7128
|
+
};
|
|
7129
|
+
|
|
7073
7130
|
// src/retrieval/rank.ts
|
|
7074
7131
|
var BM25_SCALE = 50;
|
|
7075
7132
|
var EXACT_ID = 200;
|
|
@@ -11036,6 +11093,38 @@ var runGate = (root, config, id) => {
|
|
|
11036
11093
|
if (id === "human-guide-links") return runHumanGuideLinksGate(root, config);
|
|
11037
11094
|
if (id === "okf-type") return runOkfTypeGate(root, config);
|
|
11038
11095
|
if (id === "docs-style") return runDocsStyleGate(root, config);
|
|
11096
|
+
if (id === "index-reproducible") {
|
|
11097
|
+
let index;
|
|
11098
|
+
try {
|
|
11099
|
+
index = loadDocBridgeIndex(root, config);
|
|
11100
|
+
} catch (error) {
|
|
11101
|
+
if (error instanceof IndexNotFoundError) return { id, ok: false, message: error.message };
|
|
11102
|
+
throw error;
|
|
11103
|
+
}
|
|
11104
|
+
const result = checkIndexReproducibility(
|
|
11105
|
+
root,
|
|
11106
|
+
config.index?.outFile ?? ".doc-bridge/index.json",
|
|
11107
|
+
index.knowledge.map((entry) => entry.path)
|
|
11108
|
+
);
|
|
11109
|
+
if (!result.checked) {
|
|
11110
|
+
return {
|
|
11111
|
+
id,
|
|
11112
|
+
ok: true,
|
|
11113
|
+
message: result.skipped === "index-untracked" ? "Index is not committed, so nothing has to reproduce it" : "Not a Git checkout; reproducibility was not checked"
|
|
11114
|
+
};
|
|
11115
|
+
}
|
|
11116
|
+
if (result.ignored.length === 0) {
|
|
11117
|
+
return { id, ok: true, message: "Every indexed path is committed" };
|
|
11118
|
+
}
|
|
11119
|
+
const sample = result.ignored.slice(0, 5).map((entry) => `${entry.path} (${entry.rule})`);
|
|
11120
|
+
return {
|
|
11121
|
+
id,
|
|
11122
|
+
ok: false,
|
|
11123
|
+
message: `${result.ignored.length} indexed path(s) are ignored by Git, so a clean checkout builds a different index. Add them to safety.exclude.`,
|
|
11124
|
+
expected: "every indexed path is committed",
|
|
11125
|
+
actual: sample.join(", ")
|
|
11126
|
+
};
|
|
11127
|
+
}
|
|
11039
11128
|
if (id !== "index-freshness") throw new Error(`Unsupported gate "${id}"`);
|
|
11040
11129
|
let current;
|
|
11041
11130
|
try {
|
|
@@ -13279,6 +13368,16 @@ var buildIssues = (coverage) => {
|
|
|
13279
13368
|
action: "ak-docs index"
|
|
13280
13369
|
});
|
|
13281
13370
|
}
|
|
13371
|
+
const { ignored } = coverage.reproducibility;
|
|
13372
|
+
if (ignored.length > 0) {
|
|
13373
|
+
const sample = ignored.slice(0, 5).map((entry) => `${entry.path} (${entry.rule})`);
|
|
13374
|
+
issues.push({
|
|
13375
|
+
severity: "warn",
|
|
13376
|
+
code: "index-not-reproducible",
|
|
13377
|
+
message: `${ignored.length} indexed path(s) are ignored by Git, so a clean checkout builds a different index: ${sample.join(", ")}${ignored.length > sample.length ? `, and ${ignored.length - sample.length} more` : ""}.`,
|
|
13378
|
+
action: "edit doc-bridge.config.json # add the generated paths to safety.exclude"
|
|
13379
|
+
});
|
|
13380
|
+
}
|
|
13282
13381
|
for (const id of coverage.packages.missingAgentDoc) {
|
|
13283
13382
|
issues.push({
|
|
13284
13383
|
severity: "warn",
|
|
@@ -13416,7 +13515,12 @@ var runDoctor = (root, config) => {
|
|
|
13416
13515
|
message: freshnessMessage,
|
|
13417
13516
|
hasIndex
|
|
13418
13517
|
},
|
|
13419
|
-
gates
|
|
13518
|
+
gates,
|
|
13519
|
+
reproducibility: checkIndexReproducibility(
|
|
13520
|
+
root,
|
|
13521
|
+
config.index?.outFile ?? ".doc-bridge/index.json",
|
|
13522
|
+
index.knowledge.map((entry) => entry.path)
|
|
13523
|
+
)
|
|
13420
13524
|
};
|
|
13421
13525
|
const issues = buildIssues(coverage);
|
|
13422
13526
|
const score = computeScore(coverage);
|
|
@@ -13613,7 +13717,7 @@ var evaluateQualityScorecard = (input) => {
|
|
|
13613
13717
|
};
|
|
13614
13718
|
|
|
13615
13719
|
// src/memory/github-pr.ts
|
|
13616
|
-
import { execFileSync as
|
|
13720
|
+
import { execFileSync as execFileSync3, spawnSync } from "child_process";
|
|
13617
13721
|
import { existsSync as existsSync21, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9 } from "fs";
|
|
13618
13722
|
import { join as join19 } from "path";
|
|
13619
13723
|
var run = (cmd, args, cwd) => {
|
|
@@ -13740,7 +13844,7 @@ ${auth.out}`
|
|
|
13740
13844
|
];
|
|
13741
13845
|
let prUrl = "";
|
|
13742
13846
|
try {
|
|
13743
|
-
prUrl =
|
|
13847
|
+
prUrl = execFileSync3("gh", prArgs, { cwd: root, encoding: "utf8" }).trim();
|
|
13744
13848
|
} catch (error) {
|
|
13745
13849
|
const message = error instanceof Error ? error.message : String(error);
|
|
13746
13850
|
return {
|
|
@@ -17614,6 +17718,7 @@ export {
|
|
|
17614
17718
|
canonicality,
|
|
17615
17719
|
centrality,
|
|
17616
17720
|
changeDigestView,
|
|
17721
|
+
checkIndexReproducibility,
|
|
17617
17722
|
checkPublicParity,
|
|
17618
17723
|
checkStudyExpectations,
|
|
17619
17724
|
chunksFromMarkdown,
|
|
@@ -17882,6 +17987,7 @@ export {
|
|
|
17882
17987
|
selectTaskExecutions,
|
|
17883
17988
|
sha256NormalizedV1,
|
|
17884
17989
|
singularizeSearchToken,
|
|
17990
|
+
snapshotObservationHash,
|
|
17885
17991
|
startInkChat,
|
|
17886
17992
|
startMcpStdioServer,
|
|
17887
17993
|
studyRetrievalSuite,
|