agent-comms 8.15.8 → 8.15.10
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/dist/bridges/user/web/server.d.ts.map +1 -1
- package/dist/bridges/user/web/server.js +44 -24
- package/dist/bridges/user/web/server.js.map +1 -1
- package/dist/bridges/user/web/test/web-assets.unit.test.d.ts +5 -0
- package/dist/bridges/user/web/test/web-assets.unit.test.d.ts.map +1 -0
- package/dist/bridges/user/web/test/web-assets.unit.test.js +90 -0
- package/dist/bridges/user/web/test/web-assets.unit.test.js.map +1 -0
- package/dist/bridges/user/web/test/web-server-unbuilt-frontend.integration.test.d.ts +2 -0
- package/dist/bridges/user/web/test/web-server-unbuilt-frontend.integration.test.d.ts.map +1 -0
- package/dist/bridges/user/web/test/web-server-unbuilt-frontend.integration.test.js +75 -0
- package/dist/bridges/user/web/test/web-server-unbuilt-frontend.integration.test.js.map +1 -0
- package/dist/bridges/user/web/web-assets.d.ts +28 -0
- package/dist/bridges/user/web/web-assets.d.ts.map +1 -0
- package/dist/bridges/user/web/web-assets.js +67 -0
- package/dist/bridges/user/web/web-assets.js.map +1 -0
- package/package.json +8 -2
- package/src/account-cli.ts +195 -0
- package/src/account-join-cli.ts +191 -0
- package/src/bridges/cc-peer/approval-commands.ts +82 -0
- package/src/bridges/cc-peer/bridge.ts +138 -0
- package/src/bridges/cc-peer/default-front.ts +58 -0
- package/src/bridges/cc-peer/front-controller.ts +160 -0
- package/src/bridges/cc-peer/front-relay.ts +191 -0
- package/src/bridges/cc-peer/front-runtime.ts +167 -0
- package/src/bridges/cc-peer/front.ts +59 -0
- package/src/bridges/cc-peer/reply-aliases.ts +90 -0
- package/src/bridges/cc-peer/run.ts +100 -0
- package/src/bridges/cc-peer/shared-peer.ts +28 -0
- package/src/bridges/claude-code/channel.ts +318 -0
- package/src/bridges/codex/tool.ts +132 -0
- package/src/bridges/mcp/server.ts +137 -0
- package/src/bridges/opencode/plugin.ts +130 -0
- package/src/bridges/pi/extension.ts +330 -0
- package/src/bridges/registry.ts +17 -0
- package/src/bridges/user/cli.ts +87 -0
- package/src/bridges/user/controller.ts +345 -0
- package/src/bridges/user/tui.ts +300 -0
- package/src/bridges/user/web/actions.ts +173 -0
- package/src/bridges/user/web/contract.ts +222 -0
- package/src/bridges/user/web/dist/bundle.js +49 -0
- package/src/bridges/user/web/dist/icons/icon-192x192.svg +9 -0
- package/src/bridges/user/web/dist/icons/icon-512x512.svg +9 -0
- package/src/bridges/user/web/dist/icons/icon-96x96.svg +9 -0
- package/src/bridges/user/web/dist/index.html +21 -0
- package/src/bridges/user/web/dist/manifest.json +26 -0
- package/src/bridges/user/web/dist/mesh-worker.js +64 -0
- package/src/bridges/user/web/dist/sw.js +1 -0
- package/src/bridges/user/web/event-publisher.ts +114 -0
- package/src/bridges/user/web/port-discovery.ts +49 -0
- package/src/bridges/user/web/reads.ts +35 -0
- package/src/bridges/user/web/router.ts +158 -0
- package/src/bridges/user/web/server.ts +782 -0
- package/src/bridges/user/web/vite.config.ts +71 -0
- package/src/bridges/user/web/web-access.ts +404 -0
- package/src/bridges/user/web/web-assets.ts +90 -0
- package/src/bridges/user/web/web-beacon.ts +69 -0
- package/src/bridges/user/web/web-console-static.ts +90 -0
- package/src/cli-main.ts +635 -0
- package/src/cli.ts +13 -0
- package/src/core/account-bundle.ts +264 -0
- package/src/core/account-join.ts +289 -0
- package/src/core/account-ledger-crypto.ts +154 -0
- package/src/core/account-ledger-store.ts +66 -0
- package/src/core/account-ledger.ts +385 -0
- package/src/core/agent-details.ts +216 -0
- package/src/core/agent-list-format.ts +97 -0
- package/src/core/agent-registry.ts +282 -0
- package/src/core/agent-table.ts +58 -0
- package/src/core/atomic-file.ts +46 -0
- package/src/core/bind-retry.ts +38 -0
- package/src/core/bridge-mesh.ts +176 -0
- package/src/core/bridge.ts +718 -0
- package/src/core/capability-ask.ts +162 -0
- package/src/core/capability-bubble-up.ts +237 -0
- package/src/core/comms-store.ts +130 -0
- package/src/core/connection-approval.ts +134 -0
- package/src/core/connection-code-tool.ts +92 -0
- package/src/core/connection-code.ts +296 -0
- package/src/core/coordinator-role.ts +224 -0
- package/src/core/data-directory.ts +32 -0
- package/src/core/data-frame-routing.ts +309 -0
- package/src/core/default-command.ts +12 -0
- package/src/core/delegation-policy.ts +41 -0
- package/src/core/delivery-engine.ts +649 -0
- package/src/core/device-membership-verification.ts +125 -0
- package/src/core/device-membership.ts +130 -0
- package/src/core/directory-admission.ts +155 -0
- package/src/core/discovery-mdns.ts +247 -0
- package/src/core/discovery-tailscale.ts +224 -0
- package/src/core/discovery.ts +303 -0
- package/src/core/display-name.ts +73 -0
- package/src/core/dm-grant-actions.ts +72 -0
- package/src/core/dm-send-delegation.ts +73 -0
- package/src/core/dm-token-verification.ts +76 -0
- package/src/core/election-sessions.ts +135 -0
- package/src/core/error-reporting.ts +85 -0
- package/src/core/first-contact.ts +242 -0
- package/src/core/gateway-trust-actions.ts +184 -0
- package/src/core/gateway-trust.ts +305 -0
- package/src/core/gossip-directory.ts +276 -0
- package/src/core/gossip-extensions.ts +123 -0
- package/src/core/group-proofs.ts +205 -0
- package/src/core/handshake.ts +354 -0
- package/src/core/hub-forwarding.ts +24 -0
- package/src/core/hub-link.ts +176 -0
- package/src/core/hub-session.ts +374 -0
- package/src/core/identity-store.ts +715 -0
- package/src/core/identity.ts +489 -0
- package/src/core/index.ts +65 -0
- package/src/core/issuer-grouping.ts +165 -0
- package/src/core/issuer-identity-file.ts +187 -0
- package/src/core/lan-web-actions.ts +34 -0
- package/src/core/lan-web-uis.ts +55 -0
- package/src/core/ledger-lock.ts +81 -0
- package/src/core/listener-registry.ts +133 -0
- package/src/core/loopback-address.ts +22 -0
- package/src/core/machine-identity.ts +77 -0
- package/src/core/machine-list-groups.ts +53 -0
- package/src/core/mcp-registry-retry.ts +69 -0
- package/src/core/mcp-registry-version.ts +18 -0
- package/src/core/membership-proof.ts +139 -0
- package/src/core/membership-proofs.ts +149 -0
- package/src/core/mesh-graph-trace-tool.ts +81 -0
- package/src/core/mesh-graph.ts +89 -0
- package/src/core/mesh-network-actions.ts +183 -0
- package/src/core/mesh-store-options.ts +23 -0
- package/src/core/mesh-store-shared.ts +134 -0
- package/src/core/mesh-store.ts +1114 -0
- package/src/core/name-claim.ts +145 -0
- package/src/core/naming-actions.ts +90 -0
- package/src/core/naming.ts +138 -0
- package/src/core/nanoid.ts +20 -0
- package/src/core/network-interfaces.ts +24 -0
- package/src/core/package-version.ts +34 -0
- package/src/core/peer-lifecycle.ts +377 -0
- package/src/core/peer-link-error.ts +41 -0
- package/src/core/peer-versions.ts +98 -0
- package/src/core/pending-connection.ts +53 -0
- package/src/core/petnames.ts +121 -0
- package/src/core/pgp-keyserver.ts +32 -0
- package/src/core/pid-lock-file.ts +122 -0
- package/src/core/push-manager.ts +76 -0
- package/src/core/random-id.ts +9 -0
- package/src/core/receiver-set.ts +42 -0
- package/src/core/relay-role.ts +182 -0
- package/src/core/relay-selection.ts +120 -0
- package/src/core/relay-server.ts +198 -0
- package/src/core/relay-uplink.ts +78 -0
- package/src/core/request-timeouts.ts +37 -0
- package/src/core/room-discovery.ts +48 -0
- package/src/core/room-lifecycle.ts +838 -0
- package/src/core/room-lookup.ts +41 -0
- package/src/core/room-messaging.ts +247 -0
- package/src/core/room-notice-log.ts +61 -0
- package/src/core/room-path.ts +84 -0
- package/src/core/room-protocol.ts +893 -0
- package/src/core/room-router.ts +180 -0
- package/src/core/room-token-verification.ts +85 -0
- package/src/core/room-wire-extensions.ts +60 -0
- package/src/core/self-name-claim.ts +67 -0
- package/src/core/send-outcome.ts +69 -0
- package/src/core/shutdown-signals.ts +57 -0
- package/src/core/stale-agent-checker.ts +108 -0
- package/src/core/store.ts +704 -0
- package/src/core/token-text.ts +40 -0
- package/src/core/tool.ts +853 -0
- package/src/core/transport-events.ts +73 -0
- package/src/core/transport-queries.ts +54 -0
- package/src/core/transport.ts +367 -0
- package/src/core/types.ts +550 -0
- package/src/core/user-identity.ts +290 -0
- package/src/core/vapid.ts +81 -0
- package/src/core/version-check.ts +147 -0
- package/src/core/version-report-actions.ts +79 -0
- package/src/core/web-beacon.ts +31 -0
- package/src/core/web-push.ts +322 -0
- package/src/core/wire-mesh-core-version.ts +25 -0
- package/src/core/wire-mesh-identity.ts +36 -0
- package/src/core/wire-mesh-transport-options.ts +82 -0
- package/src/core/wire-mesh-transport.ts +1007 -0
- package/src/core/wire-protocol.ts +153 -0
- package/src/core/ws-dial.ts +191 -0
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Comms — shared protocol types and Zod schemas.
|
|
3
|
+
*
|
|
4
|
+
* Every type is derived from its Zod schema (single source of truth).
|
|
5
|
+
* Use `Schema.parse(raw)` at JSON boundaries instead of `JSON.parse(raw) as T`.
|
|
6
|
+
* Use `Schema.is(value)` for type narrowing.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Schema-attached type guard helper
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
/** Narrows `value` to a schema already carrying an `is` guard -- used only to recover the type Object.defineProperty's own signature can't express, immediately after defineSchema has just added that exact property below. */
|
|
16
|
+
function hasIsGuard<T extends z.ZodType>(
|
|
17
|
+
value: T,
|
|
18
|
+
): value is T & { is: (v: unknown) => v is z.infer<T> } {
|
|
19
|
+
if (!("is" in value)) return false;
|
|
20
|
+
return typeof value.is === "function";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Attaches a type-guard `.is` method directly onto the given schema (mutating it in place, never copying it) and returns that same reference. Mutation in place is load-bearing: Zod v4 schemas carry their `.parse`/`.safeParse`/internal brand as own instance properties rather than prototype methods, so spreading into a fresh object (`{ ...schema, is }`) silently strips the brand `z.object()` checks for when this schema is nested as another schema's property value -- confirmed directly: a spread-built schema is rejected with "expected a Zod schema" the moment it's used as a nested property. */
|
|
24
|
+
function defineSchema<T extends z.ZodType>(
|
|
25
|
+
schema: T,
|
|
26
|
+
): T & { is: (value: unknown) => value is z.infer<T> } {
|
|
27
|
+
Object.defineProperty(schema, "is", {
|
|
28
|
+
value: (value: unknown): value is z.infer<T> =>
|
|
29
|
+
schema.safeParse(value).success,
|
|
30
|
+
enumerable: true,
|
|
31
|
+
});
|
|
32
|
+
if (!hasIsGuard(schema)) {
|
|
33
|
+
throw new Error("unreachable: is was just defined above");
|
|
34
|
+
}
|
|
35
|
+
return schema;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// Primitives
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
// Agent and Room IDs are plain strings internally.
|
|
43
|
+
// Branded types removed — they caused unused-var warnings since
|
|
44
|
+
// Zod brand schemas are never referenced as values.
|
|
45
|
+
export type AgentId = string;
|
|
46
|
+
export type RoomId = string;
|
|
47
|
+
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// Enums
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
// Each enum's schema is declared under a `Schema` suffix and re-exported under its bare name (matching this file's own object-schema convention) rather than sharing one identifier between the const and the inferred type -- @typescript-eslint/no-redeclare's `ignoreDeclarationMerge` allowlist covers interface/namespace/class/function/enum merges but not a value binding and a type alias sharing a name, so the two need genuinely distinct local identifiers. The re-export alias keeps the public name (and therefore every existing `import { X }` / `import type { X }` call site across the codebase) completely unchanged.
|
|
53
|
+
const MeshVisibilitySchema = defineSchema(
|
|
54
|
+
z.union([z.literal("discoverable"), z.literal("quiet"), z.literal("dark")]),
|
|
55
|
+
);
|
|
56
|
+
export type MeshVisibility = z.infer<typeof MeshVisibilitySchema>;
|
|
57
|
+
export { MeshVisibilitySchema as MeshVisibility };
|
|
58
|
+
|
|
59
|
+
const VisibilitySchema = defineSchema(
|
|
60
|
+
z.union([z.literal("visible"), z.literal("hidden"), z.literal("ghost")]),
|
|
61
|
+
);
|
|
62
|
+
export type Visibility = z.infer<typeof VisibilitySchema>;
|
|
63
|
+
export { VisibilitySchema as Visibility };
|
|
64
|
+
|
|
65
|
+
const AgentStatusSchema = defineSchema(
|
|
66
|
+
z.union([
|
|
67
|
+
z.literal("active"),
|
|
68
|
+
z.literal("idle"),
|
|
69
|
+
z.literal("busy"),
|
|
70
|
+
z.literal("offline"),
|
|
71
|
+
]),
|
|
72
|
+
);
|
|
73
|
+
export type AgentStatus = z.infer<typeof AgentStatusSchema>;
|
|
74
|
+
export { AgentStatusSchema as AgentStatus };
|
|
75
|
+
|
|
76
|
+
const RoomTypeSchema = defineSchema(
|
|
77
|
+
z.union([z.literal("public"), z.literal("private"), z.literal("secret")]),
|
|
78
|
+
);
|
|
79
|
+
export type RoomType = z.infer<typeof RoomTypeSchema>;
|
|
80
|
+
export { RoomTypeSchema as RoomType };
|
|
81
|
+
|
|
82
|
+
const StreamingBehaviorSchema = defineSchema(
|
|
83
|
+
z.union([z.literal("steer"), z.literal("followUp"), z.literal("info")]),
|
|
84
|
+
);
|
|
85
|
+
export type StreamingBehavior = z.infer<typeof StreamingBehaviorSchema>;
|
|
86
|
+
export { StreamingBehaviorSchema as StreamingBehavior };
|
|
87
|
+
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// AgentIdentity
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
|
|
92
|
+
export const AgentIdentitySchema = defineSchema(
|
|
93
|
+
z.object({
|
|
94
|
+
id: z.string(),
|
|
95
|
+
/** Monotonic revision, bumped by the mutating store; sync merges take the higher value. */
|
|
96
|
+
version: z.number(),
|
|
97
|
+
name: z.string(),
|
|
98
|
+
harness: z.string(),
|
|
99
|
+
cwd: z.string(),
|
|
100
|
+
pid: z.number(),
|
|
101
|
+
startedAt: z.string(),
|
|
102
|
+
visibility: VisibilitySchema,
|
|
103
|
+
status: AgentStatusSchema,
|
|
104
|
+
tags: z.array(z.string()),
|
|
105
|
+
subscribedRooms: z.array(z.string()),
|
|
106
|
+
}),
|
|
107
|
+
);
|
|
108
|
+
export type AgentIdentity = z.infer<typeof AgentIdentitySchema>;
|
|
109
|
+
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
// Room
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
|
|
114
|
+
export const RoomSchema = defineSchema(
|
|
115
|
+
z.object({
|
|
116
|
+
id: z.string(),
|
|
117
|
+
/** Monotonic revision, bumped by the mutating store; sync merges take the higher value. */
|
|
118
|
+
version: z.number(),
|
|
119
|
+
name: z.string(),
|
|
120
|
+
type: RoomTypeSchema,
|
|
121
|
+
owner: z.string(),
|
|
122
|
+
createdAt: z.string(),
|
|
123
|
+
description: z.string(),
|
|
124
|
+
members: z.array(z.string()),
|
|
125
|
+
invited: z.array(z.string()),
|
|
126
|
+
/**
|
|
127
|
+
* Per-agent membership operations for convergent merges. An agent is a
|
|
128
|
+
* member (or invited) iff their latest join's room revision strictly
|
|
129
|
+
* exceeds their latest leave's, so a leave at the same revision wins:
|
|
130
|
+
* concurrent kicks and joins converge with the kick honoured, while
|
|
131
|
+
* joins of different agents never interact. `members` and `invited` are
|
|
132
|
+
* derived views, refreshed after every mutation and merge.
|
|
133
|
+
*/
|
|
134
|
+
memberJoins: z.record(z.string(), z.number()),
|
|
135
|
+
memberLeaves: z.record(z.string(), z.number()),
|
|
136
|
+
invitedJoins: z.record(z.string(), z.number()),
|
|
137
|
+
invitedLeaves: z.record(z.string(), z.number()),
|
|
138
|
+
}),
|
|
139
|
+
);
|
|
140
|
+
export type Room = z.infer<typeof RoomSchema>;
|
|
141
|
+
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
// Messages
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
|
|
146
|
+
export const RoomMessageSchema = defineSchema(
|
|
147
|
+
z.object({
|
|
148
|
+
id: z.string(),
|
|
149
|
+
from: z.string(),
|
|
150
|
+
room: z.string(),
|
|
151
|
+
content: z.string(),
|
|
152
|
+
timestamp: z.string(),
|
|
153
|
+
replyTo: z.string().optional(),
|
|
154
|
+
readBy: z.array(z.string()),
|
|
155
|
+
streamingBehavior: StreamingBehaviorSchema.optional(),
|
|
156
|
+
}),
|
|
157
|
+
);
|
|
158
|
+
export type RoomMessage = z.infer<typeof RoomMessageSchema>;
|
|
159
|
+
|
|
160
|
+
export const DmMessageSchema = defineSchema(
|
|
161
|
+
z.object({
|
|
162
|
+
id: z.string(),
|
|
163
|
+
from: z.string(),
|
|
164
|
+
to: z.string(),
|
|
165
|
+
content: z.string(),
|
|
166
|
+
timestamp: z.string(),
|
|
167
|
+
readBy: z.array(z.string()),
|
|
168
|
+
streamingBehavior: StreamingBehaviorSchema.optional(),
|
|
169
|
+
}),
|
|
170
|
+
);
|
|
171
|
+
export type DmMessage = z.infer<typeof DmMessageSchema>;
|
|
172
|
+
|
|
173
|
+
/** Why a directed send did not reach its recipient yet, in a way a later retry may still fix: the request deadline passed with no answer (timeout), no route to the recipient existed when it was attempted (not_connected), or the connection carrying it dropped mid-request (connection_lost). Every other failure is a refusal the recipient will repeat on every retry, so it is never one of these. */
|
|
174
|
+
export const TransientSendFailureSchema = defineSchema(
|
|
175
|
+
z.union([
|
|
176
|
+
z.literal("timeout"),
|
|
177
|
+
z.literal("not_connected"),
|
|
178
|
+
z.literal("connection_lost"),
|
|
179
|
+
]),
|
|
180
|
+
);
|
|
181
|
+
export type TransientSendFailure = z.infer<typeof TransientSendFailureSchema>;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* What has become of one message for one recipient. Discriminated on status rather than carried as flags, so a state that has something to say carries exactly its own reason and no state can be combined with another: a message is delivered, or read, or held for retry, or refused, or gone, never two of those at once.
|
|
185
|
+
*
|
|
186
|
+
* delivered: the recipient's own side accepted the message and answered ok. read: the recipient's bridge consumed it. queued: the first attempt failed transiently and the message is held for retry, undelivered. refused: the recipient answered with a failure a retry cannot fix, naming the wire code it answered with. dropped: the message was evicted from the retry queue to keep it within its bound. expired: the message sat in the retry queue past its maximum age. The last three are terminal -- nothing further will be attempted for that recipient.
|
|
187
|
+
*/
|
|
188
|
+
export const MessageDeliverySchema = defineSchema(
|
|
189
|
+
z.discriminatedUnion("status", [
|
|
190
|
+
z.object({ status: z.literal("delivered") }),
|
|
191
|
+
z.object({ status: z.literal("read") }),
|
|
192
|
+
z.object({
|
|
193
|
+
status: z.literal("queued"),
|
|
194
|
+
reason: TransientSendFailureSchema,
|
|
195
|
+
}),
|
|
196
|
+
z.object({ status: z.literal("refused"), code: z.string() }),
|
|
197
|
+
z.object({ status: z.literal("dropped") }),
|
|
198
|
+
z.object({ status: z.literal("expired") }),
|
|
199
|
+
]),
|
|
200
|
+
);
|
|
201
|
+
export type MessageDelivery = z.infer<typeof MessageDeliverySchema>;
|
|
202
|
+
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
// Delivery events
|
|
205
|
+
// ---------------------------------------------------------------------------
|
|
206
|
+
|
|
207
|
+
export const RoomMemberSchema = defineSchema(
|
|
208
|
+
z.object({
|
|
209
|
+
id: z.string(),
|
|
210
|
+
name: z.string(),
|
|
211
|
+
status: AgentStatusSchema,
|
|
212
|
+
}),
|
|
213
|
+
);
|
|
214
|
+
export type RoomMember = z.infer<typeof RoomMemberSchema>;
|
|
215
|
+
|
|
216
|
+
export const DeliveryEventSchema = defineSchema(
|
|
217
|
+
z.discriminatedUnion("type", [
|
|
218
|
+
z.object({
|
|
219
|
+
type: z.literal("room_message"),
|
|
220
|
+
message: RoomMessageSchema,
|
|
221
|
+
}),
|
|
222
|
+
z.object({
|
|
223
|
+
type: z.literal("dm"),
|
|
224
|
+
message: DmMessageSchema,
|
|
225
|
+
}),
|
|
226
|
+
z.object({
|
|
227
|
+
type: z.literal("room_invite"),
|
|
228
|
+
room: z.string(),
|
|
229
|
+
roomDescription: z.string(),
|
|
230
|
+
from: z.string(),
|
|
231
|
+
fromName: z.string(),
|
|
232
|
+
fromCwd: z.string(),
|
|
233
|
+
}),
|
|
234
|
+
z.object({
|
|
235
|
+
type: z.literal("member_joined"),
|
|
236
|
+
room: z.string(),
|
|
237
|
+
agent: z.string(),
|
|
238
|
+
}),
|
|
239
|
+
z.object({
|
|
240
|
+
type: z.literal("member_left"),
|
|
241
|
+
room: z.string(),
|
|
242
|
+
agent: z.string(),
|
|
243
|
+
}),
|
|
244
|
+
z.object({
|
|
245
|
+
type: z.literal("room_members"),
|
|
246
|
+
room: z.string(),
|
|
247
|
+
members: z.array(RoomMemberSchema),
|
|
248
|
+
}),
|
|
249
|
+
z.object({
|
|
250
|
+
type: z.literal("member_status"),
|
|
251
|
+
room: z.string(),
|
|
252
|
+
agent: z.string(),
|
|
253
|
+
status: AgentStatusSchema,
|
|
254
|
+
}),
|
|
255
|
+
z.object({
|
|
256
|
+
type: z.literal("delivery_status"),
|
|
257
|
+
messageId: z.string(),
|
|
258
|
+
agent: z.string(),
|
|
259
|
+
delivery: MessageDeliverySchema,
|
|
260
|
+
room: z.string().optional(),
|
|
261
|
+
}),
|
|
262
|
+
z.object({
|
|
263
|
+
type: z.literal("invite_declined"),
|
|
264
|
+
room: z.string(),
|
|
265
|
+
agent: z.string(),
|
|
266
|
+
agentName: z.string(),
|
|
267
|
+
reason: z.string(),
|
|
268
|
+
}),
|
|
269
|
+
z.object({
|
|
270
|
+
type: z.literal("name_changed"),
|
|
271
|
+
agent: z.string(),
|
|
272
|
+
oldName: z.string(),
|
|
273
|
+
newName: z.string(),
|
|
274
|
+
}),
|
|
275
|
+
z.object({
|
|
276
|
+
type: z.literal("connection_request"),
|
|
277
|
+
connectionId: z.string(),
|
|
278
|
+
peerId: z.string(),
|
|
279
|
+
dataPort: z.number(),
|
|
280
|
+
name: z.string(),
|
|
281
|
+
fingerprint: z.string(),
|
|
282
|
+
}),
|
|
283
|
+
z.object({
|
|
284
|
+
type: z.literal("room_join_request"),
|
|
285
|
+
room: z.string(),
|
|
286
|
+
requesterId: z.string(),
|
|
287
|
+
}),
|
|
288
|
+
z.object({
|
|
289
|
+
type: z.literal("capability_request"),
|
|
290
|
+
requestId: z.string(),
|
|
291
|
+
capability: z.string(),
|
|
292
|
+
scopeKind: z.string(),
|
|
293
|
+
scopePath: z.string().optional(),
|
|
294
|
+
requesterDevice: z.string(),
|
|
295
|
+
}),
|
|
296
|
+
]),
|
|
297
|
+
);
|
|
298
|
+
export type DeliveryEvent = z.infer<typeof DeliveryEventSchema>;
|
|
299
|
+
|
|
300
|
+
// ---------------------------------------------------------------------------
|
|
301
|
+
// Network interfaces
|
|
302
|
+
// ---------------------------------------------------------------------------
|
|
303
|
+
|
|
304
|
+
export interface NetworkInterface {
|
|
305
|
+
name: string;
|
|
306
|
+
address: string;
|
|
307
|
+
family: "IPv4" | "IPv6";
|
|
308
|
+
internal: boolean;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// ---------------------------------------------------------------------------
|
|
312
|
+
// ConnectionCode
|
|
313
|
+
// ---------------------------------------------------------------------------
|
|
314
|
+
|
|
315
|
+
/** A single-use, short-lived artifact bootstrapping GatewayTrust between two devices that have never established a mesh connection (agent-comms#188): `code`/`expiresAt` answer freshness/liveness and are always checked; `signature` is an optional detached PGP signature (armored) over `${code}:${expiresAt}:${deviceId}`, checked only when present, never required -- a device with no PGP identity still generates and redeems a bare code. */
|
|
316
|
+
export const ConnectionCodeSchema = defineSchema(
|
|
317
|
+
z.object({
|
|
318
|
+
code: z.string(),
|
|
319
|
+
expiresAt: z.string(),
|
|
320
|
+
deviceId: z.string(),
|
|
321
|
+
signature: z.string().optional(),
|
|
322
|
+
}),
|
|
323
|
+
);
|
|
324
|
+
export type ConnectionCode = z.infer<typeof ConnectionCodeSchema>;
|
|
325
|
+
|
|
326
|
+
// ---------------------------------------------------------------------------
|
|
327
|
+
// CommsAction
|
|
328
|
+
// ---------------------------------------------------------------------------
|
|
329
|
+
|
|
330
|
+
export const CommsActionSchema = defineSchema(
|
|
331
|
+
z.discriminatedUnion("action", [
|
|
332
|
+
z.object({
|
|
333
|
+
action: z.literal("register"),
|
|
334
|
+
name: z.string(),
|
|
335
|
+
visibility: VisibilitySchema,
|
|
336
|
+
tags: z.array(z.string()),
|
|
337
|
+
}),
|
|
338
|
+
z.object({
|
|
339
|
+
action: z.literal("update"),
|
|
340
|
+
visibility: VisibilitySchema.optional(),
|
|
341
|
+
status: AgentStatusSchema.optional(),
|
|
342
|
+
name: z.string().optional(),
|
|
343
|
+
tags: z.array(z.string()).optional(),
|
|
344
|
+
}),
|
|
345
|
+
z.object({ action: z.literal("whoami") }),
|
|
346
|
+
z.object({ action: z.literal("web_url") }),
|
|
347
|
+
z.object({
|
|
348
|
+
action: z.literal("create_room"),
|
|
349
|
+
name: z.string(),
|
|
350
|
+
type: RoomTypeSchema,
|
|
351
|
+
description: z.string(),
|
|
352
|
+
}),
|
|
353
|
+
z.object({ action: z.literal("list_rooms") }),
|
|
354
|
+
z.object({
|
|
355
|
+
action: z.literal("join_room"),
|
|
356
|
+
room: z.string(),
|
|
357
|
+
}),
|
|
358
|
+
z.object({
|
|
359
|
+
action: z.literal("leave_room"),
|
|
360
|
+
room: z.string(),
|
|
361
|
+
}),
|
|
362
|
+
z.object({
|
|
363
|
+
action: z.literal("send"),
|
|
364
|
+
target: z.string(),
|
|
365
|
+
content: z.string(),
|
|
366
|
+
replyTo: z.string().optional(),
|
|
367
|
+
streamingBehavior: StreamingBehaviorSchema.optional(),
|
|
368
|
+
}),
|
|
369
|
+
z.object({
|
|
370
|
+
action: z.literal("dm"),
|
|
371
|
+
target: z.string(),
|
|
372
|
+
content: z.string(),
|
|
373
|
+
streamingBehavior: StreamingBehaviorSchema.optional(),
|
|
374
|
+
}),
|
|
375
|
+
z.object({ action: z.literal("list_agents") }),
|
|
376
|
+
z.object({
|
|
377
|
+
action: z.literal("read_room"),
|
|
378
|
+
room: z.string(),
|
|
379
|
+
since: z.string().optional(),
|
|
380
|
+
}),
|
|
381
|
+
z.object({
|
|
382
|
+
action: z.literal("invite"),
|
|
383
|
+
room: z.string(),
|
|
384
|
+
agent: z.string(),
|
|
385
|
+
}),
|
|
386
|
+
z.object({
|
|
387
|
+
action: z.literal("kick"),
|
|
388
|
+
room: z.string(),
|
|
389
|
+
agent: z.string(),
|
|
390
|
+
}),
|
|
391
|
+
z.object({
|
|
392
|
+
action: z.literal("decline_invite"),
|
|
393
|
+
room: z.string(),
|
|
394
|
+
reason: z.string(),
|
|
395
|
+
}),
|
|
396
|
+
z.object({
|
|
397
|
+
action: z.literal("destroy_room"),
|
|
398
|
+
room: z.string(),
|
|
399
|
+
}),
|
|
400
|
+
z.object({
|
|
401
|
+
action: z.literal("mesh_connect"),
|
|
402
|
+
host: z.string(),
|
|
403
|
+
port: z.number(),
|
|
404
|
+
policy: z.string().optional(),
|
|
405
|
+
}),
|
|
406
|
+
z.object({
|
|
407
|
+
action: z.literal("mesh_accept"),
|
|
408
|
+
connectionId: z.string(),
|
|
409
|
+
}),
|
|
410
|
+
z.object({
|
|
411
|
+
action: z.literal("mesh_reject"),
|
|
412
|
+
connectionId: z.string(),
|
|
413
|
+
reason: z.string(),
|
|
414
|
+
}),
|
|
415
|
+
z.object({ action: z.literal("mesh_pending") }),
|
|
416
|
+
z.object({
|
|
417
|
+
action: z.literal("room_accept"),
|
|
418
|
+
room: z.string(),
|
|
419
|
+
requesterId: z.string(),
|
|
420
|
+
}),
|
|
421
|
+
z.object({
|
|
422
|
+
action: z.literal("room_reject"),
|
|
423
|
+
room: z.string(),
|
|
424
|
+
requesterId: z.string(),
|
|
425
|
+
reason: z.string().optional(),
|
|
426
|
+
}),
|
|
427
|
+
z.object({ action: z.literal("room_pending") }),
|
|
428
|
+
z.object({
|
|
429
|
+
action: z.literal("capability_accept"),
|
|
430
|
+
requestId: z.string(),
|
|
431
|
+
expires: z.number(),
|
|
432
|
+
delegationsRemaining: z.number().optional(),
|
|
433
|
+
capability: z.string().optional(),
|
|
434
|
+
}),
|
|
435
|
+
z.object({
|
|
436
|
+
action: z.literal("capability_reject"),
|
|
437
|
+
requestId: z.string(),
|
|
438
|
+
reason: z.string().optional(),
|
|
439
|
+
}),
|
|
440
|
+
z.object({ action: z.literal("capability_pending") }),
|
|
441
|
+
z.object({
|
|
442
|
+
action: z.literal("mesh_discover"),
|
|
443
|
+
method: z.string().optional(),
|
|
444
|
+
}),
|
|
445
|
+
z.object({
|
|
446
|
+
action: z.literal("mesh_advertise"),
|
|
447
|
+
method: z.string(),
|
|
448
|
+
name: z.string(),
|
|
449
|
+
port: z.number().optional(),
|
|
450
|
+
adapter: z.string().optional(),
|
|
451
|
+
}),
|
|
452
|
+
z.object({
|
|
453
|
+
action: z.literal("mesh_unadvertise"),
|
|
454
|
+
id: z.string(),
|
|
455
|
+
}),
|
|
456
|
+
z.object({ action: z.literal("mesh_interfaces") }),
|
|
457
|
+
z.object({ action: z.literal("lan_web_uis") }),
|
|
458
|
+
z.object({
|
|
459
|
+
action: z.literal("mesh_listen"),
|
|
460
|
+
host: z.string(),
|
|
461
|
+
port: z.number().optional(),
|
|
462
|
+
policy: z.string().optional(),
|
|
463
|
+
}),
|
|
464
|
+
z.object({
|
|
465
|
+
action: z.literal("mesh_unlisten"),
|
|
466
|
+
id: z.string(),
|
|
467
|
+
}),
|
|
468
|
+
z.object({ action: z.literal("mesh_listeners") }),
|
|
469
|
+
z.object({
|
|
470
|
+
action: z.literal("mesh_set_visibility"),
|
|
471
|
+
visibility: MeshVisibilitySchema,
|
|
472
|
+
adapter: z.string().optional(),
|
|
473
|
+
}),
|
|
474
|
+
z.object({ action: z.literal("mesh_get_visibility") }),
|
|
475
|
+
z.object({
|
|
476
|
+
action: z.literal("gateway_trust"),
|
|
477
|
+
device: z.string(),
|
|
478
|
+
/** When true, `device` is trusted as a user principal (GatewayTrust.addPrincipal, agent-comms#187) rather than a bare remote device-id (agent-comms#193). Omitted or false keeps the original bare-device behaviour. */
|
|
479
|
+
principal: z.boolean().optional(),
|
|
480
|
+
/** When true, `device` is trusted as a machine (its whoami Machine line, GatewayTrust.addMachine, agent-comms#343): every device that machine vouches for becomes reachable. Cannot be combined with `principal`. */
|
|
481
|
+
machine: z.boolean().optional(),
|
|
482
|
+
}),
|
|
483
|
+
z.object({
|
|
484
|
+
action: z.literal("gateway_untrust"),
|
|
485
|
+
device: z.string(),
|
|
486
|
+
/** When true, `device` is withdrawn from the principal allowlist (GatewayTrust.removePrincipal, agent-comms#187) rather than the bare-device one (agent-comms#193). Omitted or false keeps the original bare-device behaviour. */
|
|
487
|
+
principal: z.boolean().optional(),
|
|
488
|
+
/** When true, `device` is withdrawn from the machine allowlist (GatewayTrust.removeMachine, agent-comms#343), cutting off every device reachable only through that machine in one act. Cannot be combined with `principal`. */
|
|
489
|
+
machine: z.boolean().optional(),
|
|
490
|
+
}),
|
|
491
|
+
z.object({ action: z.literal("gateway_list_trusted") }),
|
|
492
|
+
z.object({
|
|
493
|
+
action: z.literal("petname_set"),
|
|
494
|
+
/** The device-id (hex) being labelled: an agent, a machine, a principal or any other device. */
|
|
495
|
+
device: z.string(),
|
|
496
|
+
/** The viewer's own label for it, kept only in the viewer's storage and never gossiped. */
|
|
497
|
+
name: z.string(),
|
|
498
|
+
}),
|
|
499
|
+
z.object({ action: z.literal("petname_clear"), device: z.string() }),
|
|
500
|
+
z.object({ action: z.literal("petname_list") }),
|
|
501
|
+
z.object({
|
|
502
|
+
action: z.literal("machine_name"),
|
|
503
|
+
/** The name this machine asserts for itself, signed by its machine key into every bridge's advert. Omitted clears it. */
|
|
504
|
+
name: z.string().optional(),
|
|
505
|
+
}),
|
|
506
|
+
z.object({
|
|
507
|
+
action: z.literal("principal_name"),
|
|
508
|
+
/** The name this account (user principal) asserts for itself, signed by its user key into every device's advert. Omitted clears it. */
|
|
509
|
+
name: z.string().optional(),
|
|
510
|
+
}),
|
|
511
|
+
z.object({
|
|
512
|
+
action: z.literal("dm_admit"),
|
|
513
|
+
target: z.string(),
|
|
514
|
+
/** When true, `target` is a user principal (its whoami Principal line) rather than one device: every device of that user can then use the grant. */
|
|
515
|
+
principal: z.boolean().optional(),
|
|
516
|
+
}),
|
|
517
|
+
z.object({
|
|
518
|
+
action: z.literal("dm_use_grant"),
|
|
519
|
+
target: z.string(),
|
|
520
|
+
grant: z.string(),
|
|
521
|
+
}),
|
|
522
|
+
z.object({ action: z.literal("dm_revoke"), target: z.string() }),
|
|
523
|
+
z.object({
|
|
524
|
+
action: z.literal("gateway_generate_connection_code"),
|
|
525
|
+
ttlMs: z.number().optional(),
|
|
526
|
+
privateKey: z.string().optional(),
|
|
527
|
+
passphrase: z.string().optional(),
|
|
528
|
+
}),
|
|
529
|
+
z.object({
|
|
530
|
+
action: z.literal("gateway_redeem_connection_code"),
|
|
531
|
+
code: z.string(),
|
|
532
|
+
expiresAt: z.string(),
|
|
533
|
+
device: z.string(),
|
|
534
|
+
signature: z.string().optional(),
|
|
535
|
+
publicKey: z.string().optional(),
|
|
536
|
+
fingerprint: z.string().optional(),
|
|
537
|
+
}),
|
|
538
|
+
z.object({
|
|
539
|
+
action: z.literal("query_version"),
|
|
540
|
+
device: z.string(),
|
|
541
|
+
}),
|
|
542
|
+
z.object({ action: z.literal("mesh_graph") }),
|
|
543
|
+
z.object({
|
|
544
|
+
action: z.literal("mesh_trace"),
|
|
545
|
+
target: z.string(),
|
|
546
|
+
timeoutMs: z.number().optional(),
|
|
547
|
+
}),
|
|
548
|
+
]),
|
|
549
|
+
);
|
|
550
|
+
export type CommsAction = z.infer<typeof CommsActionSchema>;
|