zooid 0.9.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  buildAcpRegistry
4
- } from "./chunk-PDSJJWQW.js";
4
+ } from "./chunk-OCRQ3LWL.js";
5
5
  export {
6
6
  buildAcpRegistry
7
7
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zooid",
3
- "version": "0.9.1",
3
+ "version": "0.11.0",
4
4
  "description": "An open-source, self-hostable chat app for collaborating with AI agents alongside your team. Any model, any CLI.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,7 +25,7 @@
25
25
  "access": "public"
26
26
  },
27
27
  "zooid": {
28
- "webVersion": "0.8.0"
28
+ "webVersion": "0.9.0"
29
29
  },
30
30
  "engines": {
31
31
  "node": ">=22"
@@ -41,13 +41,13 @@
41
41
  "sanitize-html": "^2.17.4",
42
42
  "tar": "^7.5.16",
43
43
  "yaml": "^2.5.0",
44
- "@zooid/acp-client": "^0.9.1",
45
- "@zooid/context-mcp": "^0.9.1",
46
- "@zooid/core": "^0.9.1",
47
- "@zooid/runtime-docker": "^0.9.1",
48
- "@zooid/runtime-local": "^0.9.1",
49
- "@zooid/transport-http": "^0.9.1",
50
- "@zooid/transport-matrix": "^0.9.1"
44
+ "@zooid/acp-client": "^0.11.0",
45
+ "@zooid/context-mcp": "^0.11.0",
46
+ "@zooid/core": "^0.11.0",
47
+ "@zooid/runtime-local": "^0.11.0",
48
+ "@zooid/runtime-docker": "^0.11.0",
49
+ "@zooid/transport-http": "^0.11.0",
50
+ "@zooid/transport-matrix": "^0.11.0"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@agentclientprotocol/sdk": "^0.21.0",
@@ -1,6 +1,11 @@
1
1
  import { describe, it, expect, vi } from 'vitest'
2
2
  import { buildAcpRegistry } from './build-registry.js'
3
3
  import type { ZooidConfig } from '@zooid/core'
4
+ import {
5
+ CONTEXT_CONTAINER_BIN,
6
+ CONTEXT_CONTAINER_BIN_DIR,
7
+ CONTEXT_CONTAINER_SOCK,
8
+ } from '@zooid/context-mcp'
4
9
 
5
10
  const matrixCfg: ZooidConfig = {
6
11
  runtime: 'local',
@@ -59,3 +64,49 @@ describe('buildAcpRegistry — context provider wiring', () => {
59
64
  expect(registry.hasContextSpawn('architect')).toBe(false)
60
65
  })
61
66
  })
67
+
68
+ describe('buildAcpRegistry — context provider in a container runtime', () => {
69
+ function podmanCfg(): ZooidConfig {
70
+ const cfg = structuredClone(matrixCfg)
71
+ cfg.runtime = 'podman'
72
+ // podman requires a resolvable image per agent (no preset here).
73
+ ;(cfg.agents.architect as { container?: unknown }).container = { image: 'img:latest' }
74
+ return cfg
75
+ }
76
+
77
+ const opts = {
78
+ approvals: { register: vi.fn(), on: vi.fn() } as never,
79
+ contextSpawnRegistry: { register: vi.fn(() => 'spawn-1') } as never,
80
+ daemonSockPath: '/home/ubuntu/hq/data/run/context.sock',
81
+ daemonHome: '/home/ubuntu',
82
+ }
83
+
84
+ it('adds the socket (rw) and bin (ro) bind-mounts to a context-enabled agent', () => {
85
+ const registry = buildAcpRegistry(podmanCfg(), opts)
86
+ const mounts = registry.resolveSpawnMounts('architect')
87
+ const sock = mounts.find((m) => m.target === CONTEXT_CONTAINER_SOCK)
88
+ const bin = mounts.find((m) => m.target === CONTEXT_CONTAINER_BIN_DIR)
89
+ expect(sock).toMatchObject({ path: '/home/ubuntu/hq/data/run/context.sock', mode: 'rw' })
90
+ expect(bin?.mode).toBe('ro')
91
+ expect(bin?.path).toMatch(/context-mcp[/\\]dist$/)
92
+ })
93
+
94
+ it('threads a containerized mcpServers spec into the agent factory', async () => {
95
+ const registry = buildAcpRegistry(podmanCfg(), opts)
96
+ // opts is public readonly on the registry; the per-agent factory lives here.
97
+ const factory = registry.opts.contextSpawns!.architect!
98
+ const spec = await factory('!r:hs')
99
+ expect(spec.command).toBe('node')
100
+ expect(spec.args[0]).toBe(CONTEXT_CONTAINER_BIN)
101
+ expect(spec.env).toContainEqual({ name: 'ZOOID_DAEMON_SOCK', value: CONTEXT_CONTAINER_SOCK })
102
+ })
103
+
104
+ it('leaves the local runtime host-shaped (no context mounts, host command)', async () => {
105
+ // matrixCfg is runtime: local. No container mounts; factory stays host-shaped.
106
+ const registry = buildAcpRegistry(matrixCfg, opts)
107
+ const mounts = registry.resolveSpawnMounts('architect')
108
+ expect(mounts.some((m) => m.target === CONTEXT_CONTAINER_SOCK)).toBe(false)
109
+ const spec = await registry.opts.contextSpawns!.architect!('!r:hs')
110
+ expect(spec.command).toBe(process.execPath)
111
+ })
112
+ })
@@ -14,7 +14,7 @@ import {
14
14
  type TransportContextProvider,
15
15
  } from '@zooid/core'
16
16
  import { MatrixClient, MatrixContextProvider } from '@zooid/transport-matrix'
17
- import { SpawnRegistry, buildContextServerSpec } from '@zooid/context-mcp'
17
+ import { SpawnRegistry, buildContextServerSpec, contextContainerMounts } from '@zooid/context-mcp'
18
18
  import { PRESETS, type PresetMount, type PresetName } from '@zooid/acp-client'
19
19
 
20
20
  export interface BuildAcpRegistryOptions {
@@ -271,6 +271,20 @@ export function buildAcpRegistry(
271
271
 
272
272
  const contextSpawns = buildContextSpawns(cfg, opts)
273
273
 
274
+ // Container runtimes: opencode spawns the zooid-context MCP subprocess INSIDE
275
+ // its container, so the daemon socket + the (self-contained) bin must be
276
+ // bind-mounted in. Local runtime needs neither — the host spec resolves
277
+ // directly. Only agents that actually got a context factory get the mounts.
278
+ if (cfg.runtime !== 'local' && opts.daemonSockPath && contextSpawns) {
279
+ for (const name of Object.keys(cfg.agents)) {
280
+ if (!contextSpawns[name]) continue
281
+ mountsByAgent[name] = [
282
+ ...(mountsByAgent[name] ?? []),
283
+ ...contextContainerMounts({ sockPath: opts.daemonSockPath }),
284
+ ]
285
+ }
286
+ }
287
+
274
288
  return new AcpAgentRegistry({
275
289
  runtime,
276
290
  agents: cfg.agents,
@@ -322,7 +336,11 @@ function buildContextSpawns(
322
336
  threadRef: { channelId: channelId ?? threadId, threadId },
323
337
  provider,
324
338
  })
325
- return buildContextServerSpec({ spawnId, sockPath })
339
+ return buildContextServerSpec({
340
+ spawnId,
341
+ sockPath,
342
+ containerize: cfg.runtime !== 'local',
343
+ })
326
344
  }
327
345
  } else {
328
346
  result[name] = undefined