zooid 0.7.1 → 0.7.2
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/bin.js +19 -4
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-SUPTPSN3.js → chunk-O6E4CDTV.js} +177 -24
- package/dist/chunk-O6E4CDTV.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/web/assets/{index-Cz5fEZBc.js → index-1pU3tgkr.js} +85 -75
- package/dist/web/assets/index-C-ZtBp7U.css +1 -0
- package/dist/web/assets/{index-CqfWXqvO.js → index-CXOPATwH.js} +1 -1
- package/dist/web/assets/{reaction-picker-emoji-cME0vOsX.js → reaction-picker-emoji-DrlHZ5qt.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +8 -8
- package/src/build-registry.context.test.ts +1 -1
- package/src/build-registry.zod043.test.ts +1 -1
- package/src/build-registry.zod044.test.ts +2 -2
- package/src/daemon/start-daemon.ts +17 -2
- package/dist/chunk-SUPTPSN3.js.map +0 -1
- package/dist/web/assets/index-C2MAIew3.css +0 -1
|
@@ -24181,6 +24181,39 @@ function parseTransport(name, raw, processEnv) {
|
|
|
24181
24181
|
}
|
|
24182
24182
|
return { type: "http", port };
|
|
24183
24183
|
}
|
|
24184
|
+
function parseRoomBinding(path, raw, serverName) {
|
|
24185
|
+
function normalizeAlias(alias) {
|
|
24186
|
+
if (alias.length === 0) {
|
|
24187
|
+
throw new Error(`${path}: must be a non-empty alias`);
|
|
24188
|
+
}
|
|
24189
|
+
if (!MATRIX_ROOM_IDENT_RE.test(alias)) {
|
|
24190
|
+
throw new Error(
|
|
24191
|
+
`${path}: must start with '#' or '!' (got ${JSON.stringify(alias)})`
|
|
24192
|
+
);
|
|
24193
|
+
}
|
|
24194
|
+
return alias.includes(":") ? alias : `${alias}:${serverName}`;
|
|
24195
|
+
}
|
|
24196
|
+
if (typeof raw === "string") {
|
|
24197
|
+
return { alias: normalizeAlias(raw) };
|
|
24198
|
+
}
|
|
24199
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
24200
|
+
throw new Error(`${path}: must be a string or { alias, power_level } object`);
|
|
24201
|
+
}
|
|
24202
|
+
const r = raw;
|
|
24203
|
+
if (typeof r.alias !== "string" || r.alias.length === 0) {
|
|
24204
|
+
throw new Error(`${path}.alias: must be a non-empty string`);
|
|
24205
|
+
}
|
|
24206
|
+
const out = { alias: normalizeAlias(r.alias) };
|
|
24207
|
+
if (r.power_level !== void 0) {
|
|
24208
|
+
if (typeof r.power_level !== "number" || !Number.isInteger(r.power_level)) {
|
|
24209
|
+
throw new Error(
|
|
24210
|
+
`${path}.power_level: must be an integer (got ${JSON.stringify(r.power_level)})`
|
|
24211
|
+
);
|
|
24212
|
+
}
|
|
24213
|
+
out.powerLevel = r.power_level;
|
|
24214
|
+
}
|
|
24215
|
+
return out;
|
|
24216
|
+
}
|
|
24184
24217
|
function parseTransportBinding(name, entry, transports) {
|
|
24185
24218
|
const present = TRANSPORT_KINDS.filter(
|
|
24186
24219
|
(k) => entry[k] !== void 0 && entry[k] !== null
|
|
@@ -24250,16 +24283,8 @@ function parseTransportBinding(name, entry, transports) {
|
|
|
24250
24283
|
throw new Error(`agents.${name}.matrix.rooms is required and must be a non-empty array`);
|
|
24251
24284
|
}
|
|
24252
24285
|
const rooms = [];
|
|
24253
|
-
for (
|
|
24254
|
-
|
|
24255
|
-
throw new Error(`agents.${name}.matrix.rooms[] must be a non-empty string`);
|
|
24256
|
-
}
|
|
24257
|
-
if (!MATRIX_ROOM_IDENT_RE.test(r)) {
|
|
24258
|
-
throw new Error(
|
|
24259
|
-
`agents.${name}.matrix.rooms[] must start with '#' or '!' (got ${JSON.stringify(r)})`
|
|
24260
|
-
);
|
|
24261
|
-
}
|
|
24262
|
-
rooms.push(r.includes(":") ? r : `${r}:${serverName}`);
|
|
24286
|
+
for (let i = 0; i < block.rooms.length; i++) {
|
|
24287
|
+
rooms.push(parseRoomBinding(`agents.${name}.matrix.rooms[${i}]`, block.rooms[i], serverName));
|
|
24263
24288
|
}
|
|
24264
24289
|
let displayName;
|
|
24265
24290
|
if (block.display_name !== void 0) {
|
|
@@ -24785,6 +24810,22 @@ var MatrixClient = class {
|
|
|
24785
24810
|
preset: opts.preset ?? "public_chat"
|
|
24786
24811
|
};
|
|
24787
24812
|
if (opts.name !== void 0) body.name = opts.name;
|
|
24813
|
+
if (opts.roomVersion !== void 0) body.room_version = opts.roomVersion;
|
|
24814
|
+
if (opts.restrictedToSpaceId !== void 0) {
|
|
24815
|
+
body.initial_state = [
|
|
24816
|
+
{
|
|
24817
|
+
type: "m.room.join_rules",
|
|
24818
|
+
state_key: "",
|
|
24819
|
+
content: {
|
|
24820
|
+
join_rule: "restricted",
|
|
24821
|
+
allow: [{ type: "m.room_membership", room_id: opts.restrictedToSpaceId }]
|
|
24822
|
+
}
|
|
24823
|
+
}
|
|
24824
|
+
];
|
|
24825
|
+
}
|
|
24826
|
+
if (opts.userPowerLevels && Object.keys(opts.userPowerLevels).length > 0) {
|
|
24827
|
+
body.power_level_content_override = { users: opts.userPowerLevels };
|
|
24828
|
+
}
|
|
24788
24829
|
const r = await this.fetch(
|
|
24789
24830
|
`${this.homeserver}/_matrix/client/v3/createRoom?user_id=${encodeURIComponent(opts.senderUserId)}`,
|
|
24790
24831
|
{
|
|
@@ -24830,6 +24871,30 @@ var MatrixClient = class {
|
|
|
24830
24871
|
if (!r.ok) throw new Error(`sendStateEvent ${opts.eventType} failed: ${r.status}`);
|
|
24831
24872
|
return await r.json();
|
|
24832
24873
|
}
|
|
24874
|
+
/**
|
|
24875
|
+
* Invite a user to a room. Sent as the inviter (`asUserId`) — that user
|
|
24876
|
+
* needs invite power in the room. Tolerates the "already in room /
|
|
24877
|
+
* already invited" responses idempotently so bootstrap can run on a
|
|
24878
|
+
* fresh AND a populated homeserver without branching.
|
|
24879
|
+
*/
|
|
24880
|
+
async invite(opts) {
|
|
24881
|
+
const url2 = `${this.homeserver}/_matrix/client/v3/rooms/${encodeURIComponent(opts.roomId)}/invite?user_id=${encodeURIComponent(opts.asUserId)}`;
|
|
24882
|
+
const r = await this.fetch(url2, {
|
|
24883
|
+
method: "POST",
|
|
24884
|
+
headers: {
|
|
24885
|
+
Authorization: `Bearer ${this.asToken}`,
|
|
24886
|
+
"content-type": "application/json"
|
|
24887
|
+
},
|
|
24888
|
+
body: JSON.stringify({ user_id: opts.targetUserId })
|
|
24889
|
+
});
|
|
24890
|
+
if (r.ok) return;
|
|
24891
|
+
if (r.status === 403) {
|
|
24892
|
+
const body = await r.text();
|
|
24893
|
+
if (/already (in the room|invited|a member|joined)/i.test(body)) return;
|
|
24894
|
+
throw new Error(`invite(${opts.targetUserId}) failed: 403 ${body}`);
|
|
24895
|
+
}
|
|
24896
|
+
throw new Error(`invite(${opts.targetUserId}) failed: ${r.status}`);
|
|
24897
|
+
}
|
|
24833
24898
|
async joinRoom(roomIdOrAlias, asUserId) {
|
|
24834
24899
|
const url2 = `${this.homeserver}/_matrix/client/v3/join/${encodeURIComponent(roomIdOrAlias)}?user_id=${encodeURIComponent(asUserId)}`;
|
|
24835
24900
|
const r = await this.fetch(url2, {
|
|
@@ -25158,7 +25223,7 @@ function route(event, agents, threadStates) {
|
|
|
25158
25223
|
const threadState = threadRoot ? threadStates?.get(threadRoot) : void 0;
|
|
25159
25224
|
for (const a of agents) {
|
|
25160
25225
|
if (event.sender === a.userId) continue;
|
|
25161
|
-
if (!a.rooms.
|
|
25226
|
+
if (!a.rooms.some((r) => r.alias === event.room_id)) continue;
|
|
25162
25227
|
if (a.trigger === "any") {
|
|
25163
25228
|
matches.push(a);
|
|
25164
25229
|
continue;
|
|
@@ -25185,15 +25250,50 @@ async function ensureWorkforceSpace(opts) {
|
|
|
25185
25250
|
const existing = await opts.client.resolveAlias(alias);
|
|
25186
25251
|
if (existing) return existing;
|
|
25187
25252
|
const display = opts.spaceLocalpart.charAt(0).toUpperCase() + opts.spaceLocalpart.slice(1);
|
|
25188
|
-
|
|
25253
|
+
const body = {
|
|
25254
|
+
room_alias_name: opts.spaceLocalpart,
|
|
25255
|
+
name: display,
|
|
25256
|
+
preset: opts.preset,
|
|
25257
|
+
creation_content: { type: "m.space" },
|
|
25258
|
+
// A workspace is joined by invitation, not self-service. Pin the space's
|
|
25259
|
+
// join rule to invite regardless of preset so it can't be walked into
|
|
25260
|
+
// (which would otherwise satisfy every restricted child room's allow).
|
|
25261
|
+
initial_state: [{ type: "m.room.join_rules", state_key: "", content: { join_rule: "invite" } }]
|
|
25262
|
+
};
|
|
25263
|
+
if (opts.admins && opts.admins.length > 0) {
|
|
25264
|
+
body.invite = opts.admins;
|
|
25265
|
+
const users = { [opts.asUserId]: 100 };
|
|
25266
|
+
for (const a of opts.admins) users[a] = 100;
|
|
25267
|
+
body.power_level_content_override = { users };
|
|
25268
|
+
}
|
|
25269
|
+
return opts.client.createRoomRaw({ asUserId: opts.asUserId, body });
|
|
25270
|
+
}
|
|
25271
|
+
async function ensureDefaultChannel(opts) {
|
|
25272
|
+
const localpart2 = opts.channelLocalpart ?? "general";
|
|
25273
|
+
const alias = `#${localpart2}:${opts.serverName}`;
|
|
25274
|
+
const existing = await opts.client.resolveAlias(alias);
|
|
25275
|
+
if (existing) return existing;
|
|
25276
|
+
let userPowerLevels;
|
|
25277
|
+
if (opts.admins && opts.admins.length > 0) {
|
|
25278
|
+
userPowerLevels = { [opts.asUserId]: 100 };
|
|
25279
|
+
for (const a of opts.admins) userPowerLevels[a] = 100;
|
|
25280
|
+
}
|
|
25281
|
+
const roomId = await opts.client.createRoom({
|
|
25282
|
+
roomAliasName: localpart2,
|
|
25283
|
+
invite: [],
|
|
25284
|
+
senderUserId: opts.asUserId,
|
|
25285
|
+
name: localpart2.charAt(0).toUpperCase() + localpart2.slice(1),
|
|
25286
|
+
restrictedToSpaceId: opts.spaceId,
|
|
25287
|
+
...userPowerLevels ? { userPowerLevels } : {}
|
|
25288
|
+
});
|
|
25289
|
+
await opts.client.sendStateEvent({
|
|
25290
|
+
roomId: opts.spaceId,
|
|
25189
25291
|
asUserId: opts.asUserId,
|
|
25190
|
-
|
|
25191
|
-
|
|
25192
|
-
|
|
25193
|
-
preset: opts.preset,
|
|
25194
|
-
creation_content: { type: "m.space" }
|
|
25195
|
-
}
|
|
25292
|
+
eventType: "m.space.child",
|
|
25293
|
+
stateKey: roomId,
|
|
25294
|
+
content: { via: [opts.serverName] }
|
|
25196
25295
|
});
|
|
25296
|
+
return roomId;
|
|
25197
25297
|
}
|
|
25198
25298
|
function serverNameFromMxid(mxid) {
|
|
25199
25299
|
const colon = mxid.indexOf(":");
|
|
@@ -25224,8 +25324,23 @@ var BotPool = class {
|
|
|
25224
25324
|
} catch (err) {
|
|
25225
25325
|
console.warn(`[matrix] setDisplayName(${a.userId}) failed: ${err.message}`);
|
|
25226
25326
|
}
|
|
25327
|
+
if (opts.spaceRoomId && opts.asUserId) {
|
|
25328
|
+
try {
|
|
25329
|
+
await this.client.invite({
|
|
25330
|
+
roomId: opts.spaceRoomId,
|
|
25331
|
+
asUserId: opts.asUserId,
|
|
25332
|
+
targetUserId: a.userId
|
|
25333
|
+
});
|
|
25334
|
+
await this.client.joinRoom(opts.spaceRoomId, a.userId);
|
|
25335
|
+
} catch (err) {
|
|
25336
|
+
console.warn(
|
|
25337
|
+
`[matrix] space membership for ${a.userId} failed: ${err.message}`
|
|
25338
|
+
);
|
|
25339
|
+
}
|
|
25340
|
+
}
|
|
25227
25341
|
for (let i = 0; i < a.rooms.length; i++) {
|
|
25228
|
-
const
|
|
25342
|
+
const binding = a.rooms[i];
|
|
25343
|
+
const room = binding.alias;
|
|
25229
25344
|
try {
|
|
25230
25345
|
let resolved = room;
|
|
25231
25346
|
if (room.startsWith("#")) {
|
|
@@ -25240,17 +25355,25 @@ var BotPool = class {
|
|
|
25240
25355
|
const colon = room.indexOf(":");
|
|
25241
25356
|
const aliasLocalpart = colon > 1 ? room.slice(1, colon) : room.slice(1);
|
|
25242
25357
|
const sender = opts.adminUserId ?? a.userId;
|
|
25358
|
+
const userPowerLevels = buildUserPowerLevels(
|
|
25359
|
+
opts.asUserId,
|
|
25360
|
+
opts.adminUserIds,
|
|
25361
|
+
this.agents,
|
|
25362
|
+
room
|
|
25363
|
+
);
|
|
25243
25364
|
resolved = await this.client.createRoom({
|
|
25244
25365
|
roomAliasName: aliasLocalpart,
|
|
25245
25366
|
invite: opts.adminUserId ? [opts.adminUserId] : [],
|
|
25246
25367
|
senderUserId: sender,
|
|
25247
|
-
name: aliasLocalpart
|
|
25368
|
+
name: aliasLocalpart,
|
|
25369
|
+
...opts.spaceRoomId ? { restrictedToSpaceId: opts.spaceRoomId } : {},
|
|
25370
|
+
...userPowerLevels ? { userPowerLevels } : {}
|
|
25248
25371
|
});
|
|
25249
25372
|
}
|
|
25250
25373
|
aliasToId.set(room, resolved);
|
|
25251
25374
|
}
|
|
25252
25375
|
}
|
|
25253
|
-
|
|
25376
|
+
binding.alias = resolved;
|
|
25254
25377
|
await this.client.joinRoom(resolved, a.userId);
|
|
25255
25378
|
if (opts.spaceRoomId && opts.asUserId && !attachedToSpace.has(resolved)) {
|
|
25256
25379
|
attachedToSpace.add(resolved);
|
|
@@ -25289,6 +25412,18 @@ function localpart(userId) {
|
|
|
25289
25412
|
if (!m) throw new Error(`bad user id: ${userId}`);
|
|
25290
25413
|
return m[1];
|
|
25291
25414
|
}
|
|
25415
|
+
function buildUserPowerLevels(asUserId, admins, agents, roomAlias) {
|
|
25416
|
+
const users = {};
|
|
25417
|
+
if (asUserId) users[asUserId] = 100;
|
|
25418
|
+
if (admins) for (const a of admins) users[a] = 100;
|
|
25419
|
+
for (const a of agents) {
|
|
25420
|
+
for (const r of a.rooms) {
|
|
25421
|
+
if (r.alias !== roomAlias) continue;
|
|
25422
|
+
if (r.powerLevel !== void 0) users[a.userId] = r.powerLevel;
|
|
25423
|
+
}
|
|
25424
|
+
}
|
|
25425
|
+
return Object.keys(users).length > 0 ? users : void 0;
|
|
25426
|
+
}
|
|
25292
25427
|
|
|
25293
25428
|
// ../transport-matrix/src/transport.ts
|
|
25294
25429
|
import { Hono } from "hono";
|
|
@@ -25439,12 +25574,17 @@ function toMatrixHtml(markdown) {
|
|
|
25439
25574
|
// ../transport-matrix/src/transport.ts
|
|
25440
25575
|
var STARTUP_GRACE_MS = 5e3;
|
|
25441
25576
|
var SEEN_EVENT_CAP = 5e3;
|
|
25577
|
+
var DRAIN_QUIET_MS = 300;
|
|
25578
|
+
var DRAIN_MAX_MS = 3e3;
|
|
25579
|
+
var delay = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
25442
25580
|
function inboundThreadRoot2(evt) {
|
|
25443
25581
|
const r = evt.content?.["m.relates_to"];
|
|
25444
25582
|
return r?.rel_type === "m.thread" && r.event_id ? r.event_id : void 0;
|
|
25445
25583
|
}
|
|
25446
25584
|
function createMatrixTransport(opts) {
|
|
25447
25585
|
const { agents, approvals, client, bindings, hsToken, adminUserId } = opts;
|
|
25586
|
+
const drainQuietMs = opts.drainQuietMs ?? DRAIN_QUIET_MS;
|
|
25587
|
+
const drainMaxMs = opts.drainMaxMs ?? DRAIN_MAX_MS;
|
|
25448
25588
|
const pool = new BotPool(client, bindings);
|
|
25449
25589
|
const sessions = /* @__PURE__ */ new Map();
|
|
25450
25590
|
const buffers = /* @__PURE__ */ new Map();
|
|
@@ -25726,6 +25866,14 @@ function createMatrixTransport(opts) {
|
|
|
25726
25866
|
channelId: evt.room_id,
|
|
25727
25867
|
content: [{ type: "text", text: promptText }]
|
|
25728
25868
|
});
|
|
25869
|
+
const drainStart = Date.now();
|
|
25870
|
+
let drained = buffers.get(sessionId) ?? "";
|
|
25871
|
+
while (drainQuietMs > 0 && Date.now() - drainStart < drainMaxMs) {
|
|
25872
|
+
await delay(drainQuietMs);
|
|
25873
|
+
const next = buffers.get(sessionId) ?? "";
|
|
25874
|
+
if (next === drained) break;
|
|
25875
|
+
drained = next;
|
|
25876
|
+
}
|
|
25729
25877
|
const text = buffers.get(sessionId) ?? "";
|
|
25730
25878
|
if (text.length > 0) {
|
|
25731
25879
|
const html = toMatrixHtml(text);
|
|
@@ -25777,7 +25925,7 @@ function createMatrixTransport(opts) {
|
|
|
25777
25925
|
}
|
|
25778
25926
|
async function rebuildThreadState(client, roomId, rootEventId, bindings) {
|
|
25779
25927
|
const state = { participants: [], rootMentions: [] };
|
|
25780
|
-
const asUser = (bindings.find((b) => b.rooms.
|
|
25928
|
+
const asUser = (bindings.find((b) => b.rooms.some((r) => r.alias === roomId)) ?? bindings[0])?.userId;
|
|
25781
25929
|
if (!asUser) return state;
|
|
25782
25930
|
const root = await client.fetchEvent(roomId, rootEventId, asUser);
|
|
25783
25931
|
if (root) {
|
|
@@ -25832,7 +25980,11 @@ function truncate(s, n) {
|
|
|
25832
25980
|
function buildWorkforceRoster(agents) {
|
|
25833
25981
|
return {
|
|
25834
25982
|
version: 1,
|
|
25835
|
-
agents: agents.map((a) => ({
|
|
25983
|
+
agents: agents.map((a) => ({
|
|
25984
|
+
user_id: a.userId,
|
|
25985
|
+
name: a.name,
|
|
25986
|
+
rooms: a.rooms.map((r) => r.alias)
|
|
25987
|
+
}))
|
|
25836
25988
|
};
|
|
25837
25989
|
}
|
|
25838
25990
|
async function publishWorkforce(opts) {
|
|
@@ -31425,10 +31577,11 @@ export {
|
|
|
31425
31577
|
MatrixClient,
|
|
31426
31578
|
renderRegistration,
|
|
31427
31579
|
ensureWorkforceSpace,
|
|
31580
|
+
ensureDefaultChannel,
|
|
31428
31581
|
createMatrixTransport,
|
|
31429
31582
|
startWorkforcePublisher,
|
|
31430
31583
|
SpawnRegistry,
|
|
31431
31584
|
startDaemonSocketServer,
|
|
31432
31585
|
buildAcpRegistry
|
|
31433
31586
|
};
|
|
31434
|
-
//# sourceMappingURL=chunk-
|
|
31587
|
+
//# sourceMappingURL=chunk-O6E4CDTV.js.map
|