@agentskit/doc-bridge 1.4.0 → 1.4.3
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 +20 -0
- package/README.md +11 -3
- package/action.yml +1 -1
- package/dist/cli/program.js +54 -11
- package/dist/cli/program.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +3 -1
- package/dist/config/index.js.map +1 -1
- package/dist/{index-DAeq_OIi.d.ts → index-DhoAG9Ar.d.ts} +14 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +54 -11
- package/dist/index.js.map +1 -1
- package/docs/MARKETPLACE.md +1 -1
- package/docs/guides/gate-ci.md +1 -1
- package/docs/landing/index.html +1 -1
- package/docs/playbook/doc-bridge-pattern.md +1 -1
- package/docs/recipes/index-pipeline.md +1 -1
- package/ecosystem-claims.json +6 -6
- package/ecosystem-upstream.json +2 -2
- package/ecosystem.json +51 -0
- package/mcpb/manifest.json +1 -1
- package/package.json +4 -2
- package/skills/doc-bridge-handoff/SKILL.md +0 -6
- package/skills/doc-bridge-handoff/scripts/resolve-handoff.mjs +1 -1
- package/src/config/schema.ts +2 -0
- package/src/conformance/ecosystem-contract.ts +6 -3
- package/src/index-builder/human-adapters/plain-markdown.ts +17 -1
- package/src/index-builder/llms-txt.ts +22 -2
- package/src/index-builder/scan-corpus.ts +17 -1
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.4.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Keep the release audit green by pinning the available `nanoid` fix and documenting
|
|
8
|
+
the upstream `extract-zip` advisory exception until its patched npm release exists.
|
|
9
|
+
|
|
10
|
+
## 1.4.2
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- df61b17: Accept managed ecosystem products without a public repository by supporting `repo: null` and declaration-backed claims in the canonical ecosystem contract.
|
|
15
|
+
|
|
16
|
+
## 1.4.1
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- ef543f6: Publish the portable handoff skill through an Agent Plugins v1 manifest for GitHub Copilot.
|
|
21
|
+
- 8b07f46: Package the portable handoff skill and credential-free MCP server as a Claude Code plugin.
|
|
22
|
+
|
|
3
23
|
## 1.4.0
|
|
4
24
|
|
|
5
25
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -116,7 +116,7 @@ Using Cline? Follow the deterministic [`llms-install.md`](llms-install.md) setup
|
|
|
116
116
|
|---------|------------|--------------------|
|
|
117
117
|
| **CLI** | Inspect ownership, search docs, run gates, ask local questions | `ak-docs query`, `search`, `ask`, `doctor`, `gate` |
|
|
118
118
|
| **MCP server** | Let Cursor, Claude Code, Codex-style agents resolve handoffs before editing | `ak-docs mcp`, `handoff.resolve` |
|
|
119
|
-
| **GitHub Action / CI** | Fail stale indexes and broken human-doc links on PRs | `AgentsKit-io/doc-bridge@v1.
|
|
119
|
+
| **GitHub Action / CI** | Fail stale indexes and broken human-doc links on PRs | `AgentsKit-io/doc-bridge@v1.4.0` |
|
|
120
120
|
| **Documentation conformance** | Check the stable ecosystem standard with auditable evidence | `ak-docs conformance run documentation-standard-v1 --text` |
|
|
121
121
|
| **Doc adapters** | Link human docs to agent docs | `fumadocs`, `docusaurus`, `vitepress`, `starlight`, `nextra`, `plain-markdown` |
|
|
122
122
|
| **Monorepo routing** | Discover workspaces and checks | `pnpm-monorepo`, `nx` |
|
|
@@ -129,6 +129,14 @@ See [docs/getting-started.md](docs/getting-started.md), [docs/mcp.md](docs/mcp.m
|
|
|
129
129
|
|
|
130
130
|
This repository also contains a Cursor plugin that pairs the read-only Doc Bridge MCP server with a handoff skill. It resolves `startHere`, `readBeforeEditing`, `editRoots`, and `checks` before Cursor edits a routed repository. The plugin does not request credentials or write project files through MCP.
|
|
131
131
|
|
|
132
|
+
### GitHub Copilot plugin
|
|
133
|
+
|
|
134
|
+
The root Agent Plugins manifest exposes the same portable handoff skill and read-only MCP server to GitHub Copilot CLI. Copilot discovers `skills/` and `.mcp.json` from the standard plugin layout, so the integration stays source-owned instead of copying prompts into another repository.
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
copilot plugin install AgentsKit-io/doc-bridge
|
|
138
|
+
```
|
|
139
|
+
|
|
132
140
|
### Portable Agent Skill
|
|
133
141
|
|
|
134
142
|
[`skills/doc-bridge-handoff`](skills/doc-bridge-handoff) packages the same fail-closed routing contract in the open Agent Skills layout for OpenClaw-compatible clients, Hermes Agent, Pi, Cursor, and other runtimes that can execute a local skill script. The skill prefers the read-only MCP tool and falls back to a pinned, zero-credential CLI resolver. It never edits files, runs returned checks, or grants authority outside `editRoots`.
|
|
@@ -246,7 +254,7 @@ permissions:
|
|
|
246
254
|
|
|
247
255
|
steps:
|
|
248
256
|
- uses: actions/checkout@v4
|
|
249
|
-
- uses: AgentsKit-io/doc-bridge@v1.
|
|
257
|
+
- uses: AgentsKit-io/doc-bridge@v1.4.0
|
|
250
258
|
with:
|
|
251
259
|
config-path: doc-bridge.config.json
|
|
252
260
|
```
|
|
@@ -332,7 +340,7 @@ ak-docs memory promote --pr # opens draft PR via gh
|
|
|
332
340
|
|
|
333
341
|
## Status
|
|
334
342
|
|
|
335
|
-
**v1.
|
|
343
|
+
**v1.4.0 stable** — portable, fail-closed handoffs for Cursor, Pi, Hermes, and ClawHub-compatible clients; deterministic Documentation Standard v1 conformance; verified release provenance; Marketplace Action; doctor + CI + skill; and full Tier A/B/C.
|
|
336
344
|
|
|
337
345
|
```bash
|
|
338
346
|
pnpm install && pnpm build && pnpm test
|
package/action.yml
CHANGED
package/dist/cli/program.js
CHANGED
|
@@ -356,7 +356,9 @@ var IndexConfigSchema = z.object({
|
|
|
356
356
|
llmsTxt: z.object({
|
|
357
357
|
enabled: z.boolean().optional(),
|
|
358
358
|
outFile: z.string().min(1).max(512).optional(),
|
|
359
|
-
preamble: z.string().max(4e3).optional()
|
|
359
|
+
preamble: z.string().max(4e3).optional(),
|
|
360
|
+
urlPrefix: z.string().url().optional(),
|
|
361
|
+
pathPrefix: z.string().min(1).max(512).optional()
|
|
360
362
|
}).strict().optional(),
|
|
361
363
|
capabilities: z.object({
|
|
362
364
|
enabled: z.boolean().optional(),
|
|
@@ -692,7 +694,7 @@ var ProductSchema = z2.object({
|
|
|
692
694
|
role: NonEmptyStringSchema,
|
|
693
695
|
promise: NonEmptyStringSchema,
|
|
694
696
|
maturity: z2.enum(["planning", "alpha", "beta", "stable", "deprecated"]),
|
|
695
|
-
repo: RepoSchema,
|
|
697
|
+
repo: RepoSchema.nullable(),
|
|
696
698
|
accent: z2.string().regex(/^#[0-9A-Fa-f]{6}$/),
|
|
697
699
|
surfaces: SurfaceSchema,
|
|
698
700
|
navigation: z2.object({
|
|
@@ -707,7 +709,7 @@ var LegacyPropertySchema = z2.object({
|
|
|
707
709
|
barLabel: NonEmptyStringSchema,
|
|
708
710
|
domain: NonEmptyStringSchema,
|
|
709
711
|
url: HttpsUrlSchema,
|
|
710
|
-
repo: RepoSchema,
|
|
712
|
+
repo: RepoSchema.nullable(),
|
|
711
713
|
tagline: NonEmptyStringSchema,
|
|
712
714
|
kind: NonEmptyStringSchema,
|
|
713
715
|
accent: z2.string().regex(/^#[0-9A-Fa-f]{6}$/),
|
|
@@ -744,7 +746,8 @@ var ClaimProductSchema = z2.object({
|
|
|
744
746
|
productId: SlugSchema,
|
|
745
747
|
source: z2.discriminatedUnion("type", [
|
|
746
748
|
z2.object({ type: z2.literal("endpoint"), url: HttpsUrlSchema }).passthrough(),
|
|
747
|
-
z2.object({ type: z2.literal("repository"), repo: RepoSchema }).passthrough()
|
|
749
|
+
z2.object({ type: z2.literal("repository"), repo: RepoSchema }).passthrough(),
|
|
750
|
+
z2.object({ type: z2.literal("declaration"), summary: NonEmptyStringSchema }).passthrough()
|
|
748
751
|
]),
|
|
749
752
|
verification: z2.enum(["verified", "declared"]),
|
|
750
753
|
claims: z2.array(ClaimSchema)
|
|
@@ -821,8 +824,10 @@ var parseCanonicalEcosystemContract = (manifestInput, claimsInput) => {
|
|
|
821
824
|
if (!claimProduct) throw new Error(`Claims are missing product ${productId}.`);
|
|
822
825
|
if (claimProduct.source.type === "endpoint") {
|
|
823
826
|
if (claimProduct.source.url !== product.surfaces.stats) throw new Error(`Claims source for ${productId} must match stats.`);
|
|
824
|
-
} else if (claimProduct.source.repo !== product.repo) {
|
|
827
|
+
} else if (claimProduct.source.type === "repository" && claimProduct.source.repo !== product.repo) {
|
|
825
828
|
throw new Error(`Claims source for ${productId} must match repo.`);
|
|
829
|
+
} else if (claimProduct.source.type === "declaration" && product.repo !== null) {
|
|
830
|
+
throw new Error(`Declaration source for ${productId} requires a null repo.`);
|
|
826
831
|
}
|
|
827
832
|
if (claimProduct.verification === "declared" && claimProduct.claims.length > 0) {
|
|
828
833
|
throw new Error(`Declared product ${productId} cannot publish claims.`);
|
|
@@ -924,6 +929,9 @@ var defaultChecksForTarget = (root, opts) => {
|
|
|
924
929
|
return opts.strict ? ["npm test", "npm run lint"] : ["npm test"];
|
|
925
930
|
};
|
|
926
931
|
|
|
932
|
+
// src/index-builder/scan-corpus.ts
|
|
933
|
+
import { minimatch } from "minimatch";
|
|
934
|
+
|
|
927
935
|
// src/lib/bounded-text.ts
|
|
928
936
|
import { readFileSync as readFileSync3, statSync } from "fs";
|
|
929
937
|
var MAX_DOCUMENT_BYTES = 4 * 1024 * 1024;
|
|
@@ -1084,10 +1092,20 @@ var walkFiles = (root, opts) => {
|
|
|
1084
1092
|
};
|
|
1085
1093
|
|
|
1086
1094
|
// src/index-builder/scan-corpus.ts
|
|
1095
|
+
var configuredPathMatches = (relPath, include, exclude) => {
|
|
1096
|
+
const normalize = (pattern) => toPosix(pattern).replace(/^\.\//, "");
|
|
1097
|
+
const included = include?.filter(Boolean).map(normalize) ?? [];
|
|
1098
|
+
const excluded = exclude?.filter(Boolean).map(normalize) ?? [];
|
|
1099
|
+
if (excluded.some((pattern) => minimatch(relPath, pattern, { dot: true }))) return false;
|
|
1100
|
+
return included.length === 0 || included.some((pattern) => minimatch(relPath, pattern, { dot: true }));
|
|
1101
|
+
};
|
|
1087
1102
|
var scanAgentCorpus = (root, config) => {
|
|
1088
1103
|
const agentRoot = containedProjectPath(root, config.corpus.agent.root);
|
|
1089
1104
|
if (!agentRoot) throw new Error("Agent corpus root escapes the project root.");
|
|
1090
|
-
const files = walkFiles(agentRoot, { extensions: [".md", ".mdx"] })
|
|
1105
|
+
const files = walkFiles(agentRoot, { extensions: [".md", ".mdx"] }).filter((abs) => {
|
|
1106
|
+
const relToCorpus = toPosix(abs.replace(`${toPosix(agentRoot)}/`, ""));
|
|
1107
|
+
return configuredPathMatches(relToCorpus, config.corpus.agent.include, config.corpus.agent.exclude);
|
|
1108
|
+
});
|
|
1091
1109
|
const corpusRelRoot = toPosix(config.corpus.agent.root);
|
|
1092
1110
|
const budget = { used: 0 };
|
|
1093
1111
|
return files.map((abs) => {
|
|
@@ -1350,7 +1368,7 @@ var buildLookup = (config, packages, corpus, indexOutFile, humanDocs = {}, root
|
|
|
1350
1368
|
};
|
|
1351
1369
|
|
|
1352
1370
|
// src/version.ts
|
|
1353
|
-
var PACKAGE_VERSION = "1.4.
|
|
1371
|
+
var PACKAGE_VERSION = "1.4.3";
|
|
1354
1372
|
|
|
1355
1373
|
// src/index-builder/capabilities.ts
|
|
1356
1374
|
var renderCapabilitiesJson = (config, index, paths) => {
|
|
@@ -1401,6 +1419,18 @@ var sha256NormalizedV1 = (payload) => {
|
|
|
1401
1419
|
};
|
|
1402
1420
|
|
|
1403
1421
|
// src/index-builder/llms-txt.ts
|
|
1422
|
+
var routePath = (path, pathPrefix) => {
|
|
1423
|
+
const normalizedPath = path.replaceAll("\\", "/").replace(/\.(?:md|mdx)$/, "");
|
|
1424
|
+
const normalizedPrefix = pathPrefix?.replaceAll("\\", "/").replace(/\/$/, "");
|
|
1425
|
+
const relativePath2 = normalizedPrefix && normalizedPath.startsWith(`${normalizedPrefix}/`) ? normalizedPath.slice(normalizedPrefix.length + 1) : normalizedPath;
|
|
1426
|
+
return relativePath2.replace(/^\/+/, "");
|
|
1427
|
+
};
|
|
1428
|
+
var knowledgeUrl = (path, options = {}) => {
|
|
1429
|
+
const relativePath2 = routePath(path, options.pathPrefix);
|
|
1430
|
+
if (!options.urlPrefix) return path;
|
|
1431
|
+
const base = options.urlPrefix.endsWith("/") ? options.urlPrefix : `${options.urlPrefix}/`;
|
|
1432
|
+
return new URL(relativePath2, base).toString();
|
|
1433
|
+
};
|
|
1404
1434
|
var renderLlmsTxt = (config, knowledge, projectName2) => {
|
|
1405
1435
|
const preamble = config.index?.llmsTxt?.preamble ?? `# ${projectName2}
|
|
1406
1436
|
|
|
@@ -1408,7 +1438,8 @@ var renderLlmsTxt = (config, knowledge, projectName2) => {
|
|
|
1408
1438
|
`;
|
|
1409
1439
|
const lines = knowledge.slice(0, 500).map((entry) => {
|
|
1410
1440
|
const desc = entry.description ? `: ${entry.description}` : "";
|
|
1411
|
-
|
|
1441
|
+
const url = knowledgeUrl(entry.path, config.index?.llmsTxt);
|
|
1442
|
+
return `- [${entry.title}](${url})${desc}`;
|
|
1412
1443
|
});
|
|
1413
1444
|
return `${preamble.trim()}
|
|
1414
1445
|
|
|
@@ -1640,11 +1671,23 @@ var nextraAdapter = {
|
|
|
1640
1671
|
};
|
|
1641
1672
|
|
|
1642
1673
|
// src/index-builder/human-adapters/plain-markdown.ts
|
|
1674
|
+
import { minimatch as minimatch2 } from "minimatch";
|
|
1675
|
+
var stringPatterns = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string" && item.length > 0) : [];
|
|
1676
|
+
var matchesConfiguredPath = (relPath, options) => {
|
|
1677
|
+
const normalize = (pattern) => pattern.replaceAll("\\", "/").replace(/^\.\//, "");
|
|
1678
|
+
const include = stringPatterns(options?.include).map(normalize);
|
|
1679
|
+
const exclude = stringPatterns(options?.exclude).map(normalize);
|
|
1680
|
+
if (exclude.some((pattern) => minimatch2(relPath, pattern, { dot: true }))) return false;
|
|
1681
|
+
return include.length === 0 || include.some((pattern) => minimatch2(relPath, pattern, { dot: true }));
|
|
1682
|
+
};
|
|
1643
1683
|
var plainMarkdownAdapter = {
|
|
1644
1684
|
plugin: "plain-markdown",
|
|
1645
1685
|
scan: ({ root, config }) => {
|
|
1646
1686
|
const humanRoot = optionString(config.options, ["contentDir", "root", "docsDir"]) ?? "docs";
|
|
1647
|
-
return scanMarkdownDocs(root, humanRoot, {
|
|
1687
|
+
return scanMarkdownDocs(root, humanRoot, {
|
|
1688
|
+
urlPrefix: config.options?.urlPrefix,
|
|
1689
|
+
includeRelPath: (relPath) => matchesConfiguredPath(relPath, config.options)
|
|
1690
|
+
});
|
|
1648
1691
|
}
|
|
1649
1692
|
};
|
|
1650
1693
|
|
|
@@ -1673,7 +1716,7 @@ var starlightAdapter = {
|
|
|
1673
1716
|
};
|
|
1674
1717
|
|
|
1675
1718
|
// src/index-builder/human-adapters/vitepress.ts
|
|
1676
|
-
import { minimatch } from "minimatch";
|
|
1719
|
+
import { minimatch as minimatch3 } from "minimatch";
|
|
1677
1720
|
var isVitePressPage = (relPath) => !relPath.split("/").some((part) => part === ".vitepress" || part.startsWith("."));
|
|
1678
1721
|
var srcExcludePatterns = (value) => {
|
|
1679
1722
|
if (value === void 0) return [];
|
|
@@ -1687,7 +1730,7 @@ var srcExcludePatterns = (value) => {
|
|
|
1687
1730
|
return pattern;
|
|
1688
1731
|
});
|
|
1689
1732
|
};
|
|
1690
|
-
var isExcluded = (relPath, patterns) => patterns.some((pattern) =>
|
|
1733
|
+
var isExcluded = (relPath, patterns) => patterns.some((pattern) => minimatch3(relPath, pattern, { dot: true }));
|
|
1691
1734
|
var vitepressSlug = (relPath, cleanUrls) => {
|
|
1692
1735
|
const slug2 = routeSlug(relPath);
|
|
1693
1736
|
if (cleanUrls || /(?:^|\/)index\.mdx?$/.test(relPath)) return slug2;
|