zooid 0.8.0 → 0.9.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/README.md +5 -5
- package/dist/bin.js +16 -17
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-R6EDLH23.js → chunk-LOILUENL.js} +130 -52
- package/dist/{chunk-R6EDLH23.js.map → chunk-LOILUENL.js.map} +1 -1
- package/dist/index.js +1 -1
- package/package.json +10 -10
- package/src/bin.ts +1 -1
- package/src/commands/dev.ts +8 -8
- package/src/daemon/start-daemon.ts +9 -9
- package/src/web/fetch.integration.test.ts +4 -4
- package/src/web/fetch.test.ts +4 -4
- package/src/web/fetch.ts +2 -2
- package/src/web/pin.test.ts +2 -2
- package/src/web/pin.ts +2 -2
- package/src/web/resolve.test.ts +3 -3
- package/src/web/resolve.ts +3 -3
- package/src/web/test-helpers.ts +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# 🪸 Zooid
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> A chat app to collaborate with AI agents, alongside the rest of your team. Open-source, self-hostable, any model, any CLI.
|
|
4
4
|
|
|
5
|
-
Zooid is an open-source
|
|
5
|
+
Zooid is an open-source, self-hostable chat app for collaborating with AI agents alongside your team. It brings [ACP](https://agentclientprotocol.com)-compatible agents (Claude Code, [opencode](https://opencode.ai), Codex, …) into [Matrix](https://matrix.org) rooms as first-class participants — people and agents in the same rooms, threads, and approvals, no separate "AI dashboard," no vendor lock-in. Deploy with `zooid init`, run with `zooid dev`.
|
|
6
6
|
|
|
7
|
-
**Full docs: [zooid.dev/docs](https://zooid.dev/docs)**
|
|
7
|
+
**Full docs: [zooid.dev/docs](https://zooid.dev/docs)** · **Join the community server: [community.zoon.eco](https://community.zoon.eco)**
|
|
8
8
|
|
|
9
9
|
- **Protocol-first.** Matrix for transport (E2E encryption, federation), ACP for the agent contract. Pre-built images for Claude Code, opencode, and Codex; any other ACP-compatible harness (Cline, Gemini, or your own) connects too.
|
|
10
10
|
- **Containerized runtime.** Podman or Docker. Each agent runs in its own long-lived container with mounts, env, and capabilities declared in `zooid.yaml`.
|
|
@@ -34,7 +34,7 @@ Boot the local stack:
|
|
|
34
34
|
zooid dev
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
`zooid dev` starts a Tuwunel Matrix homeserver in a container, generates the Application Service registration, registers an `admin:admin` user, runs the daemon, and serves the [
|
|
37
|
+
`zooid dev` starts a Tuwunel Matrix homeserver in a container, generates the Application Service registration, registers an `admin:admin` user, runs the daemon, and serves the [Zooid web client](https://github.com/zooid-ai/clients).
|
|
38
38
|
|
|
39
39
|
Open `http://localhost:5173`, log in as `admin` / `admin`, join `#welcome`, and `@`-mention your agent.
|
|
40
40
|
|
|
@@ -48,7 +48,7 @@ Every layer is open and replaceable.
|
|
|
48
48
|
| -------- | --------- | ------------- | --------------------------------------------- |
|
|
49
49
|
| Protocol | Matrix | Open standard | Adopted by Germany, France, Switzerland, NATO |
|
|
50
50
|
| Server | Tuwunel | Apache-2.0 | Swiss government in production |
|
|
51
|
-
| Client |
|
|
51
|
+
| Client | Zooid web | Apache-2.0 | Built on `matrix-js-sdk` |
|
|
52
52
|
| Runtime | **Zooid** | MIT | This project |
|
|
53
53
|
|
|
54
54
|
## Agent images
|
package/dist/bin.js
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
renderRegistration,
|
|
17
17
|
startDaemonSocketServer,
|
|
18
18
|
startWorkforcePublisher
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-LOILUENL.js";
|
|
20
20
|
|
|
21
21
|
// src/bin.ts
|
|
22
22
|
import { resolve as resolve6 } from "path";
|
|
@@ -559,6 +559,8 @@ async function startDaemon(opts = {}) {
|
|
|
559
559
|
binding.agentWorkspacePath = isContainerRuntime ? "/workspace" : workspaceDir;
|
|
560
560
|
bindings.push(binding);
|
|
561
561
|
}
|
|
562
|
+
const serverName = matrix.transport.user_namespace.split(":").slice(1).join(":").replace(/\\?\)?$/, "") || new URL(matrix.transport.homeserver).hostname;
|
|
563
|
+
const asUserId = `@${matrix.transport.sender_localpart}:${serverName}`;
|
|
562
564
|
const transport = createMatrixTransport({
|
|
563
565
|
agents: registry,
|
|
564
566
|
approvals,
|
|
@@ -566,13 +568,12 @@ async function startDaemon(opts = {}) {
|
|
|
566
568
|
bindings,
|
|
567
569
|
hsToken: matrix.transport.hs_token,
|
|
568
570
|
adminUserId: opts.adminUserId,
|
|
571
|
+
botUserId: asUserId,
|
|
569
572
|
media: mediaClient
|
|
570
573
|
});
|
|
571
574
|
const requestedPort = matrix.transport.port ?? 9e3;
|
|
572
575
|
server = serve({ fetch: transport.app.fetch, port: requestedPort, hostname: "0.0.0.0" });
|
|
573
576
|
port = await listenAsync(server);
|
|
574
|
-
const serverName = matrix.transport.user_namespace.split(":").slice(1).join(":").replace(/\\?\)?$/, "") || new URL(matrix.transport.homeserver).hostname;
|
|
575
|
-
const asUserId = `@${matrix.transport.sender_localpart}:${serverName}`;
|
|
576
577
|
const spaceLocalpart = matrix.transport.space ?? "dev";
|
|
577
578
|
const adminUserIds = opts.adminUserId ? [opts.adminUserId] : [];
|
|
578
579
|
let spaceRoomId;
|
|
@@ -611,7 +612,7 @@ async function startDaemon(opts = {}) {
|
|
|
611
612
|
asUserId,
|
|
612
613
|
getAgents: () => bindings
|
|
613
614
|
});
|
|
614
|
-
console.log(`[matrix] published
|
|
615
|
+
console.log(`[matrix] published dev.zooid.workforce (${bindings.length} agents)`);
|
|
615
616
|
void publisher;
|
|
616
617
|
} catch (err) {
|
|
617
618
|
console.warn("[matrix] workforce roster publication failed:", err);
|
|
@@ -689,7 +690,6 @@ var TuwunelService = class {
|
|
|
689
690
|
constructor(opts) {
|
|
690
691
|
this.opts = opts;
|
|
691
692
|
}
|
|
692
|
-
opts;
|
|
693
693
|
child = null;
|
|
694
694
|
start() {
|
|
695
695
|
this.child = spawn(this.opts.engine, buildRunArgs(this.opts), {
|
|
@@ -780,7 +780,7 @@ import { mkdirSync as mkdirSync3, renameSync, rmSync, existsSync as existsSync2,
|
|
|
780
780
|
import { join as join4 } from "path";
|
|
781
781
|
import { createHash, randomUUID as randomUUID2 } from "crypto";
|
|
782
782
|
import * as tar from "tar";
|
|
783
|
-
var PKG = "@zooid/
|
|
783
|
+
var PKG = "@zooid/web";
|
|
784
784
|
var DEFAULT_REGISTRY = "https://registry.npmjs.org";
|
|
785
785
|
async function fetchWebBundle(opts) {
|
|
786
786
|
const target = join4(opts.cacheDir, opts.version);
|
|
@@ -852,11 +852,11 @@ async function ensureWebRoot(opts) {
|
|
|
852
852
|
}
|
|
853
853
|
if (!opts.version) {
|
|
854
854
|
throw new Error(
|
|
855
|
-
`No @zooid/
|
|
855
|
+
`No @zooid/web version pin (zooid.webVersion) in the cli package.json and no monorepo sibling build found.
|
|
856
856
|
Set ${ENV_OVERRIDE} to a built dist, or run from the monorepo.`
|
|
857
857
|
);
|
|
858
858
|
}
|
|
859
|
-
opts.onProgress?.(`Fetching @zooid/
|
|
859
|
+
opts.onProgress?.(`Fetching @zooid/web ${opts.version}\u2026`);
|
|
860
860
|
const fetchBundleFn = opts.fetchBundle ?? fetchWebBundle;
|
|
861
861
|
return fetchBundleFn({ version: opts.version, cacheDir: opts.cacheDir });
|
|
862
862
|
}
|
|
@@ -872,7 +872,7 @@ import { join as join6 } from "path";
|
|
|
872
872
|
function readZoonWebPin(cliRoot) {
|
|
873
873
|
try {
|
|
874
874
|
const pkg = JSON.parse(readFileSync3(join6(cliRoot, "package.json"), "utf8"));
|
|
875
|
-
return pkg.zooid?.
|
|
875
|
+
return pkg.zooid?.webVersion;
|
|
876
876
|
} catch {
|
|
877
877
|
return void 0;
|
|
878
878
|
}
|
|
@@ -1081,7 +1081,6 @@ var JsonlSink = class {
|
|
|
1081
1081
|
this.stream = createWriteStream(this.path, { flags: "a" });
|
|
1082
1082
|
})();
|
|
1083
1083
|
}
|
|
1084
|
-
path;
|
|
1085
1084
|
stream = null;
|
|
1086
1085
|
maxStringLen;
|
|
1087
1086
|
readyPromise;
|
|
@@ -1327,14 +1326,14 @@ async function runDev(flags) {
|
|
|
1327
1326
|
},
|
|
1328
1327
|
...flags.watchWeb ? [
|
|
1329
1328
|
{
|
|
1330
|
-
title: "Start @zooid/
|
|
1329
|
+
title: "Start @zooid/web watcher (vite build --watch)",
|
|
1331
1330
|
task: async () => {
|
|
1332
1331
|
const pkgDir = typeof flags.watchWeb === "string" ? resolve3(flags.watchWeb) : webSourcePackage(CLI_ROOT);
|
|
1333
1332
|
if (!pkgDir) {
|
|
1334
|
-
const defaultPath = dirname6(dirname6(dirname6(CLI_ROOT))) + "/
|
|
1333
|
+
const defaultPath = dirname6(dirname6(dirname6(CLI_ROOT))) + "/zooid-clients/packages/web";
|
|
1335
1334
|
throw new Error(
|
|
1336
|
-
`--watch-web: @zooid/
|
|
1337
|
-
Pass an explicit path: --watch-web=/path/to/
|
|
1335
|
+
`--watch-web: @zooid/web not found at ${defaultPath}.
|
|
1336
|
+
Pass an explicit path: --watch-web=/path/to/zooid-clients/packages/web`
|
|
1338
1337
|
);
|
|
1339
1338
|
}
|
|
1340
1339
|
ctx.webWatch = await startWebWatch({ webPackageDir: pkgDir });
|
|
@@ -1342,7 +1341,7 @@ Pass an explicit path: --watch-web=/path/to/zoon/packages/web`
|
|
|
1342
1341
|
}
|
|
1343
1342
|
] : [],
|
|
1344
1343
|
{
|
|
1345
|
-
title: `Serve @zooid/
|
|
1344
|
+
title: `Serve @zooid/web on http://localhost:${flags.uiPort}`,
|
|
1346
1345
|
task: async (_, t) => {
|
|
1347
1346
|
const webRoot = ctx.webWatch?.distPath ?? await ensureWebRoot({
|
|
1348
1347
|
cliRoot: CLI_ROOT,
|
|
@@ -1400,7 +1399,7 @@ Pass an explicit path: --watch-web=/path/to/zoon/packages/web`
|
|
|
1400
1399
|
chalk.bold("UI: ") + ` http://localhost:${flags.uiPort}`,
|
|
1401
1400
|
` ${chalk.cyan("admin user:")} ${flags.adminUser} / ${flags.adminPassword}`,
|
|
1402
1401
|
` ${chalk.cyan("data dir:")} ${layout.dataRoot}`,
|
|
1403
|
-
...ctx.webWatch ? [` ${chalk.cyan("web watcher:")} live (vite build --watch on @zooid/
|
|
1402
|
+
...ctx.webWatch ? [` ${chalk.cyan("web watcher:")} live (vite build --watch on @zooid/web)`] : [],
|
|
1404
1403
|
"",
|
|
1405
1404
|
chalk.dim("Press Ctrl-C to stop."),
|
|
1406
1405
|
""
|
|
@@ -1992,7 +1991,7 @@ cli.command("start", "Run the daemon (production entry-point)").option("--data <
|
|
|
1992
1991
|
});
|
|
1993
1992
|
cli.command("dev", "Tuwunel + daemon + UI for local development").option("--data <dir>", "Persistent data root dir", { default: "./data" }).option("--engine <docker|podman>", "Container engine", { default: "docker" }).option("--ui-port <n>", "UI HTTP port", { default: 5173 }).option("--admin-user <name>", "Admin username", { default: "admin" }).option("--admin-password <pw>", "Admin password", { default: "admin" }).option(
|
|
1994
1993
|
"--watch-web [path]",
|
|
1995
|
-
"Run vite build --watch on @zooid/
|
|
1994
|
+
"Run vite build --watch on @zooid/web. Path defaults to sibling ../zooid-clients/packages/web."
|
|
1996
1995
|
).action(async (flags) => {
|
|
1997
1996
|
await runDev({
|
|
1998
1997
|
dataDir: flags.data,
|