sessionpipe-core 0.9.0 → 0.10.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/control.js +121 -12
- package/dist/control.js.map +2 -2
- package/dist/index.js +846 -308
- package/dist/index.js.map +4 -4
- package/dist/schema/v1.d.ts +266 -33
- package/dist/schema/v1.d.ts.map +1 -1
- package/dist/schema.js +128 -33
- package/dist/schema.js.map +2 -2
- package/dist/service.js +155 -0
- package/dist/service.js.map +7 -0
- package/dist/src/adapters/acp-control.d.ts +87 -0
- package/dist/src/adapters/acp-control.d.ts.map +1 -0
- package/dist/src/adapters/antigravity-control.d.ts +15 -5
- package/dist/src/adapters/antigravity-control.d.ts.map +1 -1
- package/dist/src/adapters/claude-code-control.d.ts +39 -4
- package/dist/src/adapters/claude-code-control.d.ts.map +1 -1
- package/dist/src/adapters/claude-code.d.ts.map +1 -1
- package/dist/src/adapters/codex-control.d.ts +23 -7
- package/dist/src/adapters/codex-control.d.ts.map +1 -1
- package/dist/src/adapters/codex.d.ts.map +1 -1
- package/dist/src/adapters/headless.d.ts +4 -1
- package/dist/src/adapters/headless.d.ts.map +1 -1
- package/dist/src/adapters/index.d.ts +7 -1
- package/dist/src/adapters/index.d.ts.map +1 -1
- package/dist/src/control/verify.d.ts +72 -16
- package/dist/src/control/verify.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/launched-by.d.ts +12 -0
- package/dist/src/launched-by.d.ts.map +1 -0
- package/dist/src/paths.d.ts +4 -0
- package/dist/src/paths.d.ts.map +1 -1
- package/dist/src/privacy/filter.d.ts.map +1 -1
- package/dist/src/service/index.d.ts +83 -0
- package/dist/src/service/index.d.ts.map +1 -0
- package/dist/src/version.d.ts +39 -0
- package/dist/src/version.d.ts.map +1 -0
- package/dist/version.js +75 -0
- package/dist/version.js.map +7 -0
- package/package.json +9 -1
package/dist/schema.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// sessionpipe-core 0.
|
|
1
|
+
// sessionpipe-core 0.10.0 · Apache-2.0 · https://sessionpipe.org
|
|
2
2
|
|
|
3
3
|
// schema/v1.ts
|
|
4
4
|
import { z } from "zod";
|
|
@@ -84,7 +84,13 @@ var Session = z.object({
|
|
|
84
84
|
url: z.url().max(1024).optional(),
|
|
85
85
|
/** An id, never an email. */
|
|
86
86
|
account_id: z.string().max(128).optional(),
|
|
87
|
-
|
|
87
|
+
/** Whether a person attends the session, in the harness's own word. Absent = unknown, never false. */
|
|
88
|
+
attended: z.boolean().optional(),
|
|
89
|
+
parent_id: SessionId.nullable().optional(),
|
|
90
|
+
/** `<harness>:<id>` of the session that started this one on purpose (a script running
|
|
91
|
+
* `claude -p` for it), from the launcher's environment. Absent for a subagent, whose
|
|
92
|
+
* launcher is its parent, and when nothing says. */
|
|
93
|
+
launched_by: z.string().regex(/^[a-z][a-z0-9-]{0,39}:[A-Za-z0-9._:-]{1,128}$/).optional()
|
|
88
94
|
});
|
|
89
95
|
var Privacy = z.object({
|
|
90
96
|
/** The redaction rulesets that ran; `secrets@1` always above tier 0. */
|
|
@@ -111,13 +117,26 @@ var EventData = z.object({
|
|
|
111
117
|
"session.ended": Loose.extend({ reason: z.enum(["clear", "logout", "exit", "other"]) }),
|
|
112
118
|
"session.backfill": Loose.extend({ started_at: Rfc3339, last_at: Rfc3339, turns: z.int().min(0).optional() }),
|
|
113
119
|
"session.forgotten": Loose,
|
|
114
|
-
"turn.started": Loose.extend({
|
|
120
|
+
"turn.started": Loose.extend({
|
|
121
|
+
turn_id: z.string().max(128).optional(),
|
|
122
|
+
prompt_chars: z.int().min(0).optional(),
|
|
123
|
+
/** The harness's OWN word for who submitted the prompt, forwarded verbatim; not an enum
|
|
124
|
+
* of this spec (Claude Code: user, sdk, system, loop_wakeup, schedule_wakeup,
|
|
125
|
+
* poll_event), and a different vocabulary from session.started.source. A bare word:
|
|
126
|
+
* tier 0 is not redacted, so the shape is the only guard. */
|
|
127
|
+
submitted_by: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9_.-]{0,39}$/, "a bare word, at most 40 characters").optional(),
|
|
128
|
+
/** True when the prompt text is a block the harness wrote rather than words a person
|
|
129
|
+
* typed; never a claim that no person caused the turn. */
|
|
130
|
+
injected: z.boolean().optional()
|
|
131
|
+
}),
|
|
115
132
|
"turn.ended": Loose.extend({
|
|
116
133
|
turn_id: z.string().max(128).optional(),
|
|
117
134
|
reason: z.enum(["stop", "interrupt", "error"]),
|
|
118
135
|
/** The harness's error class when reason is error (rate_limit, overloaded, authentication_failed, server_error …). */
|
|
119
136
|
error: z.string().max(200).optional(),
|
|
120
|
-
ms: z.int().min(0).optional()
|
|
137
|
+
ms: z.int().min(0).optional(),
|
|
138
|
+
/** Background work the harness reports still in flight as the turn ends, each of which wakes the session when it finishes (Claude Code: shell commands, monitors, subagents, workflows). Absent when the harness doesn't say. */
|
|
139
|
+
background: z.int().min(0).optional()
|
|
121
140
|
}),
|
|
122
141
|
"turn.transcript": Loose.extend({
|
|
123
142
|
turn: z.int().min(0),
|
|
@@ -186,7 +205,12 @@ var B64Url = z.string().regex(/^[A-Za-z0-9_-]*$/, "base64url, no padding");
|
|
|
186
205
|
var MachineId = z.string().regex(/^m_[A-Za-z0-9_-]{16,40}$/, "m_ + 16\u201340 base64url");
|
|
187
206
|
var SessionRef = z.string().regex(/^[a-z][a-z0-9-]{0,39}:[A-Za-z0-9._:-]{1,128}$/, "<harness>:<session id>");
|
|
188
207
|
var ControlKind = z.enum(["prompt", "permission.answer", "cancel", "start", "key.add"]);
|
|
208
|
+
var KeyTypes = z.array(z.enum(["passkey", "device"])).min(1).max(2);
|
|
189
209
|
var DeliveryMode = z.enum(["sdk", "waiter", "turn", "api", "resume", "fork"]);
|
|
210
|
+
var StartPermission = z.enum(["read", "safe", "edits", "auto"]);
|
|
211
|
+
var RunLevel = z.enum(["read", "safe", "edits", "auto", "inherit"]);
|
|
212
|
+
var ModelId = z.string().min(1).max(100).regex(/^[A-Za-z0-9][A-Za-z0-9._:/@[\]-]*$/, "a model id");
|
|
213
|
+
var HarnessName = z.string().regex(/^[a-z][a-z0-9-]{0,39}$/);
|
|
190
214
|
var ControlFile = z.object({
|
|
191
215
|
/** Written as is (NFC) into the session's folder: no slash, backslash or control
|
|
192
216
|
* character, not starting with a dot. */
|
|
@@ -215,20 +239,24 @@ var ControlCommand = z.object({
|
|
|
215
239
|
decision: z.enum(["allow", "deny"]).optional(),
|
|
216
240
|
/** Shown to the model beside a decision. */
|
|
217
241
|
note: z.string().max(2e3).optional(),
|
|
218
|
-
/** start: the
|
|
242
|
+
/** start: the folder the new session runs in: absolute, or `~` / `~/…` under the
|
|
243
|
+
* home of the user the machine's daemon runs as, as events write it. */
|
|
219
244
|
cwd: z.string().max(1024).optional(),
|
|
220
|
-
/** key.add (session `sessionpipe:keys`): the new device's passkey
|
|
221
|
-
* trusts once a key it already trusts
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
alg: z.union([z.literal(-7), z.literal(-257)]),
|
|
225
|
-
spki: z.string().regex(/^[A-Za-z0-9_-]{40,2000}$/)
|
|
226
|
-
}).optional(),
|
|
245
|
+
/** key.add (session `sessionpipe:keys`): the new device's key (a passkey or a device
|
|
246
|
+
* key, control-key.json), which the machine trusts once a key it already trusts
|
|
247
|
+
* signed this command. */
|
|
248
|
+
key: z.lazy(() => ControlKey).optional(),
|
|
227
249
|
/** key.add: what the person calls the device. */
|
|
228
250
|
name: z.string().min(1).max(80).optional(),
|
|
229
|
-
/** start
|
|
230
|
-
* before the session starts.
|
|
251
|
+
/** start, prompt: 1–10 files, together at most 50 MiB, downloaded and checked by hash
|
|
252
|
+
* before the session starts or the message is delivered. On a prompt, only to a
|
|
253
|
+
* machine whose hello says `prompt_files`. */
|
|
231
254
|
files: z.array(ControlFile).min(1).max(10).optional(),
|
|
255
|
+
/** start only: the level the new session runs at, at most the machine's mode. Send
|
|
256
|
+
* it only to a machine whose hello advertises it for the harness (`start`). */
|
|
257
|
+
permission: StartPermission.optional(),
|
|
258
|
+
/** start only: the model the harness runs. As `permission`: only when advertised. */
|
|
259
|
+
model: ModelId.optional(),
|
|
232
260
|
/** At least 16 random bytes, base64url. */
|
|
233
261
|
nonce: z.string().regex(/^[A-Za-z0-9_-]{22,64}$/),
|
|
234
262
|
/** Epoch ms, the signing device's clock. */
|
|
@@ -250,11 +278,29 @@ var ControlAssertion = z.object({
|
|
|
250
278
|
cd: B64Url.min(1),
|
|
251
279
|
sig: B64Url.min(1)
|
|
252
280
|
});
|
|
253
|
-
var
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
281
|
+
var ControlDeviceSignature = z.strictObject({
|
|
282
|
+
cred: B64Url.min(1),
|
|
283
|
+
/** 64 bytes r‖s, base64url without padding. */
|
|
284
|
+
sig: B64Url.min(1)
|
|
257
285
|
});
|
|
286
|
+
var ControlKey = z.xor([
|
|
287
|
+
z.strictObject({
|
|
288
|
+
id: B64Url.min(16).max(1400),
|
|
289
|
+
alg: z.union([z.literal(-7), z.literal(-257)]),
|
|
290
|
+
spki: B64Url.min(1)
|
|
291
|
+
}),
|
|
292
|
+
z.strictObject({
|
|
293
|
+
/** SHA-256 of the SPKI bytes, base64url without padding. */
|
|
294
|
+
id: z.string().regex(/^[A-Za-z0-9_-]{43}$/, "SHA-256 of the spki, base64url"),
|
|
295
|
+
alg: z.literal(-7),
|
|
296
|
+
spki: B64Url.min(1),
|
|
297
|
+
type: z.literal("device"),
|
|
298
|
+
/** The private key was made in a hardware key store and never leaves it. */
|
|
299
|
+
store: z.literal("hardware"),
|
|
300
|
+
/** The store will not sign without verifying the person, every time. */
|
|
301
|
+
uv: z.literal("each-use")
|
|
302
|
+
})
|
|
303
|
+
]);
|
|
258
304
|
var ControlMessage = z.object({
|
|
259
305
|
/** The receiver's id for this message; the ack key. Not signed: the nonce inside cmd is. */
|
|
260
306
|
id: Ulid,
|
|
@@ -262,10 +308,14 @@ var ControlMessage = z.object({
|
|
|
262
308
|
cmd: z.string().min(1).max(48e3),
|
|
263
309
|
/** The day key's ECDSA P-256 / SHA-256 signature over cmd: raw r‖s, base64url. */
|
|
264
310
|
csig: B64Url.nullable().optional(),
|
|
265
|
-
/** The grant vouching for the day key: its string plus the passkey's assertion over
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
311
|
+
/** The grant vouching for the day key: its string plus the passkey's assertion over
|
|
312
|
+
* sha256(str), or a device key's signature over it (CONTROL.md §3.2). */
|
|
313
|
+
grant: z.xor([
|
|
314
|
+
ControlAssertion.extend({ str: z.string().min(1).max(2e3) }),
|
|
315
|
+
ControlDeviceSignature.extend({ str: z.string().min(1).max(2e3) })
|
|
316
|
+
]).nullable().optional(),
|
|
317
|
+
/** Instead of csig + grant: one passkey assertion (or device signature) over sha256(cmd). */
|
|
318
|
+
confirm: z.xor([ControlAssertion, ControlDeviceSignature]).nullable().optional(),
|
|
269
319
|
/** The receiver's clock. */
|
|
270
320
|
at: Rfc3339,
|
|
271
321
|
/** After this the machine MUST NOT act and acks `expired`; at most 24 h after `at`. */
|
|
@@ -284,20 +334,27 @@ var ControlAck = z.object({
|
|
|
284
334
|
/** The session that took it, when not the one named (a fork's copy, a started session). */
|
|
285
335
|
session: SessionRef.optional(),
|
|
286
336
|
/** refused: the verifier's code, or the machine's own (`folder`, `no_attention`, `busy`);
|
|
287
|
-
* failed: `file` when a start's attachment couldn't be fetched, checked or written
|
|
337
|
+
* failed: `file` when a start's attachment couldn't be fetched, checked or written,
|
|
338
|
+
* `model` when the harness wouldn't run the start's model. */
|
|
288
339
|
code: z.string().regex(/^[a-z_]{1,40}$/).optional(),
|
|
289
340
|
detail: z.string().max(500).optional(),
|
|
290
341
|
/** resume / fork / start: the agent's reply, redacted by the secrets ruleset. */
|
|
291
342
|
reply: z.string().max(2e4).optional(),
|
|
292
343
|
/** progress only: rises with every progress ack for this id; a receiver keeps the highest. */
|
|
293
|
-
seq: z.int().min(0).optional()
|
|
344
|
+
seq: z.int().min(0).optional(),
|
|
345
|
+
/** taken, delivered of a start: the options it ran with (`model` only when one was
|
|
346
|
+
* asked for). A receiver shows this, never what was asked. */
|
|
347
|
+
applied: z.strictObject({ permission: RunLevel.optional(), model: ModelId.optional() }).optional()
|
|
294
348
|
})
|
|
295
349
|
).min(1)
|
|
296
350
|
});
|
|
297
351
|
var HarnessAccount = z.object({
|
|
298
352
|
harness: z.string().regex(/^[a-z][a-z0-9-]{0,39}$/),
|
|
299
353
|
id: z.string().min(1).max(128),
|
|
300
|
-
email: z.string().max(254).optional()
|
|
354
|
+
email: z.string().max(254).optional(),
|
|
355
|
+
/** What to call an account that has no email: a Claude Code home that runs on
|
|
356
|
+
* another API is named by its endpoint's host (`api.z.ai`). */
|
|
357
|
+
name: z.string().min(1).max(200).optional()
|
|
301
358
|
});
|
|
302
359
|
var ControlPairStart = z.object({
|
|
303
360
|
/** Open pairing: a random secret only this terminal knows. Status polls present it
|
|
@@ -312,14 +369,18 @@ var ControlPairStart = z.object({
|
|
|
312
369
|
/** The folders the machine lets sessions run in, for the receiver's "new session"
|
|
313
370
|
* picker. Informational: the machine checks its own list again. */
|
|
314
371
|
folders: z.array(z.string().max(1024)).max(50).optional(),
|
|
315
|
-
/** safe: nothing that needs approval runs unattended; auto: the harness's auto mode
|
|
316
|
-
|
|
372
|
+
/** safe: nothing that needs approval runs unattended; auto: the harness's auto mode;
|
|
373
|
+
* inherit: no permission flag, each harness's own default there. Chosen at the machine. */
|
|
374
|
+
mode: z.enum(["safe", "auto", "inherit"]).optional(),
|
|
317
375
|
/** The harness accounts signed in here, so the receiver's board can name each
|
|
318
376
|
* `session.account_id` (CONTROL.md §2). */
|
|
319
377
|
accounts: z.array(HarnessAccount).max(20).optional(),
|
|
320
378
|
/** The machine takes `files` on a start (downloads, checks and writes them). A
|
|
321
379
|
* machine that doesn't say so may ignore them: a receiver SHOULD NOT send it files. */
|
|
322
|
-
files: z.boolean().optional()
|
|
380
|
+
files: z.boolean().optional(),
|
|
381
|
+
/** The kinds of key this machine takes (unique; absent means `["passkey"]`). A
|
|
382
|
+
* client offers a device key only to a machine that lists `device`. */
|
|
383
|
+
key_types: KeyTypes.optional()
|
|
323
384
|
});
|
|
324
385
|
var ControlPairStarted = z.object({
|
|
325
386
|
machine: MachineId,
|
|
@@ -331,8 +392,10 @@ var ControlPairStarted = z.object({
|
|
|
331
392
|
});
|
|
332
393
|
var ControlPaired = z.object({
|
|
333
394
|
status: z.enum(["pending", "paired", "expired"]),
|
|
395
|
+
/** The key approved, whole: a device key keeps its type, store and uv. */
|
|
334
396
|
key: ControlKey.optional(),
|
|
335
|
-
proof:
|
|
397
|
+
/** The key's proof: a passkey assertion, or a device signature for purpose `pair`. */
|
|
398
|
+
proof: z.xor([ControlAssertion, ControlDeviceSignature]).optional(),
|
|
336
399
|
/** The machine's own bearer for polls, acks and hello: opens nothing else. Minted
|
|
337
400
|
* once, at the first pairing of a machine. */
|
|
338
401
|
token: z.string().min(16).max(256).optional(),
|
|
@@ -354,11 +417,32 @@ var ControlHello = z.object({
|
|
|
354
417
|
waiting: z.array(SessionRef).max(500).optional(),
|
|
355
418
|
/** As in control-pair.json: informational, re-checked on the machine. */
|
|
356
419
|
folders: z.array(z.string().max(1024)).max(50).optional(),
|
|
357
|
-
mode: z.enum(["safe", "auto"]).optional(),
|
|
420
|
+
mode: z.enum(["safe", "auto", "inherit"]).optional(),
|
|
358
421
|
/** As in control-pair.json: read again for every hello, so a new sign-in is named. */
|
|
359
422
|
accounts: z.array(HarnessAccount).max(20).optional(),
|
|
360
423
|
/** As in control-pair.json. */
|
|
361
|
-
files: z.boolean().optional()
|
|
424
|
+
files: z.boolean().optional(),
|
|
425
|
+
/** The machine takes `files` on a prompt too (CONTROL.md §6 `prompt`). One that
|
|
426
|
+
* doesn't say so refuses them: a receiver SHOULD NOT send it a prompt with files. */
|
|
427
|
+
prompt_files: z.boolean().optional(),
|
|
428
|
+
/** Per harness in `harnesses`: the options a start may carry (CONTROL.md §2). No
|
|
429
|
+
* entry: neither `permission` nor `model`. */
|
|
430
|
+
start: z.record(
|
|
431
|
+
HarnessName,
|
|
432
|
+
z.object({
|
|
433
|
+
/** The levels it starts at here, already capped by `mode`. */
|
|
434
|
+
permissions: z.array(StartPermission).min(1).max(4).meta({ uniqueItems: true }),
|
|
435
|
+
/** What a start that names none gets: one of `permissions`, or `inherit` on an
|
|
436
|
+
* inherit machine. */
|
|
437
|
+
permission: RunLevel,
|
|
438
|
+
/** Model ids the harness offers here: a suggestion, not a promise. */
|
|
439
|
+
models: z.array(ModelId).max(50).optional(),
|
|
440
|
+
/** Any well-formed model is passed to the harness (which may still reject it). */
|
|
441
|
+
any_model: z.boolean().optional()
|
|
442
|
+
})
|
|
443
|
+
).refine((o) => Object.keys(o).length <= 50, "at most 50 harnesses").meta({ maxProperties: 50 }).optional(),
|
|
444
|
+
/** As in control-pair.json. */
|
|
445
|
+
key_types: KeyTypes.optional()
|
|
362
446
|
});
|
|
363
447
|
var WellKnown = z.object({
|
|
364
448
|
protocol: z.array(z.int().min(1)).min(1),
|
|
@@ -381,11 +465,17 @@ var WellKnown = z.object({
|
|
|
381
465
|
/** How commands are signed: the WebAuthn rp id keys are enrolled for, and the algorithms. */
|
|
382
466
|
signing: z.object({
|
|
383
467
|
rp_id: z.string().min(1).max(253),
|
|
384
|
-
algs: z.array(z.union([z.literal(-7), z.literal(-257)])).min(1)
|
|
468
|
+
algs: z.array(z.union([z.literal(-7), z.literal(-257)])).min(1),
|
|
469
|
+
/** The kinds of key the receiver stores and carries whole (CONTROL.md §2).
|
|
470
|
+
* Absent means `["passkey"]`. */
|
|
471
|
+
key_types: KeyTypes.optional()
|
|
385
472
|
}),
|
|
386
473
|
/** Informational: the receiver accepts `files` on a start and serves
|
|
387
474
|
* `GET {control}/files/{sha256}`. */
|
|
388
|
-
files: z.boolean().optional()
|
|
475
|
+
files: z.boolean().optional(),
|
|
476
|
+
/** The receiver shows a machine in `inherit` mode as that, never as safe or auto.
|
|
477
|
+
* A daemon pairs in, or switches to, `inherit` only with receivers that say so. */
|
|
478
|
+
inherit: z.boolean().optional()
|
|
389
479
|
}).optional()
|
|
390
480
|
});
|
|
391
481
|
var SCHEMAS = {
|
|
@@ -414,6 +504,7 @@ export {
|
|
|
414
504
|
ControlAck,
|
|
415
505
|
ControlAssertion,
|
|
416
506
|
ControlCommand,
|
|
507
|
+
ControlDeviceSignature,
|
|
417
508
|
ControlFile,
|
|
418
509
|
ControlGrant,
|
|
419
510
|
ControlHello,
|
|
@@ -434,14 +525,18 @@ export {
|
|
|
434
525
|
Harness,
|
|
435
526
|
HarnessAccount,
|
|
436
527
|
KNOWN_TYPES,
|
|
528
|
+
KeyTypes,
|
|
437
529
|
MachineId,
|
|
530
|
+
ModelId,
|
|
438
531
|
PROTOCOL,
|
|
439
532
|
Privacy,
|
|
440
533
|
Rfc3339,
|
|
534
|
+
RunLevel,
|
|
441
535
|
SCHEMAS,
|
|
442
536
|
Session,
|
|
443
537
|
SessionId,
|
|
444
538
|
SessionRef,
|
|
539
|
+
StartPermission,
|
|
445
540
|
TYPE_TIER,
|
|
446
541
|
Tier,
|
|
447
542
|
ToolName,
|
package/dist/schema.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../schema/v1.ts"],
|
|
4
|
-
"sourcesContent": ["// SPDX-License-Identifier: Apache-2.0\n// The one source for the protocol's shapes. schemas/v1/*.json are GENERATED from\n// this file (`npm run schemas`); core's runtime types are inferred from it with\n// type-only imports, so zod never enters the zero-dependency bundle. Prose lives in\n// spec/PROTOCOL.md; a rule that is not encoded here is a MUST in words only.\nimport { z } from \"zod\";\n\nexport const PROTOCOL = 1;\n\n/** Dotted, lowercase. Unknown types MUST be accepted and stored. */\nexport const EventType = z\n .string()\n .regex(/^(?:native|[a-z][a-z0-9]*(?:\\.[a-z][a-z0-9_]*)+)$/, \"dotted lowercase type, or native\");\n\nexport const KNOWN_TYPES = [\n \"session.started\",\n \"session.heartbeat\",\n \"session.ended\",\n \"session.backfill\",\n \"session.forgotten\",\n \"turn.started\",\n \"turn.ended\",\n \"turn.transcript\",\n \"turn.progress\",\n \"tool.started\",\n \"tool.ended\",\n \"files.changed\",\n \"attention.needed\",\n \"attention.cleared\",\n \"subagent.started\",\n \"subagent.ended\",\n \"context.compacted\",\n \"native\",\n] as const;\n\n/** The lowest tier that carries each known type. */\nexport const TYPE_TIER: Record<(typeof KNOWN_TYPES)[number], 0 | 1 | 2 | 3> = {\n \"session.started\": 0,\n \"session.heartbeat\": 0,\n \"session.ended\": 0,\n \"session.backfill\": 0,\n \"session.forgotten\": 0,\n \"turn.started\": 0,\n \"turn.ended\": 0,\n \"turn.transcript\": 2,\n \"turn.progress\": 2,\n \"tool.started\": 1,\n \"tool.ended\": 1,\n \"files.changed\": 1,\n \"attention.needed\": 0,\n \"attention.cleared\": 0,\n \"subagent.started\": 1,\n \"subagent.ended\": 1,\n \"context.compacted\": 1,\n native: 3,\n};\n\nexport const HARNESS_NAMES = [\n \"claude-code\",\n \"codex\",\n \"gemini-cli\",\n \"antigravity\",\n \"devin\",\n \"cursor\",\n \"copilot-cli\",\n \"droid\",\n \"kiro\",\n \"opencode\",\n] as const;\n\nexport const Tier = z.int().min(0).max(3);\nexport const Ulid = z.string().regex(/^[0-9A-HJKMNP-TV-Z]{26}$/, \"ULID\");\nexport const Rfc3339 = z.iso.datetime({ offset: false, precision: 3 });\nexport const SessionId = z\n .string()\n .min(1)\n .max(128)\n .regex(/^[A-Za-z0-9._:-]+$/);\nexport const ToolName = z.string().regex(/^[A-Za-z0-9_.:-]{1,120}$/);\n\nexport const Harness = z.object({\n /** From the registry in ADAPTERS.md; a name outside it is allowed ([a-z0-9-]). */\n name: z.string().regex(/^[a-z][a-z0-9-]{0,39}$/),\n version: z.string().max(64).optional(),\n /** The harness's own event name (`PostToolUse`, `agentStop`). */\n event: z.string().max(64).optional(),\n});\n\nexport const Session = z.object({\n id: SessionId,\n /** Monotonic per session per sender; the dedup key with harness.name and id. */\n seq: z.int().min(0),\n machine: z.string().max(80).optional(),\n /** Home is written `~`. */\n cwd: z.string().max(1024).optional(),\n /** A remote URL with credentials stripped. */\n repo: z.string().max(512).optional(),\n branch: z.string().max(256).optional(),\n model: z.string().max(128).optional(),\n title: z.string().max(200).optional(),\n title_source: z.enum([\"custom\", \"harness\", \"first-ask\"]).optional(),\n url: z.url().max(1024).optional(),\n /** An id, never an email. */\n account_id: z.string().max(128).optional(),\n parent_id: SessionId.nullable().optional(),\n});\n\nexport const Privacy = z.object({\n /** The redaction rulesets that ran; `secrets@1` always above tier 0. */\n rulesets: z.array(z.string().regex(/^[a-z][a-z0-9-]*@\\d+$/)),\n pii: z.boolean(),\n});\n\nexport const Event = z.object({\n protocol: z.literal(PROTOCOL),\n id: Ulid,\n type: EventType,\n time: Rfc3339,\n tier: Tier,\n harness: Harness,\n session: Session,\n privacy: Privacy,\n /** Per type (see EventData); extra keys allowed and kept. */\n data: z.record(z.string(), z.unknown()),\n});\n\n// --- data per type --------------------------------------------------------------\n\nconst Loose = z.object({}).loose();\nexport const AttentionKind = z.enum([\"permission\", \"question\", \"elicitation\", \"idle\", \"error\"]);\n\nexport const EventData = z.object({\n \"session.started\": Loose.extend({ source: z.enum([\"startup\", \"resume\", \"clear\", \"compact\", \"fork\", \"unknown\"]) }),\n \"session.heartbeat\": Loose,\n \"session.ended\": Loose.extend({ reason: z.enum([\"clear\", \"logout\", \"exit\", \"other\"]) }),\n \"session.backfill\": Loose.extend({ started_at: Rfc3339, last_at: Rfc3339, turns: z.int().min(0).optional() }),\n \"session.forgotten\": Loose,\n \"turn.started\": Loose.extend({ turn_id: z.string().max(128).optional(), prompt_chars: z.int().min(0).optional() }),\n \"turn.ended\": Loose.extend({\n turn_id: z.string().max(128).optional(),\n reason: z.enum([\"stop\", \"interrupt\", \"error\"]),\n /** The harness's error class when reason is error (rate_limit, overloaded, authentication_failed, server_error \u2026). */\n error: z.string().max(200).optional(),\n ms: z.int().min(0).optional(),\n }),\n \"turn.transcript\": Loose.extend({\n turn: z.int().min(0),\n user: z.string().max(20_000),\n assistant: z.string().max(20_000),\n at: Rfc3339,\n }),\n /** The turn still running: its prompt and what the assistant has said so far. A\n * later turn.progress for the same turn replaces it; the turn.transcript with the\n * same number supersedes it. Over 20 000 chars, the assistant side keeps its END. */\n \"turn.progress\": Loose.extend({\n turn: z.int().min(0),\n user: z.string().max(20_000),\n assistant: z.string().max(20_000),\n at: Rfc3339,\n }),\n \"tool.started\": Loose.extend({\n tool: ToolName,\n call_id: z.string().max(128).optional(),\n turn_id: z.string().max(128).optional(),\n /** Set when a subagent made the call. */\n agent_id: z.string().max(128).optional(),\n input: z.unknown().optional(),\n }),\n \"tool.ended\": Loose.extend({\n tool: ToolName,\n call_id: z.string().max(128).optional(),\n turn_id: z.string().max(128).optional(),\n agent_id: z.string().max(128).optional(),\n ms: z.int().min(0).optional(),\n ok: z.boolean(),\n error: z.string().max(2000).optional(),\n input: z.unknown().optional(),\n output: z.unknown().optional(),\n }),\n \"files.changed\": Loose.extend({ paths: z.array(z.string().max(1024)).max(500) }),\n \"attention.needed\": Loose.extend({\n attention_id: z.string().max(128),\n kind: AttentionKind,\n tool: ToolName.optional(),\n message: z.string().max(200).optional(),\n }),\n \"attention.cleared\": Loose.extend({\n attention_id: z.string().max(128),\n how: z.enum([\"answered\", \"cancelled\", \"timeout\", \"unknown\"]),\n }),\n \"subagent.started\": Loose.extend({ agent_id: z.string().max(128), agent_type: z.string().max(128).optional() }),\n \"subagent.ended\": Loose.extend({ agent_id: z.string().max(128), agent_type: z.string().max(128).optional() }),\n \"context.compacted\": Loose.extend({ trigger: z.enum([\"manual\", \"auto\"]) }),\n native: Loose,\n});\n\n// --- wire -----------------------------------------------------------------------\n\nexport const Batch = z.object({ events: z.array(Event).min(1).max(50) });\n\nexport const BatchResponse = z.object({\n accepted: z.int().min(0),\n duplicates: z.int().min(0),\n rejected: z.array(z.object({ id: Ulid, reason: z.string().max(200) })),\n max_tier: Tier,\n});\n\nexport const ErrorResponse = z.object({\n reason: z.string().max(200),\n supported: z.array(z.int()).optional(),\n max_tier: Tier.optional(),\n});\n\nexport const Capability = z.enum([\"events\", \"backfill\", \"forget\", \"control\", \"native\"]);\n\n// --- control (CONTROL.md) ---------------------------------------------------------\n\nconst B64Url = z.string().regex(/^[A-Za-z0-9_-]*$/, \"base64url, no padding\");\nexport const MachineId = z.string().regex(/^m_[A-Za-z0-9_-]{16,40}$/, \"m_ + 16\u201340 base64url\");\n/** `<harness>:<id>`; the id follows its adapter's rule (Claude Code: a UUID). */\nexport const SessionRef = z.string().regex(/^[a-z][a-z0-9-]{0,39}:[A-Za-z0-9._:-]{1,128}$/, \"<harness>:<session id>\");\nexport const ControlKind = z.enum([\"prompt\", \"permission.answer\", \"cancel\", \"start\", \"key.add\"]);\nexport const DeliveryMode = z.enum([\"sdk\", \"waiter\", \"turn\", \"api\", \"resume\", \"fork\"]);\n\n/** A file attached to a `start` (CONTROL.md \u00A73.1). The bytes wait on the receiver\n * (`GET {control}/files/{sha256}`); the signed hash is what the machine checks.\n * Beyond this shape the verifier also checks: the name's length after NFC, names\n * unique case-insensitively, and the sizes adding up to at most 50 MiB. */\nexport const ControlFile = z.object({\n /** Written as is (NFC) into the session's folder: no slash, backslash or control\n * character, not starting with a dot. */\n name: z\n .string()\n .min(1)\n .max(200)\n .regex(\n // biome-ignore lint/suspicious/noControlCharactersInRegex: control characters are what it rejects\n /^[^./\\\\\\x00-\\x1f\\x7f][^/\\\\\\x00-\\x1f\\x7f]*$/,\n \"a file name: no slash, backslash, control character or leading dot\",\n ),\n /** Media type, `type/subtype` (case-insensitive). */\n type: z\n .string()\n .min(1)\n .max(100)\n .regex(/^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]*\\/[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]*$/, \"type/subtype\"),\n /** Bytes: 1 to 25 MiB. */\n size: z.int().min(1).max(26_214_400),\n /** SHA-256 of the bytes, base64url without padding. */\n sha256: z.string().regex(/^[A-Za-z0-9_-]{43}$/, \"43 base64url characters\"),\n});\n\n/** The signed command, as the device writes it. The machine verifies the EXACT string\n * it received (control.json `cmd`) and never re-serializes it. */\nexport const ControlCommand = z.object({\n v: z.literal(1),\n t: z.literal(\"sessionpipe.control\"),\n machine: MachineId,\n kind: ControlKind,\n session: SessionRef,\n /** prompt, start: the message for the model. */\n text: z.string().min(1).max(20_000).optional(),\n /** permission.answer: the attention_id being answered. */\n for: z.string().min(1).max(128).optional(),\n decision: z.enum([\"allow\", \"deny\"]).optional(),\n /** Shown to the model beside a decision. */\n note: z.string().max(2000).optional(),\n /** start: the absolute folder the new session runs in. */\n cwd: z.string().max(1024).optional(),\n /** key.add (session `sessionpipe:keys`): the new device's passkey, which the machine\n * trusts once a key it already trusts signed this command. */\n key: z\n .object({\n id: z.string().regex(/^[A-Za-z0-9_-]{16,1400}$/),\n alg: z.union([z.literal(-7), z.literal(-257)]),\n spki: z.string().regex(/^[A-Za-z0-9_-]{40,2000}$/),\n })\n .optional(),\n /** key.add: what the person calls the device. */\n name: z.string().min(1).max(80).optional(),\n /** start only: 1\u201310 files, together at most 50 MiB, downloaded and checked by hash\n * before the session starts. */\n files: z.array(ControlFile).min(1).max(10).optional(),\n /** At least 16 random bytes, base64url. */\n nonce: z.string().regex(/^[A-Za-z0-9_-]{22,64}$/),\n /** Epoch ms, the signing device's clock. */\n iat: z.int().min(1),\n});\n\n/** A day grant's signed string: a passkey vouches for a device key for \u2264 24 h. */\nexport const ControlGrant = z.object({\n v: z.literal(1),\n t: z.literal(\"sessionpipe.grant\"),\n /** The day key: P-256 SPKI, base64url. */\n pub: B64Url.min(1),\n iat: z.int().min(1),\n exp: z.int().min(1),\n /** The receiver's WebAuthn rp id (well-known control.signing.rp_id). */\n rp: z.string().min(1).max(253),\n});\n\n/** A WebAuthn assertion: credential id, authenticatorData, clientDataJSON, signature. */\nexport const ControlAssertion = z.object({\n cred: B64Url.min(1),\n ad: B64Url.min(1),\n cd: B64Url.min(1),\n sig: B64Url.min(1),\n});\n\n/** A key enrolled on a machine: a passkey's credential id, COSE alg, SPKI. */\nexport const ControlKey = z.object({\n id: B64Url.min(16).max(1400),\n alg: z.union([z.literal(-7), z.literal(-257)]),\n spki: B64Url.min(1),\n});\n\n/** One message as a receiver carries it: its own envelope around the signed bytes. */\nexport const ControlMessage = z.object({\n /** The receiver's id for this message; the ack key. Not signed: the nonce inside cmd is. */\n id: Ulid,\n /** The command string, exactly as signed (\u2264 48 000 characters). */\n cmd: z.string().min(1).max(48_000),\n /** The day key's ECDSA P-256 / SHA-256 signature over cmd: raw r\u2016s, base64url. */\n csig: B64Url.nullable().optional(),\n /** The grant vouching for the day key: its string plus the passkey's assertion over sha256(str). */\n grant: ControlAssertion.extend({ str: z.string().min(1).max(2000) })\n .nullable()\n .optional(),\n /** Instead of csig + grant: one passkey assertion over sha256(cmd). */\n confirm: ControlAssertion.nullable().optional(),\n /** The receiver's clock. */\n at: Rfc3339,\n /** After this the machine MUST NOT act and acks `expired`; at most 24 h after `at`. */\n expires_at: Rfc3339,\n});\n\nexport const ControlPoll = z.object({ messages: z.array(ControlMessage) });\n\n/** `taken` is the one non-final outcome: the machine verified the message and is\n * delivering it (a headless resume can take minutes); a final ack follows. */\n/** `progress` (not final): the answer so far, whole, in `reply`, with a rising `seq`.\n * `taken` (not final): verified and being delivered. Every other outcome is final. */\nexport const ControlOutcome = z.enum([\"progress\", \"taken\", \"delivered\", \"expired\", \"unsupported\", \"failed\", \"refused\"]);\n\nexport const ControlAck = z.object({\n acks: z\n .array(\n z.object({\n id: Ulid,\n outcome: ControlOutcome,\n at: Rfc3339,\n /** delivered: how it reached the session. */\n mode: DeliveryMode.optional(),\n /** The session that took it, when not the one named (a fork's copy, a started session). */\n session: SessionRef.optional(),\n /** refused: the verifier's code, or the machine's own (`folder`, `no_attention`, `busy`);\n * failed: `file` when a start's attachment couldn't be fetched, checked or written. */\n code: z\n .string()\n .regex(/^[a-z_]{1,40}$/)\n .optional(),\n detail: z.string().max(500).optional(),\n /** resume / fork / start: the agent's reply, redacted by the secrets ruleset. */\n reply: z.string().max(20_000).optional(),\n /** progress only: rises with every progress ack for this id; a receiver keeps the highest. */\n seq: z.int().min(0).optional(),\n }),\n )\n .min(1),\n});\n\n/** A harness account signed in on the machine: the id `session.account_id` carries,\n * and the email it signs in with, so a receiver the person paired with can name the\n * account rather than show an id. Only pair and hello carry it, never an event. */\nexport const HarnessAccount = z.object({\n harness: z.string().regex(/^[a-z][a-z0-9-]{0,39}$/),\n id: z.string().min(1).max(128),\n email: z.string().max(254).optional(),\n});\n\n/** `POST {control}/pair`, sent with the person's sink token from their own terminal \u2014\n * or, where the receiver declares `control.open_pairing`, with no token and a\n * `poll_key` (CONTROL.md \u00A72). */\nexport const ControlPairStart = z.object({\n /** Open pairing: a random secret only this terminal knows. Status polls present it\n * as their bearer; the receiver keeps only a hash. */\n poll_key: z\n .string()\n .regex(/^[A-Za-z0-9_-]{22,128}$/)\n .optional(),\n /** Set when adding a key to a machine already paired. */\n machine: MachineId.optional(),\n name: z.string().min(1).max(80),\n harnesses: z.array(z.string().regex(/^[a-z][a-z0-9-]{0,39}$/)).max(20),\n modes: z.array(DeliveryMode),\n version: z.string().max(40),\n /** The folders the machine lets sessions run in, for the receiver's \"new session\"\n * picker. Informational: the machine checks its own list again. */\n folders: z.array(z.string().max(1024)).max(50).optional(),\n /** safe: nothing that needs approval runs unattended; auto: the harness's auto mode. */\n mode: z.enum([\"safe\", \"auto\"]).optional(),\n /** The harness accounts signed in here, so the receiver's board can name each\n * `session.account_id` (CONTROL.md \u00A72). */\n accounts: z.array(HarnessAccount).max(20).optional(),\n /** The machine takes `files` on a start (downloads, checks and writes them). A\n * machine that doesn't say so may ignore them: a receiver SHOULD NOT send it files. */\n files: z.boolean().optional(),\n});\n\n/** The receiver's answer: where the person confirms, and the digits both screens show. */\nexport const ControlPairStarted = z.object({\n machine: MachineId,\n code: z.string().regex(/^[A-Za-z0-9_-]{6,32}$/),\n url: z.url(),\n /** Six digits the terminal and the receiver's page both show. */\n check: z.string().regex(/^\\d{6}$/),\n expires_at: Rfc3339,\n});\n\n/** `GET {control}/pair?code=\u2026` once the person confirmed. The machine verifies `proof`\n * over sha256(\"sessionpipe.pair:<machine>:<code>\") before it trusts `key`. */\nexport const ControlPaired = z.object({\n status: z.enum([\"pending\", \"paired\", \"expired\"]),\n key: ControlKey.optional(),\n proof: ControlAssertion.optional(),\n /** The machine's own bearer for polls, acks and hello: opens nothing else. Minted\n * once, at the first pairing of a machine. */\n token: z.string().min(16).max(256).optional(),\n /** Optional: a key for the events lane (`sink add`), so the receiver's session board\n * shows this machine without a second step. Handed over once. */\n sink_token: z.string().min(16).max(256).optional(),\n /** Optional: who approved, in the receiver's words (a @handle), so the terminal can\n * say whose passkey it now trusts. */\n account: z.string().max(200).optional(),\n});\n\n/** `POST {control}/hello`: what the machine can do right now. */\nexport const ControlHello = z.object({\n name: z.string().min(1).max(80),\n harnesses: z.array(z.string().regex(/^[a-z][a-z0-9-]{0,39}$/)).max(20),\n modes: z.array(DeliveryMode),\n /** Credential ids of the keys enrolled on the machine. */\n keys: z.array(B64Url.min(16).max(1400)).max(50),\n version: z.string().max(40),\n /** Live sessions with a waiter parked on the daemon's socket. */\n waiting: z.array(SessionRef).max(500).optional(),\n /** As in control-pair.json: informational, re-checked on the machine. */\n folders: z.array(z.string().max(1024)).max(50).optional(),\n mode: z.enum([\"safe\", \"auto\"]).optional(),\n /** As in control-pair.json: read again for every hello, so a new sign-in is named. */\n accounts: z.array(HarnessAccount).max(20).optional(),\n /** As in control-pair.json. */\n files: z.boolean().optional(),\n});\n\nexport const WellKnown = z.object({\n protocol: z.array(z.int().min(1)).min(1),\n max_tier: Tier,\n capabilities: z.array(z.string().regex(/^[a-z][a-z0-9-]*$/)),\n auth: z.array(z.enum([\"bearer\"])).default([\"bearer\"]),\n endpoints: z.object({\n events: z.string(),\n control: z.string().optional(),\n native: z.string().optional(),\n }),\n batch: z.object({ max_events: z.int().min(1).max(50), max_bytes: z.int().min(1024).max(262_144) }),\n control: z\n .object({\n wait_max_s: z.int().min(1).max(60),\n /** Pairing may start with no token: the person approves the link signed in. */\n open_pairing: z.boolean().optional(),\n /** MCP servers (`mcp__<server>`) a session answering this receiver's message may\n * use without asking. MCP servers only: a daemon ignores anything else. */\n session_tools: z\n .array(z.string().regex(/^mcp__[A-Za-z0-9_-]{1,64}$/))\n .max(8)\n .optional(),\n /** How commands are signed: the WebAuthn rp id keys are enrolled for, and the algorithms. */\n signing: z.object({\n rp_id: z.string().min(1).max(253),\n algs: z.array(z.union([z.literal(-7), z.literal(-257)])).min(1),\n }),\n /** Informational: the receiver accepts `files` on a start and serves\n * `GET {control}/files/{sha256}`. */\n files: z.boolean().optional(),\n })\n .optional(),\n});\n\n/** What `npm run schemas` writes to schemas/v1/<name>.json. */\nexport const SCHEMAS = {\n event: Event,\n \"event-data\": EventData,\n batch: Batch,\n \"batch-response\": BatchResponse,\n error: ErrorResponse,\n \"well-known\": WellKnown,\n control: ControlMessage,\n \"control-command\": ControlCommand,\n \"control-grant\": ControlGrant,\n \"control-key\": ControlKey,\n \"control-poll\": ControlPoll,\n \"control-ack\": ControlAck,\n \"control-pair\": ControlPairStart,\n \"control-pair-started\": ControlPairStarted,\n \"control-paired\": ControlPaired,\n \"control-hello\": ControlHello,\n} as const;\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["// SPDX-License-Identifier: Apache-2.0\n// The one source for the protocol's shapes. schemas/v1/*.json are GENERATED from\n// this file (`npm run schemas`); core's runtime types are inferred from it with\n// type-only imports, so zod never enters the zero-dependency bundle. Prose lives in\n// spec/PROTOCOL.md; a rule that is not encoded here is a MUST in words only.\nimport { z } from \"zod\";\n\nexport const PROTOCOL = 1;\n\n/** Dotted, lowercase. Unknown types MUST be accepted and stored. */\nexport const EventType = z\n .string()\n .regex(/^(?:native|[a-z][a-z0-9]*(?:\\.[a-z][a-z0-9_]*)+)$/, \"dotted lowercase type, or native\");\n\nexport const KNOWN_TYPES = [\n \"session.started\",\n \"session.heartbeat\",\n \"session.ended\",\n \"session.backfill\",\n \"session.forgotten\",\n \"turn.started\",\n \"turn.ended\",\n \"turn.transcript\",\n \"turn.progress\",\n \"tool.started\",\n \"tool.ended\",\n \"files.changed\",\n \"attention.needed\",\n \"attention.cleared\",\n \"subagent.started\",\n \"subagent.ended\",\n \"context.compacted\",\n \"native\",\n] as const;\n\n/** The lowest tier that carries each known type. */\nexport const TYPE_TIER: Record<(typeof KNOWN_TYPES)[number], 0 | 1 | 2 | 3> = {\n \"session.started\": 0,\n \"session.heartbeat\": 0,\n \"session.ended\": 0,\n \"session.backfill\": 0,\n \"session.forgotten\": 0,\n \"turn.started\": 0,\n \"turn.ended\": 0,\n \"turn.transcript\": 2,\n \"turn.progress\": 2,\n \"tool.started\": 1,\n \"tool.ended\": 1,\n \"files.changed\": 1,\n \"attention.needed\": 0,\n \"attention.cleared\": 0,\n \"subagent.started\": 1,\n \"subagent.ended\": 1,\n \"context.compacted\": 1,\n native: 3,\n};\n\nexport const HARNESS_NAMES = [\n \"claude-code\",\n \"codex\",\n \"gemini-cli\",\n \"antigravity\",\n \"devin\",\n \"cursor\",\n \"copilot-cli\",\n \"droid\",\n \"kiro\",\n \"opencode\",\n] as const;\n\nexport const Tier = z.int().min(0).max(3);\nexport const Ulid = z.string().regex(/^[0-9A-HJKMNP-TV-Z]{26}$/, \"ULID\");\nexport const Rfc3339 = z.iso.datetime({ offset: false, precision: 3 });\nexport const SessionId = z\n .string()\n .min(1)\n .max(128)\n .regex(/^[A-Za-z0-9._:-]+$/);\nexport const ToolName = z.string().regex(/^[A-Za-z0-9_.:-]{1,120}$/);\n\nexport const Harness = z.object({\n /** From the registry in ADAPTERS.md; a name outside it is allowed ([a-z0-9-]). */\n name: z.string().regex(/^[a-z][a-z0-9-]{0,39}$/),\n version: z.string().max(64).optional(),\n /** The harness's own event name (`PostToolUse`, `agentStop`). */\n event: z.string().max(64).optional(),\n});\n\nexport const Session = z.object({\n id: SessionId,\n /** Monotonic per session per sender; the dedup key with harness.name and id. */\n seq: z.int().min(0),\n machine: z.string().max(80).optional(),\n /** Home is written `~`. */\n cwd: z.string().max(1024).optional(),\n /** A remote URL with credentials stripped. */\n repo: z.string().max(512).optional(),\n branch: z.string().max(256).optional(),\n model: z.string().max(128).optional(),\n title: z.string().max(200).optional(),\n title_source: z.enum([\"custom\", \"harness\", \"first-ask\"]).optional(),\n url: z.url().max(1024).optional(),\n /** An id, never an email. */\n account_id: z.string().max(128).optional(),\n /** Whether a person attends the session, in the harness's own word. Absent = unknown, never false. */\n attended: z.boolean().optional(),\n parent_id: SessionId.nullable().optional(),\n /** `<harness>:<id>` of the session that started this one on purpose (a script running\n * `claude -p` for it), from the launcher's environment. Absent for a subagent, whose\n * launcher is its parent, and when nothing says. */\n launched_by: z\n .string()\n .regex(/^[a-z][a-z0-9-]{0,39}:[A-Za-z0-9._:-]{1,128}$/)\n .optional(),\n});\n\nexport const Privacy = z.object({\n /** The redaction rulesets that ran; `secrets@1` always above tier 0. */\n rulesets: z.array(z.string().regex(/^[a-z][a-z0-9-]*@\\d+$/)),\n pii: z.boolean(),\n});\n\nexport const Event = z.object({\n protocol: z.literal(PROTOCOL),\n id: Ulid,\n type: EventType,\n time: Rfc3339,\n tier: Tier,\n harness: Harness,\n session: Session,\n privacy: Privacy,\n /** Per type (see EventData); extra keys allowed and kept. */\n data: z.record(z.string(), z.unknown()),\n});\n\n// --- data per type --------------------------------------------------------------\n\nconst Loose = z.object({}).loose();\nexport const AttentionKind = z.enum([\"permission\", \"question\", \"elicitation\", \"idle\", \"error\"]);\n\nexport const EventData = z.object({\n \"session.started\": Loose.extend({ source: z.enum([\"startup\", \"resume\", \"clear\", \"compact\", \"fork\", \"unknown\"]) }),\n \"session.heartbeat\": Loose,\n \"session.ended\": Loose.extend({ reason: z.enum([\"clear\", \"logout\", \"exit\", \"other\"]) }),\n \"session.backfill\": Loose.extend({ started_at: Rfc3339, last_at: Rfc3339, turns: z.int().min(0).optional() }),\n \"session.forgotten\": Loose,\n \"turn.started\": Loose.extend({\n turn_id: z.string().max(128).optional(),\n prompt_chars: z.int().min(0).optional(),\n /** The harness's OWN word for who submitted the prompt, forwarded verbatim; not an enum\n * of this spec (Claude Code: user, sdk, system, loop_wakeup, schedule_wakeup,\n * poll_event), and a different vocabulary from session.started.source. A bare word:\n * tier 0 is not redacted, so the shape is the only guard. */\n submitted_by: z\n .string()\n .regex(/^[A-Za-z0-9][A-Za-z0-9_.-]{0,39}$/, \"a bare word, at most 40 characters\")\n .optional(),\n /** True when the prompt text is a block the harness wrote rather than words a person\n * typed; never a claim that no person caused the turn. */\n injected: z.boolean().optional(),\n }),\n \"turn.ended\": Loose.extend({\n turn_id: z.string().max(128).optional(),\n reason: z.enum([\"stop\", \"interrupt\", \"error\"]),\n /** The harness's error class when reason is error (rate_limit, overloaded, authentication_failed, server_error \u2026). */\n error: z.string().max(200).optional(),\n ms: z.int().min(0).optional(),\n /** Background work the harness reports still in flight as the turn ends, each of which wakes the session when it finishes (Claude Code: shell commands, monitors, subagents, workflows). Absent when the harness doesn't say. */\n background: z.int().min(0).optional(),\n }),\n \"turn.transcript\": Loose.extend({\n turn: z.int().min(0),\n user: z.string().max(20_000),\n assistant: z.string().max(20_000),\n at: Rfc3339,\n }),\n /** The turn still running: its prompt and what the assistant has said so far. A\n * later turn.progress for the same turn replaces it; the turn.transcript with the\n * same number supersedes it. Over 20 000 chars, the assistant side keeps its END. */\n \"turn.progress\": Loose.extend({\n turn: z.int().min(0),\n user: z.string().max(20_000),\n assistant: z.string().max(20_000),\n at: Rfc3339,\n }),\n \"tool.started\": Loose.extend({\n tool: ToolName,\n call_id: z.string().max(128).optional(),\n turn_id: z.string().max(128).optional(),\n /** Set when a subagent made the call. */\n agent_id: z.string().max(128).optional(),\n input: z.unknown().optional(),\n }),\n \"tool.ended\": Loose.extend({\n tool: ToolName,\n call_id: z.string().max(128).optional(),\n turn_id: z.string().max(128).optional(),\n agent_id: z.string().max(128).optional(),\n ms: z.int().min(0).optional(),\n ok: z.boolean(),\n error: z.string().max(2000).optional(),\n input: z.unknown().optional(),\n output: z.unknown().optional(),\n }),\n \"files.changed\": Loose.extend({ paths: z.array(z.string().max(1024)).max(500) }),\n \"attention.needed\": Loose.extend({\n attention_id: z.string().max(128),\n kind: AttentionKind,\n tool: ToolName.optional(),\n message: z.string().max(200).optional(),\n }),\n \"attention.cleared\": Loose.extend({\n attention_id: z.string().max(128),\n how: z.enum([\"answered\", \"cancelled\", \"timeout\", \"unknown\"]),\n }),\n \"subagent.started\": Loose.extend({ agent_id: z.string().max(128), agent_type: z.string().max(128).optional() }),\n \"subagent.ended\": Loose.extend({ agent_id: z.string().max(128), agent_type: z.string().max(128).optional() }),\n \"context.compacted\": Loose.extend({ trigger: z.enum([\"manual\", \"auto\"]) }),\n native: Loose,\n});\n\n// --- wire -----------------------------------------------------------------------\n\nexport const Batch = z.object({ events: z.array(Event).min(1).max(50) });\n\nexport const BatchResponse = z.object({\n accepted: z.int().min(0),\n duplicates: z.int().min(0),\n rejected: z.array(z.object({ id: Ulid, reason: z.string().max(200) })),\n max_tier: Tier,\n});\n\nexport const ErrorResponse = z.object({\n reason: z.string().max(200),\n supported: z.array(z.int()).optional(),\n max_tier: Tier.optional(),\n});\n\nexport const Capability = z.enum([\"events\", \"backfill\", \"forget\", \"control\", \"native\"]);\n\n// --- control (CONTROL.md) ---------------------------------------------------------\n\nconst B64Url = z.string().regex(/^[A-Za-z0-9_-]*$/, \"base64url, no padding\");\nexport const MachineId = z.string().regex(/^m_[A-Za-z0-9_-]{16,40}$/, \"m_ + 16\u201340 base64url\");\n/** `<harness>:<id>`; the id follows its adapter's rule (Claude Code: a UUID). */\nexport const SessionRef = z.string().regex(/^[a-z][a-z0-9-]{0,39}:[A-Za-z0-9._:-]{1,128}$/, \"<harness>:<session id>\");\nexport const ControlKind = z.enum([\"prompt\", \"permission.answer\", \"cancel\", \"start\", \"key.add\"]);\n/** The kinds of key a machine or a receiver handles (CONTROL.md \u00A72). Absent: passkeys only. */\nexport const KeyTypes = z\n .array(z.enum([\"passkey\", \"device\"]))\n .min(1)\n .max(2);\nexport const DeliveryMode = z.enum([\"sdk\", \"waiter\", \"turn\", \"api\", \"resume\", \"fork\"]);\n/** How much a started session may do without anyone approving it (CONTROL.md \u00A73.1),\n * narrowest first. Closed: nothing is wider than `auto`. */\nexport const StartPermission = z.enum([\"read\", \"safe\", \"edits\", \"auto\"]);\n/** What a start ran with, or gets by default: a level, or `inherit` (no permission flag,\n * the harness's own default) on a machine the person put in inherit mode. Never a\n * command's `permission`. */\nexport const RunLevel = z.enum([\"read\", \"safe\", \"edits\", \"auto\", \"inherit\"]);\n/** A model id as the harness names it, passed as one argument: never a leading dash. */\nexport const ModelId = z\n .string()\n .min(1)\n .max(100)\n .regex(/^[A-Za-z0-9][A-Za-z0-9._:/@[\\]-]*$/, \"a model id\");\nconst HarnessName = z.string().regex(/^[a-z][a-z0-9-]{0,39}$/);\n\n/** A file attached to a `start` (CONTROL.md \u00A73.1). The bytes wait on the receiver\n * (`GET {control}/files/{sha256}`); the signed hash is what the machine checks.\n * Beyond this shape the verifier also checks: the name's length after NFC, names\n * unique case-insensitively, and the sizes adding up to at most 50 MiB. */\nexport const ControlFile = z.object({\n /** Written as is (NFC) into the session's folder: no slash, backslash or control\n * character, not starting with a dot. */\n name: z\n .string()\n .min(1)\n .max(200)\n .regex(\n // biome-ignore lint/suspicious/noControlCharactersInRegex: control characters are what it rejects\n /^[^./\\\\\\x00-\\x1f\\x7f][^/\\\\\\x00-\\x1f\\x7f]*$/,\n \"a file name: no slash, backslash, control character or leading dot\",\n ),\n /** Media type, `type/subtype` (case-insensitive). */\n type: z\n .string()\n .min(1)\n .max(100)\n .regex(/^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]*\\/[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]*$/, \"type/subtype\"),\n /** Bytes: 1 to 25 MiB. */\n size: z.int().min(1).max(26_214_400),\n /** SHA-256 of the bytes, base64url without padding. */\n sha256: z.string().regex(/^[A-Za-z0-9_-]{43}$/, \"43 base64url characters\"),\n});\n\n/** The signed command, as the device writes it. The machine verifies the EXACT string\n * it received (control.json `cmd`) and never re-serializes it. */\nexport const ControlCommand = z.object({\n v: z.literal(1),\n t: z.literal(\"sessionpipe.control\"),\n machine: MachineId,\n kind: ControlKind,\n session: SessionRef,\n /** prompt, start: the message for the model. */\n text: z.string().min(1).max(20_000).optional(),\n /** permission.answer: the attention_id being answered. */\n for: z.string().min(1).max(128).optional(),\n decision: z.enum([\"allow\", \"deny\"]).optional(),\n /** Shown to the model beside a decision. */\n note: z.string().max(2000).optional(),\n /** start: the folder the new session runs in: absolute, or `~` / `~/\u2026` under the\n * home of the user the machine's daemon runs as, as events write it. */\n cwd: z.string().max(1024).optional(),\n /** key.add (session `sessionpipe:keys`): the new device's key (a passkey or a device\n * key, control-key.json), which the machine trusts once a key it already trusts\n * signed this command. */\n key: z.lazy(() => ControlKey).optional(),\n /** key.add: what the person calls the device. */\n name: z.string().min(1).max(80).optional(),\n /** start, prompt: 1\u201310 files, together at most 50 MiB, downloaded and checked by hash\n * before the session starts or the message is delivered. On a prompt, only to a\n * machine whose hello says `prompt_files`. */\n files: z.array(ControlFile).min(1).max(10).optional(),\n /** start only: the level the new session runs at, at most the machine's mode. Send\n * it only to a machine whose hello advertises it for the harness (`start`). */\n permission: StartPermission.optional(),\n /** start only: the model the harness runs. As `permission`: only when advertised. */\n model: ModelId.optional(),\n /** At least 16 random bytes, base64url. */\n nonce: z.string().regex(/^[A-Za-z0-9_-]{22,64}$/),\n /** Epoch ms, the signing device's clock. */\n iat: z.int().min(1),\n});\n\n/** A day grant's signed string: a passkey vouches for a device key for \u2264 24 h. */\nexport const ControlGrant = z.object({\n v: z.literal(1),\n t: z.literal(\"sessionpipe.grant\"),\n /** The day key: P-256 SPKI, base64url. */\n pub: B64Url.min(1),\n iat: z.int().min(1),\n exp: z.int().min(1),\n /** The receiver's WebAuthn rp id (well-known control.signing.rp_id). */\n rp: z.string().min(1).max(253),\n});\n\n/** A WebAuthn assertion: credential id, authenticatorData, clientDataJSON, signature. */\nexport const ControlAssertion = z.object({\n cred: B64Url.min(1),\n ad: B64Url.min(1),\n cd: B64Url.min(1),\n sig: B64Url.min(1),\n});\n\n/** A device key's signature (CONTROL.md \u00A73.2): its id and 64 bytes r\u2016s over\n * `sessionpipe.device.v1\u23CE<purpose>\u23CE<rp id>\u23CE<challenge>`. Nothing else. The shape\n * only, like an assertion's: the machine reads the key from its own record and checks\n * the rest (a 43-character id, exactly 64 bytes), so a carrier never decides a kind. */\nexport const ControlDeviceSignature = z.strictObject({\n cred: B64Url.min(1),\n /** 64 bytes r\u2016s, base64url without padding. */\n sig: B64Url.min(1),\n});\n\n/** A key enrolled on a machine, closed: a passkey (credential id, COSE alg, SPKI), or a\n * device key an app holds in hardware (CONTROL.md \u00A72 \"Device keys\"), which names\n * itself by its SPKI's SHA-256 and says how it is held. A machine refuses any other\n * field or value, so a kind added later is refused by every machine that predates it. */\nexport const ControlKey = z.xor([\n z.strictObject({\n id: B64Url.min(16).max(1400),\n alg: z.union([z.literal(-7), z.literal(-257)]),\n spki: B64Url.min(1),\n }),\n z.strictObject({\n /** SHA-256 of the SPKI bytes, base64url without padding. */\n id: z.string().regex(/^[A-Za-z0-9_-]{43}$/, \"SHA-256 of the spki, base64url\"),\n alg: z.literal(-7),\n spki: B64Url.min(1),\n type: z.literal(\"device\"),\n /** The private key was made in a hardware key store and never leaves it. */\n store: z.literal(\"hardware\"),\n /** The store will not sign without verifying the person, every time. */\n uv: z.literal(\"each-use\"),\n }),\n]);\n\n/** One message as a receiver carries it: its own envelope around the signed bytes. */\nexport const ControlMessage = z.object({\n /** The receiver's id for this message; the ack key. Not signed: the nonce inside cmd is. */\n id: Ulid,\n /** The command string, exactly as signed (\u2264 48 000 characters). */\n cmd: z.string().min(1).max(48_000),\n /** The day key's ECDSA P-256 / SHA-256 signature over cmd: raw r\u2016s, base64url. */\n csig: B64Url.nullable().optional(),\n /** The grant vouching for the day key: its string plus the passkey's assertion over\n * sha256(str), or a device key's signature over it (CONTROL.md \u00A73.2). */\n grant: z\n .xor([\n ControlAssertion.extend({ str: z.string().min(1).max(2000) }),\n ControlDeviceSignature.extend({ str: z.string().min(1).max(2000) }),\n ])\n .nullable()\n .optional(),\n /** Instead of csig + grant: one passkey assertion (or device signature) over sha256(cmd). */\n confirm: z.xor([ControlAssertion, ControlDeviceSignature]).nullable().optional(),\n /** The receiver's clock. */\n at: Rfc3339,\n /** After this the machine MUST NOT act and acks `expired`; at most 24 h after `at`. */\n expires_at: Rfc3339,\n});\n\nexport const ControlPoll = z.object({ messages: z.array(ControlMessage) });\n\n/** `taken` is the one non-final outcome: the machine verified the message and is\n * delivering it (a headless resume can take minutes); a final ack follows. */\n/** `progress` (not final): the answer so far, whole, in `reply`, with a rising `seq`.\n * `taken` (not final): verified and being delivered. Every other outcome is final. */\nexport const ControlOutcome = z.enum([\"progress\", \"taken\", \"delivered\", \"expired\", \"unsupported\", \"failed\", \"refused\"]);\n\nexport const ControlAck = z.object({\n acks: z\n .array(\n z.object({\n id: Ulid,\n outcome: ControlOutcome,\n at: Rfc3339,\n /** delivered: how it reached the session. */\n mode: DeliveryMode.optional(),\n /** The session that took it, when not the one named (a fork's copy, a started session). */\n session: SessionRef.optional(),\n /** refused: the verifier's code, or the machine's own (`folder`, `no_attention`, `busy`);\n * failed: `file` when a start's attachment couldn't be fetched, checked or written,\n * `model` when the harness wouldn't run the start's model. */\n code: z\n .string()\n .regex(/^[a-z_]{1,40}$/)\n .optional(),\n detail: z.string().max(500).optional(),\n /** resume / fork / start: the agent's reply, redacted by the secrets ruleset. */\n reply: z.string().max(20_000).optional(),\n /** progress only: rises with every progress ack for this id; a receiver keeps the highest. */\n seq: z.int().min(0).optional(),\n /** taken, delivered of a start: the options it ran with (`model` only when one was\n * asked for). A receiver shows this, never what was asked. */\n applied: z.strictObject({ permission: RunLevel.optional(), model: ModelId.optional() }).optional(),\n }),\n )\n .min(1),\n});\n\n/** A harness account signed in on the machine: the id `session.account_id` carries,\n * and the email it signs in with, so a receiver the person paired with can name the\n * account rather than show an id. Only pair and hello carry it, never an event. */\nexport const HarnessAccount = z.object({\n harness: z.string().regex(/^[a-z][a-z0-9-]{0,39}$/),\n id: z.string().min(1).max(128),\n email: z.string().max(254).optional(),\n /** What to call an account that has no email: a Claude Code home that runs on\n * another API is named by its endpoint's host (`api.z.ai`). */\n name: z.string().min(1).max(200).optional(),\n});\n\n/** `POST {control}/pair`, sent with the person's sink token from their own terminal \u2014\n * or, where the receiver declares `control.open_pairing`, with no token and a\n * `poll_key` (CONTROL.md \u00A72). */\nexport const ControlPairStart = z.object({\n /** Open pairing: a random secret only this terminal knows. Status polls present it\n * as their bearer; the receiver keeps only a hash. */\n poll_key: z\n .string()\n .regex(/^[A-Za-z0-9_-]{22,128}$/)\n .optional(),\n /** Set when adding a key to a machine already paired. */\n machine: MachineId.optional(),\n name: z.string().min(1).max(80),\n harnesses: z.array(z.string().regex(/^[a-z][a-z0-9-]{0,39}$/)).max(20),\n modes: z.array(DeliveryMode),\n version: z.string().max(40),\n /** The folders the machine lets sessions run in, for the receiver's \"new session\"\n * picker. Informational: the machine checks its own list again. */\n folders: z.array(z.string().max(1024)).max(50).optional(),\n /** safe: nothing that needs approval runs unattended; auto: the harness's auto mode;\n * inherit: no permission flag, each harness's own default there. Chosen at the machine. */\n mode: z.enum([\"safe\", \"auto\", \"inherit\"]).optional(),\n /** The harness accounts signed in here, so the receiver's board can name each\n * `session.account_id` (CONTROL.md \u00A72). */\n accounts: z.array(HarnessAccount).max(20).optional(),\n /** The machine takes `files` on a start (downloads, checks and writes them). A\n * machine that doesn't say so may ignore them: a receiver SHOULD NOT send it files. */\n files: z.boolean().optional(),\n /** The kinds of key this machine takes (unique; absent means `[\"passkey\"]`). A\n * client offers a device key only to a machine that lists `device`. */\n key_types: KeyTypes.optional(),\n});\n\n/** The receiver's answer: where the person confirms, and the digits both screens show. */\nexport const ControlPairStarted = z.object({\n machine: MachineId,\n code: z.string().regex(/^[A-Za-z0-9_-]{6,32}$/),\n url: z.url(),\n /** Six digits the terminal and the receiver's page both show. */\n check: z.string().regex(/^\\d{6}$/),\n expires_at: Rfc3339,\n});\n\n/** `GET {control}/pair?code=\u2026` once the person confirmed. The machine verifies `proof`\n * over sha256(\"sessionpipe.pair:<machine>:<code>\") before it trusts `key`. */\nexport const ControlPaired = z.object({\n status: z.enum([\"pending\", \"paired\", \"expired\"]),\n /** The key approved, whole: a device key keeps its type, store and uv. */\n key: ControlKey.optional(),\n /** The key's proof: a passkey assertion, or a device signature for purpose `pair`. */\n proof: z.xor([ControlAssertion, ControlDeviceSignature]).optional(),\n /** The machine's own bearer for polls, acks and hello: opens nothing else. Minted\n * once, at the first pairing of a machine. */\n token: z.string().min(16).max(256).optional(),\n /** Optional: a key for the events lane (`sink add`), so the receiver's session board\n * shows this machine without a second step. Handed over once. */\n sink_token: z.string().min(16).max(256).optional(),\n /** Optional: who approved, in the receiver's words (a @handle), so the terminal can\n * say whose passkey it now trusts. */\n account: z.string().max(200).optional(),\n});\n\n/** `POST {control}/hello`: what the machine can do right now. */\nexport const ControlHello = z.object({\n name: z.string().min(1).max(80),\n harnesses: z.array(z.string().regex(/^[a-z][a-z0-9-]{0,39}$/)).max(20),\n modes: z.array(DeliveryMode),\n /** Credential ids of the keys enrolled on the machine. */\n keys: z.array(B64Url.min(16).max(1400)).max(50),\n version: z.string().max(40),\n /** Live sessions with a waiter parked on the daemon's socket. */\n waiting: z.array(SessionRef).max(500).optional(),\n /** As in control-pair.json: informational, re-checked on the machine. */\n folders: z.array(z.string().max(1024)).max(50).optional(),\n mode: z.enum([\"safe\", \"auto\", \"inherit\"]).optional(),\n /** As in control-pair.json: read again for every hello, so a new sign-in is named. */\n accounts: z.array(HarnessAccount).max(20).optional(),\n /** As in control-pair.json. */\n files: z.boolean().optional(),\n /** The machine takes `files` on a prompt too (CONTROL.md \u00A76 `prompt`). One that\n * doesn't say so refuses them: a receiver SHOULD NOT send it a prompt with files. */\n prompt_files: z.boolean().optional(),\n /** Per harness in `harnesses`: the options a start may carry (CONTROL.md \u00A72). No\n * entry: neither `permission` nor `model`. */\n start: z\n .record(\n HarnessName,\n z.object({\n /** The levels it starts at here, already capped by `mode`. */\n permissions: z.array(StartPermission).min(1).max(4).meta({ uniqueItems: true }),\n /** What a start that names none gets: one of `permissions`, or `inherit` on an\n * inherit machine. */\n permission: RunLevel,\n /** Model ids the harness offers here: a suggestion, not a promise. */\n models: z.array(ModelId).max(50).optional(),\n /** Any well-formed model is passed to the harness (which may still reject it). */\n any_model: z.boolean().optional(),\n }),\n )\n .refine((o) => Object.keys(o).length <= 50, \"at most 50 harnesses\")\n .meta({ maxProperties: 50 })\n .optional(),\n /** As in control-pair.json. */\n key_types: KeyTypes.optional(),\n});\n\nexport const WellKnown = z.object({\n protocol: z.array(z.int().min(1)).min(1),\n max_tier: Tier,\n capabilities: z.array(z.string().regex(/^[a-z][a-z0-9-]*$/)),\n auth: z.array(z.enum([\"bearer\"])).default([\"bearer\"]),\n endpoints: z.object({\n events: z.string(),\n control: z.string().optional(),\n native: z.string().optional(),\n }),\n batch: z.object({ max_events: z.int().min(1).max(50), max_bytes: z.int().min(1024).max(262_144) }),\n control: z\n .object({\n wait_max_s: z.int().min(1).max(60),\n /** Pairing may start with no token: the person approves the link signed in. */\n open_pairing: z.boolean().optional(),\n /** MCP servers (`mcp__<server>`) a session answering this receiver's message may\n * use without asking. MCP servers only: a daemon ignores anything else. */\n session_tools: z\n .array(z.string().regex(/^mcp__[A-Za-z0-9_-]{1,64}$/))\n .max(8)\n .optional(),\n /** How commands are signed: the WebAuthn rp id keys are enrolled for, and the algorithms. */\n signing: z.object({\n rp_id: z.string().min(1).max(253),\n algs: z.array(z.union([z.literal(-7), z.literal(-257)])).min(1),\n /** The kinds of key the receiver stores and carries whole (CONTROL.md \u00A72).\n * Absent means `[\"passkey\"]`. */\n key_types: KeyTypes.optional(),\n }),\n /** Informational: the receiver accepts `files` on a start and serves\n * `GET {control}/files/{sha256}`. */\n files: z.boolean().optional(),\n /** The receiver shows a machine in `inherit` mode as that, never as safe or auto.\n * A daemon pairs in, or switches to, `inherit` only with receivers that say so. */\n inherit: z.boolean().optional(),\n })\n .optional(),\n});\n\n/** What `npm run schemas` writes to schemas/v1/<name>.json. */\nexport const SCHEMAS = {\n event: Event,\n \"event-data\": EventData,\n batch: Batch,\n \"batch-response\": BatchResponse,\n error: ErrorResponse,\n \"well-known\": WellKnown,\n control: ControlMessage,\n \"control-command\": ControlCommand,\n \"control-grant\": ControlGrant,\n \"control-key\": ControlKey,\n \"control-poll\": ControlPoll,\n \"control-ack\": ControlAck,\n \"control-pair\": ControlPairStart,\n \"control-pair-started\": ControlPairStarted,\n \"control-paired\": ControlPaired,\n \"control-hello\": ControlHello,\n} as const;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/service.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// sessionpipe-core 0.10.0 · Apache-2.0 · https://sessionpipe.org
|
|
2
|
+
|
|
3
|
+
// src/service/index.ts
|
|
4
|
+
import { execFileSync } from "node:child_process";
|
|
5
|
+
import { existsSync, mkdirSync, unlinkSync, writeFileSync } from "node:fs";
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
var execQuiet = (cmd, args) => execFileSync(cmd, args, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 15e3 });
|
|
9
|
+
var xml = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
10
|
+
var sd = (s) => `"${s.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/%/g, "%%")}"`;
|
|
11
|
+
function serviceFiles(s) {
|
|
12
|
+
const home = s.home ?? os.homedir();
|
|
13
|
+
const env = (manager) => ({ SESSIONPIPE_SERVICE: manager, ...s.env });
|
|
14
|
+
const plistEnv = Object.entries(env("launchd")).map(([k, v]) => `<key>${xml(k)}</key><string>${xml(v)}</string>`).join("");
|
|
15
|
+
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
16
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
17
|
+
<plist version="1.0">
|
|
18
|
+
<dict>
|
|
19
|
+
<key>Label</key><string>${xml(s.label)}</string>
|
|
20
|
+
<key>ProgramArguments</key>
|
|
21
|
+
<array>${s.argv.map((a) => `<string>${xml(a)}</string>`).join("")}</array>
|
|
22
|
+
<key>EnvironmentVariables</key><dict>${plistEnv}</dict>
|
|
23
|
+
<key>RunAtLoad</key><true/>
|
|
24
|
+
<key>KeepAlive</key><dict><key>SuccessfulExit</key><false/></dict>
|
|
25
|
+
<key>ProcessType</key><string>Background</string>
|
|
26
|
+
<key>StandardOutPath</key><string>${xml(s.logPath)}</string>
|
|
27
|
+
<key>StandardErrorPath</key><string>${xml(s.logPath)}</string>
|
|
28
|
+
</dict>
|
|
29
|
+
</plist>
|
|
30
|
+
`;
|
|
31
|
+
const unitEnv = Object.entries(env("systemd")).map(([k, v]) => `Environment=${k === "SESSIONPIPE_SERVICE" ? `${k}=${v}` : sd(`${k}=${v}`)}`).join("\n");
|
|
32
|
+
const unit = `[Unit]
|
|
33
|
+
Description=${s.description.replace(/\n/g, " ")}
|
|
34
|
+
After=network-online.target
|
|
35
|
+
|
|
36
|
+
[Service]
|
|
37
|
+
ExecStart=${s.argv.map(sd).join(" ")}
|
|
38
|
+
${unitEnv}
|
|
39
|
+
Restart=on-failure
|
|
40
|
+
RestartForceExitStatus=75
|
|
41
|
+
RestartSec=5
|
|
42
|
+
|
|
43
|
+
[Install]
|
|
44
|
+
WantedBy=default.target
|
|
45
|
+
`;
|
|
46
|
+
return {
|
|
47
|
+
plist: { path: path.join(home, "Library", "LaunchAgents", `${s.label}.plist`), text: plist },
|
|
48
|
+
unit: { path: path.join(home, ".config", "systemd", "user", s.unit), text: unit }
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function ensureLinger(user, exec = execQuiet) {
|
|
52
|
+
const lingering = () => {
|
|
53
|
+
try {
|
|
54
|
+
return /^Linger=yes/m.test(exec("loginctl", ["show-user", user, "--property=Linger"]));
|
|
55
|
+
} catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
if (lingering()) return { on: true, note: "it keeps running after you log out (linger was already on)" };
|
|
60
|
+
try {
|
|
61
|
+
exec("loginctl", ["enable-linger", user]);
|
|
62
|
+
} catch {
|
|
63
|
+
}
|
|
64
|
+
if (lingering()) return { on: true, note: "it keeps running after you log out (turned linger on)" };
|
|
65
|
+
return {
|
|
66
|
+
on: false,
|
|
67
|
+
note: `it stops when you log out: run \`sudo loginctl enable-linger ${user}\` once to keep it running`
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
var line = (cmd, args) => [cmd, ...args].join(" ");
|
|
71
|
+
function installService(o) {
|
|
72
|
+
const f = serviceFiles(o);
|
|
73
|
+
const platform = o.platform ?? process.platform;
|
|
74
|
+
const uid = o.uid ?? String(process.getuid?.() ?? "");
|
|
75
|
+
const commands = [];
|
|
76
|
+
const real = o.exec ?? execQuiet;
|
|
77
|
+
const run = (cmd, args) => {
|
|
78
|
+
commands.push(line(cmd, args));
|
|
79
|
+
return o.dryRun ? "" : real(cmd, args);
|
|
80
|
+
};
|
|
81
|
+
const write = (file) => {
|
|
82
|
+
if (o.dryRun) return;
|
|
83
|
+
mkdirSync(path.dirname(file.path), { recursive: true });
|
|
84
|
+
writeFileSync(file.path, file.text);
|
|
85
|
+
};
|
|
86
|
+
if (platform === "darwin") {
|
|
87
|
+
write(f.plist);
|
|
88
|
+
for (const d of ["gui", "user"])
|
|
89
|
+
try {
|
|
90
|
+
run("launchctl", ["bootout", `${d}/${uid}/${o.label}`]);
|
|
91
|
+
} catch {
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
run("launchctl", ["bootstrap", `gui/${uid}`, f.plist.path]);
|
|
95
|
+
return { files: [f.plist], commands, manager: "launchd", domain: "gui" };
|
|
96
|
+
} catch {
|
|
97
|
+
}
|
|
98
|
+
run("launchctl", ["bootstrap", `user/${uid}`, f.plist.path]);
|
|
99
|
+
return { files: [f.plist], commands, manager: "launchd", domain: "user" };
|
|
100
|
+
}
|
|
101
|
+
if (platform === "linux") {
|
|
102
|
+
write(f.unit);
|
|
103
|
+
try {
|
|
104
|
+
run("systemctl", ["--user", "daemon-reload"]);
|
|
105
|
+
run("systemctl", ["--user", "enable", "--now", o.unit]);
|
|
106
|
+
} catch {
|
|
107
|
+
return { files: [f.unit], commands, manager: null, unreachable: f.unit.path };
|
|
108
|
+
}
|
|
109
|
+
const user = o.user ?? os.userInfo().username;
|
|
110
|
+
if (o.dryRun) {
|
|
111
|
+
commands.push(line("loginctl", ["enable-linger", user]));
|
|
112
|
+
return { files: [f.unit], commands, manager: "systemd", linger: { on: false, note: "dry run" } };
|
|
113
|
+
}
|
|
114
|
+
return { files: [f.unit], commands, manager: "systemd", linger: ensureLinger(user, run) };
|
|
115
|
+
}
|
|
116
|
+
return { files: [], commands, manager: null };
|
|
117
|
+
}
|
|
118
|
+
function uninstallService(o) {
|
|
119
|
+
const f = serviceFiles({ ...o, description: "", argv: [], logPath: "" });
|
|
120
|
+
const platform = o.platform ?? process.platform;
|
|
121
|
+
const uid = o.uid ?? String(process.getuid?.() ?? "");
|
|
122
|
+
const commands = [];
|
|
123
|
+
const files = [];
|
|
124
|
+
const real = o.exec ?? execQuiet;
|
|
125
|
+
const run = (cmd, args) => {
|
|
126
|
+
commands.push(line(cmd, args));
|
|
127
|
+
if (o.dryRun) return;
|
|
128
|
+
try {
|
|
129
|
+
real(cmd, args);
|
|
130
|
+
} catch {
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const remove = (file) => {
|
|
134
|
+
files.push(file);
|
|
135
|
+
if (!o.dryRun) unlinkSync(file);
|
|
136
|
+
};
|
|
137
|
+
if (platform === "darwin" && existsSync(f.plist.path)) {
|
|
138
|
+
run("launchctl", ["bootout", `gui/${uid}/${o.label}`]);
|
|
139
|
+
run("launchctl", ["bootout", `user/${uid}/${o.label}`]);
|
|
140
|
+
remove(f.plist.path);
|
|
141
|
+
}
|
|
142
|
+
if (platform === "linux" && existsSync(f.unit.path)) {
|
|
143
|
+
run("systemctl", ["--user", "disable", "--now", o.unit]);
|
|
144
|
+
remove(f.unit.path);
|
|
145
|
+
run("systemctl", ["--user", "daemon-reload"]);
|
|
146
|
+
}
|
|
147
|
+
return { files, commands };
|
|
148
|
+
}
|
|
149
|
+
export {
|
|
150
|
+
ensureLinger,
|
|
151
|
+
installService,
|
|
152
|
+
serviceFiles,
|
|
153
|
+
uninstallService
|
|
154
|
+
};
|
|
155
|
+
//# sourceMappingURL=service.js.map
|