@agentskit/doc-bridge 1.4.3 → 1.5.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/ecosystem.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
- "$comment": "Canonical registry of AgentsKit ecosystem products. Stable identity lives in products[] (seven). Numeric values live in the generated ecosystem-claims ledger. The properties array is the full seven-product v1 projection of products[] (same order) for sibling consumers.",
3
+ "$comment": "Canonical registry of AgentsKit ecosystem products. Stable identity lives in products[] (seven). Numeric values live in the generated ecosystem-claims ledger. The deprecated properties array remains a v1 four-product shim for Doc Bridge / sibling consumers until those schemas accept the full seven-product set \u2014 do not treat properties as the product catalog.",
4
4
  "parentBrand": {
5
5
  "id": "agentskit",
6
6
  "name": "AgentsKit"
@@ -9,26 +9,18 @@
9
9
  "canonicalDescription": "AgentsKit is the open-source TypeScript ecosystem for building production AI agents without locking application architecture to a model provider, framework, database, or hosted platform.",
10
10
  "metaDescription": "Open-source TypeScript ecosystem for production AI agents. Swap models, providers, tools, memory, RAG, and interfaces without architectural lock-in.",
11
11
  "commercialBoundary": "AgentsKit, Chat, Registry, Playbook, Doc Bridge, and Code Review are free and open source. AKOS is the optional paid managed control plane for teams that need enterprise operations, governance, and infrastructure.",
12
- "openSourceProductIds": [
13
- "agentskit",
14
- "registry",
15
- "agentskit-chat",
16
- "playbook",
17
- "doc-bridge",
18
- "code-review"
19
- ],
20
- "managedProductIds": [
21
- "akos"
22
- ]
12
+ "openSourceProductIds": ["agentskit", "registry", "agentskit-chat", "playbook", "doc-bridge", "code-review"],
13
+ "managedProductIds": ["akos"]
23
14
  },
24
15
  "products": [
25
16
  {
26
17
  "id": "agentskit",
18
+ "public": true,
19
+ "distributionClass": "open-source",
27
20
  "name": "AgentsKit",
28
21
  "shortName": "AgentsKit",
29
22
  "kind": "library",
30
23
  "role": "foundation",
31
- "accessModel": "open-source",
32
24
  "promise": "Build agents without gluing many libraries together.",
33
25
  "maturity": "beta",
34
26
  "repo": "AgentsKit-io/agentskit",
@@ -75,20 +67,19 @@
75
67
  "stage": "Build",
76
68
  "headline": "One foundation. Every layer stays yours.",
77
69
  "detail": "Compose runtime, adapters, tools, memory, RAG, and UI without glue code or lock-in.",
78
- "proof": "{{packages}} packages · <{{core-size-kb-gzip}} KB core",
70
+ "proof": "22 packages · 10 KB core budget",
79
71
  "sales": {
80
72
  "kind": "integration-stack",
81
73
  "headline": "Swap the stack. Keep the agent.",
82
74
  "metrics": [
83
- { "value": "{{catalog-providers}}", "label": "providers" },
84
- { "value": "{{native-adapters}}", "label": "adapters" },
85
- { "value": "{{integrations}}", "label": "integrations" }
75
+ { "value": "140+", "label": "providers" },
76
+ { "value": "25", "label": "adapters" },
77
+ { "value": "50", "label": "integrations" }
86
78
  ],
87
79
  "capabilities": ["Tools", "RAG", "Memory", "MCP"],
88
80
  "steps": ["Choose any adapter", "Add tools and memory", "Ship without rewrites"]
89
81
  },
90
- "cta": "Build with AgentsKit",
91
- "ctaSurface": "docs"
82
+ "cta": "Build with AgentsKit"
92
83
  },
93
84
  "surfaces": {
94
85
  "home": "https://www.agentskit.io",
@@ -113,11 +104,12 @@
113
104
  },
114
105
  {
115
106
  "id": "registry",
107
+ "public": true,
108
+ "distributionClass": "open-source",
116
109
  "name": "AgentsKit Registry",
117
110
  "shortName": "Registry",
118
111
  "kind": "registry",
119
112
  "role": "starting-point",
120
- "accessModel": "open-source",
121
113
  "promise": "Copy ready-made agents and own the source.",
122
114
  "maturity": "beta",
123
115
  "repo": "AgentsKit-io/agentskit-registry",
@@ -136,15 +128,14 @@
136
128
  "proof": "Ready-made · source-owned",
137
129
  "sales": {
138
130
  "kind": "registry-install",
139
- "headline": "Ready-to-use agents from the live Registry.",
140
- "metric": "{{agents}}",
141
- "metricLabel": "shadcn-like agents",
142
- "capabilities": ["Research", "Support", "Coding", "Data", "Marketing", "{{remaining-categories}} additional categories"],
131
+ "headline": "Source-owned agents for your project.",
132
+ "metric": "Source-owned",
133
+ "metricLabel": "agent code",
134
+ "capabilities": ["Ready-made agents", "Source ownership", "CLI installation"],
143
135
  "steps": ["Find the right agent", "Run npx agentskit add", "Own every line"],
144
136
  "command": "npx agentskit add research"
145
137
  },
146
- "cta": "Explore the Registry",
147
- "ctaSurface": "home"
138
+ "cta": "Explore the Registry"
148
139
  },
149
140
  "surfaces": {
150
141
  "home": "https://registry.agentskit.io",
@@ -169,11 +160,12 @@
169
160
  },
170
161
  {
171
162
  "id": "agentskit-chat",
163
+ "public": true,
164
+ "distributionClass": "open-source",
172
165
  "name": "AgentsKit Chat",
173
166
  "shortName": "Chat",
174
167
  "kind": "framework",
175
168
  "role": "experience",
176
- "accessModel": "open-source",
177
169
  "promise": "Define one agent experience and deliver it across interfaces.",
178
170
  "maturity": "alpha",
179
171
  "repo": "AgentsKit-io/agentskit-chat",
@@ -181,24 +173,22 @@
181
173
  "showcase": {
182
174
  "stage": "Deliver",
183
175
  "headline": "One agent. Every conversation surface.",
184
- "detail": "Define the experience once and deliver it across web, desktop, CLI, and mobile.",
185
- "proof": "Web · Desktop · CLI · Mobile",
176
+ "detail": "Define the experience once and connect the conversation surface that fits the product.",
177
+ "proof": "Human ↔ agent · shared experience",
186
178
  "sales": {
187
179
  "kind": "human-agent",
188
180
  "headline": "Human ↔ agent. Without losing control.",
189
- "metric": "4",
190
- "metricLabel": "surfaces · one conversation",
181
+ "metric": "One",
182
+ "metricLabel": "agent experience",
191
183
  "logos": [
192
- { "id": "web", "label": "Web" },
193
- { "id": "desktop", "label": "Desktop" },
194
- { "id": "cli", "label": "CLI" },
195
- { "id": "mobile", "label": "Mobile" }
184
+ { "id": "human", "label": "Human" },
185
+ { "id": "agent", "label": "Agent" },
186
+ { "id": "tools", "label": "Tools" }
196
187
  ],
197
- "capabilities": ["Streaming", "Approvals", "Tool results", "Shared state"],
198
- "steps": ["Agent requests a protected action", "Human approves", "The conversation continues everywhere"]
188
+ "capabilities": ["Conversation", "Human control", "Tool results"],
189
+ "steps": ["Define the agent experience", "Connect the conversation surface", "Keep the human in control"]
199
190
  },
200
- "cta": "Explore AgentsKit Chat",
201
- "ctaSurface": "home"
191
+ "cta": "Explore AgentsKit Chat"
202
192
  },
203
193
  "surfaces": {
204
194
  "home": "https://chat.agentskit.io",
@@ -222,20 +212,21 @@
222
212
  },
223
213
  {
224
214
  "id": "playbook",
215
+ "public": true,
216
+ "distributionClass": "open-source",
225
217
  "name": "Agents Playbook",
226
218
  "shortName": "Playbook",
227
219
  "kind": "methodology",
228
220
  "role": "discipline",
229
- "accessModel": "open-source",
230
- "promise": "Train coding agents to ship code your team would merge.",
221
+ "promise": "Make agents ship code a human would actually merge.",
231
222
  "maturity": "stable",
232
223
  "repo": "AgentsKit-io/agents-playbook",
233
224
  "accent": "#8B5CF6",
234
225
  "showcase": {
235
226
  "stage": "Standardize",
236
- "headline": "The open engineering harness for coding agents.",
237
- "detail": "Open rules, prompts, memory, evals, and executable gates turn every correction into behavior coding agents can repeat.",
238
- "proof": "Train the behavior · not the model",
227
+ "headline": "Engineering standards agents can execute.",
228
+ "detail": "Turn repeatable practices into guidance that coding agents can follow in every repository.",
229
+ "proof": "Convention → executable guidance",
239
230
  "sales": {
240
231
  "kind": "standards-flow",
241
232
  "headline": "Your standards. Every agent. Every repository.",
@@ -250,8 +241,7 @@
250
241
  "capabilities": ["Repository rules", "Review criteria", "Agent guidance", "Team conventions"],
251
242
  "steps": ["Define the standard once", "Agents receive executable guidance", "Review consistent output"]
252
243
  },
253
- "cta": "Explore the harness",
254
- "ctaSurface": "home"
244
+ "cta": "Explore the Playbook"
255
245
  },
256
246
  "surfaces": {
257
247
  "home": "https://playbook.agentskit.io",
@@ -276,11 +266,12 @@
276
266
  },
277
267
  {
278
268
  "id": "doc-bridge",
269
+ "public": true,
270
+ "distributionClass": "open-source",
279
271
  "name": "Doc Bridge",
280
272
  "shortName": "Doc Bridge",
281
273
  "kind": "developer-tool",
282
274
  "role": "understanding",
283
- "accessModel": "open-source",
284
275
  "promise": "Turn repository documentation into executable agent handoffs.",
285
276
  "maturity": "stable",
286
277
  "repo": "AgentsKit-io/doc-bridge",
@@ -304,8 +295,7 @@
304
295
  "capabilities": ["ADRs", "Handoffs", "Agent findings", "Human-readable docs"],
305
296
  "steps": ["Humans document decisions", "Agents receive precise context", "Agent findings return to humans"]
306
297
  },
307
- "cta": "Generate your first handoff",
308
- "ctaSurface": "home"
298
+ "cta": "Explore Doc Bridge"
309
299
  },
310
300
  "surfaces": {
311
301
  "home": "https://doc-bridge.agentskit.io/",
@@ -329,11 +319,12 @@
329
319
  },
330
320
  {
331
321
  "id": "code-review",
322
+ "public": true,
323
+ "distributionClass": "open-source",
332
324
  "name": "AgentsKit Code Review",
333
325
  "shortName": "Code Review",
334
326
  "kind": "developer-tool",
335
327
  "role": "verification",
336
- "accessModel": "open-source",
337
328
  "promise": "Run deep, low-noise review with the model already in use.",
338
329
  "maturity": "alpha",
339
330
  "repo": "AgentsKit-io/code-review-cli",
@@ -360,36 +351,38 @@
360
351
  },
361
352
  {
362
353
  "id": "akos",
363
- "name": "AgentsKit OS",
354
+ "public": false,
355
+ "distributionClass": "managed-service",
356
+ "accessModel": "paid-managed-service",
357
+ "aliases": ["AgentsKit OS"],
358
+ "name": "AKOS",
364
359
  "shortName": "AKOS",
365
- "kind": "product",
360
+ "kind": "managed-service",
366
361
  "role": "operation",
367
- "accessModel": "paid-managed-service",
368
- "promise": "Run and govern agents in production.",
362
+ "promise": "Add optional managed operations when production governance calls for it.",
369
363
  "maturity": "stable",
370
- "repo": "AgentsKit-io/agentskit-os",
364
+ "repo": null,
365
+ "distributionPolicy": "Public commercial references only; never use private implementation as contribution evidence.",
371
366
  "accent": "#34D399",
372
367
  "showcase": {
373
368
  "stage": "Operate",
374
- "headline": "Run and govern agents in production.",
375
- "detail": "Add orchestration, governance, and operational control when your system needs it.",
376
- "proof": "Orchestration · governance · control",
369
+ "headline": "Optional managed operations for agents.",
370
+ "detail": "A managed layer for teams that need additional operational controls. AgentsKit can be used without it.",
371
+ "proof": "Optional · managed operations",
377
372
  "sales": {
378
373
  "kind": "enterprise-control",
379
- "headline": "The enterprise control plane for agents.",
380
- "metric": "Enterprise",
381
- "metricLabel": "operations and governance",
374
+ "headline": "Managed operations for production agents.",
375
+ "metric": "Optional",
376
+ "metricLabel": "managed layer",
382
377
  "logos": [
383
- { "id": "logs", "label": "Logs" },
384
- { "id": "approvals", "label": "Approvals" },
385
- { "id": "rbac", "label": "RBAC" },
386
- { "id": "policies", "label": "Policies" }
378
+ { "id": "managed", "label": "Managed" },
379
+ { "id": "optional", "label": "Optional" },
380
+ { "id": "operations", "label": "Operations" }
387
381
  ],
388
- "capabilities": ["Logs", "Approvals", "RBAC", "Policies", "Tracing", "Costs"],
389
- "steps": ["Agent requests a protected action", "RBAC and policy gates evaluate", "Human approves; logs and trace persist"]
382
+ "capabilities": ["Managed operations", "Production support", "Optional adoption"],
383
+ "steps": ["Assess the operational need", "Evaluate the managed layer", "Adopt it only when it fits"]
390
384
  },
391
- "cta": "Explore AgentsKit OS",
392
- "ctaSurface": "home"
385
+ "cta": "Evaluate managed operations"
393
386
  },
394
387
  "surfaces": {
395
388
  "home": "https://akos.agentskit.io",
@@ -420,29 +413,16 @@
420
413
  "stats": "https://www.agentskit.io/api/stats.json"
421
414
  },
422
415
  {
423
- "id": "registry",
424
- "name": "AgentsKit Registry",
425
- "barLabel": "Registry",
426
- "domain": "registry.agentskit.io",
427
- "url": "https://registry.agentskit.io",
428
- "repo": "AgentsKit-io/agentskit-registry",
429
- "tagline": "Copy ready-made agents and own the source.",
430
- "kind": "registry",
431
- "accent": "#58A6FF",
432
- "llms": "https://registry.agentskit.io/llms.txt",
433
- "stats": "https://registry.agentskit.io/r/index.json"
434
- },
435
- {
436
- "id": "agentskit-chat",
437
- "name": "AgentsKit Chat",
438
- "barLabel": "Chat",
439
- "domain": "chat.agentskit.io",
440
- "url": "https://chat.agentskit.io",
441
- "repo": "AgentsKit-io/agentskit-chat",
442
- "tagline": "Define one agent experience and deliver it across interfaces.",
443
- "kind": "framework",
444
- "accent": "#F59E0B",
445
- "llms": "https://chat.agentskit.io/llms.txt"
416
+ "id": "akos",
417
+ "name": "AKOS",
418
+ "barLabel": "AKOS",
419
+ "domain": "akos.agentskit.io",
420
+ "url": "https://akos.agentskit.io",
421
+ "repo": null,
422
+ "tagline": "Add optional managed operations when production governance calls for it.",
423
+ "kind": "managed-service",
424
+ "accent": "#34D399",
425
+ "llms": "https://akos.agentskit.io/llms.txt"
446
426
  },
447
427
  {
448
428
  "id": "playbook",
@@ -451,47 +431,24 @@
451
431
  "domain": "playbook.agentskit.io",
452
432
  "url": "https://playbook.agentskit.io",
453
433
  "repo": "AgentsKit-io/agents-playbook",
454
- "tagline": "Train coding agents to ship code your team would merge.",
434
+ "tagline": "Make agents ship code a human would actually merge.",
455
435
  "kind": "methodology",
456
436
  "accent": "#8B5CF6",
457
437
  "llms": "https://playbook.agentskit.io/llms.txt",
458
438
  "stats": "https://playbook.agentskit.io/api/stats.json"
459
439
  },
460
440
  {
461
- "id": "doc-bridge",
462
- "name": "Doc Bridge",
463
- "barLabel": "Doc Bridge",
464
- "domain": "doc-bridge.agentskit.io",
465
- "url": "https://doc-bridge.agentskit.io/",
466
- "repo": "AgentsKit-io/doc-bridge",
467
- "tagline": "Turn repository documentation into executable agent handoffs.",
468
- "kind": "developer-tool",
469
- "accent": "#06B6D4",
470
- "llms": "https://doc-bridge.agentskit.io/llms.txt"
471
- },
472
- {
473
- "id": "code-review",
474
- "name": "AgentsKit Code Review",
475
- "barLabel": "Code Review",
476
- "domain": "github.com",
477
- "url": "https://github.com/AgentsKit-io/code-review-cli",
478
- "repo": "AgentsKit-io/code-review-cli",
479
- "tagline": "Run deep, low-noise review with the model already in use.",
480
- "kind": "developer-tool",
481
- "accent": "#F97316",
482
- "llms": "https://raw.githubusercontent.com/AgentsKit-io/code-review-cli/main/llms.txt"
483
- },
484
- {
485
- "id": "akos",
486
- "name": "AgentsKit OS",
487
- "barLabel": "AKOS",
488
- "domain": "akos.agentskit.io",
489
- "url": "https://akos.agentskit.io",
490
- "repo": "AgentsKit-io/agentskit-os",
491
- "tagline": "Run and govern agents in production.",
492
- "kind": "product",
493
- "accent": "#34D399",
494
- "llms": "https://akos.agentskit.io/llms.txt"
441
+ "id": "registry",
442
+ "name": "AgentsKit Registry",
443
+ "barLabel": "Registry",
444
+ "domain": "registry.agentskit.io",
445
+ "url": "https://registry.agentskit.io",
446
+ "repo": "AgentsKit-io/agentskit-registry",
447
+ "tagline": "Copy ready-made agents and own the source.",
448
+ "kind": "registry",
449
+ "accent": "#58A6FF",
450
+ "llms": "https://registry.agentskit.io/llms.txt",
451
+ "stats": "https://registry.agentskit.io/r/index.json"
495
452
  }
496
453
  ],
497
454
  "builder": {
@@ -2,7 +2,7 @@
2
2
  "manifest_version": "0.3",
3
3
  "name": "doc-bridge",
4
4
  "display_name": "Doc Bridge",
5
- "version": "1.4.3",
5
+ "version": "1.5.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": {
@@ -63,6 +63,30 @@
63
63
  {
64
64
  "name": "registry.topology",
65
65
  "description": "Return the static Doc Bridge curator and delegate topology."
66
+ },
67
+ {
68
+ "name": "docbridge.snapshot",
69
+ "description": "Read the latest discovery snapshot from the resumable workflow."
70
+ },
71
+ {
72
+ "name": "docbridge.report",
73
+ "description": "Read the latest reconciliation report from the resumable workflow."
74
+ },
75
+ {
76
+ "name": "docbridge.diagnostics",
77
+ "description": "Read reconciliation diagnostics from the latest workflow report."
78
+ },
79
+ {
80
+ "name": "docbridge.relations",
81
+ "description": "Read bounded architecture relations from the latest workflow snapshot."
82
+ },
83
+ {
84
+ "name": "docbridge.run",
85
+ "description": "Read the latest resumable Doc Bridge workflow state."
86
+ },
87
+ {
88
+ "name": "docbridge.proposals",
89
+ "description": "Create, inspect, approve, and apply human-gated Doc Bridge proposals."
66
90
  }
67
91
  ],
68
92
  "tools_generated": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentskit/doc-bridge",
3
- "version": "1.4.3",
3
+ "version": "1.5.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",
@@ -117,6 +117,7 @@
117
117
  "github-slugger": "^2.0.0",
118
118
  "mermaid": "^11.16.1",
119
119
  "minimatch": "^10.2.6",
120
+ "typescript": "^6.0.3",
120
121
  "zod": "^3.24.2"
121
122
  },
122
123
  "peerDependencies": {
@@ -171,7 +172,6 @@
171
172
  "react-dom": "19.2.0",
172
173
  "tailwindcss": "4.3.2",
173
174
  "tsup": "^8.5.0",
174
- "typescript": "^6.0.3",
175
175
  "vitest": "^4.1.9"
176
176
  },
177
177
  "directories": {
@@ -3,7 +3,7 @@
3
3
  import { spawnSync } from 'node:child_process'
4
4
  import { isAbsolute } from 'node:path'
5
5
 
6
- const VERSION = '1.4.3'
6
+ const VERSION = '1.5.0'
7
7
  const kinds = new Set(['package', 'ownership'])
8
8
  const args = process.argv.slice(2)
9
9
  const id = args[0]
@@ -0,0 +1,97 @@
1
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs'
2
+ import { join, resolve } from 'node:path'
3
+ import { pathToFileURL } from 'node:url'
4
+ import { z } from 'zod'
5
+
6
+ import type { DocBridgeConfigV1 } from '../config/schema.js'
7
+ import { AgentProposalV1Schema, type AgentProposalV1, type DiscoverySnapshotV1, type ReconciliationReportV1 } from '../schemas/knowledge.js'
8
+ import { contentHashForArtifactV1 } from '../index-builder/content-hash.js'
9
+ import { containedPath, redactValue } from '../safety/repository.js'
10
+
11
+ export const DEFAULT_REGISTRY_AGENT_ID = 'ecosystem-doc-bridge-corpus-scanner'
12
+
13
+ const RegistryAgentMetadataSchema = z.object({
14
+ id: z.string().min(1).max(256),
15
+ version: z.string().min(1).max(64),
16
+ provider: z.string().min(1).max(128).optional(),
17
+ model: z.string().min(1).max(256).optional(),
18
+ capabilities: z.array(z.string().min(1).max(128)).max(32).default([]),
19
+ }).strict()
20
+
21
+ export type RegistryAgentMetadata = z.infer<typeof RegistryAgentMetadataSchema> & { readonly root: string }
22
+
23
+ export type RegistryAgentContext = {
24
+ readonly snapshot: DiscoverySnapshotV1
25
+ readonly report: ReconciliationReportV1
26
+ readonly evidence: readonly ReconciliationReportV1['diagnostics'][number]['evidence'][number][]
27
+ readonly capabilities: readonly ['snapshot.read', 'evidence.read', 'proposal.write']
28
+ readonly network: false
29
+ readonly shell: false
30
+ }
31
+
32
+ export type RegistryAgentRunner = (context: RegistryAgentContext) => Promise<unknown> | unknown
33
+
34
+ export type RegistryAgentAdapter = {
35
+ readonly metadata: RegistryAgentMetadata
36
+ readonly run: (snapshot: DiscoverySnapshotV1, report: ReconciliationReportV1, evidence?: readonly RegistryAgentContext['evidence'][number][]) => Promise<AgentProposalV1>
37
+ }
38
+
39
+ const deepFreeze = <T>(value: T): T => {
40
+ if (value && typeof value === 'object' && !Object.isFrozen(value)) {
41
+ Object.freeze(value)
42
+ for (const child of Object.values(value as Record<string, unknown>)) deepFreeze(child)
43
+ }
44
+ return value
45
+ }
46
+
47
+ const registryConfig = (config: DocBridgeConfigV1) => config.intelligence?.registry
48
+
49
+ export const loadRegistryAgentRunner = async (root: string, config: DocBridgeConfigV1): Promise<RegistryAgentRunner> => {
50
+ const metadata = loadRegistryAgentMetadata(root, config)
51
+ const configured = registryConfig(config)?.runnerModule
52
+ const modulePath = configured ? containedPath(root, configured) : containedPath(root, join(metadata.root, 'doc-bridge-adapter.js'))
53
+ if (!modulePath || !existsSync(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.`)
54
+ const loaded = await import(pathToFileURL(modulePath).href) as { default?: unknown; run?: unknown }
55
+ 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 : undefined
56
+ if (!runner) throw new Error(`Registry agent runner at ${modulePath} must export a function or { run }. `)
57
+ return runner as RegistryAgentRunner
58
+ }
59
+
60
+ export const loadRegistryAgentMetadata = (root: string, config: DocBridgeConfigV1): RegistryAgentMetadata => {
61
+ const settings = registryConfig(config)
62
+ const id = settings?.agentId ?? DEFAULT_REGISTRY_AGENT_ID
63
+ const agentRoot = settings?.agentRoot ?? 'agents'
64
+ const agentPath = containedPath(root, join(agentRoot, id))
65
+ if (!agentPath || !existsSync(agentPath)) throw new Error(`AgentsKit Registry agent "${id}" is not installed at ${join(agentRoot, id)}. Install it with: npx agentskit add ${id}`)
66
+ const metadataPath = [join(agentPath, 'agent.json'), join(agentPath, 'manifest.json')].find(existsSync)
67
+ if (!metadataPath) throw new Error(`Registry agent "${id}" is installed but has no agent.json or manifest.json metadata.`)
68
+ const metadata = RegistryAgentMetadataSchema.parse(JSON.parse(readFileSync(metadataPath, 'utf8')) as unknown)
69
+ if (metadata.id !== id) throw new Error(`Installed Registry agent metadata id "${metadata.id}" does not match configured id "${id}".`)
70
+ return { ...metadata, root: agentPath }
71
+ }
72
+
73
+ export const createRegistryAgentAdapter = (root: string, config: DocBridgeConfigV1, runner: RegistryAgentRunner): RegistryAgentAdapter => {
74
+ if (!registryConfig(config)?.enabled) throw new Error('Registry agents are disabled. Set intelligence.registry.enabled: true to run an assisted workflow.')
75
+ const metadata = loadRegistryAgentMetadata(resolve(root), config)
76
+ return {
77
+ metadata,
78
+ run: async (snapshot, report, evidence = report.diagnostics.flatMap((diagnostic) => diagnostic.evidence).slice(0, 64)) => {
79
+ const context = deepFreeze({ snapshot: redactValue(snapshot), report: redactValue(report), evidence: redactValue(evidence), capabilities: ['snapshot.read', 'evidence.read', 'proposal.write'] as const, network: false as const, shell: false as const }) as RegistryAgentContext
80
+ const proposal = AgentProposalV1Schema.parse(await runner(context))
81
+ if (proposal.contentHash !== contentHashForArtifactV1(proposal)) throw new Error('Registry agent proposal contentHash does not match its canonical contents.')
82
+ if (proposal.baseSnapshotHash !== snapshot.contentHash || proposal.baseReportHash !== report.contentHash) throw new Error('Registry agent proposal is not based on the supplied snapshot/report hashes.')
83
+ if (proposal.origin.kind !== 'registry-agent' || proposal.origin.id !== metadata.id) throw new Error(`Registry agent proposal origin must be ${metadata.id}.`)
84
+ return proposal
85
+ },
86
+ }
87
+ }
88
+
89
+ export const persistRegistryAgentProposal = (stateDir: string, proposal: AgentProposalV1): string => {
90
+ AgentProposalV1Schema.parse(proposal)
91
+ if (proposal.contentHash !== contentHashForArtifactV1(proposal)) throw new Error('Cannot persist a Registry agent proposal with an invalid contentHash.')
92
+ const safeHash = contentHashForArtifactV1(proposal)
93
+ mkdirSync(join(resolve(stateDir), 'agents'), { recursive: true })
94
+ const path = join(resolve(stateDir), 'agents', `${proposal.origin.id}-${safeHash}.json`)
95
+ writeFileSync(path, `${JSON.stringify(proposal, null, 2)}\n`, 'utf8')
96
+ return path
97
+ }