@byok-sdk/protocol 0.1.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/LICENSE +21 -0
- package/README.md +10 -0
- package/dist/agent-event.d.ts +146 -0
- package/dist/blob.d.ts +24 -0
- package/dist/codec.d.ts +116 -0
- package/dist/envelope.d.ts +333 -0
- package/dist/errors.d.ts +25 -0
- package/dist/http-api.d.ts +725 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +432 -0
- package/dist/index.js.map +1 -0
- package/dist/messages.d.ts +646 -0
- package/dist/permission.d.ts +39 -0
- package/dist/task-state.d.ts +21 -0
- package/dist/version.d.ts +70 -0
- package/package.json +49 -0
|
@@ -0,0 +1,646 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const RuntimeIdSchema: z.ZodEnum<{
|
|
3
|
+
claude: "claude";
|
|
4
|
+
codex: "codex";
|
|
5
|
+
pi: "pi";
|
|
6
|
+
}>;
|
|
7
|
+
export type RuntimeId = z.infer<typeof RuntimeIdSchema>;
|
|
8
|
+
/**
|
|
9
|
+
* Per-runtime feature flags reported in `conn.hello.runtimes[].capabilities`
|
|
10
|
+
* (pre-freeze addition). Distinct from the connection-level `CAPABILITY_FLAGS`
|
|
11
|
+
* (`version.ts`) / `conn.hello.capabilities` array: those are protocol-level
|
|
12
|
+
* flags negotiated for the whole connection, while this is what one specific
|
|
13
|
+
* detected runtime (pi/claude/codex) supports. The whole field is optional
|
|
14
|
+
* end-to-end — older daemons omit `capabilities` entirely — and every field
|
|
15
|
+
* inside it is itself optional, since detection can be partial.
|
|
16
|
+
*
|
|
17
|
+
* Per-tool allow/deny lists are deliberately NOT included here (noise).
|
|
18
|
+
* `permissionModes` mirrors `PERMISSION_MODES` (`permission.ts`) but is kept
|
|
19
|
+
* as a bare `string[]` rather than `z.enum(PERMISSION_MODES)`: this is a
|
|
20
|
+
* runtime's self-reported observability data, not a control/security field,
|
|
21
|
+
* so — per the freeze rule (tolerate unknown for observability, fail closed
|
|
22
|
+
* for control/security; see `agent-event.ts`'s unknown-variant tolerance for
|
|
23
|
+
* the same asymmetry applied to `task.progress` events) — it stays tolerant
|
|
24
|
+
* of a mode string a newer runtime might report that this schema doesn't
|
|
25
|
+
* enumerate yet, rather than rejecting the whole `conn.hello`.
|
|
26
|
+
*
|
|
27
|
+
* Unrecognized keys inside `capabilities` itself, by contrast, are silently
|
|
28
|
+
* stripped (zod's default object behavior — same as every other payload
|
|
29
|
+
* schema in this file) rather than passed through: this is a closed, typed
|
|
30
|
+
* shape consumers can rely on, and a genuinely new capability flag gets added
|
|
31
|
+
* here explicitly rather than round-tripped opaquely.
|
|
32
|
+
*/
|
|
33
|
+
export declare const RuntimeCapabilitiesSchema: z.ZodObject<{
|
|
34
|
+
steer: z.ZodOptional<z.ZodBoolean>;
|
|
35
|
+
resume: z.ZodOptional<z.ZodBoolean>;
|
|
36
|
+
approvalInteractive: z.ZodOptional<z.ZodBoolean>;
|
|
37
|
+
permissionModes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
export type RuntimeCapabilities = z.infer<typeof RuntimeCapabilitiesSchema>;
|
|
40
|
+
/**
|
|
41
|
+
* Runtime detection info reported in `conn.hello`. Supersedes the M0
|
|
42
|
+
* `agents: unknown` field (M1 gap #4): typed, so the server no longer has to
|
|
43
|
+
* best-effort-normalize an untyped blob.
|
|
44
|
+
*/
|
|
45
|
+
export declare const RuntimeInfoSchema: z.ZodObject<{
|
|
46
|
+
id: z.ZodEnum<{
|
|
47
|
+
claude: "claude";
|
|
48
|
+
codex: "codex";
|
|
49
|
+
pi: "pi";
|
|
50
|
+
}>;
|
|
51
|
+
version: z.ZodOptional<z.ZodString>;
|
|
52
|
+
authPresent: z.ZodOptional<z.ZodBoolean>;
|
|
53
|
+
capabilities: z.ZodOptional<z.ZodObject<{
|
|
54
|
+
steer: z.ZodOptional<z.ZodBoolean>;
|
|
55
|
+
resume: z.ZodOptional<z.ZodBoolean>;
|
|
56
|
+
approvalInteractive: z.ZodOptional<z.ZodBoolean>;
|
|
57
|
+
permissionModes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
58
|
+
}, z.core.$strip>>;
|
|
59
|
+
}, z.core.$strip>;
|
|
60
|
+
export type RuntimeInfo = z.infer<typeof RuntimeInfoSchema>;
|
|
61
|
+
/** daemon -> server: opening handshake. */
|
|
62
|
+
export declare const ConnHelloPayloadSchema: z.ZodObject<{
|
|
63
|
+
protocolVersions: z.ZodArray<z.ZodNumber>;
|
|
64
|
+
capabilities: z.ZodArray<z.ZodString>;
|
|
65
|
+
deviceId: z.ZodString;
|
|
66
|
+
productId: z.ZodString;
|
|
67
|
+
runtimes: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
68
|
+
id: z.ZodEnum<{
|
|
69
|
+
claude: "claude";
|
|
70
|
+
codex: "codex";
|
|
71
|
+
pi: "pi";
|
|
72
|
+
}>;
|
|
73
|
+
version: z.ZodOptional<z.ZodString>;
|
|
74
|
+
authPresent: z.ZodOptional<z.ZodBoolean>;
|
|
75
|
+
capabilities: z.ZodOptional<z.ZodObject<{
|
|
76
|
+
steer: z.ZodOptional<z.ZodBoolean>;
|
|
77
|
+
resume: z.ZodOptional<z.ZodBoolean>;
|
|
78
|
+
approvalInteractive: z.ZodOptional<z.ZodBoolean>;
|
|
79
|
+
permissionModes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
80
|
+
}, z.core.$strip>>;
|
|
81
|
+
}, z.core.$strip>>>;
|
|
82
|
+
cursor: z.ZodOptional<z.ZodNumber>;
|
|
83
|
+
}, z.core.$strip>;
|
|
84
|
+
export type ConnHelloPayload = z.infer<typeof ConnHelloPayloadSchema>;
|
|
85
|
+
/** server -> daemon: handshake acknowledgement. */
|
|
86
|
+
export declare const ConnAckPayloadSchema: z.ZodObject<{
|
|
87
|
+
protocolVersion: z.ZodNumber;
|
|
88
|
+
capabilities: z.ZodArray<z.ZodString>;
|
|
89
|
+
serverTime: z.ZodISODateTime;
|
|
90
|
+
}, z.core.$strip>;
|
|
91
|
+
export type ConnAckPayload = z.infer<typeof ConnAckPayloadSchema>;
|
|
92
|
+
/**
|
|
93
|
+
* server -> daemon: offer a task for a device to claim.
|
|
94
|
+
*
|
|
95
|
+
* `taskId` used to be duplicated here; it is now carried only by the
|
|
96
|
+
* envelope's `task_id` (M1 gap #7 — single source of truth for routing).
|
|
97
|
+
*/
|
|
98
|
+
export declare const TaskOfferPayloadSchema: z.ZodObject<{
|
|
99
|
+
instruction: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
100
|
+
blobRef: z.ZodObject<{
|
|
101
|
+
blobId: z.ZodString;
|
|
102
|
+
contentHash: z.ZodString;
|
|
103
|
+
size: z.ZodNumber;
|
|
104
|
+
contentType: z.ZodString;
|
|
105
|
+
url: z.ZodOptional<z.ZodString>;
|
|
106
|
+
}, z.core.$strip>;
|
|
107
|
+
}, z.core.$strict>]>;
|
|
108
|
+
policy: z.ZodObject<{
|
|
109
|
+
mode: z.ZodEnum<{
|
|
110
|
+
auto: "auto";
|
|
111
|
+
confirm: "confirm";
|
|
112
|
+
plan: "plan";
|
|
113
|
+
readonly: "readonly";
|
|
114
|
+
}>;
|
|
115
|
+
allowTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
116
|
+
denyTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
117
|
+
workspaceRoot: z.ZodOptional<z.ZodString>;
|
|
118
|
+
network: z.ZodOptional<z.ZodBoolean>;
|
|
119
|
+
}, z.core.$strict>;
|
|
120
|
+
runtime: z.ZodOptional<z.ZodEnum<{
|
|
121
|
+
claude: "claude";
|
|
122
|
+
codex: "codex";
|
|
123
|
+
pi: "pi";
|
|
124
|
+
}>>;
|
|
125
|
+
sessionRef: z.ZodOptional<z.ZodString>;
|
|
126
|
+
workspaceHint: z.ZodOptional<z.ZodString>;
|
|
127
|
+
limits: z.ZodOptional<z.ZodObject<{
|
|
128
|
+
maxDurationMs: z.ZodOptional<z.ZodNumber>;
|
|
129
|
+
maxTokens: z.ZodOptional<z.ZodNumber>;
|
|
130
|
+
}, z.core.$strip>>;
|
|
131
|
+
}, z.core.$strip>;
|
|
132
|
+
export type TaskOfferPayload = z.infer<typeof TaskOfferPayloadSchema>;
|
|
133
|
+
/**
|
|
134
|
+
* server -> daemon: approve a pending `task.await_approval` request.
|
|
135
|
+
*
|
|
136
|
+
* Semantics (M1 gap #3): the server's own state is authoritative on its own
|
|
137
|
+
* action — calling the server-side `approve()` API moves the task record
|
|
138
|
+
* `AwaitApproval -> Running` immediately. This wire message is a best-effort
|
|
139
|
+
* *notification* telling the daemon to resume the paused runtime session; the
|
|
140
|
+
* daemon does not send a dedicated ack. Its outcome is observable through the
|
|
141
|
+
* task's existing message stream (e.g. `task.progress` resuming, or
|
|
142
|
+
* `task.fail`/`task.cancelled` if resuming turns out to be impossible) — no
|
|
143
|
+
* new ack message type is introduced. See docs/protocol.md "Approval flow".
|
|
144
|
+
*
|
|
145
|
+
* `approvalId` (M5, additive-minor — docs/protocol.md §5.3): OPTIONAL target
|
|
146
|
+
* identity for the SPECIFIC pending approval this decision resolves, rather
|
|
147
|
+
* than "whichever one is currently pending" (the pre-M5 behavior, and still
|
|
148
|
+
* what happens when this field is absent — a legacy server that never
|
|
149
|
+
* learned an id, or one talking to a legacy daemon). When present, the
|
|
150
|
+
* daemon compares it against its own currently-dispatched approval id
|
|
151
|
+
* (`ActiveTask.pendingApprovalId`, `packages/client`'s `task-runner.ts`) and
|
|
152
|
+
* treats a mismatch as a stale, audit-only no-op instead of resolving
|
|
153
|
+
* whatever happens to be pending right now — see `TaskRunner.handleApprove`.
|
|
154
|
+
*/
|
|
155
|
+
export declare const TaskApprovePayloadSchema: z.ZodObject<{
|
|
156
|
+
approvalId: z.ZodOptional<z.ZodString>;
|
|
157
|
+
}, z.core.$strip>;
|
|
158
|
+
export type TaskApprovePayload = z.infer<typeof TaskApprovePayloadSchema>;
|
|
159
|
+
/**
|
|
160
|
+
* server -> daemon: reject a pending `task.await_approval` request.
|
|
161
|
+
*
|
|
162
|
+
* Same best-effort-notification semantics as `task.approve` (M1 gap #3): the
|
|
163
|
+
* server moves its own record `AwaitApproval -> Failed` immediately; this
|
|
164
|
+
* message just tells the daemon to stop, and the daemon reports the outcome
|
|
165
|
+
* via its existing `task.fail` terminal message.
|
|
166
|
+
*
|
|
167
|
+
* `approvalId` (M5, additive-minor — docs/protocol.md §5.3): same optional
|
|
168
|
+
* targeting semantics as `TaskApprovePayloadSchema.approvalId` above, applied
|
|
169
|
+
* to the reject path (`TaskRunner.handleReject`).
|
|
170
|
+
*/
|
|
171
|
+
export declare const TaskRejectPayloadSchema: z.ZodObject<{
|
|
172
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
173
|
+
approvalId: z.ZodOptional<z.ZodString>;
|
|
174
|
+
}, z.core.$strip>;
|
|
175
|
+
export type TaskRejectPayload = z.infer<typeof TaskRejectPayloadSchema>;
|
|
176
|
+
/**
|
|
177
|
+
* server -> daemon: cancel a task in any non-terminal state.
|
|
178
|
+
*
|
|
179
|
+
* Same best-effort-notification semantics (M1 gap #3): the server moves its
|
|
180
|
+
* own record to `Cancelled` immediately on its own action and does not wait
|
|
181
|
+
* for a daemon ack; this message just tells the daemon to stop local work.
|
|
182
|
+
* The daemon reports the outcome via the explicit `task.cancelled` terminal
|
|
183
|
+
* message (M1 gap #6) — not `task.fail`.
|
|
184
|
+
*/
|
|
185
|
+
export declare const TaskCancelPayloadSchema: z.ZodObject<{
|
|
186
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
187
|
+
}, z.core.$strip>;
|
|
188
|
+
export type TaskCancelPayload = z.infer<typeof TaskCancelPayloadSchema>;
|
|
189
|
+
/** server -> daemon: inject steering text into a running task. */
|
|
190
|
+
export declare const TaskSteerPayloadSchema: z.ZodObject<{
|
|
191
|
+
text: z.ZodString;
|
|
192
|
+
}, z.core.$strip>;
|
|
193
|
+
export type TaskSteerPayload = z.infer<typeof TaskSteerPayloadSchema>;
|
|
194
|
+
/**
|
|
195
|
+
* daemon -> server: claim an offered task (idempotent CAS on the server
|
|
196
|
+
* side). `taskId` used to be duplicated here; it is now carried only by the
|
|
197
|
+
* envelope's `task_id` (M1 gap #7).
|
|
198
|
+
*
|
|
199
|
+
* Claiming no longer implies the task is `Running` (M1 gap #2) — see
|
|
200
|
+
* `task.started`.
|
|
201
|
+
*
|
|
202
|
+
* `runtime` (M5, additive-minor — docs/protocol.md §3.1): the ACTUAL
|
|
203
|
+
* adapter this device selected for the task, distinct from `task.offer`'s
|
|
204
|
+
* own `runtime` (the merely REQUESTED one, `TaskOfferPayloadSchema.runtime`
|
|
205
|
+
* above). When an offer names no runtime the daemon auto-selects (pi-first —
|
|
206
|
+
* `TaskRunner.pickAdapter`, `packages/client`'s `task-runner.ts`), and before
|
|
207
|
+
* this field existed the server had no way to learn which adapter actually
|
|
208
|
+
* ran — `TaskSnapshot.runtime` (`packages/server`'s `types.ts`) only ever
|
|
209
|
+
* recorded what was requested. Plain optional property on this already-
|
|
210
|
+
* tolerant `z.object()`: an old server simply never reads it, so this needed
|
|
211
|
+
* no version bump and no emission gating (same shape as `approvalId` on
|
|
212
|
+
* `task.await_approval`/`task.approve`/`task.reject`, §5.3) — a new daemon
|
|
213
|
+
* sends it unconditionally, regardless of whether the connected server is
|
|
214
|
+
* new enough to store it.
|
|
215
|
+
*
|
|
216
|
+
* `capabilities` (S0/D-4, additive-minor — docs/protocol.md §2.4): the
|
|
217
|
+
* TASK-level capability authority — what the claiming adapter reported about
|
|
218
|
+
* itself at the moment it took this task, reusing `RuntimeCapabilitiesSchema`
|
|
219
|
+
* (above) rather than introducing a second capability shape. Same source of
|
|
220
|
+
* truth as `conn.hello.runtimes[].capabilities`, different scope: `conn.hello`
|
|
221
|
+
* is CONNECTION-level discovery ("what could this device run"), which no
|
|
222
|
+
* server-side control decision may read, because it is transport-shaped — a
|
|
223
|
+
* long-poll-only daemon never sends `conn.hello` at all — and it describes a
|
|
224
|
+
* device, not a task. This field is task-shaped: it shares a lifecycle with
|
|
225
|
+
* the task↔runtime binding the claim itself establishes, so a control gate
|
|
226
|
+
* (`steerTask()`, `packages/server`'s `hub.ts`) can key off it and stay
|
|
227
|
+
* correct across reconnects, adapter-set changes, and transports. Plain
|
|
228
|
+
* optional property on this already-tolerant `z.object()`, exactly like
|
|
229
|
+
* `runtime` above: an old daemon simply omits it, and a consumer that gates on
|
|
230
|
+
* it must fail closed on absence rather than assume a default.
|
|
231
|
+
*/
|
|
232
|
+
export declare const TaskClaimPayloadSchema: z.ZodObject<{
|
|
233
|
+
deviceId: z.ZodString;
|
|
234
|
+
agentId: z.ZodOptional<z.ZodString>;
|
|
235
|
+
runtime: z.ZodOptional<z.ZodEnum<{
|
|
236
|
+
claude: "claude";
|
|
237
|
+
codex: "codex";
|
|
238
|
+
pi: "pi";
|
|
239
|
+
}>>;
|
|
240
|
+
capabilities: z.ZodOptional<z.ZodObject<{
|
|
241
|
+
steer: z.ZodOptional<z.ZodBoolean>;
|
|
242
|
+
resume: z.ZodOptional<z.ZodBoolean>;
|
|
243
|
+
approvalInteractive: z.ZodOptional<z.ZodBoolean>;
|
|
244
|
+
permissionModes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
245
|
+
}, z.core.$strip>>;
|
|
246
|
+
}, z.core.$strip>;
|
|
247
|
+
export type TaskClaimPayload = z.infer<typeof TaskClaimPayloadSchema>;
|
|
248
|
+
/**
|
|
249
|
+
* daemon -> server: explicit `Claimed -> Running` transition (M1 gap #2).
|
|
250
|
+
* A `task.claim` no longer implies the task started running; the daemon
|
|
251
|
+
* sends this once it has actually started the runtime session for the task.
|
|
252
|
+
*/
|
|
253
|
+
export declare const TaskStartedPayloadSchema: z.ZodObject<{}, z.core.$strip>;
|
|
254
|
+
export type TaskStartedPayload = z.infer<typeof TaskStartedPayloadSchema>;
|
|
255
|
+
/**
|
|
256
|
+
* daemon -> server: decline an offer *before* claiming it (M1 gap #5) — e.g.
|
|
257
|
+
* no compatible/available runtime, or the offered policy exceeds this
|
|
258
|
+
* device's ceiling. Fail-closed rejections must use this instead of silently
|
|
259
|
+
* dropping the offer.
|
|
260
|
+
*
|
|
261
|
+
* Decision (see docs/protocol.md "Declined vs. Failed" for the full
|
|
262
|
+
* writeup): declining does *not* introduce a new `Declined` terminal state.
|
|
263
|
+
* It maps onto the existing `Failed` state via a new `Offered -> Failed`
|
|
264
|
+
* transition. `reason`/`retryable` intentionally mirror `TaskFailPayload`
|
|
265
|
+
* exactly, because a pre-claim decline and a post-claim failure are the same
|
|
266
|
+
* outcome from the dispatcher's point of view (this attempt produced no
|
|
267
|
+
* result; here's whether retrying — e.g. offering to a different device —
|
|
268
|
+
* makes sense), and keeping the state machine minimal avoids forking every
|
|
269
|
+
* terminal-state consumer into "Failed or Declined, handle both".
|
|
270
|
+
*/
|
|
271
|
+
export declare const TaskDeclinePayloadSchema: z.ZodObject<{
|
|
272
|
+
reason: z.ZodString;
|
|
273
|
+
retryable: z.ZodOptional<z.ZodBoolean>;
|
|
274
|
+
}, z.core.$strip>;
|
|
275
|
+
export type TaskDeclinePayload = z.infer<typeof TaskDeclinePayloadSchema>;
|
|
276
|
+
/**
|
|
277
|
+
* daemon -> server: batch of normalized agent events.
|
|
278
|
+
*
|
|
279
|
+
* `events` elements are known-or-unknown (`AgentEventOrUnknownSchema` —
|
|
280
|
+
* `agent-event.ts`), not bare `AgentEventSchema`: pre-freeze, an unrecognized
|
|
281
|
+
* event `type` must not fail the whole batch, since a peer running a newer
|
|
282
|
+
* minor version may have emitted an additive event variant this schema
|
|
283
|
+
* doesn't know about yet. See `agent-event.ts` for the full rationale and
|
|
284
|
+
* `partitionAgentEvents`/`isKnownAgentEvent` for how consumers should skip
|
|
285
|
+
* unknowns instead of choking on them.
|
|
286
|
+
*/
|
|
287
|
+
export declare const TaskProgressPayloadSchema: z.ZodObject<{
|
|
288
|
+
seq: z.ZodNumber;
|
|
289
|
+
events: z.ZodArray<z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
290
|
+
type: z.ZodLiteral<"progress">;
|
|
291
|
+
text: z.ZodString;
|
|
292
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
293
|
+
type: z.ZodLiteral<"tool_use">;
|
|
294
|
+
tool: z.ZodString;
|
|
295
|
+
input: z.ZodOptional<z.ZodUnknown>;
|
|
296
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
297
|
+
type: z.ZodLiteral<"tool_result">;
|
|
298
|
+
tool: z.ZodString;
|
|
299
|
+
output: z.ZodOptional<z.ZodUnknown>;
|
|
300
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
301
|
+
type: z.ZodLiteral<"artifact">;
|
|
302
|
+
name: z.ZodString;
|
|
303
|
+
contentType: z.ZodString;
|
|
304
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
305
|
+
type: z.ZodLiteral<"needs_approval">;
|
|
306
|
+
summary: z.ZodString;
|
|
307
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
308
|
+
type: z.ZodLiteral<"turn_end">;
|
|
309
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
310
|
+
type: z.ZodLiteral<"error">;
|
|
311
|
+
message: z.ZodString;
|
|
312
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
313
|
+
type: z.ZodLiteral<"usage">;
|
|
314
|
+
inputTokens: z.ZodOptional<z.ZodNumber>;
|
|
315
|
+
cachedInputTokens: z.ZodOptional<z.ZodNumber>;
|
|
316
|
+
outputTokens: z.ZodOptional<z.ZodNumber>;
|
|
317
|
+
reasoningTokens: z.ZodOptional<z.ZodNumber>;
|
|
318
|
+
totalTokens: z.ZodOptional<z.ZodNumber>;
|
|
319
|
+
}, z.core.$strip>], "type">, z.ZodObject<{
|
|
320
|
+
type: z.ZodString;
|
|
321
|
+
}, z.core.$loose>]>>;
|
|
322
|
+
}, z.core.$strip>;
|
|
323
|
+
export type TaskProgressPayload = z.infer<typeof TaskProgressPayloadSchema>;
|
|
324
|
+
/** daemon -> server: an artifact produced by the task, inline or by blob ref. */
|
|
325
|
+
export declare const TaskArtifactPayloadSchema: z.ZodObject<{
|
|
326
|
+
name: z.ZodString;
|
|
327
|
+
contentType: z.ZodString;
|
|
328
|
+
inline: z.ZodOptional<z.ZodString>;
|
|
329
|
+
blobRef: z.ZodOptional<z.ZodObject<{
|
|
330
|
+
blobId: z.ZodString;
|
|
331
|
+
contentHash: z.ZodString;
|
|
332
|
+
size: z.ZodNumber;
|
|
333
|
+
contentType: z.ZodString;
|
|
334
|
+
url: z.ZodOptional<z.ZodString>;
|
|
335
|
+
}, z.core.$strip>>;
|
|
336
|
+
}, z.core.$strip>;
|
|
337
|
+
export type TaskArtifactPayload = z.infer<typeof TaskArtifactPayloadSchema>;
|
|
338
|
+
/**
|
|
339
|
+
* daemon -> server: task is blocked on an out-of-band approval.
|
|
340
|
+
*
|
|
341
|
+
* `approvalId` (M5, additive-minor — docs/protocol.md §5.3): the daemon's own
|
|
342
|
+
* locally-generated identity for THIS SPECIFIC pending approval
|
|
343
|
+
* (`ApprovalRegistry`, `packages/client`'s `approvals.ts`) — included
|
|
344
|
+
* unconditionally by an M5+ daemon, regardless of whether the connected
|
|
345
|
+
* server has advertised the `approval-targeting` capability flag
|
|
346
|
+
* (`version.ts`; see that flag's own doc comment for why no emission gating
|
|
347
|
+
* is needed here — it's a tolerant `z.object()` field, so an older server
|
|
348
|
+
* simply ignores it). Optional purely for wire tolerance with a pre-M5
|
|
349
|
+
* daemon build that never set it at all: a server that never learns an id
|
|
350
|
+
* for a task's current approval can't target a later `approve`/`reject`
|
|
351
|
+
* decision and falls back to resolving "whichever approval is currently
|
|
352
|
+
* pending" — the same behavior every server had before this field existed.
|
|
353
|
+
*/
|
|
354
|
+
export declare const TaskAwaitApprovalPayloadSchema: z.ZodObject<{
|
|
355
|
+
summary: z.ZodString;
|
|
356
|
+
approvalId: z.ZodOptional<z.ZodString>;
|
|
357
|
+
}, z.core.$strip>;
|
|
358
|
+
export type TaskAwaitApprovalPayload = z.infer<typeof TaskAwaitApprovalPayloadSchema>;
|
|
359
|
+
/** daemon -> server: task finished successfully. */
|
|
360
|
+
export declare const TaskCompletePayloadSchema: z.ZodObject<{
|
|
361
|
+
summary: z.ZodString;
|
|
362
|
+
sessionRef: z.ZodString;
|
|
363
|
+
artifactRefs: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
364
|
+
blobId: z.ZodString;
|
|
365
|
+
contentHash: z.ZodString;
|
|
366
|
+
size: z.ZodNumber;
|
|
367
|
+
contentType: z.ZodString;
|
|
368
|
+
url: z.ZodOptional<z.ZodString>;
|
|
369
|
+
}, z.core.$strip>>>;
|
|
370
|
+
}, z.core.$strip>;
|
|
371
|
+
export type TaskCompletePayload = z.infer<typeof TaskCompletePayloadSchema>;
|
|
372
|
+
/** daemon -> server: task failed. */
|
|
373
|
+
export declare const TaskFailPayloadSchema: z.ZodObject<{
|
|
374
|
+
reason: z.ZodString;
|
|
375
|
+
retryable: z.ZodOptional<z.ZodBoolean>;
|
|
376
|
+
}, z.core.$strip>;
|
|
377
|
+
export type TaskFailPayload = z.infer<typeof TaskFailPayloadSchema>;
|
|
378
|
+
/**
|
|
379
|
+
* daemon -> server: task ended in the `Cancelled` state (M1 gap #6) — either
|
|
380
|
+
* in response to a server-sent `task.cancel`, or a cancellation the daemon
|
|
381
|
+
* observed/decided locally (e.g. a local stop action) that the server didn't
|
|
382
|
+
* initiate. This is the canonical way to report a `Cancelled` outcome; it
|
|
383
|
+
* supersedes the M0 convention of `task.fail({ reason: 'cancelled' })`.
|
|
384
|
+
*
|
|
385
|
+
* This is deliberately its own message rather than folded into `task.fail`
|
|
386
|
+
* (decision: prefer the explicit message — see docs/protocol.md) because
|
|
387
|
+
* `Cancelled` is semantically distinct from `Failed`: one is an intentional
|
|
388
|
+
* stop, the other an error. Overloading `task.fail` with a magic
|
|
389
|
+
* `reason: 'cancelled'` string convention hid that distinction on the wire.
|
|
390
|
+
*
|
|
391
|
+
* Dual-purpose on receipt: if the server already moved its own record to
|
|
392
|
+
* `Cancelled` (it initiated the cancel — M1 gap #3's "server state is
|
|
393
|
+
* authoritative" rule), this is an idempotent no-op ack. If the server
|
|
394
|
+
* hasn't yet (a locally-observed cancellation), this is the authoritative
|
|
395
|
+
* trigger that moves `Claimed`/`Running`/`AwaitApproval -> Cancelled`.
|
|
396
|
+
*/
|
|
397
|
+
export declare const TaskCancelledPayloadSchema: z.ZodObject<{
|
|
398
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
399
|
+
}, z.core.$strip>;
|
|
400
|
+
export type TaskCancelledPayload = z.infer<typeof TaskCancelledPayloadSchema>;
|
|
401
|
+
/**
|
|
402
|
+
* daemon -> server: a pending `task.await_approval` was resolved entirely
|
|
403
|
+
* LOCALLY on the device — the local control-socket `approvals.resolve` RPC,
|
|
404
|
+
* a fail-closed `requestApproval` timeout, or a fail-closed eviction/finish
|
|
405
|
+
* rejection (see `packages/client`'s `task-runner.ts`/`approvals.ts`) —
|
|
406
|
+
* *without* a wire `task.approve`/`task.reject` ever having been exchanged
|
|
407
|
+
* for it. This is the additive-minor answer to a gap the M4 Phase 3 approval
|
|
408
|
+
* work left open (see the "Deferred additive candidate" note this schema
|
|
409
|
+
* resolves, `docs/protocol.md`): today the server only learns of a local
|
|
410
|
+
* resolution IMPLICITLY, after the fact, once the daemon's next
|
|
411
|
+
* `task.progress`/`task.artifact`/`task.complete` proves the task already
|
|
412
|
+
* moved on (`ConnectionHub.resumeIfImplicitlyApproved`,
|
|
413
|
+
* `packages/server/src/hub.ts`) — a window in which a SaaS-side
|
|
414
|
+
* `TaskHandle.approve()`/`.reject()` can independently decide (and win) the
|
|
415
|
+
* server's own authoritative record before that evidence ever arrives. This
|
|
416
|
+
* message lets the daemon report the local resolution explicitly and
|
|
417
|
+
* immediately, narrowing that window from "until the next progress message"
|
|
418
|
+
* down to ordinary network latency; the implicit-inference path stays as-is,
|
|
419
|
+
* unconditionally, as the compatibility fallback for an old server that
|
|
420
|
+
* never advertises the `approval_resolved` capability flag (`version.ts`) or
|
|
421
|
+
* an old daemon that predates this message entirely.
|
|
422
|
+
*
|
|
423
|
+
* Observability-class tolerance applies (not control/security — see the
|
|
424
|
+
* freeze rule's asymmetry, `docs/protocol.md`): this is a daemon reporting
|
|
425
|
+
* what it already did locally, not a payload that grants/denies anything on
|
|
426
|
+
* its own — the receiving server's own state machine (`TASK_TRANSITIONS`,
|
|
427
|
+
* `task-state.ts`) is still what decides whether the reported resolution is
|
|
428
|
+
* legal to apply. Plain `z.object()` (not `.strict()`), same as every other
|
|
429
|
+
* non-control payload in this file.
|
|
430
|
+
*
|
|
431
|
+
* `resolvedBy` is a single-value enum (`'local'`) rather than a bare string:
|
|
432
|
+
* deliberately future-proof (a later wave could add e.g. `'operator-cli'` as
|
|
433
|
+
* a DISTINCT value without a version bump — a new enum member is additive,
|
|
434
|
+
* same as a new message type or capability flag), while still being a closed,
|
|
435
|
+
* typed shape today rather than an open string a typo could silently widen.
|
|
436
|
+
*/
|
|
437
|
+
export declare const TaskApprovalResolvedPayloadSchema: z.ZodObject<{
|
|
438
|
+
approvalId: z.ZodString;
|
|
439
|
+
decision: z.ZodEnum<{
|
|
440
|
+
approve: "approve";
|
|
441
|
+
reject: "reject";
|
|
442
|
+
}>;
|
|
443
|
+
resolvedBy: z.ZodEnum<{
|
|
444
|
+
local: "local";
|
|
445
|
+
}>;
|
|
446
|
+
at: z.ZodISODateTime;
|
|
447
|
+
}, z.core.$strip>;
|
|
448
|
+
export type TaskApprovalResolvedPayload = z.infer<typeof TaskApprovalResolvedPayloadSchema>;
|
|
449
|
+
export declare const MESSAGE_PAYLOAD_SCHEMAS: {
|
|
450
|
+
readonly 'conn.hello': z.ZodObject<{
|
|
451
|
+
protocolVersions: z.ZodArray<z.ZodNumber>;
|
|
452
|
+
capabilities: z.ZodArray<z.ZodString>;
|
|
453
|
+
deviceId: z.ZodString;
|
|
454
|
+
productId: z.ZodString;
|
|
455
|
+
runtimes: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
456
|
+
id: z.ZodEnum<{
|
|
457
|
+
claude: "claude";
|
|
458
|
+
codex: "codex";
|
|
459
|
+
pi: "pi";
|
|
460
|
+
}>;
|
|
461
|
+
version: z.ZodOptional<z.ZodString>;
|
|
462
|
+
authPresent: z.ZodOptional<z.ZodBoolean>;
|
|
463
|
+
capabilities: z.ZodOptional<z.ZodObject<{
|
|
464
|
+
steer: z.ZodOptional<z.ZodBoolean>;
|
|
465
|
+
resume: z.ZodOptional<z.ZodBoolean>;
|
|
466
|
+
approvalInteractive: z.ZodOptional<z.ZodBoolean>;
|
|
467
|
+
permissionModes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
468
|
+
}, z.core.$strip>>;
|
|
469
|
+
}, z.core.$strip>>>;
|
|
470
|
+
cursor: z.ZodOptional<z.ZodNumber>;
|
|
471
|
+
}, z.core.$strip>;
|
|
472
|
+
readonly 'conn.ack': z.ZodObject<{
|
|
473
|
+
protocolVersion: z.ZodNumber;
|
|
474
|
+
capabilities: z.ZodArray<z.ZodString>;
|
|
475
|
+
serverTime: z.ZodISODateTime;
|
|
476
|
+
}, z.core.$strip>;
|
|
477
|
+
readonly 'task.offer': z.ZodObject<{
|
|
478
|
+
instruction: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
479
|
+
blobRef: z.ZodObject<{
|
|
480
|
+
blobId: z.ZodString;
|
|
481
|
+
contentHash: z.ZodString;
|
|
482
|
+
size: z.ZodNumber;
|
|
483
|
+
contentType: z.ZodString;
|
|
484
|
+
url: z.ZodOptional<z.ZodString>;
|
|
485
|
+
}, z.core.$strip>;
|
|
486
|
+
}, z.core.$strict>]>;
|
|
487
|
+
policy: z.ZodObject<{
|
|
488
|
+
mode: z.ZodEnum<{
|
|
489
|
+
auto: "auto";
|
|
490
|
+
confirm: "confirm";
|
|
491
|
+
plan: "plan";
|
|
492
|
+
readonly: "readonly";
|
|
493
|
+
}>;
|
|
494
|
+
allowTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
495
|
+
denyTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
496
|
+
workspaceRoot: z.ZodOptional<z.ZodString>;
|
|
497
|
+
network: z.ZodOptional<z.ZodBoolean>;
|
|
498
|
+
}, z.core.$strict>;
|
|
499
|
+
runtime: z.ZodOptional<z.ZodEnum<{
|
|
500
|
+
claude: "claude";
|
|
501
|
+
codex: "codex";
|
|
502
|
+
pi: "pi";
|
|
503
|
+
}>>;
|
|
504
|
+
sessionRef: z.ZodOptional<z.ZodString>;
|
|
505
|
+
workspaceHint: z.ZodOptional<z.ZodString>;
|
|
506
|
+
limits: z.ZodOptional<z.ZodObject<{
|
|
507
|
+
maxDurationMs: z.ZodOptional<z.ZodNumber>;
|
|
508
|
+
maxTokens: z.ZodOptional<z.ZodNumber>;
|
|
509
|
+
}, z.core.$strip>>;
|
|
510
|
+
}, z.core.$strip>;
|
|
511
|
+
readonly 'task.approve': z.ZodObject<{
|
|
512
|
+
approvalId: z.ZodOptional<z.ZodString>;
|
|
513
|
+
}, z.core.$strip>;
|
|
514
|
+
readonly 'task.reject': z.ZodObject<{
|
|
515
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
516
|
+
approvalId: z.ZodOptional<z.ZodString>;
|
|
517
|
+
}, z.core.$strip>;
|
|
518
|
+
readonly 'task.cancel': z.ZodObject<{
|
|
519
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
520
|
+
}, z.core.$strip>;
|
|
521
|
+
readonly 'task.steer': z.ZodObject<{
|
|
522
|
+
text: z.ZodString;
|
|
523
|
+
}, z.core.$strip>;
|
|
524
|
+
readonly 'task.claim': z.ZodObject<{
|
|
525
|
+
deviceId: z.ZodString;
|
|
526
|
+
agentId: z.ZodOptional<z.ZodString>;
|
|
527
|
+
runtime: z.ZodOptional<z.ZodEnum<{
|
|
528
|
+
claude: "claude";
|
|
529
|
+
codex: "codex";
|
|
530
|
+
pi: "pi";
|
|
531
|
+
}>>;
|
|
532
|
+
capabilities: z.ZodOptional<z.ZodObject<{
|
|
533
|
+
steer: z.ZodOptional<z.ZodBoolean>;
|
|
534
|
+
resume: z.ZodOptional<z.ZodBoolean>;
|
|
535
|
+
approvalInteractive: z.ZodOptional<z.ZodBoolean>;
|
|
536
|
+
permissionModes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
537
|
+
}, z.core.$strip>>;
|
|
538
|
+
}, z.core.$strip>;
|
|
539
|
+
readonly 'task.started': z.ZodObject<{}, z.core.$strip>;
|
|
540
|
+
readonly 'task.decline': z.ZodObject<{
|
|
541
|
+
reason: z.ZodString;
|
|
542
|
+
retryable: z.ZodOptional<z.ZodBoolean>;
|
|
543
|
+
}, z.core.$strip>;
|
|
544
|
+
readonly 'task.progress': z.ZodObject<{
|
|
545
|
+
seq: z.ZodNumber;
|
|
546
|
+
events: z.ZodArray<z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
547
|
+
type: z.ZodLiteral<"progress">;
|
|
548
|
+
text: z.ZodString;
|
|
549
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
550
|
+
type: z.ZodLiteral<"tool_use">;
|
|
551
|
+
tool: z.ZodString;
|
|
552
|
+
input: z.ZodOptional<z.ZodUnknown>;
|
|
553
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
554
|
+
type: z.ZodLiteral<"tool_result">;
|
|
555
|
+
tool: z.ZodString;
|
|
556
|
+
output: z.ZodOptional<z.ZodUnknown>;
|
|
557
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
558
|
+
type: z.ZodLiteral<"artifact">;
|
|
559
|
+
name: z.ZodString;
|
|
560
|
+
contentType: z.ZodString;
|
|
561
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
562
|
+
type: z.ZodLiteral<"needs_approval">;
|
|
563
|
+
summary: z.ZodString;
|
|
564
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
565
|
+
type: z.ZodLiteral<"turn_end">;
|
|
566
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
567
|
+
type: z.ZodLiteral<"error">;
|
|
568
|
+
message: z.ZodString;
|
|
569
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
570
|
+
type: z.ZodLiteral<"usage">;
|
|
571
|
+
inputTokens: z.ZodOptional<z.ZodNumber>;
|
|
572
|
+
cachedInputTokens: z.ZodOptional<z.ZodNumber>;
|
|
573
|
+
outputTokens: z.ZodOptional<z.ZodNumber>;
|
|
574
|
+
reasoningTokens: z.ZodOptional<z.ZodNumber>;
|
|
575
|
+
totalTokens: z.ZodOptional<z.ZodNumber>;
|
|
576
|
+
}, z.core.$strip>], "type">, z.ZodObject<{
|
|
577
|
+
type: z.ZodString;
|
|
578
|
+
}, z.core.$loose>]>>;
|
|
579
|
+
}, z.core.$strip>;
|
|
580
|
+
readonly 'task.artifact': z.ZodObject<{
|
|
581
|
+
name: z.ZodString;
|
|
582
|
+
contentType: z.ZodString;
|
|
583
|
+
inline: z.ZodOptional<z.ZodString>;
|
|
584
|
+
blobRef: z.ZodOptional<z.ZodObject<{
|
|
585
|
+
blobId: z.ZodString;
|
|
586
|
+
contentHash: z.ZodString;
|
|
587
|
+
size: z.ZodNumber;
|
|
588
|
+
contentType: z.ZodString;
|
|
589
|
+
url: z.ZodOptional<z.ZodString>;
|
|
590
|
+
}, z.core.$strip>>;
|
|
591
|
+
}, z.core.$strip>;
|
|
592
|
+
readonly 'task.await_approval': z.ZodObject<{
|
|
593
|
+
summary: z.ZodString;
|
|
594
|
+
approvalId: z.ZodOptional<z.ZodString>;
|
|
595
|
+
}, z.core.$strip>;
|
|
596
|
+
readonly 'task.complete': z.ZodObject<{
|
|
597
|
+
summary: z.ZodString;
|
|
598
|
+
sessionRef: z.ZodString;
|
|
599
|
+
artifactRefs: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
600
|
+
blobId: z.ZodString;
|
|
601
|
+
contentHash: z.ZodString;
|
|
602
|
+
size: z.ZodNumber;
|
|
603
|
+
contentType: z.ZodString;
|
|
604
|
+
url: z.ZodOptional<z.ZodString>;
|
|
605
|
+
}, z.core.$strip>>>;
|
|
606
|
+
}, z.core.$strip>;
|
|
607
|
+
readonly 'task.fail': z.ZodObject<{
|
|
608
|
+
reason: z.ZodString;
|
|
609
|
+
retryable: z.ZodOptional<z.ZodBoolean>;
|
|
610
|
+
}, z.core.$strip>;
|
|
611
|
+
readonly 'task.cancelled': z.ZodObject<{
|
|
612
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
613
|
+
}, z.core.$strip>;
|
|
614
|
+
readonly 'task.approval_resolved': z.ZodObject<{
|
|
615
|
+
approvalId: z.ZodString;
|
|
616
|
+
decision: z.ZodEnum<{
|
|
617
|
+
approve: "approve";
|
|
618
|
+
reject: "reject";
|
|
619
|
+
}>;
|
|
620
|
+
resolvedBy: z.ZodEnum<{
|
|
621
|
+
local: "local";
|
|
622
|
+
}>;
|
|
623
|
+
at: z.ZodISODateTime;
|
|
624
|
+
}, z.core.$strip>;
|
|
625
|
+
};
|
|
626
|
+
export type MessageType = keyof typeof MESSAGE_PAYLOAD_SCHEMAS;
|
|
627
|
+
export declare const MESSAGE_TYPES: MessageType[];
|
|
628
|
+
/**
|
|
629
|
+
* Message types the server sends to the daemon. Used by {@link EnvelopeSchema}
|
|
630
|
+
* (`envelope.ts`) to decide which branches require envelope `seq` (M1
|
|
631
|
+
* redelivery cursor).
|
|
632
|
+
*/
|
|
633
|
+
export declare const SERVER_TO_DAEMON_TYPES: readonly ["conn.ack", "task.offer", "task.approve", "task.reject", "task.cancel", "task.steer"];
|
|
634
|
+
/**
|
|
635
|
+
* Message types the daemon sends to the server — the flip side of
|
|
636
|
+
* {@link SERVER_TO_DAEMON_TYPES}. `conn.hello` is deliberately excluded: it's
|
|
637
|
+
* only ever valid as the first frame of a WS handshake (`ws-server.ts`), not
|
|
638
|
+
* as ongoing inbound traffic through `ConnectionHub.handleInbound`.
|
|
639
|
+
*
|
|
640
|
+
* Used by `handleInbound` (`@byok-sdk/server`'s `hub.ts`) as the type-allow gate
|
|
641
|
+
* for every inbound envelope, WS and `POST /byok/messages` alike (finding
|
|
642
|
+
* P2): a `type` outside this set — a server -> daemon type arriving inbound,
|
|
643
|
+
* or anything unrecognized — is rejected before it's dispatched to any
|
|
644
|
+
* handler or counted `accepted` on the `/byok/messages` wire.
|
|
645
|
+
*/
|
|
646
|
+
export declare const DAEMON_TO_SERVER_TYPES: readonly ["task.claim", "task.started", "task.decline", "task.progress", "task.artifact", "task.await_approval", "task.complete", "task.fail", "task.cancelled", "task.approval_resolved"];
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const PERMISSION_MODES: readonly ['auto', 'confirm', 'readonly', 'plan'];
|
|
3
|
+
export type PermissionMode = (typeof PERMISSION_MODES)[number];
|
|
4
|
+
/**
|
|
5
|
+
* Policy the server proposes for a task. The daemon/runtime adapter maps this
|
|
6
|
+
* onto the concrete runtime's flags; anything that can't be expressed exactly
|
|
7
|
+
* must fail closed (deny) rather than silently widen the grant.
|
|
8
|
+
*
|
|
9
|
+
* `.strict()`: this is control/security data, so per the freeze rule's
|
|
10
|
+
* observability-vs-control asymmetry (docs/protocol.md "Freeze rule") an
|
|
11
|
+
* unrecognized field must be REJECTED, not silently stripped-and-ignored the
|
|
12
|
+
* way an ordinary payload's unknown field is (plain `z.object()`'s default
|
|
13
|
+
* behavior). Without `.strict()`, a policy carrying a future constraint this
|
|
14
|
+
* schema doesn't know about yet would parse successfully with that
|
|
15
|
+
* constraint silently discarded — exactly the silent-widening failure mode
|
|
16
|
+
* this type's own doc comment above warns against, since a stripped
|
|
17
|
+
* constraint is indistinguishable from a constraint that was never sent.
|
|
18
|
+
*
|
|
19
|
+
* Consequence: adding a new field to this schema post-freeze is therefore a
|
|
20
|
+
* BREAKING change requiring a `PROTOCOL_VERSION` bump — unlike the general
|
|
21
|
+
* "a new optional field on an existing payload is non-breaking" rule the
|
|
22
|
+
* freeze rule grants every other schema. That's intentional: a new
|
|
23
|
+
* security/control constraint must force a conscious version bump so an
|
|
24
|
+
* unupgraded peer can never silently ignore it, rather than being added the
|
|
25
|
+
* same low-friction way a harmless observability field would be.
|
|
26
|
+
*/
|
|
27
|
+
export declare const PermissionPolicySchema: z.ZodObject<{
|
|
28
|
+
mode: z.ZodEnum<{
|
|
29
|
+
auto: "auto";
|
|
30
|
+
confirm: "confirm";
|
|
31
|
+
plan: "plan";
|
|
32
|
+
readonly: "readonly";
|
|
33
|
+
}>;
|
|
34
|
+
allowTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
35
|
+
denyTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
36
|
+
workspaceRoot: z.ZodOptional<z.ZodString>;
|
|
37
|
+
network: z.ZodOptional<z.ZodBoolean>;
|
|
38
|
+
}, z.core.$strict>;
|
|
39
|
+
export type PermissionPolicy = z.infer<typeof PermissionPolicySchema>;
|