@dispatch-foo/protocol 0.0.0 → 0.2.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.
@@ -0,0 +1,388 @@
1
+ import { d as REF_TYPES, n as BUILT_IN_KINDS, r as DELIVERY_STATES } from "./constants-CUM7Sm5u.js";
2
+
3
+ //#region src/address.d.ts
4
+ type Address = string;
5
+ type ParsedAddress = {
6
+ kind: 'human';
7
+ handle: string;
8
+ address: Address;
9
+ } | {
10
+ kind: 'agent';
11
+ handle: string;
12
+ operator: string | null;
13
+ address: Address;
14
+ } | {
15
+ kind: 'task';
16
+ id: string;
17
+ address: Address;
18
+ } | {
19
+ kind: 'run';
20
+ id: string;
21
+ address: Address;
22
+ } | {
23
+ kind: 'channel';
24
+ name: string;
25
+ address: Address;
26
+ } | {
27
+ kind: 'a2a';
28
+ alias: string;
29
+ address: Address;
30
+ };
31
+ /** An outbound A2A peer's alias: the handle grammar, at most 40 characters. */
32
+ declare const PEER_ALIAS_PATTERN: RegExp;
33
+ declare function parseAddress(raw: string, field?: string): ParsedAddress;
34
+ /** An outbound A2A peer (`a2a:<alias>`); every message it sends is recorded by the daemon. */
35
+ declare function isPeerAddress(address: Address): boolean;
36
+ /** True for senders the ping-pong breaker counts: runs, agents and A2A peers, not the system. */
37
+ declare function isAgentAuthored(address: Address): boolean;
38
+ //#endregion
39
+ //#region src/envelope.d.ts
40
+ type JsonValue = null | boolean | number | string | JsonValue[] | {
41
+ [key: string]: JsonValue;
42
+ };
43
+ type BuiltInKind = (typeof BUILT_IN_KINDS)[number];
44
+ type MessageKind = BuiltInKind | `x-${string}`;
45
+ /** A ref type the registry lists; a received ref may carry any other identifier. */
46
+ type RefType = (typeof REF_TYPES)[number];
47
+ interface Ref {
48
+ /** A registered ref type, or any identifier on a ref received from a peer (§4.4). */
49
+ type: RefType | (string & {});
50
+ id: string;
51
+ /** A commit sha for `file` refs; a section anchor for `doc` refs. */
52
+ at?: string;
53
+ }
54
+ interface Message {
55
+ id: string;
56
+ thread: string;
57
+ replyTo: string | null;
58
+ from: Address;
59
+ session?: string;
60
+ to: Address[];
61
+ kind: MessageKind;
62
+ body: string;
63
+ refs: Ref[];
64
+ data?: JsonValue;
65
+ urgent: boolean;
66
+ blocking: boolean;
67
+ choices?: string[];
68
+ choice?: string;
69
+ wake: 'none' | 'request';
70
+ createdAt: string;
71
+ /** The replica that created a remote message; absent when created here. */
72
+ origin?: string;
73
+ /** The origin's hybrid clock at send; threads order by it. */
74
+ hlc?: string;
75
+ }
76
+ interface SendInput {
77
+ to: Address[];
78
+ kind: MessageKind;
79
+ body: string;
80
+ refs?: Ref[];
81
+ data?: JsonValue;
82
+ urgent?: boolean;
83
+ blocking?: boolean;
84
+ choices?: string[];
85
+ choice?: string;
86
+ replyTo?: string | null;
87
+ wake?: 'none' | 'request';
88
+ session?: string;
89
+ /** The sender's own dedupe key; a repeat returns the first message (A2A §3.3.1). */
90
+ idempotencyKey?: string;
91
+ }
92
+ declare const MEMORY_GATE_KINDS: readonly ["preference", "convention", "constraint", "hazard", "decision", "fact", "reference"];
93
+ type GateData = {
94
+ type: 'tool-approval';
95
+ requestId: string;
96
+ runId?: string;
97
+ conversation?: string;
98
+ tool: string;
99
+ input: JsonValue;
100
+ truncated?: true;
101
+ floor: boolean;
102
+ } | {
103
+ type: 'scope';
104
+ paths: string[];
105
+ reason: string;
106
+ } | {
107
+ type: 'wake';
108
+ target: Address;
109
+ message: string;
110
+ } | {
111
+ type: 'agent-registration';
112
+ agent: Address;
113
+ client: string;
114
+ requestedBy?: Address;
115
+ key?: string;
116
+ } | {
117
+ type: 'overseer-action';
118
+ conversation: string;
119
+ actionId: string;
120
+ summary: string;
121
+ } | {
122
+ type: 'memory';
123
+ proposalId: string;
124
+ action: 'add' | 'supersede' | 'retire';
125
+ scope: 'project' | 'team';
126
+ kind: (typeof MEMORY_GATE_KINDS)[number];
127
+ } | {
128
+ type: 'task-proposal';
129
+ task: string;
130
+ proposedBy: Address;
131
+ message: string;
132
+ } | {
133
+ type: 'doc';
134
+ doc: string;
135
+ proposal: string;
136
+ taskId?: string;
137
+ runId?: string;
138
+ };
139
+ /** How validateSendInput judges gates, refs and a missing reply target. */
140
+ interface ValidateOptions {
141
+ /** The gate types the host implements; default every GATE_TYPES entry. */
142
+ gateTypes?: ReadonlySet<string>;
143
+ /** `received` for a message that arrived through a binding: it keeps unknown ref types. */
144
+ origin?: 'local' | 'received';
145
+ /** A federated receive: a reply whose target is not stored skips the checks that need it. */
146
+ parentOptional?: boolean;
147
+ }
148
+ /** The gate payload a message carries, or null when `data` is not a gate. */
149
+ declare function gateOf(message: {
150
+ data?: JsonValue;
151
+ }): GateData | null;
152
+ declare function isSystemMarker(message: Pick<Message, 'from' | 'data' | 'origin'>, type: 'x-closed' | 'x-breaker'): boolean;
153
+ declare function checkIdempotencyKey(key: string): void;
154
+ declare function validateSendInput(input: SendInput, sender: Address, canDecide: boolean, replyTarget: Message | null, options?: ValidateOptions): void;
155
+ //#endregion
156
+ //#region src/store.d.ts
157
+ type DeliveryState = (typeof DELIVERY_STATES)[number];
158
+ type DeliveryVia = 'direct' | 'channel';
159
+ /** How a federated thread settled an answer; superseded and candidate rows are stored as `message`. */
160
+ type SettledAs = 'pending' | 'accepted' | 'superseded' | 'candidate';
161
+ /** A recipient homed on another replica: the furthest state its homes report. */
162
+ type RemoteState = 'forwarded' | 'held' | 'pushed' | 'notified' | 'read' | 'answered' | 'refused';
163
+ declare const REMOTE_STATES: readonly RemoteState[];
164
+ interface RemoteDelivery {
165
+ messageId: string;
166
+ recipient: Address;
167
+ via: DeliveryVia;
168
+ state: RemoteState;
169
+ /** The replicas placement chose for this recipient. */
170
+ homes: string[];
171
+ /** The one home that runs a wake request for a task recipient. */
172
+ wakeAt: string | null;
173
+ refusedBy: string[];
174
+ updatedAt: string;
175
+ }
176
+ /** A question's outcome as its settler recorded it: an answer or a close reason. */
177
+ interface Settlement {
178
+ questionId: string;
179
+ answerId: string | null;
180
+ closedReason: string | null;
181
+ settler: string;
182
+ at: string;
183
+ }
184
+ /** Per-row facts that are not part of the message itself. */
185
+ interface StoredMeta {
186
+ /** Local arrival time of a remote message; quotas count by it. */
187
+ receivedAt?: string;
188
+ settledAs?: SettledAs;
189
+ }
190
+ interface Delivery {
191
+ id: string;
192
+ messageId: string;
193
+ recipient: Address;
194
+ runId: string | null;
195
+ via: DeliveryVia;
196
+ state: DeliveryState;
197
+ updatedAt: string;
198
+ }
199
+ type AgentStatus = 'pending' | 'approved' | 'revoked';
200
+ interface AgentRecord {
201
+ address: Address;
202
+ displayName: string;
203
+ client: string;
204
+ tokenHash: string;
205
+ status: AgentStatus;
206
+ muted: boolean;
207
+ approvedBy: string | null;
208
+ createdAt: string;
209
+ }
210
+ interface ChannelRecord {
211
+ name: string;
212
+ createdAt: string;
213
+ auto: boolean;
214
+ }
215
+ /** One thread's most recent state: its opening message, its latest message
216
+ * (the same one when a thread has only one message), and how many it holds. */
217
+ interface ThreadSummary {
218
+ thread: string;
219
+ root: Message;
220
+ last: Message;
221
+ count: number;
222
+ }
223
+ interface DeliveryFilter {
224
+ recipient?: Address;
225
+ states?: DeliveryState[];
226
+ runId?: string;
227
+ messageId?: string;
228
+ /** Matches recipients starting with this prefix, e.g. `run:`. */
229
+ recipientPrefix?: string;
230
+ }
231
+ interface MessageStore {
232
+ transaction<T>(fn: () => T): T;
233
+ /** `idemKey` is the sender's dedupe key, unique per sender when set. */
234
+ insertMessage(message: Message, idemKey?: string, meta?: StoredMeta): void;
235
+ insertDelivery(delivery: Delivery): void;
236
+ /** Removes one local delivery row; returns whether it existed. */
237
+ deleteDelivery(id: string): boolean;
238
+ getMessage(id: string): Message | null;
239
+ /** The message `from` sent under `key`, or null. */
240
+ byIdemKey(from: Address, key: string): Message | null;
241
+ /** Each given message's dedupe key; keyless and unknown ids are left out. */
242
+ idemKeysFor(messageIds: string[]): Map<string, string>;
243
+ /** What `address` sent at or after `sinceIso`, oldest first, optionally only these kinds. */
244
+ messagesFrom(address: Address, sinceIso: string, kinds?: MessageKind[]): Message[];
245
+ thread(threadId: string): Message[];
246
+ answersTo(messageId: string): Message[];
247
+ openBlocking(): Message[];
248
+ getDelivery(id: string): Delivery | null;
249
+ deliveries(filter: DeliveryFilter): Delivery[];
250
+ /** With `expected`, updates only if the row is still in that state; returns whether it changed. */
251
+ setDelivery(id: string, state: DeliveryState, runId: string | null, at: string, expected?: DeliveryState): boolean;
252
+ markGateApplied(questionId: string, at: string): void;
253
+ /** Turns an answer back into a message and records it voided, which reopens its question. */
254
+ voidAnswer(answerId: string, questionId: string, at: string): boolean;
255
+ /** Answered gate questions (closes excluded) whose host effect is not yet recorded. */
256
+ unappliedAnsweredGates(): {
257
+ question: Message;
258
+ answer: Message;
259
+ }[];
260
+ /** Messages from `from` that arrived at or after `sinceIso`, and not after
261
+ * `untilIso` when given; `origin` narrows to one replica's. */
262
+ countFrom(from: Address, sinceIso: string, urgentOnly: boolean, origin?: string, untilIso?: string): number;
263
+ /** Messages created in [sinceIso, untilIso] with a delivery to `recipient`; the per-peer quota. */
264
+ countDeliveredTo(recipient: Address, sinceIso: string, untilIso?: string): number;
265
+ /** Threads `from` started since `sinceIso` that name an agent, run or task and reach no human. */
266
+ countAgentThreadsFrom(from: Address, sinceIso: string): number;
267
+ /** Agent-authored messages in a thread by arrival; a remote `exclude` still counts. */
268
+ countAgentAuthored(threadId: string, sinceIso: string, exclude: Address): number;
269
+ /** The row's settled state, or null when unset or the message is unknown. */
270
+ settledAs(messageId: string): SettledAs | null;
271
+ /** Rewrites a reply's stored kind and settled state together. */
272
+ setSettled(messageId: string, kind: 'answer' | 'message', settledAs: SettledAs | null): void;
273
+ /** Replies to a question that are or were answers, in arrival order. */
274
+ answerCandidates(questionId: string): {
275
+ message: Message;
276
+ settledAs: SettledAs | null;
277
+ }[];
278
+ /** Adds a remote recipient's row; returns false when one already exists. */
279
+ insertRemote(row: RemoteDelivery): boolean;
280
+ /** Remote recipient rows matching every given field. */
281
+ remoteDeliveries(filter: {
282
+ messageId?: string;
283
+ recipient?: Address;
284
+ states?: RemoteState[];
285
+ }): RemoteDelivery[];
286
+ /** With `expected`, updates only if the row is still in that state; returns whether it changed. */
287
+ setRemote(messageId: string, recipient: Address, patch: {
288
+ state?: RemoteState;
289
+ refusedBy?: string[];
290
+ homes?: string[];
291
+ }, at: string, expected?: RemoteState): boolean;
292
+ /** Removes a remote recipient's row; returns whether it existed. */
293
+ deleteRemote(messageId: string, recipient: Address): boolean;
294
+ /** A question's recorded settlement, or null. */
295
+ settlement(questionId: string): Settlement | null;
296
+ /** Records or replaces a question's settlement. */
297
+ putSettlement(settlement: Settlement): void;
298
+ /** Keeps a settle for a question not stored yet, one per publisher; never read as a settlement. */
299
+ putEarlySettlement(settlement: Settlement): void;
300
+ /** The early settles kept for a question, one per publisher. */
301
+ earlySettlements(questionId: string): Settlement[];
302
+ /** Drops a question's early settles once it has been stored. */
303
+ clearEarlySettlements(questionId: string): void;
304
+ /** Messages created here after `rowid`, oldest first; remote rows are skipped. */
305
+ messagesAfter(rowid: number, limit: number): {
306
+ rowid: number;
307
+ message: Message;
308
+ }[];
309
+ /** The highest message rowid, or 0 for an empty store. */
310
+ maxRowid(): number;
311
+ ensureChannel(name: string, at: string, auto: boolean): void;
312
+ channels(): ChannelRecord[];
313
+ /** Adds a member; false when it was already in the channel. */
314
+ addMember(channel: string, member: Address, at: string): boolean;
315
+ removeMember(channel: string, member: Address): boolean;
316
+ members(channel: string): Address[];
317
+ channelsOf(member: Address): string[];
318
+ putAgent(agent: AgentRecord): void;
319
+ getAgent(address: Address): AgentRecord | null;
320
+ agentByTokenHash(hash: string): AgentRecord | null;
321
+ agents(): AgentRecord[];
322
+ }
323
+ //#endregion
324
+ //#region ../core/dist/untrusted-DJNiucEX.d.ts
325
+
326
+ type DocStatus = 'draft' | 'accepted' | 'archived';
327
+ type RevisionCause = 'create' | 'save' | 'edit' | 'merge' | 'revert' | 'import' | 'restore' | 'proposal' | 'approve' | 'reject' | 'sync';
328
+ type LinkRel = 'spec' | 'plan' | 'context';
329
+ type LinkTargetType = 'task' | 'run' | 'thread' | 'memory' | 'doc';
330
+ interface LinkTarget {
331
+ type: LinkTargetType;
332
+ id: string;
333
+ }
334
+ //#endregion
335
+ //#region src/sqliteDb.d.ts
336
+ /**
337
+ * The slice of a synchronous SQLite driver everything above this module uses.
338
+ *
339
+ * It is declared here rather than imported from either driver so that no other
340
+ * file names `node:sqlite` or `bun:sqlite` — sqliteTaskStore, sqliteRecords and
341
+ * storeBackend all type their handle as `SqliteDatabase` and stay driver-blind.
342
+ */
343
+ type SqlValue = null | number | bigint | string | Uint8Array;
344
+ interface SqliteStatement {
345
+ all(...params: SqlValue[]): unknown[];
346
+ /** The matched row, or `undefined` when the query matched none. */
347
+ get(...params: SqlValue[]): unknown;
348
+ run(...params: SqlValue[]): {
349
+ changes: number | bigint;
350
+ lastInsertRowid: number | bigint;
351
+ };
352
+ }
353
+ interface SqliteDatabase {
354
+ /**
355
+ * Which driver module this handle was actually built from.
356
+ *
357
+ * It earns its place twice. A test can assert what `openDispatchDb` LOADED
358
+ * rather than what `sqliteDriver()` would answer, and those are different
359
+ * claims: the selector returning 'bun:sqlite' proves nothing about the
360
+ * module the loader reached for. And it brands the interface, so a raw
361
+ * `bun:sqlite` Database — which is otherwise structurally identical, but
362
+ * whose `get()` answers a miss with null — can no longer be passed to
363
+ * anything typed `SqliteDatabase`.
364
+ */
365
+ readonly driver: SqliteDriver;
366
+ prepare(sql: string): SqliteStatement;
367
+ exec(sql: string): void;
368
+ close(): void;
369
+ }
370
+ /** The module `openDispatchDb` loads its driver from on the current runtime. */
371
+ type SqliteDriver = 'bun:sqlite' | 'node:sqlite';
372
+ /**
373
+ * Picks a driver by runtime: Bun gets `bun:sqlite`, everything else
374
+ * `node:sqlite`.
375
+ *
376
+ * Bun is not a runtime that happens to also have `node:sqlite` — it only
377
+ * gained that module in 1.4.0, and the shipped `dispatch` CLI, the dispatchd
378
+ * sidecar and the MCP server are single-file binaries compiled with the Bun
379
+ * pinned in `.prototools`. Loading `node:sqlite` under Bun therefore worked on
380
+ * a developer machine with a newer Bun on PATH and threw "No such built-in
381
+ * module: node:sqlite" in every released binary, taking `dispatch migrate` and
382
+ * every database-backed project with it. Keying off `process.versions.bun`
383
+ * rather than off a probe means the choice does not silently drift back the
384
+ * day the pinned Bun is bumped.
385
+ */
386
+ //#endregion
387
+ export { ValidateOptions as A, parseAddress as B, JsonValue as C, Ref as D, MessageKind as E, Address as F, PEER_ALIAS_PATTERN as I, ParsedAddress as L, gateOf as M, isSystemMarker as N, RefType as O, validateSendInput as P, isAgentAuthored as R, GateData as S, Message as T, SettledAs as _, SqliteDatabase as a, ThreadSummary as b, ChannelRecord as c, DeliveryState as d, DeliveryVia as f, RemoteState as g, RemoteDelivery as h, RevisionCause as i, checkIdempotencyKey as j, SendInput as k, Delivery as l, REMOTE_STATES as m, LinkRel as n, AgentRecord as o, MessageStore as p, LinkTarget as r, AgentStatus as s, DocStatus as t, DeliveryFilter as u, Settlement as v, MEMORY_GATE_KINDS as w, BuiltInKind as x, StoredMeta as y, isPeerAddress as z };
388
+ //# sourceMappingURL=untrusted-DJNiucEX-tUd9XZzz.d.ts.map