@agentskit/doc-bridge 1.0.2 → 1.2.1
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 +50 -0
- package/CONTRIBUTING.md +8 -0
- package/README.md +114 -17
- package/SECURITY.md +1 -1
- package/action.yml +23 -26
- package/dist/cli/program.js +1241 -309
- package/dist/cli/program.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +338 -13
- package/dist/config/index.js.map +1 -1
- package/dist/{index-CPUJbTbg.d.ts → index-DGI9TBLE.d.ts} +906 -11
- package/dist/index.d.ts +65 -11
- package/dist/index.js +1084 -171
- package/dist/index.js.map +1 -1
- package/docs/DOGFOOD-ROUND2.md +5 -0
- package/docs/DOGFOOD-ROUND3.md +5 -0
- package/docs/DOGFOOD-V1.md +5 -0
- package/docs/DOGFOOD.md +5 -0
- package/docs/MARKETPLACE-ECOSYSTEM-PLAN.md +16 -0
- package/docs/MARKETPLACE.md +39 -0
- package/docs/POSITIONING.md +5 -0
- package/docs/RELEASE.md +26 -19
- package/docs/agent-corpus/INDEX.md +10 -0
- package/docs/agent-corpus/OVERVIEW.md +9 -0
- package/docs/agent-corpus/chat.md +10 -0
- package/docs/agent-corpus/cli.md +10 -0
- package/docs/agent-corpus/conformance.md +10 -0
- package/docs/agent-corpus/doc-bridge.md +10 -0
- package/docs/agent-corpus/doctor.md +10 -0
- package/docs/agent-corpus/gates.md +10 -0
- package/docs/agent-corpus/mcp.md +10 -0
- package/docs/agent-corpus/memory.md +10 -0
- package/docs/agent-corpus/query.md +10 -0
- package/docs/chat-and-rag.md +34 -0
- package/docs/examples.md +5 -0
- package/docs/for-agents.md +31 -0
- package/docs/getting-started.md +32 -2
- package/docs/index.md +23 -0
- package/docs/landing/assets/doc-bridge-hero.webp +0 -0
- package/docs/landing/assets/doc-bridge-surfaces.webp +0 -0
- package/docs/landing/assets/doc-bridge-two-way.webp +0 -0
- package/docs/landing/index.html +70 -10
- package/docs/mcp.md +5 -0
- package/docs/meta.json +20 -0
- package/docs/ollama-demo.md +6 -1
- package/docs/playbook/doc-bridge-pattern.md +4 -2
- package/docs/query.md +34 -0
- package/docs/recipes/index-pipeline.md +7 -2
- package/docs/schemas/agent-handoff-v1.md +5 -0
- package/docs/schemas/doc-bridge-index-v1.md +5 -0
- package/docs/schemas/memory-candidate-v1.md +15 -1
- package/docs/skills/doc-bridge.md +6 -1
- package/docs/spec/cli.md +6 -0
- package/docs/spec/config-v1.md +56 -6
- package/docs/spec/documentation-standard-v1.md +136 -0
- package/docs/spec/playbook-feedback.md +5 -0
- package/docs/spec/registry-agents.md +5 -0
- package/ecosystem-claims.json +187 -0
- package/ecosystem-upstream.json +9 -0
- package/ecosystem.json +235 -0
- package/examples/verify-handoff.mjs +5 -0
- package/package.json +46 -4
- package/scripts/check-ecosystem-upstream.mjs +50 -0
- package/src/cli/program.ts +36 -3
- package/src/config/index.ts +7 -1
- package/src/config/load-config.ts +4 -14
- package/src/config/schema.ts +91 -0
- package/src/conformance/documentation-standard-v1.ts +502 -0
- package/src/conformance/ecosystem-contract.ts +175 -0
- package/src/gates/run-gates.ts +33 -4
- package/src/index-builder/human-adapters/core.ts +12 -5
- package/src/index-builder/human-adapters/docusaurus.ts +29 -44
- package/src/index-builder/human-adapters/index.ts +15 -3
- package/src/index-builder/scan-corpus.ts +6 -6
- package/src/index.ts +17 -0
- package/src/lib/bounded-text.ts +25 -0
- package/src/lib/paths.ts +20 -2
- package/src/lib/static-js-literal.ts +261 -0
- package/src/lib/walk.ts +23 -4
- package/src/version.ts +1 -1
package/ecosystem.json
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 2,
|
|
3
|
+
"$comment": "Canonical registry of AgentsKit ecosystem products. Stable identity lives here; numeric values live in the generated ecosystem-claims ledger. The deprecated properties array temporarily preserves v1 sibling consumers.",
|
|
4
|
+
"parentBrand": {
|
|
5
|
+
"id": "agentskit",
|
|
6
|
+
"name": "AgentsKit"
|
|
7
|
+
},
|
|
8
|
+
"products": [
|
|
9
|
+
{
|
|
10
|
+
"id": "agentskit",
|
|
11
|
+
"name": "AgentsKit",
|
|
12
|
+
"shortName": "AgentsKit",
|
|
13
|
+
"kind": "library",
|
|
14
|
+
"role": "foundation",
|
|
15
|
+
"promise": "Build agents without gluing many libraries together.",
|
|
16
|
+
"maturity": "beta",
|
|
17
|
+
"repo": "AgentsKit-io/agentskit",
|
|
18
|
+
"accent": "#2EA043",
|
|
19
|
+
"surfaces": {
|
|
20
|
+
"home": "https://www.agentskit.io",
|
|
21
|
+
"docs": "https://www.agentskit.io/docs",
|
|
22
|
+
"llms": "https://www.agentskit.io/llms.txt",
|
|
23
|
+
"stats": "https://www.agentskit.io/api/stats.json",
|
|
24
|
+
"documentation": "fumadocs",
|
|
25
|
+
"chat": "agentschat"
|
|
26
|
+
},
|
|
27
|
+
"navigation": {
|
|
28
|
+
"showInBar": true,
|
|
29
|
+
"order": 0,
|
|
30
|
+
"next": ["registry", "agentskit-chat", "playbook", "doc-bridge", "code-review", "akos"]
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "registry",
|
|
35
|
+
"name": "AgentsKit Registry",
|
|
36
|
+
"shortName": "Registry",
|
|
37
|
+
"kind": "registry",
|
|
38
|
+
"role": "starting-point",
|
|
39
|
+
"promise": "Copy ready-made agents and own the source.",
|
|
40
|
+
"maturity": "beta",
|
|
41
|
+
"repo": "AgentsKit-io/agentskit-registry",
|
|
42
|
+
"accent": "#58A6FF",
|
|
43
|
+
"surfaces": {
|
|
44
|
+
"home": "https://registry.agentskit.io",
|
|
45
|
+
"docs": "https://registry.agentskit.io/docs",
|
|
46
|
+
"llms": "https://registry.agentskit.io/llms.txt",
|
|
47
|
+
"stats": "https://registry.agentskit.io/r/index.json",
|
|
48
|
+
"documentation": "fumadocs",
|
|
49
|
+
"chat": "agentschat"
|
|
50
|
+
},
|
|
51
|
+
"navigation": {
|
|
52
|
+
"showInBar": true,
|
|
53
|
+
"order": 1,
|
|
54
|
+
"next": ["agentskit", "agentskit-chat", "playbook", "doc-bridge", "code-review", "akos"]
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"id": "agentskit-chat",
|
|
59
|
+
"name": "AgentsKit Chat",
|
|
60
|
+
"shortName": "Chat",
|
|
61
|
+
"kind": "framework",
|
|
62
|
+
"role": "experience",
|
|
63
|
+
"promise": "Define one agent experience and deliver it across interfaces.",
|
|
64
|
+
"maturity": "alpha",
|
|
65
|
+
"repo": "AgentsKit-io/agentskit-chat",
|
|
66
|
+
"accent": "#F59E0B",
|
|
67
|
+
"surfaces": {
|
|
68
|
+
"home": "https://chat.agentskit.io",
|
|
69
|
+
"docs": "https://chat.agentskit.io/docs",
|
|
70
|
+
"llms": "https://chat.agentskit.io/llms.txt",
|
|
71
|
+
"documentation": "fumadocs",
|
|
72
|
+
"chat": "agentschat"
|
|
73
|
+
},
|
|
74
|
+
"navigation": {
|
|
75
|
+
"showInBar": true,
|
|
76
|
+
"order": 2,
|
|
77
|
+
"next": ["agentskit", "registry", "playbook", "doc-bridge", "code-review", "akos"]
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"id": "playbook",
|
|
82
|
+
"name": "Agents Playbook",
|
|
83
|
+
"shortName": "Playbook",
|
|
84
|
+
"kind": "methodology",
|
|
85
|
+
"role": "discipline",
|
|
86
|
+
"promise": "Make agents ship code a human would actually merge.",
|
|
87
|
+
"maturity": "stable",
|
|
88
|
+
"repo": "AgentsKit-io/agents-playbook",
|
|
89
|
+
"accent": "#8B5CF6",
|
|
90
|
+
"surfaces": {
|
|
91
|
+
"home": "https://playbook.agentskit.io",
|
|
92
|
+
"docs": "https://playbook.agentskit.io/docs",
|
|
93
|
+
"llms": "https://playbook.agentskit.io/llms.txt",
|
|
94
|
+
"stats": "https://playbook.agentskit.io/api/stats.json",
|
|
95
|
+
"documentation": "fumadocs",
|
|
96
|
+
"chat": "custom"
|
|
97
|
+
},
|
|
98
|
+
"navigation": {
|
|
99
|
+
"showInBar": true,
|
|
100
|
+
"order": 3,
|
|
101
|
+
"next": ["agentskit", "registry", "agentskit-chat", "doc-bridge", "code-review", "akos"]
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "doc-bridge",
|
|
106
|
+
"name": "Doc Bridge",
|
|
107
|
+
"shortName": "Doc Bridge",
|
|
108
|
+
"kind": "developer-tool",
|
|
109
|
+
"role": "understanding",
|
|
110
|
+
"promise": "Turn repository documentation into executable agent handoffs.",
|
|
111
|
+
"maturity": "stable",
|
|
112
|
+
"repo": "AgentsKit-io/doc-bridge",
|
|
113
|
+
"accent": "#06B6D4",
|
|
114
|
+
"surfaces": {
|
|
115
|
+
"home": "https://agentskit-io.github.io/doc-bridge/",
|
|
116
|
+
"docs": "https://agentskit-io.github.io/doc-bridge/",
|
|
117
|
+
"llms": "https://agentskit-io.github.io/doc-bridge/llms.txt",
|
|
118
|
+
"documentation": "fumadocs",
|
|
119
|
+
"chat": "none"
|
|
120
|
+
},
|
|
121
|
+
"navigation": {
|
|
122
|
+
"showInBar": true,
|
|
123
|
+
"order": 4,
|
|
124
|
+
"next": ["agentskit", "registry", "agentskit-chat", "playbook", "code-review", "akos"]
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"id": "code-review",
|
|
129
|
+
"name": "AgentsKit Code Review",
|
|
130
|
+
"shortName": "Code Review",
|
|
131
|
+
"kind": "developer-tool",
|
|
132
|
+
"role": "verification",
|
|
133
|
+
"promise": "Run deep, low-noise review with the model already in use.",
|
|
134
|
+
"maturity": "alpha",
|
|
135
|
+
"repo": "AgentsKit-io/code-review-cli",
|
|
136
|
+
"accent": "#F97316",
|
|
137
|
+
"surfaces": {
|
|
138
|
+
"home": "https://github.com/AgentsKit-io/code-review-cli",
|
|
139
|
+
"docs": "https://github.com/AgentsKit-io/code-review-cli#readme",
|
|
140
|
+
"llms": "https://raw.githubusercontent.com/AgentsKit-io/code-review-cli/main/llms.txt",
|
|
141
|
+
"documentation": "repository",
|
|
142
|
+
"chat": "none"
|
|
143
|
+
},
|
|
144
|
+
"navigation": {
|
|
145
|
+
"showInBar": true,
|
|
146
|
+
"order": 5,
|
|
147
|
+
"next": ["agentskit", "registry", "agentskit-chat", "playbook", "doc-bridge", "akos"]
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"id": "akos",
|
|
152
|
+
"name": "AgentsKit OS",
|
|
153
|
+
"shortName": "AKOS",
|
|
154
|
+
"kind": "product",
|
|
155
|
+
"role": "operation",
|
|
156
|
+
"promise": "Run and govern agents in production.",
|
|
157
|
+
"maturity": "stable",
|
|
158
|
+
"repo": "AgentsKit-io/agentskit-os",
|
|
159
|
+
"accent": "#34D399",
|
|
160
|
+
"surfaces": {
|
|
161
|
+
"home": "https://akos.agentskit.io",
|
|
162
|
+
"docs": "https://akos.agentskit.io/docs",
|
|
163
|
+
"llms": "https://akos.agentskit.io/llms.txt",
|
|
164
|
+
"stats": "https://akos.agentskit.io/api/stats.json",
|
|
165
|
+
"documentation": "fumadocs",
|
|
166
|
+
"chat": "none"
|
|
167
|
+
},
|
|
168
|
+
"navigation": {
|
|
169
|
+
"showInBar": true,
|
|
170
|
+
"order": 6,
|
|
171
|
+
"next": []
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
],
|
|
175
|
+
"properties": [
|
|
176
|
+
{
|
|
177
|
+
"id": "agentskit",
|
|
178
|
+
"name": "AgentsKit",
|
|
179
|
+
"barLabel": "AgentsKit",
|
|
180
|
+
"domain": "www.agentskit.io",
|
|
181
|
+
"url": "https://www.agentskit.io",
|
|
182
|
+
"repo": "AgentsKit-io/agentskit",
|
|
183
|
+
"tagline": "Build agents without gluing many libraries together.",
|
|
184
|
+
"kind": "library",
|
|
185
|
+
"accent": "#2EA043",
|
|
186
|
+
"llms": "https://www.agentskit.io/llms.txt",
|
|
187
|
+
"stats": "https://www.agentskit.io/api/stats.json"
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"id": "akos",
|
|
191
|
+
"name": "AgentsKit OS",
|
|
192
|
+
"barLabel": "AKOS",
|
|
193
|
+
"domain": "akos.agentskit.io",
|
|
194
|
+
"url": "https://akos.agentskit.io",
|
|
195
|
+
"repo": "AgentsKit-io/agentskit-os",
|
|
196
|
+
"tagline": "Run and govern agents in production.",
|
|
197
|
+
"kind": "product",
|
|
198
|
+
"accent": "#34D399",
|
|
199
|
+
"llms": "https://akos.agentskit.io/llms.txt",
|
|
200
|
+
"stats": "https://akos.agentskit.io/api/stats.json"
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"id": "playbook",
|
|
204
|
+
"name": "Agents Playbook",
|
|
205
|
+
"barLabel": "Playbook",
|
|
206
|
+
"domain": "playbook.agentskit.io",
|
|
207
|
+
"url": "https://playbook.agentskit.io",
|
|
208
|
+
"repo": "AgentsKit-io/agents-playbook",
|
|
209
|
+
"tagline": "Make agents ship code a human would actually merge.",
|
|
210
|
+
"kind": "methodology",
|
|
211
|
+
"accent": "#8B5CF6",
|
|
212
|
+
"llms": "https://playbook.agentskit.io/llms.txt",
|
|
213
|
+
"stats": "https://playbook.agentskit.io/api/stats.json"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"id": "registry",
|
|
217
|
+
"name": "AgentsKit Registry",
|
|
218
|
+
"barLabel": "Registry",
|
|
219
|
+
"domain": "registry.agentskit.io",
|
|
220
|
+
"url": "https://registry.agentskit.io",
|
|
221
|
+
"repo": "AgentsKit-io/agentskit-registry",
|
|
222
|
+
"tagline": "Copy ready-made agents and own the source.",
|
|
223
|
+
"kind": "registry",
|
|
224
|
+
"accent": "#58A6FF",
|
|
225
|
+
"llms": "https://registry.agentskit.io/llms.txt",
|
|
226
|
+
"stats": "https://registry.agentskit.io/r/index.json"
|
|
227
|
+
}
|
|
228
|
+
],
|
|
229
|
+
"builder": {
|
|
230
|
+
"id": "emersonbraun",
|
|
231
|
+
"name": "Emerson Braun",
|
|
232
|
+
"url": "https://emersonbraun.dev",
|
|
233
|
+
"$comment": "Link-source only. The builder is not a peer product and is not shown in shared product navigation."
|
|
234
|
+
}
|
|
235
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentskit/doc-bridge",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Human↔agent documentation bridge — deterministic handoffs, doc-site links, memory→docs, optional AgentsKit RAG/chat.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -23,6 +23,10 @@
|
|
|
23
23
|
"bin",
|
|
24
24
|
"action.yml",
|
|
25
25
|
"scripts/prepare.mjs",
|
|
26
|
+
"scripts/check-ecosystem-upstream.mjs",
|
|
27
|
+
"ecosystem.json",
|
|
28
|
+
"ecosystem-claims.json",
|
|
29
|
+
"ecosystem-upstream.json",
|
|
26
30
|
"docs",
|
|
27
31
|
"examples",
|
|
28
32
|
"README.md",
|
|
@@ -41,6 +45,8 @@
|
|
|
41
45
|
"test": "vitest run",
|
|
42
46
|
"test:watch": "vitest",
|
|
43
47
|
"coverage": "vitest run --coverage",
|
|
48
|
+
"check:ecosystem-upstream": "node scripts/check-ecosystem-upstream.mjs",
|
|
49
|
+
"check:no-legacy-chat-imports": "node scripts/check-no-legacy-chat-imports.mjs",
|
|
44
50
|
"typecheck": "tsc --noEmit",
|
|
45
51
|
"smoke:packaged": "node scripts/smoke-packaged.mjs",
|
|
46
52
|
"smoke:docsites": "node scripts/smoke-docsites.mjs",
|
|
@@ -48,12 +54,24 @@
|
|
|
48
54
|
"smoke:ollama": "node scripts/smoke-ollama.mjs",
|
|
49
55
|
"coverage:badge": "node scripts/update-coverage-badge.mjs",
|
|
50
56
|
"changeset": "changeset",
|
|
51
|
-
"version-packages": "changeset version",
|
|
57
|
+
"version-packages": "changeset version && node scripts/sync-version.mjs",
|
|
52
58
|
"release": "npm run build && npm test && changeset publish",
|
|
53
|
-
"version": "node scripts/sync-version.mjs && git add package.json src/version.ts",
|
|
59
|
+
"version": "node scripts/sync-version.mjs && git add package.json src/version.ts action.yml",
|
|
54
60
|
"prepublishOnly": "npm run build && npm test",
|
|
55
61
|
"prepare": "node scripts/prepare.mjs",
|
|
56
|
-
"prepack": "npm run build"
|
|
62
|
+
"prepack": "npm run build",
|
|
63
|
+
"docs:dev": "cd apps/docs && next dev",
|
|
64
|
+
"docs:artifacts": "node scripts/build-docs-artifacts.mjs",
|
|
65
|
+
"docs:build": "pnpm build && node bin/ak-docs.js index && pnpm docs:artifacts && cd apps/docs && next build",
|
|
66
|
+
"docs:typecheck": "cd apps/docs && fumadocs-mdx && tsc --noEmit",
|
|
67
|
+
"docs:e2e": "playwright test",
|
|
68
|
+
"docs:lighthouse": "lhci autorun",
|
|
69
|
+
"test:readme-standard": "node --test scripts/readme-standard.test.mjs",
|
|
70
|
+
"test:marketplace": "node --test scripts/marketplace-contract.test.mjs",
|
|
71
|
+
"check:marketplace": "node scripts/check-marketplace-contract.mjs",
|
|
72
|
+
"test:docs-artifacts": "node --test scripts/docs-artifacts-contract.test.mjs",
|
|
73
|
+
"check:readme-standard": "node scripts/check-readme-standard.mjs",
|
|
74
|
+
"check:docs": "pnpm check:readme-standard && node bin/ak-docs.js gate run && node bin/ak-docs.js conformance run documentation-standard-v1 --text && pnpm docs:typecheck && pnpm docs:build && pnpm test:docs-artifacts"
|
|
57
75
|
},
|
|
58
76
|
"keywords": [
|
|
59
77
|
"agentskit",
|
|
@@ -108,13 +126,37 @@
|
|
|
108
126
|
}
|
|
109
127
|
},
|
|
110
128
|
"devDependencies": {
|
|
129
|
+
"@agentskit/chat": "0.3.0",
|
|
130
|
+
"@agentskit/core": "1.12.3",
|
|
131
|
+
"@agentskit/react": "0.7.4",
|
|
111
132
|
"@changesets/cli": "^2.31.0",
|
|
133
|
+
"@lhci/cli": "^0.15.1",
|
|
134
|
+
"@playwright/test": "1.61.1",
|
|
135
|
+
"@tailwindcss/postcss": "4.3.2",
|
|
112
136
|
"@types/node": "^22.15.3",
|
|
137
|
+
"@types/react": "19.0.0",
|
|
138
|
+
"@types/react-dom": "19.0.0",
|
|
113
139
|
"@vitest/coverage-v8": "4.1.10",
|
|
140
|
+
"fumadocs-core": "15.6.5",
|
|
141
|
+
"fumadocs-mdx": "11.6.4",
|
|
142
|
+
"fumadocs-ui": "15.6.5",
|
|
143
|
+
"lucide-react": "0.460.0",
|
|
144
|
+
"next": "15.5.19",
|
|
145
|
+
"react": "19.2.0",
|
|
146
|
+
"react-dom": "19.2.0",
|
|
147
|
+
"tailwindcss": "4.3.2",
|
|
114
148
|
"tsup": "^8.5.0",
|
|
115
149
|
"typescript": "^6.0.3",
|
|
116
150
|
"vitest": "^4.1.9"
|
|
117
151
|
},
|
|
152
|
+
"pnpm": {
|
|
153
|
+
"overrides": {
|
|
154
|
+
"esbuild": "^0.28.1",
|
|
155
|
+
"postcss": "8.5.19",
|
|
156
|
+
"tmp": "0.2.7",
|
|
157
|
+
"uuid": "11.1.1"
|
|
158
|
+
}
|
|
159
|
+
},
|
|
118
160
|
"directories": {
|
|
119
161
|
"doc": "docs",
|
|
120
162
|
"example": "examples",
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createHash } from 'node:crypto'
|
|
3
|
+
import { readFileSync } from 'node:fs'
|
|
4
|
+
import { dirname, join, resolve } from 'node:path'
|
|
5
|
+
import { fileURLToPath } from 'node:url'
|
|
6
|
+
|
|
7
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
|
8
|
+
const metadata = JSON.parse(readFileSync(join(root, 'ecosystem-upstream.json'), 'utf8'))
|
|
9
|
+
if (metadata.schemaVersion !== 1 || typeof metadata.repository !== 'string' || typeof metadata.ref !== 'string') {
|
|
10
|
+
throw new Error('Invalid ecosystem-upstream.json metadata.')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const sha256 = (value) => createHash('sha256').update(value).digest('hex')
|
|
14
|
+
const requiredFiles = ['ecosystem.json', 'ecosystem-claims.json']
|
|
15
|
+
if (
|
|
16
|
+
!metadata.files ||
|
|
17
|
+
Object.keys(metadata.files).length !== requiredFiles.length ||
|
|
18
|
+
requiredFiles.some((file) => !/^[a-f0-9]{64}$/.test(metadata.files[file] ?? ''))
|
|
19
|
+
) {
|
|
20
|
+
throw new Error('Upstream metadata must contain SHA-256 digests for both canonical files.')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const fetchText = async (url) => {
|
|
24
|
+
let lastError
|
|
25
|
+
for (let attempt = 1; attempt <= 2; attempt += 1) {
|
|
26
|
+
try {
|
|
27
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(10_000) })
|
|
28
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`)
|
|
29
|
+
return await response.text()
|
|
30
|
+
} catch (error) {
|
|
31
|
+
lastError = error
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
throw new Error(`Unable to verify ${url}: ${lastError instanceof Error ? lastError.message : String(lastError)}`)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for (const file of requiredFiles) {
|
|
38
|
+
const expectedDigest = metadata.files[file]
|
|
39
|
+
const local = readFileSync(join(root, file), 'utf8')
|
|
40
|
+
const localDigest = sha256(local)
|
|
41
|
+
if (localDigest !== expectedDigest) {
|
|
42
|
+
throw new Error(`${file} differs from its recorded upstream SHA-256 digest.`)
|
|
43
|
+
}
|
|
44
|
+
const url = `https://raw.githubusercontent.com/${metadata.repository}/${metadata.ref}/${file}`
|
|
45
|
+
const upstream = await fetchText(url)
|
|
46
|
+
if (sha256(upstream) !== expectedDigest || upstream !== local) {
|
|
47
|
+
throw new Error(`${file} is stale against ${metadata.repository}@${metadata.ref}. Sync the canonical snapshot and digest.`)
|
|
48
|
+
}
|
|
49
|
+
process.stdout.write(`ecosystem upstream parity: ${file}\n`)
|
|
50
|
+
}
|
package/src/cli/program.ts
CHANGED
|
@@ -4,6 +4,11 @@ import { createInterface } from 'node:readline/promises'
|
|
|
4
4
|
|
|
5
5
|
import { loadConfig, projectRootFromConfigPath } from '../config/load-config.js'
|
|
6
6
|
import type { DocBridgeConfigV1 } from '../config/schema.js'
|
|
7
|
+
import {
|
|
8
|
+
DOCUMENTATION_STANDARD_V1_ID,
|
|
9
|
+
formatDocumentationStandardText,
|
|
10
|
+
runDocumentationStandardV1,
|
|
11
|
+
} from '../conformance/documentation-standard-v1.js'
|
|
7
12
|
import { buildDocBridgeIndex } from '../index-builder/build-index.js'
|
|
8
13
|
import { discoverPnpmPackages } from '../index-builder/plugins/pnpm-monorepo.js'
|
|
9
14
|
import { scanHumanDocRecords } from '../index-builder/human-adapters/index.js'
|
|
@@ -55,6 +60,7 @@ type Command =
|
|
|
55
60
|
| 'chat'
|
|
56
61
|
| 'rag'
|
|
57
62
|
| 'list'
|
|
63
|
+
| 'conformance'
|
|
58
64
|
|
|
59
65
|
const usage = `ak-docs — human↔agent documentation bridge (@agentskit/doc-bridge)
|
|
60
66
|
|
|
@@ -68,6 +74,7 @@ Core (no API key):
|
|
|
68
74
|
ak-docs list <packages|intents|changes|knowledge> [--text]
|
|
69
75
|
ak-docs ask [question] local consult (no LLM)
|
|
70
76
|
ak-docs gate run [gate-id]
|
|
77
|
+
ak-docs conformance run documentation-standard-v1 [--text|--json]
|
|
71
78
|
ak-docs mcp
|
|
72
79
|
ak-docs mcp install --cursor | --claude
|
|
73
80
|
ak-docs memory ingest|classify|promote [--pr] [--dry-run]
|
|
@@ -92,7 +99,13 @@ Global flags:
|
|
|
92
99
|
|
|
93
100
|
const QUERY_KINDS = new Set<QueryKind>(['package', 'ownership', 'intent', 'change', 'search'])
|
|
94
101
|
const LIST_KINDS = new Set(['packages', 'intents', 'changes', 'knowledge'])
|
|
95
|
-
const GATE_IDS = new Set<GateId>([
|
|
102
|
+
const GATE_IDS = new Set<GateId>([
|
|
103
|
+
'index-freshness',
|
|
104
|
+
'human-guide-links',
|
|
105
|
+
'okf-type',
|
|
106
|
+
'docs-style',
|
|
107
|
+
'documentation-standard-v1',
|
|
108
|
+
])
|
|
96
109
|
|
|
97
110
|
const parseArgs = (argv: readonly string[]) => {
|
|
98
111
|
const flags = new Set<string>()
|
|
@@ -136,6 +149,7 @@ const parseArgs = (argv: readonly string[]) => {
|
|
|
136
149
|
else if (positional[0] === 'chat') command = 'chat'
|
|
137
150
|
else if (positional[0] === 'rag') command = 'rag'
|
|
138
151
|
else if (positional[0] === 'list') command = 'list'
|
|
152
|
+
else if (positional[0] === 'conformance') command = 'conformance'
|
|
139
153
|
|
|
140
154
|
return { command, flags, configPath, positional }
|
|
141
155
|
}
|
|
@@ -782,12 +796,12 @@ export const runCli = (argv: readonly string[]): number | undefined | Promise<nu
|
|
|
782
796
|
const action = positional[1]
|
|
783
797
|
const gateId = positional[2] as GateId | undefined
|
|
784
798
|
if (action !== 'run') {
|
|
785
|
-
process.stderr.write('Usage: ak-docs gate run [
|
|
799
|
+
process.stderr.write('Usage: ak-docs gate run [gate-id]\n')
|
|
786
800
|
return 1
|
|
787
801
|
}
|
|
788
802
|
if (gateId && !GATE_IDS.has(gateId)) {
|
|
789
803
|
process.stderr.write(
|
|
790
|
-
`Unsupported gate "${gateId}". Supported gates:
|
|
804
|
+
`Unsupported gate "${gateId}". Supported gates: ${[...GATE_IDS].join(', ')}\n`,
|
|
791
805
|
)
|
|
792
806
|
return 1
|
|
793
807
|
}
|
|
@@ -802,6 +816,25 @@ export const runCli = (argv: readonly string[]): number | undefined | Promise<nu
|
|
|
802
816
|
}
|
|
803
817
|
}
|
|
804
818
|
|
|
819
|
+
if (command === 'conformance') {
|
|
820
|
+
const action = positional[1]
|
|
821
|
+
const profile = positional[2]
|
|
822
|
+
if (action !== 'run' || profile !== DOCUMENTATION_STANDARD_V1_ID) {
|
|
823
|
+
process.stderr.write(`Usage: ak-docs conformance run ${DOCUMENTATION_STANDARD_V1_ID} [--text|--json]\n`)
|
|
824
|
+
return 1
|
|
825
|
+
}
|
|
826
|
+
try {
|
|
827
|
+
const { config, root } = loadProject(configPath)
|
|
828
|
+
const report = runDocumentationStandardV1(root, config)
|
|
829
|
+
if (wantsTextOutput(flags, config)) writeLines(formatDocumentationStandardText(report))
|
|
830
|
+
else writeJson(report)
|
|
831
|
+
return report.ok ? 0 : 1
|
|
832
|
+
} catch (error) {
|
|
833
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`)
|
|
834
|
+
return 1
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
805
838
|
if (command === 'mcp') {
|
|
806
839
|
if (positional[1] === 'install') {
|
|
807
840
|
const target = flags.has('--claude') ? 'claude' : flags.has('--cursor') ? 'cursor' : undefined
|
package/src/config/index.ts
CHANGED
|
@@ -10,6 +10,12 @@ export {
|
|
|
10
10
|
DocBridgeConfigV1Schema,
|
|
11
11
|
AgentCorpusConfigSchema,
|
|
12
12
|
HumanCorpusConfigSchema,
|
|
13
|
+
DocumentationStandardRuleIdSchema,
|
|
14
|
+
DocumentationStandardV1ConfigSchema,
|
|
15
|
+
EcosystemContractEvidenceSchema,
|
|
16
|
+
ConformanceConfigSchema,
|
|
13
17
|
type DocBridgeConfigV1,
|
|
14
18
|
type AgentCorpusConfig,
|
|
15
|
-
|
|
19
|
+
type DocumentationStandardRuleId,
|
|
20
|
+
type DocumentationStandardV1Config,
|
|
21
|
+
} from './schema.js'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs'
|
|
2
2
|
import { basename, dirname, join, resolve } from 'node:path'
|
|
3
|
-
import vm from 'node:vm'
|
|
4
3
|
|
|
4
|
+
import { parseStaticJsObject } from '../lib/static-js-literal.js'
|
|
5
5
|
import { applyConfigDefaults } from './defaults.js'
|
|
6
6
|
import { DocBridgeConfigV1Schema, type DocBridgeConfigV1 } from './schema.js'
|
|
7
7
|
|
|
@@ -60,28 +60,18 @@ const parseJsonConfig = (raw: string, path: string): unknown => {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
const parseCodeConfig = (raw: string, path: string): unknown => {
|
|
63
|
-
const
|
|
63
|
+
const unsupportedImports = raw
|
|
64
64
|
.replace(/import\s+type\s+[\s\S]*?;?\n/g, '')
|
|
65
65
|
.replace(/import\s+\{\s*defineConfig\s*\}\s+from\s+['"]@agentskit\/doc-bridge(?:\/config)?['"];?\n?/g, '')
|
|
66
|
-
|
|
67
|
-
.replace(/export\s+default/, 'module.exports.default =')
|
|
68
|
-
|
|
69
|
-
if (/\bimport\b/.test(code)) {
|
|
66
|
+
if (/\bimport\b/.test(unsupportedImports)) {
|
|
70
67
|
throw new Error(`Unsupported import in ${path}. Static config only supports defineConfig imports.`)
|
|
71
68
|
}
|
|
72
|
-
|
|
73
|
-
const sandbox = {
|
|
74
|
-
module: { exports: {} as { default?: unknown } },
|
|
75
|
-
exports: {},
|
|
76
|
-
defineConfig: (config: unknown) => config,
|
|
77
|
-
}
|
|
78
69
|
try {
|
|
79
|
-
|
|
70
|
+
return parseStaticJsObject(raw)
|
|
80
71
|
} catch (error) {
|
|
81
72
|
const message = error instanceof Error ? error.message : String(error)
|
|
82
73
|
throw new Error(`Failed to load config at ${path}: ${message}`)
|
|
83
74
|
}
|
|
84
|
-
return sandbox.module.exports.default
|
|
85
75
|
}
|
|
86
76
|
|
|
87
77
|
const parseConfig = (input: unknown): DocBridgeConfigV1 => {
|
package/src/config/schema.ts
CHANGED
|
@@ -124,6 +124,7 @@ export const GatesConfigSchema = z
|
|
|
124
124
|
'docs-style',
|
|
125
125
|
'routing-currency',
|
|
126
126
|
'bootstrap-size',
|
|
127
|
+
'documentation-standard-v1',
|
|
127
128
|
]),
|
|
128
129
|
)
|
|
129
130
|
.max(16)
|
|
@@ -138,6 +139,7 @@ export const GatesConfigSchema = z
|
|
|
138
139
|
'docs-style',
|
|
139
140
|
'routing-currency',
|
|
140
141
|
'bootstrap-size',
|
|
142
|
+
'documentation-standard-v1',
|
|
141
143
|
]),
|
|
142
144
|
)
|
|
143
145
|
.max(16)
|
|
@@ -264,6 +266,92 @@ export const FederationConfigSchema = z
|
|
|
264
266
|
})
|
|
265
267
|
.strict()
|
|
266
268
|
|
|
269
|
+
export const DocumentationEvidenceFileSchema = z
|
|
270
|
+
.object({
|
|
271
|
+
path: z.string().min(1).max(512),
|
|
272
|
+
contains: z.array(z.string().min(1).max(512)).min(1).max(32),
|
|
273
|
+
})
|
|
274
|
+
.strict()
|
|
275
|
+
|
|
276
|
+
export const DocumentationLinkEvidenceSchema = z
|
|
277
|
+
.object({
|
|
278
|
+
url: z.string().url().max(512),
|
|
279
|
+
paths: z.array(z.string().min(1).max(512)).min(1).max(32),
|
|
280
|
+
})
|
|
281
|
+
.strict()
|
|
282
|
+
|
|
283
|
+
export const DocumentationQuickstartEvidenceSchema = z
|
|
284
|
+
.object({
|
|
285
|
+
id: z.string().regex(/^[a-z][a-z0-9-]*$/).max(128),
|
|
286
|
+
doc: z.string().min(1).max(512),
|
|
287
|
+
test: z.string().min(1).max(512),
|
|
288
|
+
command: z.string().min(1).max(512),
|
|
289
|
+
testContains: z.array(z.string().min(1).max(256)).min(1).max(16),
|
|
290
|
+
})
|
|
291
|
+
.strict()
|
|
292
|
+
|
|
293
|
+
export const EcosystemContractEvidenceSchema = z
|
|
294
|
+
.object({
|
|
295
|
+
manifest: z.string().min(1).max(512),
|
|
296
|
+
claims: z.string().min(1).max(512),
|
|
297
|
+
productId: z.string().regex(/^[a-z][a-z0-9-]*$/).max(128),
|
|
298
|
+
})
|
|
299
|
+
.strict()
|
|
300
|
+
|
|
301
|
+
export const DocumentationStandardRuleIdSchema = z.enum([
|
|
302
|
+
'human-docs',
|
|
303
|
+
'llms-and-raw-source',
|
|
304
|
+
'agent-handoffs',
|
|
305
|
+
'contribution',
|
|
306
|
+
'metadata',
|
|
307
|
+
'cross-links',
|
|
308
|
+
'tested-quickstarts',
|
|
309
|
+
'visual-explanations',
|
|
310
|
+
'structured-diagrams',
|
|
311
|
+
])
|
|
312
|
+
|
|
313
|
+
export const DocumentationStandardExceptionSchema = z
|
|
314
|
+
.object({
|
|
315
|
+
ruleId: DocumentationStandardRuleIdSchema,
|
|
316
|
+
reason: z.string().min(10).max(1_024),
|
|
317
|
+
approvedBy: z.string().min(1).max(256),
|
|
318
|
+
trackingUrl: z.string().url().max(512),
|
|
319
|
+
})
|
|
320
|
+
.strict()
|
|
321
|
+
|
|
322
|
+
export const DocumentationStandardV1ConfigSchema = z
|
|
323
|
+
.object({
|
|
324
|
+
rawSources: z.array(z.string().min(1).max(512)).max(64).optional(),
|
|
325
|
+
contributionPaths: z.array(z.string().min(1).max(512)).max(16).optional(),
|
|
326
|
+
metadata: z.array(DocumentationEvidenceFileSchema).max(32).optional(),
|
|
327
|
+
links: z.array(DocumentationLinkEvidenceSchema).max(64).optional(),
|
|
328
|
+
quickstarts: z.array(DocumentationQuickstartEvidenceSchema).max(32).optional(),
|
|
329
|
+
visuals: z.array(z.string().min(1).max(512)).max(64).optional(),
|
|
330
|
+
diagrams: z.array(DocumentationEvidenceFileSchema).max(32).optional(),
|
|
331
|
+
ecosystemContract: EcosystemContractEvidenceSchema.optional(),
|
|
332
|
+
exceptions: z.array(DocumentationStandardExceptionSchema).max(32).optional(),
|
|
333
|
+
})
|
|
334
|
+
.strict()
|
|
335
|
+
.superRefine((value, context) => {
|
|
336
|
+
const seen = new Set<string>()
|
|
337
|
+
for (const [index, exception] of (value.exceptions ?? []).entries()) {
|
|
338
|
+
if (seen.has(exception.ruleId)) {
|
|
339
|
+
context.addIssue({
|
|
340
|
+
code: 'custom',
|
|
341
|
+
path: ['exceptions', index, 'ruleId'],
|
|
342
|
+
message: `Duplicate exception for rule ${exception.ruleId}`,
|
|
343
|
+
})
|
|
344
|
+
}
|
|
345
|
+
seen.add(exception.ruleId)
|
|
346
|
+
}
|
|
347
|
+
})
|
|
348
|
+
|
|
349
|
+
export const ConformanceConfigSchema = z
|
|
350
|
+
.object({
|
|
351
|
+
documentationStandardV1: DocumentationStandardV1ConfigSchema.optional(),
|
|
352
|
+
})
|
|
353
|
+
.strict()
|
|
354
|
+
|
|
267
355
|
export const DocBridgeConfigV1Schema = z
|
|
268
356
|
.object({
|
|
269
357
|
schemaVersion: z.literal(CONFIG_SCHEMA_VERSION),
|
|
@@ -286,9 +374,12 @@ export const DocBridgeConfigV1Schema = z
|
|
|
286
374
|
surfaces: SurfacesConfigSchema.optional(),
|
|
287
375
|
intelligence: IntelligenceConfigSchema.optional(),
|
|
288
376
|
federation: FederationConfigSchema.optional(),
|
|
377
|
+
conformance: ConformanceConfigSchema.optional(),
|
|
289
378
|
})
|
|
290
379
|
.strict()
|
|
291
380
|
|
|
292
381
|
export type DocBridgeConfigV1 = z.infer<typeof DocBridgeConfigV1Schema>
|
|
293
382
|
export type AgentCorpusConfig = z.infer<typeof AgentCorpusConfigSchema>
|
|
294
383
|
export type HumanCorpusConfig = z.infer<typeof HumanCorpusConfigSchema>
|
|
384
|
+
export type DocumentationStandardV1Config = z.infer<typeof DocumentationStandardV1ConfigSchema>
|
|
385
|
+
export type DocumentationStandardRuleId = z.infer<typeof DocumentationStandardRuleIdSchema>
|