@agentskit/doc-bridge 1.2.6 → 1.4.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 +19 -0
- package/README.md +32 -6
- package/action.yml +1 -1
- package/dist/cli/program.js +344 -130
- 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-DGI9TBLE.d.ts → index-DAeq_OIi.d.ts} +22 -22
- package/dist/index.d.ts +7 -4
- package/dist/index.js +320 -105
- package/dist/index.js.map +1 -1
- package/docs/MARKETPLACE.md +1 -1
- package/docs/POSITIONING.md +1 -1
- package/docs/examples.md +4 -0
- package/docs/getting-started.md +1 -1
- package/docs/guides/choose-context-layer.md +129 -0
- package/docs/guides/gate-ci.md +1 -1
- package/docs/guides/meta.json +1 -0
- package/docs/landing/index.html +2 -2
- package/docs/playbook/doc-bridge-pattern.md +1 -1
- package/docs/qa/vitepress-starlight-adapters.md +19 -0
- package/docs/recipes/index-pipeline.md +1 -1
- package/docs/spec/config-v1.md +33 -2
- package/examples/nextra-only.config.ts +17 -0
- package/examples/nx-monorepo.config.ts +11 -0
- package/examples/starlight-only.config.ts +17 -0
- package/examples/vitepress-only.config.ts +19 -0
- package/mcpb/manifest.json +1 -1
- package/package.json +15 -4
- package/skills/doc-bridge-handoff/SKILL.md +38 -0
- package/skills/doc-bridge-handoff/fixtures/synthetic-repo/doc-bridge.config.json +23 -0
- package/skills/doc-bridge-handoff/fixtures/synthetic-repo/docs/for-agents/packages/payments.md +5 -0
- package/skills/doc-bridge-handoff/fixtures/synthetic-repo/packages/payments/package.json +4 -0
- package/skills/doc-bridge-handoff/scripts/resolve-handoff.mjs +70 -0
- package/src/config/schema.ts +3 -1
- package/src/index-builder/build-handoffs.ts +2 -0
- package/src/index-builder/build-index.ts +7 -1
- package/src/index-builder/human-adapters/index.ts +6 -0
- package/src/index-builder/human-adapters/nextra.ts +43 -0
- package/src/index-builder/human-adapters/starlight.ts +40 -0
- package/src/index-builder/human-adapters/vitepress.ts +43 -0
- package/src/index-builder/plugins/nx.ts +161 -0
- package/src/index-builder/plugins/pnpm-monorepo.ts +1 -0
- package/src/index-builder/watch-index.ts +11 -2
- package/src/index.ts +1 -0
- package/src/version.ts +1 -1
package/docs/MARKETPLACE.md
CHANGED
package/docs/POSITIONING.md
CHANGED
|
@@ -70,7 +70,7 @@ Engineering teams with real ownership (monorepos first). Secondary: solo libs, i
|
|
|
70
70
|
|
|
71
71
|
```
|
|
72
72
|
required: index, CLI, MCP handoff tools, gate presets
|
|
73
|
-
optional: fumadocs | docusaurus | plain-markdown plugins
|
|
73
|
+
optional: fumadocs | docusaurus | vitepress | starlight | nextra | plain-markdown plugins
|
|
74
74
|
optional: memory ingest → promote
|
|
75
75
|
optional: @agentskit/rag + ink chat (intelligence.*)
|
|
76
76
|
optional: Playbook / Registry federation
|
package/docs/examples.md
CHANGED
|
@@ -11,8 +11,12 @@ Config sketches under [`examples/`](../examples/):
|
|
|
11
11
|
|------|---------|
|
|
12
12
|
| `minimal-plain-markdown.config.ts` | Solo markdown, Layer 0 only |
|
|
13
13
|
| `pnpm-monorepo.config.ts` | Workspace discovery + ownership |
|
|
14
|
+
| `nx-monorepo.config.ts` | Static Nx project discovery + inferred checks |
|
|
14
15
|
| `fumadocs-only.config.ts` | Human bridge via Fumadocs |
|
|
15
16
|
| `docusaurus-only.config.ts` | Human bridge via Docusaurus |
|
|
17
|
+
| `vitepress-only.config.ts` | Human bridge via VitePress |
|
|
18
|
+
| `starlight-only.config.ts` | Human bridge via Astro Starlight |
|
|
19
|
+
| `nextra-only.config.ts` | Human bridge via Nextra |
|
|
16
20
|
| `fumadocs-with-chat.config.ts` | Standard + intelligence (AgentsKit peers) |
|
|
17
21
|
| `docusaurus-with-memory.config.ts` | Assisted memory promotion path |
|
|
18
22
|
|
package/docs/getting-started.md
CHANGED
|
@@ -105,7 +105,7 @@ Tools: `handoff.resolve`, `doc.search`, `doc.get`, `gate.status`, …
|
|
|
105
105
|
## Human ↔ agent bridge
|
|
106
106
|
|
|
107
107
|
```bash
|
|
108
|
-
# After configuring corpus.human (fumadocs | docusaurus | plain-markdown)
|
|
108
|
+
# After configuring corpus.human (fumadocs | docusaurus | vitepress | starlight | nextra | plain-markdown)
|
|
109
109
|
ak-docs index
|
|
110
110
|
ak-docs query package <id> --agent # includes humanDoc when linked
|
|
111
111
|
ak-docs gate run human-guide-links
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Choose the right context layer
|
|
3
|
+
description: Decide when an agent needs repository rules, deterministic routing, code search, RAG, or human review.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Choose the right context layer
|
|
7
|
+
|
|
8
|
+
Coding agents rarely fail because a repository has no context. They fail because the right context arrives too late, or because several different kinds of context are treated as interchangeable.
|
|
9
|
+
|
|
10
|
+
`AGENTS.md`, Doc Bridge, code search, RAG, and human review solve different problems. The most reliable workflow composes them in that order instead of asking one layer to do every job.
|
|
11
|
+
|
|
12
|
+
## The short version
|
|
13
|
+
|
|
14
|
+
| Layer | Best question | Use it for | Do not rely on it for |
|
|
15
|
+
| --- | --- | --- | --- |
|
|
16
|
+
| `AGENTS.md` | What rules apply here? | Repository-wide invariants, conventions, safety rules, and workflow expectations | Selecting the owner of every task in a large monorepo |
|
|
17
|
+
| Doc Bridge | Where does this task belong? | Deterministic ownership, starting docs, declared edit roots, package checks, and matching human docs | Explaining every implementation detail or enforcing filesystem permissions |
|
|
18
|
+
| Code search | Where is this exact thing used? | Symbols, imports, references, call sites, and concrete strings | Deciding ownership from similarity alone |
|
|
19
|
+
| RAG | What broader context may be relevant? | Design history, migrations, scattered documentation, and open-ended questions | Overriding an explicit ownership contract |
|
|
20
|
+
| Human review | Is this boundary still correct? | Ambiguous, cross-cutting, security-sensitive, or high-impact decisions | Routine routing that the repository can declare and test |
|
|
21
|
+
|
|
22
|
+
## Start with repository rules
|
|
23
|
+
|
|
24
|
+
An `AGENTS.md` file is the right place for rules that should survive individual tasks:
|
|
25
|
+
|
|
26
|
+
- required coding conventions;
|
|
27
|
+
- security and privacy constraints;
|
|
28
|
+
- commands that must run before a change is accepted;
|
|
29
|
+
- architectural invariants;
|
|
30
|
+
- contribution and release expectations.
|
|
31
|
+
|
|
32
|
+
Doc Bridge does not replace those rules. A handoff can include `AGENTS.md` in `readBeforeEditing`, then narrow the task to the package-specific material that matters.
|
|
33
|
+
|
|
34
|
+
## Use Doc Bridge for deterministic routing
|
|
35
|
+
|
|
36
|
+
When the repository already knows which package owns authentication, the agent should not infer ownership from filenames or semantic similarity. Resolve a handoff first:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
ak-docs query package auth --agent
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
A useful handoff answers four operational questions:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"startHere": "docs/for-agents/packages/auth.md",
|
|
47
|
+
"editRoots": ["packages/auth"],
|
|
48
|
+
"checks": [
|
|
49
|
+
"pnpm --filter @example/auth test",
|
|
50
|
+
"pnpm --filter @example/auth lint"
|
|
51
|
+
],
|
|
52
|
+
"humanDoc": "docs/guides/auth.md"
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This is intentionally smaller than a repository dump. It gives the agent an explicit starting point, declared scope, evidence to run, and a human-facing description of the same feature.
|
|
57
|
+
|
|
58
|
+
`editRoots` is a routing and audit contract. It does not create an operating-system sandbox by itself. If a workflow must technically prevent writes outside those roots, enforce that boundary with the agent runner, sandbox, permissions, or CI policy.
|
|
59
|
+
|
|
60
|
+
## Search after scope is known
|
|
61
|
+
|
|
62
|
+
Code search is strongest after the owner is resolved. Inside the intended scope, use it to find:
|
|
63
|
+
|
|
64
|
+
- the implementation of a symbol;
|
|
65
|
+
- all imports of an adapter;
|
|
66
|
+
- tests for an error code;
|
|
67
|
+
- callers affected by a signature change.
|
|
68
|
+
|
|
69
|
+
Search can reveal that a task is genuinely cross-cutting. When it does, expand the declared handoff or ask for human review. Do not quietly turn a package-scoped change into a repository-wide edit.
|
|
70
|
+
|
|
71
|
+
## Add RAG for open-ended context
|
|
72
|
+
|
|
73
|
+
RAG is useful when the question does not have one exact answer:
|
|
74
|
+
|
|
75
|
+
- Why did the authentication design change?
|
|
76
|
+
- Which migration notes mention token rotation?
|
|
77
|
+
- What guidance exists for moving from one provider to another?
|
|
78
|
+
|
|
79
|
+
That context can improve the implementation, but it should expand a deterministic handoff rather than replace one. Similar documents are evidence, not ownership.
|
|
80
|
+
|
|
81
|
+
Doc Bridge keeps this distinction explicit: Layer 0 indexing and handoffs work offline without a model or API key; RAG and chat are optional intelligence layers.
|
|
82
|
+
|
|
83
|
+
## Escalate ambiguity to a human
|
|
84
|
+
|
|
85
|
+
Some changes should not be forced into a convenient directory. Ask for human review when:
|
|
86
|
+
|
|
87
|
+
- multiple packages legitimately own part of the change;
|
|
88
|
+
- a public contract or security boundary may change;
|
|
89
|
+
- the handoff conflicts with the current repository shape;
|
|
90
|
+
- checks are missing or no longer prove the behavior;
|
|
91
|
+
- the cost of a wrong boundary is high.
|
|
92
|
+
|
|
93
|
+
A useful routing system should make uncertainty visible. It should not produce false confidence when the repository has not declared an answer.
|
|
94
|
+
|
|
95
|
+
## Recommended order
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
resolve handoff
|
|
99
|
+
→ read AGENTS.md and startHere
|
|
100
|
+
→ search exact code inside the declared scope
|
|
101
|
+
→ retrieve broader context when needed
|
|
102
|
+
→ edit the intended roots
|
|
103
|
+
→ run the declared checks
|
|
104
|
+
→ request human review for unresolved boundaries
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
For an existing repository, the smallest adoption path is:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm install --save-dev @agentskit/doc-bridge@1.2.6
|
|
111
|
+
npx ak-docs init
|
|
112
|
+
npx ak-docs index
|
|
113
|
+
npx ak-docs query package example --agent
|
|
114
|
+
npx ak-docs gate run
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The gate makes drift visible when ownership inputs or linked documentation change without a refreshed index. That keeps the routing contract reviewable instead of silently rebuilding it during validation.
|
|
118
|
+
|
|
119
|
+
## A practical decision rule
|
|
120
|
+
|
|
121
|
+
If the question begins with **must**, put the invariant in repository instructions. If it begins with **where**, resolve a Doc Bridge handoff. If it begins with **which exact reference**, search the code. If it begins with **why** or **what else**, retrieve broader context. If the answers disagree, stop and ask a human.
|
|
122
|
+
|
|
123
|
+
## Related
|
|
124
|
+
|
|
125
|
+
- [Index and query](./index-and-query.md)
|
|
126
|
+
- [For agents](../for-agents.md)
|
|
127
|
+
- [Chat and RAG](../chat-and-rag.md)
|
|
128
|
+
- [Gate in CI](./gate-ci.md)
|
|
129
|
+
- [AgentHandoff schema](../schemas/agent-handoff-v1.md)
|
package/docs/guides/gate-ci.md
CHANGED
package/docs/guides/meta.json
CHANGED
package/docs/landing/index.html
CHANGED
|
@@ -272,7 +272,7 @@
|
|
|
272
272
|
<tr><td>CLI</td><td>Query ownership, inspect handoffs, run doctor, search docs.</td><td><code>ak-docs query package auth --agent</code></td></tr>
|
|
273
273
|
<tr><td>MCP</td><td>Lets Cursor, Claude Code, and Codex-style agents resolve before editing.</td><td><code>ak-docs mcp install --cursor</code></td></tr>
|
|
274
274
|
<tr><td>CI</td><td>Blocks stale indexes and broken human-doc bridges.</td><td><code>ak-docs index && ak-docs gate run</code></td></tr>
|
|
275
|
-
<tr><td>Adapters</td><td>Connect Fumadocs, Docusaurus, plain markdown, and pnpm workspaces.</td><td><code>fumadocs</code> · <code>docusaurus</code> · <code>plain-markdown</code></td></tr>
|
|
275
|
+
<tr><td>Adapters</td><td>Connect Fumadocs, Docusaurus, VitePress, Starlight, Nextra, plain markdown, and pnpm workspaces.</td><td><code>fumadocs</code> · <code>docusaurus</code> · <code>vitepress</code> · <code>starlight</code> · <code>nextra</code> · <code>plain-markdown</code></td></tr>
|
|
276
276
|
<tr><td>Memory pipeline</td><td>Classifies local agent memory and drafts documentation updates.</td><td><code>ak-docs memory promote --pr</code></td></tr>
|
|
277
277
|
<tr><td>Optional RAG/chat</td><td>Adds handoff-first chat when you install AgentsKit peers.</td><td><code>ak-docs rag ingest && ak-docs chat</code></td></tr>
|
|
278
278
|
</tbody>
|
|
@@ -337,7 +337,7 @@
|
|
|
337
337
|
<div class="terminal-bar"><span class="dot dot-r"></span><span class="dot dot-y"></span><span class="dot dot-g"></span></div>
|
|
338
338
|
<div class="terminal-body">
|
|
339
339
|
<div class="t-dim"># .github/workflows/pr.yml</div>
|
|
340
|
-
<div>- uses: <span class="t-hi">AgentsKit-io/doc-bridge@v1.
|
|
340
|
+
<div>- uses: <span class="t-hi">AgentsKit-io/doc-bridge@v1.3.0</span></div>
|
|
341
341
|
<div> with:</div>
|
|
342
342
|
<div> config-path: doc-bridge.config.json</div>
|
|
343
343
|
</div>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# VitePress and Starlight adapter QA plan
|
|
2
|
+
|
|
3
|
+
This plan records the local acceptance criteria for the first-party VitePress and Astro Starlight human-documentation adapters.
|
|
4
|
+
|
|
5
|
+
## Contract checks
|
|
6
|
+
|
|
7
|
+
- A VitePress corpus scans Markdown and MDX below its configured documentation root, maps `index` files to their directory route, follows the framework's default `.html` routes or optional `cleanUrls`, applies declarative `srcExclude` globs, respects an optional `urlPrefix`, and keeps Doc Bridge join metadata (`package`, `module`, or `id`) stable.
|
|
8
|
+
- A Starlight corpus scans Markdown and MDX below its configured content root, uses Astro's optional `slug` frontmatter for the public route, maps index pages correctly, respects an optional `urlPrefix`, and keeps Doc Bridge join metadata stable.
|
|
9
|
+
- Both adapters reject roots outside the project through the shared bounded, containment-aware scanner.
|
|
10
|
+
- Neither adapter executes framework configuration or user JavaScript.
|
|
11
|
+
- Existing Fumadocs, Docusaurus, and plain-Markdown behavior remains unchanged.
|
|
12
|
+
|
|
13
|
+
## Local verification
|
|
14
|
+
|
|
15
|
+
1. Add focused fixtures for default routes, index routes, metadata overrides, URL prefixes, and nested agent-corpus exclusion.
|
|
16
|
+
2. Run `pnpm vitest run tests/human-adapters.test.ts tests/schemas.test.ts`.
|
|
17
|
+
3. Run `pnpm typecheck` and `pnpm build` to validate the public configuration type and emitted declarations.
|
|
18
|
+
4. Run the complete `pnpm test` suite to detect regressions.
|
|
19
|
+
5. Run `git diff --check` and inspect the final diff for scope and generated-file noise.
|
package/docs/spec/config-v1.md
CHANGED
|
@@ -129,10 +129,34 @@ type HumanCorpusPluginId =
|
|
|
129
129
|
| 'fumadocs' // markdown scan with index routes, (group) slugs, pages allowlists
|
|
130
130
|
| 'docusaurus' // markdown scan with id/slug frontmatter + static sidebars.js
|
|
131
131
|
| 'mkdocs' // planned
|
|
132
|
-
| 'vitepress' //
|
|
132
|
+
| 'vitepress' // file routes, srcDir/docsDir, optional cleanUrls
|
|
133
|
+
| 'starlight' // Astro content routes, slug and draft frontmatter
|
|
134
|
+
| 'nextra' // content-directory routes and contentDirBasePath
|
|
133
135
|
| 'custom' // path to user plugin module
|
|
134
136
|
```
|
|
135
137
|
|
|
138
|
+
VitePress options accept `docsDir` (also `root` or `srcDir`), `urlPrefix`,
|
|
139
|
+
`cleanUrls`, and up to 64 declarative `srcExclude` glob patterns. Doc Bridge
|
|
140
|
+
uses `.html` routes unless `cleanUrls: true`, matching
|
|
141
|
+
VitePress routing without loading or executing `.vitepress/config.*`. Route
|
|
142
|
+
rewrites must therefore be reflected in the configured corpus or URL prefix.
|
|
143
|
+
|
|
144
|
+
Starlight options accept `contentDir` (also `docsDir` or `root`) and
|
|
145
|
+
`urlPrefix`. The adapter reads the standard `slug` and `draft` frontmatter,
|
|
146
|
+
follows the default filename sluggifier, excludes underscore-prefixed
|
|
147
|
+
partials, and never executes `astro.config.*`. Sites using a custom
|
|
148
|
+
`docsLoader({ generateId })` should add explicit `slug` frontmatter so Doc
|
|
149
|
+
Bridge can resolve the same public route without executing project code.
|
|
150
|
+
|
|
151
|
+
Nextra options accept `contentDir` (also `docsDir` or `root`), `urlPrefix`,
|
|
152
|
+
and `contentDirBasePath`. The adapter maps `index.md` and `index.mdx` to the
|
|
153
|
+
containing route and uses Doc Bridge `package`, `module`, or `id` frontmatter
|
|
154
|
+
as the join key. `urlPrefix` takes precedence over `contentDirBasePath`. Point
|
|
155
|
+
`contentDir` at either `content` or `src/content`; Doc Bridge never imports or
|
|
156
|
+
executes `next.config.*`, `_meta.*`, themes, or other project code. This
|
|
157
|
+
adapter targets Nextra's content-directory convention; app-router `page.mdx`
|
|
158
|
+
trees are not inferred by this plugin.
|
|
159
|
+
|
|
136
160
|
### Bridge to agent docs
|
|
137
161
|
|
|
138
162
|
When `corpus.human` is set, plugins MUST:
|
|
@@ -199,7 +223,7 @@ Without `routing`, handoffs are inferred from agent corpus links only. Monorepo
|
|
|
199
223
|
|
|
200
224
|
```ts
|
|
201
225
|
type RoutingConfig = {
|
|
202
|
-
plugin?: 'pnpm-monorepo' | 'npm-workspaces' | 'yarn-workspaces' | 'custom'
|
|
226
|
+
plugin?: 'pnpm-monorepo' | 'npm-workspaces' | 'yarn-workspaces' | 'nx' | 'pattern-files' | 'custom'
|
|
203
227
|
|
|
204
228
|
options?: {
|
|
205
229
|
/** Workspace globs; default from package manager */
|
|
@@ -240,6 +264,13 @@ type ChangeRouteEntry = {
|
|
|
240
264
|
}
|
|
241
265
|
```
|
|
242
266
|
|
|
267
|
+
`routing.plugin: 'nx'` reads `project.json` and package manifests with an `nx`
|
|
268
|
+
object. It does not load Nx plugins or execute workspace code. Project roots must
|
|
269
|
+
resolve inside the configured project root. Declared `test` targets become Nx test
|
|
270
|
+
checks; non-minimal gate presets also include declared `lint` targets. Explicit
|
|
271
|
+
`routing.options.ownership` remains authoritative. Targets created only at runtime
|
|
272
|
+
by Nx plugins are intentionally not inferred by this read-only adapter.
|
|
273
|
+
|
|
243
274
|
### Join keys (agent ↔ human ↔ ownership)
|
|
244
275
|
|
|
245
276
|
| Entity | Primary key | Human plugin maps via |
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defineConfig } from '@agentskit/doc-bridge'
|
|
2
|
+
|
|
3
|
+
/** Nextra bridge only: no chat, no memory, no provider key. */
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
schemaVersion: 1,
|
|
6
|
+
corpus: {
|
|
7
|
+
agent: { root: 'docs/for-agents' },
|
|
8
|
+
human: {
|
|
9
|
+
plugin: 'nextra',
|
|
10
|
+
options: {
|
|
11
|
+
contentDir: 'content',
|
|
12
|
+
contentDirBasePath: '/docs',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
gates: { preset: 'standard' },
|
|
17
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineConfig } from '@agentskit/doc-bridge'
|
|
2
|
+
|
|
3
|
+
/** Nx — infer project ownership and available test/lint checks without executing Nx */
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
schemaVersion: 1,
|
|
6
|
+
corpus: {
|
|
7
|
+
agent: { root: 'docs/for-agents' },
|
|
8
|
+
},
|
|
9
|
+
routing: { plugin: 'nx' },
|
|
10
|
+
gates: { preset: 'standard' },
|
|
11
|
+
})
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defineConfig } from '@agentskit/doc-bridge'
|
|
2
|
+
|
|
3
|
+
/** Starlight bridge only: no chat, no memory, no provider key. */
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
schemaVersion: 1,
|
|
6
|
+
corpus: {
|
|
7
|
+
agent: { root: 'docs/for-agents' },
|
|
8
|
+
human: {
|
|
9
|
+
plugin: 'starlight',
|
|
10
|
+
options: {
|
|
11
|
+
contentDir: 'src/content/docs',
|
|
12
|
+
urlPrefix: '/docs',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
gates: { preset: 'standard' },
|
|
17
|
+
})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defineConfig } from '@agentskit/doc-bridge'
|
|
2
|
+
|
|
3
|
+
/** VitePress bridge only: no chat, no memory, no provider key. */
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
schemaVersion: 1,
|
|
6
|
+
corpus: {
|
|
7
|
+
agent: { root: 'docs/for-agents' },
|
|
8
|
+
human: {
|
|
9
|
+
plugin: 'vitepress',
|
|
10
|
+
options: {
|
|
11
|
+
docsDir: 'docs',
|
|
12
|
+
urlPrefix: '/docs',
|
|
13
|
+
cleanUrls: true,
|
|
14
|
+
srcExclude: ['archive/**'],
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
gates: { preset: 'standard' },
|
|
19
|
+
})
|
package/mcpb/manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"manifest_version": "0.3",
|
|
3
3
|
"name": "doc-bridge",
|
|
4
4
|
"display_name": "Doc Bridge",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.4.0",
|
|
6
6
|
"description": "Deterministic repository handoffs for coding agents, running locally without an LLM or API key.",
|
|
7
7
|
"long_description": "Doc Bridge turns a repository's own documentation and ownership metadata into deterministic handoffs: where an agent should start, which paths it may edit, which checks it must run, and when a human must take over. The local connector exposes the same read-only contract available through Doc Bridge CLI and CI.",
|
|
8
8
|
"author": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentskit/doc-bridge",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"mcpName": "io.github.AgentsKit-io/doc-bridge",
|
|
5
5
|
"description": "Human↔agent documentation bridge — deterministic handoffs, doc-site links, memory→docs, optional AgentsKit RAG/chat.",
|
|
6
6
|
"type": "module",
|
|
@@ -40,12 +40,13 @@
|
|
|
40
40
|
"mcpb",
|
|
41
41
|
"tsup.config.ts",
|
|
42
42
|
"tsconfig.json",
|
|
43
|
-
"src"
|
|
43
|
+
"src",
|
|
44
|
+
"skills"
|
|
44
45
|
],
|
|
45
46
|
"scripts": {
|
|
46
47
|
"prebuild": "node scripts/sync-version.mjs",
|
|
47
48
|
"build": "tsup",
|
|
48
|
-
"test": "vitest run",
|
|
49
|
+
"test": "vitest run && pnpm test:cursor-plugin && pnpm test:portable-skill",
|
|
49
50
|
"test:watch": "vitest",
|
|
50
51
|
"coverage": "vitest run --coverage",
|
|
51
52
|
"check:ecosystem-upstream": "node scripts/check-ecosystem-upstream.mjs",
|
|
@@ -60,6 +61,8 @@
|
|
|
60
61
|
"mcpb:smoke": "node scripts/smoke-mcpb.mjs",
|
|
61
62
|
"mcpb:pack": "npm run mcpb:stage && npm run mcpb:smoke && node scripts/build-mcpb.mjs pack",
|
|
62
63
|
"test:mcpb": "node --test scripts/mcpb-contract.test.mjs",
|
|
64
|
+
"test:cursor-plugin": "node --test scripts/cursor-plugin-contract.test.mjs",
|
|
65
|
+
"test:portable-skill": "node --test scripts/portable-skill-contract.test.mjs",
|
|
63
66
|
"coverage:badge": "node scripts/update-coverage-badge.mjs",
|
|
64
67
|
"changeset": "changeset",
|
|
65
68
|
"version-packages": "changeset version && node scripts/sync-version.mjs",
|
|
@@ -85,12 +88,18 @@
|
|
|
85
88
|
"agentskit",
|
|
86
89
|
"documentation",
|
|
87
90
|
"mcp",
|
|
91
|
+
"pi-package",
|
|
88
92
|
"for-agents",
|
|
89
93
|
"llms-txt",
|
|
90
94
|
"agent-handoff",
|
|
91
95
|
"rag",
|
|
92
96
|
"human-agent-bridge"
|
|
93
97
|
],
|
|
98
|
+
"pi": {
|
|
99
|
+
"skills": [
|
|
100
|
+
"./skills"
|
|
101
|
+
]
|
|
102
|
+
},
|
|
94
103
|
"license": "MIT",
|
|
95
104
|
"repository": {
|
|
96
105
|
"type": "git",
|
|
@@ -103,7 +112,9 @@
|
|
|
103
112
|
"access": "public"
|
|
104
113
|
},
|
|
105
114
|
"dependencies": {
|
|
106
|
-
"
|
|
115
|
+
"github-slugger": "^2.0.0",
|
|
116
|
+
"mermaid": "^11.16.1",
|
|
117
|
+
"minimatch": "^10.2.6",
|
|
107
118
|
"zod": "^3.24.2"
|
|
108
119
|
},
|
|
109
120
|
"peerDependencies": {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: doc-bridge-handoff
|
|
3
|
+
description: Resolve Doc Bridge boundaries before changing code.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
author: AgentsKit
|
|
6
|
+
license: MIT
|
|
7
|
+
platforms:
|
|
8
|
+
- darwin
|
|
9
|
+
- linux
|
|
10
|
+
- windows
|
|
11
|
+
metadata:
|
|
12
|
+
hermes:
|
|
13
|
+
tags:
|
|
14
|
+
- documentation
|
|
15
|
+
- coding-agents
|
|
16
|
+
- repository-routing
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Doc Bridge handoff
|
|
20
|
+
|
|
21
|
+
Use this skill before editing a repository that contains `doc-bridge.config.json`.
|
|
22
|
+
|
|
23
|
+
1. Resolve the package or ownership id that best matches the requested change:
|
|
24
|
+
- Prefer the read-only MCP tool `handoff.resolve` when it is available.
|
|
25
|
+
- Otherwise run `node <skill-directory>/scripts/resolve-handoff.mjs <id>` from the repository.
|
|
26
|
+
2. Read every file in `readBeforeEditing`, beginning with `startHere`.
|
|
27
|
+
3. Keep changes inside `editRoots`. If the requested path is not covered, stop and report the missing route instead of guessing.
|
|
28
|
+
4. Make the smallest change that satisfies the request.
|
|
29
|
+
5. Run every command in `checks` before claiming completion.
|
|
30
|
+
6. If documentation changed, refresh the Doc Bridge index and run its gate.
|
|
31
|
+
|
|
32
|
+
If resolution fails, returns incomplete fields, or names an unknown target, stop. Do not infer edit permission from repository layout.
|
|
33
|
+
|
|
34
|
+
The resolver and MCP tools are read-only. They resolve project guidance but never authorize edits, publish changes, execute returned checks, or replace repository instructions. The skill uses no credentials and has no provider, hosted service, or AKOS dependency.
|
|
35
|
+
|
|
36
|
+
## Portable runtimes
|
|
37
|
+
|
|
38
|
+
This directory follows the open Agent Skills layout: one `SKILL.md` plus optional scripts and fixtures. It can be loaded as a local skill by OpenClaw-compatible clients, Hermes Agent, Pi, Cursor, or another runtime that supports Agent Skills and shell execution. Runtime-specific publication metadata is intentionally kept outside the skill.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"corpus": {
|
|
4
|
+
"agent": {
|
|
5
|
+
"root": "docs/for-agents"
|
|
6
|
+
}
|
|
7
|
+
},
|
|
8
|
+
"routing": {
|
|
9
|
+
"options": {
|
|
10
|
+
"ownership": {
|
|
11
|
+
"payments": {
|
|
12
|
+
"path": "packages/payments",
|
|
13
|
+
"purpose": "Synthetic package used only to verify portable handoff routing",
|
|
14
|
+
"checks": ["npm test -- payments"],
|
|
15
|
+
"agentDoc": "docs/for-agents/packages/payments.md"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"gates": {
|
|
21
|
+
"preset": "minimal"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawnSync } from 'node:child_process'
|
|
4
|
+
import { isAbsolute } from 'node:path'
|
|
5
|
+
|
|
6
|
+
const VERSION = '1.4.0'
|
|
7
|
+
const kinds = new Set(['package', 'ownership'])
|
|
8
|
+
const args = process.argv.slice(2)
|
|
9
|
+
const id = args[0]
|
|
10
|
+
const kindFlag = args.indexOf('--kind')
|
|
11
|
+
const configFlag = args.indexOf('--config')
|
|
12
|
+
const kind = kindFlag === -1 ? 'package' : args[kindFlag + 1]
|
|
13
|
+
const config = configFlag === -1 ? undefined : args[configFlag + 1]
|
|
14
|
+
|
|
15
|
+
const fail = (message) => {
|
|
16
|
+
process.stderr.write(`Doc Bridge handoff blocked: ${message}\n`)
|
|
17
|
+
process.exit(1)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!id || id.startsWith('--') || /[\u0000-\u001f\u007f]/u.test(id)) {
|
|
21
|
+
fail('provide a package or ownership id')
|
|
22
|
+
}
|
|
23
|
+
if (!kind || !kinds.has(kind)) fail('--kind must be package or ownership')
|
|
24
|
+
if (configFlag !== -1 && (!config || config.startsWith('--'))) fail('--config requires a path')
|
|
25
|
+
|
|
26
|
+
const queryArgs = ['query', kind, id, '--agent']
|
|
27
|
+
if (config) queryArgs.push('--config', config)
|
|
28
|
+
|
|
29
|
+
const localBin = process.env.DOC_BRIDGE_BIN
|
|
30
|
+
const command = localBin ? process.execPath : 'npx'
|
|
31
|
+
const commandArgs = localBin
|
|
32
|
+
? [localBin, ...queryArgs]
|
|
33
|
+
: ['-y', `@agentskit/doc-bridge@${VERSION}`, ...queryArgs]
|
|
34
|
+
const result = spawnSync(command, commandArgs, {
|
|
35
|
+
cwd: process.cwd(),
|
|
36
|
+
encoding: 'utf8',
|
|
37
|
+
timeout: 60_000,
|
|
38
|
+
maxBuffer: 1024 * 1024,
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
if (result.error) fail(result.error.message)
|
|
42
|
+
if (result.status !== 0) fail(result.stderr.trim() || `resolver exited with status ${result.status}`)
|
|
43
|
+
|
|
44
|
+
let handoff
|
|
45
|
+
try {
|
|
46
|
+
handoff = JSON.parse(result.stdout)
|
|
47
|
+
} catch {
|
|
48
|
+
fail('resolver returned invalid JSON')
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const nonEmptyStrings = (value) =>
|
|
52
|
+
Array.isArray(value) && value.length > 0 && value.every((item) => typeof item === 'string' && item.trim())
|
|
53
|
+
const safeRelativePath = (value) => {
|
|
54
|
+
if (typeof value !== 'string' || !value.trim() || isAbsolute(value)) return false
|
|
55
|
+
if (/^(?:[a-z]:[\\/]|\\\\)/iu.test(value)) return false
|
|
56
|
+
return !value.split(/[\\/]+/u).includes('..')
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (handoff?.target?.id !== id) fail('resolver returned a different target')
|
|
60
|
+
if (!safeRelativePath(handoff.startHere)) fail('startHere is missing or unsafe')
|
|
61
|
+
if (!nonEmptyStrings(handoff.readBeforeEditing) || !handoff.readBeforeEditing.every(safeRelativePath)) {
|
|
62
|
+
fail('readBeforeEditing is missing or unsafe')
|
|
63
|
+
}
|
|
64
|
+
if (!handoff.readBeforeEditing.includes(handoff.startHere)) fail('readBeforeEditing omits startHere')
|
|
65
|
+
if (!nonEmptyStrings(handoff.editRoots) || !handoff.editRoots.every(safeRelativePath)) {
|
|
66
|
+
fail('editRoots is missing or unsafe')
|
|
67
|
+
}
|
|
68
|
+
if (!nonEmptyStrings(handoff.checks)) fail('checks are missing')
|
|
69
|
+
|
|
70
|
+
process.stdout.write(`${JSON.stringify(handoff, null, 2)}\n`)
|
package/src/config/schema.ts
CHANGED
|
@@ -8,6 +8,8 @@ export const HumanCorpusPluginIdSchema = z.enum([
|
|
|
8
8
|
'docusaurus',
|
|
9
9
|
'mkdocs',
|
|
10
10
|
'vitepress',
|
|
11
|
+
'starlight',
|
|
12
|
+
'nextra',
|
|
11
13
|
'custom',
|
|
12
14
|
])
|
|
13
15
|
|
|
@@ -71,7 +73,7 @@ export const OwnershipEntrySchema = z
|
|
|
71
73
|
export const RoutingConfigSchema = z
|
|
72
74
|
.object({
|
|
73
75
|
plugin: z
|
|
74
|
-
.enum(['pnpm-monorepo', 'npm-workspaces', 'yarn-workspaces', 'pattern-files', 'custom'])
|
|
76
|
+
.enum(['pnpm-monorepo', 'npm-workspaces', 'yarn-workspaces', 'nx', 'pattern-files', 'custom'])
|
|
75
77
|
.optional(),
|
|
76
78
|
options: z
|
|
77
79
|
.object({
|
|
@@ -70,6 +70,7 @@ export const collectPackages = (
|
|
|
70
70
|
id: pkg.id,
|
|
71
71
|
path: existing.path || pkg.path,
|
|
72
72
|
...(pkg.name ? { name: pkg.name } : existing.name ? { name: existing.name } : {}),
|
|
73
|
+
...(pkg.checks ? { checks: pkg.checks } : existing.checks ? { checks: existing.checks } : {}),
|
|
73
74
|
})
|
|
74
75
|
}
|
|
75
76
|
|
|
@@ -163,6 +164,7 @@ export const buildLookup = (
|
|
|
163
164
|
const checks = [
|
|
164
165
|
...(override?.checks ??
|
|
165
166
|
fm?.checks ??
|
|
167
|
+
pkg.checks ??
|
|
166
168
|
defaultChecksForTarget(root, {
|
|
167
169
|
packageId: pkg.id,
|
|
168
170
|
packagePath: path,
|