@paradow/ledge 0.19.1 → 0.21.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/cli/{attach-3BKQSEWC.js → attach-IVICSJYB.js} +11 -11
- package/dist/cli/{bridge-APNFBPNE.js → bridge-H3ZPGIUY.js} +2 -2
- package/dist/cli/{chunk-3HCID6NW.js → chunk-24AHC55Y.js} +3 -3
- package/dist/cli/{chunk-3EIRKAX7.js → chunk-2VSEIOGA.js} +4 -4
- package/dist/cli/{chunk-TRTS24PF.js → chunk-35BPMR6P.js} +2 -2
- package/dist/cli/{chunk-43D6NMYH.js → chunk-6IYPRUQG.js} +1 -1
- package/dist/cli/{chunk-ZUYOA55W.js → chunk-AJFC33TH.js} +2 -2
- package/dist/cli/{chunk-LOOOHYZR.js → chunk-ALEZJFJ3.js} +8 -8
- package/dist/cli/{chunk-BVBX222F.js → chunk-EBBAOQ2Z.js} +7 -6
- package/dist/cli/{chunk-WP77O5LC.js → chunk-EKXZ45MQ.js} +1182 -621
- package/dist/cli/{chunk-HP3G2TYJ.js → chunk-EX66KH66.js} +730 -646
- package/dist/cli/{chunk-7ZAA75HG.js → chunk-HOOHS3MX.js} +1 -1
- package/dist/cli/{chunk-FQZ3IX6E.js → chunk-K7UEKSB2.js} +2 -2
- package/dist/cli/{chunk-GXFU4XAX.js → chunk-KACRWFN3.js} +1 -1
- package/dist/cli/chunk-NFXFY5CT.js +6 -0
- package/dist/cli/{chunk-WJ6YMZTT.js → chunk-NLL2EQJ2.js} +2 -2
- package/dist/cli/{chunk-KKNE7BFZ.js → chunk-WRE3PUTV.js} +35 -11
- package/dist/cli/{chunk-WCS24ICX.js → chunk-ZQON4EV7.js} +2 -2
- package/dist/cli/{chunk-Y5DJ5INP.js → chunk-ZZMZDAF6.js} +3 -3
- package/dist/cli/{daemon-YHRAZSRS.js → daemon-5FPZG5R3.js} +87 -25
- package/dist/cli/decide-2ZKSX7O5.js +56 -0
- package/dist/cli/{handover-UXISKYPS.js → handover-AZ35QZRK.js} +5 -5
- package/dist/cli/{hook-5UAARBWU.js → hook-KANGO46Y.js} +21 -14
- package/dist/cli/index.js +23 -16
- package/dist/cli/launch-DEKJ5HI4.js +34 -0
- package/dist/cli/{send-NLVR6PL2.js → send-BFPJBXXH.js} +5 -5
- package/dist/cli/{setup-EEIXRAMU.js → setup-47ODKJBM.js} +4 -4
- package/dist/cli/{status-2OCYHOWZ.js → status-JPF4NZNI.js} +3 -3
- package/dist/cli/{task-AOOWHPMN.js → task-UTRG4KA5.js} +5 -5
- package/dist/cli/{team-TVNSVYWW.js → team-SZJHGA7D.js} +6 -6
- package/dist/cli/{tui-5XPPX4GR.js → tui-GEJHBWP5.js} +817 -367
- package/dist/cli/{uninstall-UUN7LIIT.js → uninstall-QNWRD27D.js} +4 -4
- package/dist/cli/{version-HB3S4IVG.js → version-YUO6SLAF.js} +1 -1
- package/dist/cli/who-NYPVBO64.js +11 -0
- package/package.json +1 -1
- package/dist/cli/chunk-TVIAHOOD.js +0 -6
- package/dist/cli/launch-YQYCDZ7N.js +0 -34
- package/dist/cli/who-52MENZTT.js +0 -11
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
paths
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HOOHS3MX.js";
|
|
4
4
|
|
|
5
5
|
// ../protocol/src/handover.ts
|
|
6
6
|
import { z } from "zod";
|
|
@@ -164,6 +164,19 @@ import { z as z3 } from "zod";
|
|
|
164
164
|
var TASK_TITLE_MAX = 200;
|
|
165
165
|
var TASK_TEXT_MAX = 2e4;
|
|
166
166
|
var LEDGE_GIVER = "ledge";
|
|
167
|
+
var TASK_OPS = ["give", "take", "pass", "done", "refuse", "cancel", "drop"];
|
|
168
|
+
var TRANSMISSION_OPS = ["give", "pass", "done", "refuse", "cancel"];
|
|
169
|
+
var TaskLogEntrySchema = z3.object({
|
|
170
|
+
at: z3.string(),
|
|
171
|
+
by: z3.string(),
|
|
172
|
+
what: z3.string(),
|
|
173
|
+
op: z3.enum(TASK_OPS).optional(),
|
|
174
|
+
from: z3.string().optional(),
|
|
175
|
+
to: z3.string().optional(),
|
|
176
|
+
fromName: z3.string().optional(),
|
|
177
|
+
toName: z3.string().optional(),
|
|
178
|
+
note: z3.string().optional()
|
|
179
|
+
});
|
|
167
180
|
var TaskSchema = z3.object({
|
|
168
181
|
id: z3.string(),
|
|
169
182
|
title: z3.string(),
|
|
@@ -180,8 +193,12 @@ var TaskSchema = z3.object({
|
|
|
180
193
|
seen: z3.boolean().optional(),
|
|
181
194
|
at: z3.string(),
|
|
182
195
|
updatedAt: z3.string(),
|
|
183
|
-
log: z3.array(
|
|
196
|
+
log: z3.array(TaskLogEntrySchema)
|
|
184
197
|
});
|
|
198
|
+
var handOver = (op) => TRANSMISSION_OPS.includes(op ?? "");
|
|
199
|
+
function transmissions(t) {
|
|
200
|
+
return t.log.flatMap((e, index) => handOver(e.op) && e.from !== void 0 && e.to !== void 0 ? [{ index, at: e.at, op: e.op, from: e.from, to: e.to, fromName: e.fromName ?? "", toName: e.toName ?? "", ...e.note !== void 0 ? { note: e.note } : {} }] : []);
|
|
201
|
+
}
|
|
185
202
|
var givenByLedge = (t) => t.giver === LEDGE_GIVER;
|
|
186
203
|
var taskClosed = (t) => t.state === "done" || t.state === "refused" || t.state === "dropped";
|
|
187
204
|
var TaskCmdSchema = z3.object({
|
|
@@ -208,170 +225,205 @@ var TaskResultSchema = z3.object({
|
|
|
208
225
|
});
|
|
209
226
|
|
|
210
227
|
// ../protocol/src/messages.ts
|
|
211
|
-
import { z as
|
|
228
|
+
import { z as z19 } from "zod";
|
|
212
229
|
|
|
213
230
|
// ../protocol/src/chat.ts
|
|
231
|
+
import { z as z5 } from "zod";
|
|
232
|
+
|
|
233
|
+
// ../protocol/src/attachments.ts
|
|
214
234
|
import { z as z4 } from "zod";
|
|
215
|
-
var
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
235
|
+
var ATTACHMENT_ID = /^[0-9a-f]{64}$/;
|
|
236
|
+
var AttachmentIdSchema = z4.string().regex(ATTACHMENT_ID);
|
|
237
|
+
var IMAGE_MIMES = ["image/webp", "image/jpeg", "image/png", "image/gif"];
|
|
238
|
+
var ImageMimeSchema = z4.enum(IMAGE_MIMES);
|
|
239
|
+
var ATTACHMENT_MAX = 4e5;
|
|
240
|
+
var ATTACHMENT_LOCAL_MAX = 2e6;
|
|
241
|
+
var PREVIEW_MAX = 4e4;
|
|
242
|
+
var ATTACHMENTS_MAX = 5;
|
|
243
|
+
var b64Max = (bytes) => Math.ceil(bytes / 3) * 4;
|
|
244
|
+
var AttachmentRefSchema = z4.object({
|
|
245
|
+
id: AttachmentIdSchema,
|
|
246
|
+
mime: ImageMimeSchema,
|
|
247
|
+
width: z4.number().int().positive(),
|
|
248
|
+
height: z4.number().int().positive(),
|
|
249
|
+
bytes: z4.number().int().positive(),
|
|
250
|
+
preview: z4.boolean()
|
|
220
251
|
});
|
|
221
|
-
var
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
252
|
+
var ImageUploadSchema = z4.object({
|
|
253
|
+
mime: ImageMimeSchema,
|
|
254
|
+
data: z4.string().min(1).max(b64Max(ATTACHMENT_LOCAL_MAX)),
|
|
255
|
+
preview: z4.object({ mime: ImageMimeSchema, data: z4.string().min(1).max(b64Max(PREVIEW_MAX)) }).optional()
|
|
256
|
+
});
|
|
257
|
+
var AttachmentErrorReasonSchema = z4.enum(["too_large", "not_image", "unreadable", "not_found", "offline"]);
|
|
258
|
+
var requestId = z4.string().min(1).max(100);
|
|
259
|
+
var AttachmentPutSchema = z4.object({ type: z4.literal("attachment.put"), requestId, id: z4.string().optional(), image: ImageUploadSchema });
|
|
260
|
+
var AttachmentGetSchema = z4.object({ type: z4.literal("attachment.get"), requestId, attachment: AttachmentIdSchema, preview: z4.boolean().optional(), id: z4.string().optional(), machine: z4.string().optional() });
|
|
261
|
+
var AttachmentStoredSchema = z4.object({ type: z4.literal("attachment.stored"), requestId, ref: AttachmentRefSchema });
|
|
262
|
+
var AttachmentDataSchema = z4.object({ type: z4.literal("attachment.data"), requestId, attachment: AttachmentIdSchema, mime: ImageMimeSchema, data: z4.string() });
|
|
263
|
+
var AttachmentErrorSchema = z4.object({ type: z4.literal("attachment.error"), requestId, reason: AttachmentErrorReasonSchema });
|
|
264
|
+
|
|
265
|
+
// ../protocol/src/chat.ts
|
|
266
|
+
var ChatStepSchema = z5.object({
|
|
267
|
+
kind: z5.enum(["sessions", "pane", "reply", "git", "repo"]),
|
|
268
|
+
id: z5.string().optional(),
|
|
269
|
+
name: z5.string().optional(),
|
|
270
|
+
path: z5.string().optional()
|
|
271
|
+
});
|
|
272
|
+
var ChatProposalSchema = z5.object({
|
|
273
|
+
cwd: z5.string().min(1),
|
|
274
|
+
project: z5.string(),
|
|
275
|
+
prompt: z5.string().optional(),
|
|
225
276
|
tool: ToolSchema,
|
|
226
|
-
launchedId:
|
|
227
|
-
error:
|
|
277
|
+
launchedId: z5.string().optional(),
|
|
278
|
+
error: z5.string().optional()
|
|
228
279
|
});
|
|
229
280
|
var MAX_PROPOSALS = 8;
|
|
230
|
-
var ChatProposalsSchema =
|
|
231
|
-
var ChatRelaySchema =
|
|
232
|
-
id:
|
|
233
|
-
name:
|
|
281
|
+
var ChatProposalsSchema = z5.array(ChatProposalSchema).min(1).max(MAX_PROPOSALS);
|
|
282
|
+
var ChatRelaySchema = z5.object({
|
|
283
|
+
id: z5.string().min(1),
|
|
284
|
+
name: z5.string(),
|
|
234
285
|
tool: ToolSchema,
|
|
235
|
-
text:
|
|
236
|
-
status:
|
|
237
|
-
sentAt:
|
|
238
|
-
error:
|
|
286
|
+
text: z5.string().min(1),
|
|
287
|
+
status: z5.enum(["queued", "sent"]).optional(),
|
|
288
|
+
sentAt: z5.string().datetime().optional(),
|
|
289
|
+
error: z5.string().optional()
|
|
239
290
|
});
|
|
240
|
-
var ChatCloseSchema =
|
|
241
|
-
id:
|
|
242
|
-
name:
|
|
291
|
+
var ChatCloseSchema = z5.object({
|
|
292
|
+
id: z5.string().min(1),
|
|
293
|
+
name: z5.string(),
|
|
243
294
|
tool: ToolSchema,
|
|
244
|
-
closedAt:
|
|
245
|
-
how:
|
|
246
|
-
error:
|
|
295
|
+
closedAt: z5.string().datetime().optional(),
|
|
296
|
+
how: z5.enum(["exit", "killed"]).optional(),
|
|
297
|
+
error: z5.string().optional()
|
|
247
298
|
});
|
|
248
|
-
var ChatClosesSchema =
|
|
249
|
-
var ChatProjectProposalSchema =
|
|
250
|
-
name:
|
|
251
|
-
description:
|
|
252
|
-
repos:
|
|
253
|
-
addTo:
|
|
299
|
+
var ChatClosesSchema = z5.array(ChatCloseSchema).min(1).max(MAX_PROPOSALS);
|
|
300
|
+
var ChatProjectProposalSchema = z5.object({
|
|
301
|
+
name: z5.string().min(1).max(80),
|
|
302
|
+
description: z5.string().max(500).optional(),
|
|
303
|
+
repos: z5.array(z5.object({ path: z5.string().min(1).max(4096), why: z5.string().min(1).max(200) })).min(1).max(50),
|
|
304
|
+
addTo: z5.string().min(1).max(80).optional()
|
|
254
305
|
});
|
|
255
|
-
var ChatTeamSeatSchema =
|
|
256
|
-
role:
|
|
257
|
-
label:
|
|
306
|
+
var ChatTeamSeatSchema = z5.object({
|
|
307
|
+
role: z5.string().min(1),
|
|
308
|
+
label: z5.string(),
|
|
258
309
|
tool: ToolSchema,
|
|
259
|
-
model:
|
|
260
|
-
effort:
|
|
310
|
+
model: z5.string().optional(),
|
|
311
|
+
effort: z5.string().optional(),
|
|
261
312
|
autonomy: AutonomySchema.optional(),
|
|
262
|
-
name:
|
|
313
|
+
name: z5.string().optional()
|
|
263
314
|
});
|
|
264
|
-
var ChatTeamProposalSchema =
|
|
265
|
-
cwd:
|
|
266
|
-
project:
|
|
267
|
-
projectName:
|
|
268
|
-
name:
|
|
269
|
-
template:
|
|
270
|
-
seats:
|
|
271
|
-
teamId:
|
|
272
|
-
launchedAt:
|
|
273
|
-
error:
|
|
274
|
-
savedPath:
|
|
315
|
+
var ChatTeamProposalSchema = z5.object({
|
|
316
|
+
cwd: z5.string().min(1),
|
|
317
|
+
project: z5.string(),
|
|
318
|
+
projectName: z5.string().optional(),
|
|
319
|
+
name: z5.string().min(1),
|
|
320
|
+
template: z5.string().optional(),
|
|
321
|
+
seats: z5.array(ChatTeamSeatSchema).min(1).max(8),
|
|
322
|
+
teamId: z5.string().optional(),
|
|
323
|
+
launchedAt: z5.string().datetime().optional(),
|
|
324
|
+
error: z5.string().optional(),
|
|
325
|
+
savedPath: z5.string().optional()
|
|
275
326
|
});
|
|
276
|
-
var ChatTaskProposalSchema =
|
|
277
|
-
to:
|
|
278
|
-
toName:
|
|
279
|
-
team:
|
|
280
|
-
title:
|
|
281
|
-
text:
|
|
282
|
-
taskId:
|
|
283
|
-
ownerName:
|
|
284
|
-
state:
|
|
285
|
-
givenAt:
|
|
286
|
-
error:
|
|
327
|
+
var ChatTaskProposalSchema = z5.object({
|
|
328
|
+
to: z5.string().min(1),
|
|
329
|
+
toName: z5.string().optional(),
|
|
330
|
+
team: z5.string().optional(),
|
|
331
|
+
title: z5.string().min(1).max(200),
|
|
332
|
+
text: z5.string().max(2e4).optional(),
|
|
333
|
+
taskId: z5.string().optional(),
|
|
334
|
+
ownerName: z5.string().optional(),
|
|
335
|
+
state: z5.enum(["open", "taken", "done", "refused", "dropped"]).optional(),
|
|
336
|
+
givenAt: z5.string().datetime().optional(),
|
|
337
|
+
error: z5.string().optional()
|
|
287
338
|
});
|
|
288
|
-
var ChatTasksSchema =
|
|
289
|
-
var ChatTurnSchema =
|
|
290
|
-
machineId:
|
|
291
|
-
machineName:
|
|
292
|
-
choices:
|
|
293
|
-
qid:
|
|
294
|
-
question:
|
|
295
|
-
askedAt:
|
|
296
|
-
steps:
|
|
297
|
-
answer:
|
|
298
|
-
answeredAt:
|
|
299
|
-
error:
|
|
339
|
+
var ChatTasksSchema = z5.array(ChatTaskProposalSchema).min(1).max(MAX_PROPOSALS);
|
|
340
|
+
var ChatTurnSchema = z5.object({
|
|
341
|
+
machineId: z5.string().optional(),
|
|
342
|
+
machineName: z5.string().optional(),
|
|
343
|
+
choices: z5.array(z5.object({ id: z5.string(), label: z5.string() })).optional(),
|
|
344
|
+
qid: z5.string().min(1),
|
|
345
|
+
question: z5.string(),
|
|
346
|
+
askedAt: z5.string().datetime(),
|
|
347
|
+
steps: z5.array(ChatStepSchema),
|
|
348
|
+
answer: z5.string().optional(),
|
|
349
|
+
answeredAt: z5.string().datetime().optional(),
|
|
350
|
+
error: z5.string().optional(),
|
|
300
351
|
proposal: ChatProposalSchema.optional(),
|
|
301
352
|
proposals: ChatProposalsSchema.optional(),
|
|
302
353
|
relay: ChatRelaySchema.optional(),
|
|
303
354
|
closes: ChatClosesSchema.optional(),
|
|
304
355
|
projectProposal: ChatProjectProposalSchema.optional(),
|
|
305
356
|
team: ChatTeamProposalSchema.optional(),
|
|
306
|
-
tasks: ChatTasksSchema.optional()
|
|
357
|
+
tasks: ChatTasksSchema.optional(),
|
|
358
|
+
attachments: z5.array(AttachmentRefSchema).optional()
|
|
307
359
|
});
|
|
308
360
|
var proposalRows = (t) => t?.proposals ?? (t?.proposal ? [t.proposal] : []);
|
|
309
361
|
|
|
310
362
|
// ../protocol/src/repos.ts
|
|
311
|
-
import { z as
|
|
312
|
-
var ReposInspectSchema =
|
|
313
|
-
type:
|
|
314
|
-
requestId:
|
|
315
|
-
paths:
|
|
316
|
-
machineId:
|
|
363
|
+
import { z as z6 } from "zod";
|
|
364
|
+
var ReposInspectSchema = z6.object({
|
|
365
|
+
type: z6.literal("repos.inspect"),
|
|
366
|
+
requestId: z6.string().min(1).max(100),
|
|
367
|
+
paths: z6.array(z6.string().min(1)).min(1).max(50),
|
|
368
|
+
machineId: z6.string().optional()
|
|
317
369
|
});
|
|
318
|
-
var RepoInfoSchema =
|
|
319
|
-
var ReposInfoSchema =
|
|
370
|
+
var RepoInfoSchema = z6.object({ path: z6.string(), exists: z6.boolean(), branch: z6.string().nullable() });
|
|
371
|
+
var ReposInfoSchema = z6.object({ type: z6.literal("repos.info"), requestId: z6.string(), repos: z6.array(RepoInfoSchema) });
|
|
320
372
|
|
|
321
373
|
// ../protocol/src/models.ts
|
|
322
|
-
import { z as
|
|
323
|
-
var ModelIdSchema =
|
|
324
|
-
var EffortSchema =
|
|
325
|
-
var ModelChoiceSchema =
|
|
374
|
+
import { z as z7 } from "zod";
|
|
375
|
+
var ModelIdSchema = z7.string().min(1).max(200).regex(/^[A-Za-z0-9][A-Za-z0-9._:/@[\]=,+-]*$/, "not a model id");
|
|
376
|
+
var EffortSchema = z7.string().min(1).max(20).regex(/^[a-z]+$/, "not an effort");
|
|
377
|
+
var ModelChoiceSchema = z7.object({
|
|
326
378
|
id: ModelIdSchema,
|
|
327
|
-
label:
|
|
328
|
-
description:
|
|
329
|
-
efforts:
|
|
379
|
+
label: z7.string(),
|
|
380
|
+
description: z7.string().optional(),
|
|
381
|
+
efforts: z7.array(EffortSchema).optional(),
|
|
330
382
|
defaultEffort: EffortSchema.optional(),
|
|
331
|
-
isDefault:
|
|
383
|
+
isDefault: z7.boolean().optional()
|
|
332
384
|
});
|
|
333
|
-
var ModelsListSchema =
|
|
334
|
-
type:
|
|
335
|
-
requestId:
|
|
385
|
+
var ModelsListSchema = z7.object({
|
|
386
|
+
type: z7.literal("models.list"),
|
|
387
|
+
requestId: z7.string().min(1).max(100),
|
|
336
388
|
tool: ToolSchema,
|
|
337
|
-
machineId:
|
|
389
|
+
machineId: z7.string().optional()
|
|
338
390
|
});
|
|
339
|
-
var ModelsListingSchema =
|
|
340
|
-
type:
|
|
341
|
-
requestId:
|
|
391
|
+
var ModelsListingSchema = z7.object({
|
|
392
|
+
type: z7.literal("models.listing"),
|
|
393
|
+
requestId: z7.string(),
|
|
342
394
|
tool: ToolSchema,
|
|
343
|
-
models:
|
|
344
|
-
error:
|
|
395
|
+
models: z7.array(ModelChoiceSchema),
|
|
396
|
+
error: z7.string().optional()
|
|
345
397
|
});
|
|
346
398
|
|
|
347
399
|
// ../protocol/src/scan.ts
|
|
348
|
-
import { z as
|
|
349
|
-
var ReposScanSchema =
|
|
350
|
-
var FoundRepoSchema =
|
|
351
|
-
var ReposFoundSchema =
|
|
400
|
+
import { z as z8 } from "zod";
|
|
401
|
+
var ReposScanSchema = z8.object({ type: z8.literal("repos.scan"), requestId: z8.string().min(1).max(100), machineId: z8.string().optional() });
|
|
402
|
+
var FoundRepoSchema = z8.object({ path: z8.string(), branch: z8.string().nullable(), remote: z8.string().optional(), manifest: z8.string().max(200).optional() });
|
|
403
|
+
var ReposFoundSchema = z8.object({ type: z8.literal("repos.found"), requestId: z8.string(), repos: z8.array(FoundRepoSchema).max(500), truncated: z8.boolean(), error: z8.string().optional() });
|
|
352
404
|
|
|
353
405
|
// ../protocol/src/documents.ts
|
|
354
|
-
import { z as
|
|
406
|
+
import { z as z9 } from "zod";
|
|
355
407
|
var DOCUMENT_MAX_BYTES = 1048576;
|
|
356
|
-
var path =
|
|
357
|
-
var
|
|
358
|
-
var DocumentReadSchema =
|
|
359
|
-
type:
|
|
360
|
-
requestId,
|
|
408
|
+
var path = z9.string().min(1).max(4096);
|
|
409
|
+
var requestId2 = z9.string().min(1);
|
|
410
|
+
var DocumentReadSchema = z9.object({
|
|
411
|
+
type: z9.literal("document.read"),
|
|
412
|
+
requestId: requestId2,
|
|
361
413
|
path,
|
|
362
|
-
machineId:
|
|
363
|
-
sessionId:
|
|
414
|
+
machineId: z9.string().optional(),
|
|
415
|
+
sessionId: z9.string().min(1).optional(),
|
|
364
416
|
basePath: path.optional()
|
|
365
417
|
});
|
|
366
|
-
var DocumentContentSchema =
|
|
367
|
-
type:
|
|
368
|
-
requestId,
|
|
418
|
+
var DocumentContentSchema = z9.object({
|
|
419
|
+
type: z9.literal("document.content"),
|
|
420
|
+
requestId: requestId2,
|
|
369
421
|
path,
|
|
370
|
-
text:
|
|
371
|
-
bytes:
|
|
372
|
-
modifiedAt:
|
|
422
|
+
text: z9.string(),
|
|
423
|
+
bytes: z9.number().int().nonnegative(),
|
|
424
|
+
modifiedAt: z9.string().datetime()
|
|
373
425
|
});
|
|
374
|
-
var DocumentErrorCodeSchema =
|
|
426
|
+
var DocumentErrorCodeSchema = z9.enum([
|
|
375
427
|
"not_found",
|
|
376
428
|
"not_file",
|
|
377
429
|
"unsupported_path",
|
|
@@ -383,47 +435,47 @@ var DocumentErrorCodeSchema = z8.enum([
|
|
|
383
435
|
"session_missing",
|
|
384
436
|
"read_failed"
|
|
385
437
|
]);
|
|
386
|
-
var DocumentErrorSchema =
|
|
387
|
-
type:
|
|
388
|
-
requestId,
|
|
438
|
+
var DocumentErrorSchema = z9.object({
|
|
439
|
+
type: z9.literal("document.error"),
|
|
440
|
+
requestId: requestId2,
|
|
389
441
|
path,
|
|
390
442
|
code: DocumentErrorCodeSchema
|
|
391
443
|
});
|
|
392
444
|
|
|
393
445
|
// ../protocol/src/routing.ts
|
|
394
|
-
import { z as
|
|
395
|
-
var MachineInventorySchema =
|
|
396
|
-
id:
|
|
397
|
-
label:
|
|
398
|
-
online:
|
|
399
|
-
local:
|
|
400
|
-
sessions:
|
|
401
|
-
folders:
|
|
446
|
+
import { z as z10 } from "zod";
|
|
447
|
+
var MachineInventorySchema = z10.object({
|
|
448
|
+
id: z10.string().min(1).max(80),
|
|
449
|
+
label: z10.string().min(1).max(120),
|
|
450
|
+
online: z10.boolean(),
|
|
451
|
+
local: z10.boolean(),
|
|
452
|
+
sessions: z10.array(z10.object({ id: z10.string(), name: z10.string(), project: z10.string(), cwd: z10.string(), topic: z10.string().optional(), state: z10.string(), readOnly: z10.boolean() })).max(500),
|
|
453
|
+
folders: z10.array(z10.object({ project: z10.string(), cwd: z10.string() })).max(100)
|
|
402
454
|
});
|
|
403
|
-
var RoutingContextSchema =
|
|
404
|
-
machines:
|
|
405
|
-
history:
|
|
455
|
+
var RoutingContextSchema = z10.object({
|
|
456
|
+
machines: z10.array(MachineInventorySchema).min(1).max(20),
|
|
457
|
+
history: z10.array(z10.object({ question: z10.string().max(2e4), answer: z10.string().max(2e4).optional(), machineId: z10.string().optional() })).max(50)
|
|
406
458
|
});
|
|
407
|
-
var RouteResultSchema =
|
|
459
|
+
var RouteResultSchema = z10.object({
|
|
408
460
|
/** Null means an answer or a clarification, never an implicit local destination. */
|
|
409
|
-
machineId:
|
|
410
|
-
text:
|
|
411
|
-
choices:
|
|
461
|
+
machineId: z10.string().nullable(),
|
|
462
|
+
text: z10.string().min(1).max(2e4),
|
|
463
|
+
choices: z10.array(z10.string()).max(20).optional()
|
|
412
464
|
});
|
|
413
465
|
|
|
414
466
|
// ../protocol/src/ssh.ts
|
|
415
|
-
import { z as
|
|
416
|
-
var SshAliasSchema =
|
|
467
|
+
import { z as z11 } from "zod";
|
|
468
|
+
var SshAliasSchema = z11.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/);
|
|
417
469
|
|
|
418
470
|
// ../protocol/src/machines.ts
|
|
419
|
-
import { z as
|
|
420
|
-
var MachineIdSchema =
|
|
421
|
-
var MachineSchema =
|
|
471
|
+
import { z as z12 } from "zod";
|
|
472
|
+
var MachineIdSchema = z12.string().regex(/^[a-zA-Z0-9_-]{1,64}$/);
|
|
473
|
+
var MachineSchema = z12.object({
|
|
422
474
|
id: MachineIdSchema,
|
|
423
|
-
label:
|
|
475
|
+
label: z12.string().trim().min(1).max(80),
|
|
424
476
|
ssh: SshAliasSchema.optional()
|
|
425
477
|
});
|
|
426
|
-
var MachinesSchema =
|
|
478
|
+
var MachinesSchema = z12.array(MachineSchema).min(1).max(20).superRefine((list, ctx) => {
|
|
427
479
|
if (list[0]?.id !== "local" || list[0].ssh !== void 0) ctx.addIssue({ code: "custom", message: "the first machine is local, without ssh", path: [0] });
|
|
428
480
|
const ids = /* @__PURE__ */ new Set(), aliases = /* @__PURE__ */ new Set();
|
|
429
481
|
list.forEach((m, i) => {
|
|
@@ -438,53 +490,53 @@ var MachinesSchema = z11.array(MachineSchema).min(1).max(20).superRefine((list,
|
|
|
438
490
|
});
|
|
439
491
|
|
|
440
492
|
// ../protocol/src/island.ts
|
|
441
|
-
import { z as
|
|
442
|
-
var IslandScaleSchema =
|
|
443
|
-
var IslandPrefsSchema =
|
|
493
|
+
import { z as z13 } from "zod";
|
|
494
|
+
var IslandScaleSchema = z13.union([z13.literal("auto"), z13.literal(1), z13.literal(1.25), z13.literal(1.5), z13.literal(2)]);
|
|
495
|
+
var IslandPrefsSchema = z13.object({
|
|
444
496
|
/** Shown at the top of the screen; hidden, Desktop still notifies. */
|
|
445
|
-
visible:
|
|
497
|
+
visible: z13.boolean(),
|
|
446
498
|
/** `primary` (whichever it is after a reconfiguration), or a monitor's id as the shell lists it (`list_monitors`: the OS
|
|
447
499
|
* name, `#index` without one). `second`, written by older fronts, is the first monitor that is not the primary. */
|
|
448
|
-
screen:
|
|
449
|
-
position:
|
|
500
|
+
screen: z13.string().trim().min(1).max(200),
|
|
501
|
+
position: z13.enum(["center", "left", "right"]),
|
|
450
502
|
/** A strip under a maximised window. */
|
|
451
|
-
discreet:
|
|
503
|
+
discreet: z13.boolean(),
|
|
452
504
|
islandScale: IslandScaleSchema,
|
|
453
505
|
panelScale: IslandScaleSchema,
|
|
454
506
|
/** What the island shows besides asks and questions, which it always shows. */
|
|
455
|
-
shows:
|
|
507
|
+
shows: z13.object({
|
|
456
508
|
/** Allow, deny or answer in a line from the island; off, its cards only say « Open in Ledge ». */
|
|
457
|
-
quick:
|
|
509
|
+
quick: z13.boolean(),
|
|
458
510
|
/** The 6 s bubble when an agent finishes. */
|
|
459
|
-
finished:
|
|
511
|
+
finished: z13.boolean(),
|
|
460
512
|
/** An agent's sentence in a bubble. */
|
|
461
|
-
say:
|
|
513
|
+
say: z13.boolean(),
|
|
462
514
|
/** The sub-agents next to their main agent. */
|
|
463
|
-
helpers:
|
|
515
|
+
helpers: z13.boolean()
|
|
464
516
|
}),
|
|
465
517
|
/** The global shortcut that opens the island, as shown (`Ctrl Alt L`). */
|
|
466
|
-
shortcut:
|
|
518
|
+
shortcut: z13.string().trim().min(1).max(40)
|
|
467
519
|
});
|
|
468
520
|
|
|
469
521
|
// ../protocol/src/projects.ts
|
|
470
|
-
import { z as
|
|
522
|
+
import { z as z14 } from "zod";
|
|
471
523
|
var PROJECT_COLORS = { blue: "#3b82f6", green: "#10b981", amber: "#f59e0b", violet: "#8b5cf6", teal: "#14b8a6", pink: "#ec4899", red: "#ef4444", slate: "#64748b" };
|
|
472
|
-
var ProjectColorSchema =
|
|
473
|
-
var ProjectIdSchema =
|
|
524
|
+
var ProjectColorSchema = z14.enum(["blue", "green", "amber", "violet", "teal", "pink", "red", "slate"]);
|
|
525
|
+
var ProjectIdSchema = z14.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/);
|
|
474
526
|
function normalizePath(raw) {
|
|
475
527
|
const p = raw.trim().replace(/\/+/g, "/");
|
|
476
528
|
return p.length > 1 && p.endsWith("/") ? p.slice(0, -1) : p;
|
|
477
529
|
}
|
|
478
|
-
var PathSchema =
|
|
479
|
-
var RepoSchema =
|
|
480
|
-
var ProjectSchema =
|
|
530
|
+
var PathSchema = z14.string().max(4096).refine((p) => p.startsWith("/") && p === normalizePath(p), "an absolute, normalized path");
|
|
531
|
+
var RepoSchema = z14.object({ machine: MachineIdSchema, path: PathSchema });
|
|
532
|
+
var ProjectSchema = z14.object({
|
|
481
533
|
id: ProjectIdSchema,
|
|
482
|
-
name:
|
|
534
|
+
name: z14.string().trim().min(1).max(80),
|
|
483
535
|
color: ProjectColorSchema,
|
|
484
|
-
description:
|
|
485
|
-
repos:
|
|
536
|
+
description: z14.string().max(500).default(""),
|
|
537
|
+
repos: z14.array(RepoSchema).max(50)
|
|
486
538
|
});
|
|
487
|
-
var RuleSchema =
|
|
539
|
+
var RuleSchema = z14.object({ machine: MachineIdSchema, path: PathSchema, project: ProjectIdSchema });
|
|
488
540
|
function projectsProblems(p) {
|
|
489
541
|
const out = [];
|
|
490
542
|
const ids = /* @__PURE__ */ new Set(), names = /* @__PURE__ */ new Set(), repos = /* @__PURE__ */ new Set(), rules = /* @__PURE__ */ new Set();
|
|
@@ -510,7 +562,7 @@ ${rule.path}`;
|
|
|
510
562
|
});
|
|
511
563
|
return out;
|
|
512
564
|
}
|
|
513
|
-
var ProjectsSchema =
|
|
565
|
+
var ProjectsSchema = z14.object({ projects: z14.array(ProjectSchema).max(100), rules: z14.array(RuleSchema).max(1e3) }).superRefine((p, ctx) => {
|
|
514
566
|
for (const problem of projectsProblems(p)) ctx.addIssue({ code: "custom", message: problem.code, path: problem.path });
|
|
515
567
|
});
|
|
516
568
|
var DEFAULT_PROJECTS = { projects: [], rules: [] };
|
|
@@ -528,51 +580,54 @@ function projectOf(session, state) {
|
|
|
528
580
|
}
|
|
529
581
|
|
|
530
582
|
// ../protocol/src/thread.ts
|
|
531
|
-
import { z as
|
|
532
|
-
var ToolStatusSchema =
|
|
533
|
-
var FileChangeSchema =
|
|
534
|
-
var base = { id:
|
|
535
|
-
var ThreadItemSchema =
|
|
536
|
-
|
|
537
|
-
|
|
583
|
+
import { z as z15 } from "zod";
|
|
584
|
+
var ToolStatusSchema = z15.enum(["running", "success", "failed", "unknown"]);
|
|
585
|
+
var FileChangeSchema = z15.object({ path: z15.string().min(1), from: z15.string().min(1).optional(), change: z15.enum(["add", "edit", "delete", "write"]), diff: z15.string().optional() });
|
|
586
|
+
var base = { id: z15.string().min(1), at: z15.string().datetime(), turn: z15.number().int().nonnegative(), helperId: z15.string().optional() };
|
|
587
|
+
var ThreadItemSchema = z15.discriminatedUnion("kind", [
|
|
588
|
+
z15.object({ kind: z15.literal("prompt"), ...base, text: z15.string(), images: z15.array(AttachmentRefSchema).optional() }),
|
|
589
|
+
z15.object({ kind: z15.literal("message"), ...base, text: z15.string() }),
|
|
538
590
|
/** `id` is the harness's tool_use_id when it gives one, so the result updates the same row; `byClose`: a question
|
|
539
591
|
* dismissed by Ledge closing the session. */
|
|
540
|
-
|
|
592
|
+
z15.object({ kind: z15.literal("tool"), ...base, tool: z15.string(), label: z15.string(), input: z15.string().optional(), output: z15.string().optional(), error: z15.string().optional(), status: ToolStatusSchema, durationMs: z15.number().nonnegative().optional(), files: z15.array(FileChangeSchema).default([]), byClose: z15.literal(true).optional() }),
|
|
541
593
|
/** `unknown`: answered in the terminal, the daemon only saw the prompt go away; `always`: allowed and not asked again;
|
|
542
594
|
* `byClose`: denied by Ledge closing the session. */
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
595
|
+
z15.object({ kind: z15.literal("permission"), ...base, tool: z15.string(), text: z15.string(), decision: z15.enum(["accept", "deny", "always", "unknown"]).optional(), byClose: z15.literal(true).optional() }),
|
|
596
|
+
z15.object({ kind: z15.literal("reply"), ...base, text: z15.string() }),
|
|
597
|
+
z15.object({ kind: z15.literal("helper"), ...base, task: z15.string(), agentType: z15.string().optional(), state: z15.enum(["working", "exited"]) }),
|
|
546
598
|
/** A message this session sent to another agent; `id` is the tool_use_id, `to` the address it used, `peer` the Ledge session id, `received` the paired item's id in the peer's thread, `via` set when Ledge's mailbox carries it. */
|
|
547
|
-
|
|
599
|
+
z15.object({ kind: z15.literal("sent"), ...base, to: z15.string(), peer: z15.string().optional(), summary: z15.string().optional(), text: z15.string(), status: z15.enum(["sending", "delivered", "read", "failed"]), received: z15.string().optional(), via: z15.literal("ledge").optional() }),
|
|
548
600
|
/** A message another agent sent to this session; `from` is its from-name (else its address), `sent` the paired item's id in the peer's thread. */
|
|
549
|
-
|
|
601
|
+
z15.object({ kind: z15.literal("received"), ...base, from: z15.string(), peer: z15.string().optional(), text: z15.string(), sent: z15.string().optional() }),
|
|
550
602
|
/** An automated notice of the agent's harness about messages between sessions (Claude Code's `[Cross-session idle
|
|
551
603
|
* notice]` / `[Cross-session delivery notice]`): a system event, never the user's words. `name` is the session it is
|
|
552
604
|
* about as quoted, `peer` its Ledge session id; a delivery notice says the outcome of `count` messages to `recipients`. */
|
|
553
|
-
|
|
554
|
-
kind:
|
|
605
|
+
z15.object({
|
|
606
|
+
kind: z15.literal("notice"),
|
|
555
607
|
...base,
|
|
556
|
-
notice:
|
|
608
|
+
notice: z15.enum(["idle", "exited", "unavailable", "expired", "delivery", "other"]),
|
|
557
609
|
/** An `other` notice from Ledge: `task`, the task a `<ledge-task>` is about; `team`, the team a `<ledge-notice team>` seated the
|
|
558
610
|
* session in (roles spec §3.3). An older front, which knows neither, shows it as any other notice. */
|
|
559
|
-
task:
|
|
560
|
-
team:
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
611
|
+
task: z15.string().optional(),
|
|
612
|
+
team: z15.string().optional(),
|
|
613
|
+
/** A task this session handed over (`outgoing`), and how (issue #92). */
|
|
614
|
+
taskOp: z15.enum(TRANSMISSION_OPS).optional(),
|
|
615
|
+
outgoing: z15.literal(true).optional(),
|
|
616
|
+
name: z15.string().optional(),
|
|
617
|
+
peer: z15.string().optional(),
|
|
618
|
+
time: z15.string().optional(),
|
|
619
|
+
summary: z15.string().optional(),
|
|
620
|
+
status: z15.enum(["held", "denied", "expired", "delivered", "refused", "dropped", "unknown"]).optional(),
|
|
621
|
+
count: z15.number().int().positive().optional(),
|
|
622
|
+
recipients: z15.array(z15.string()).optional(),
|
|
623
|
+
reason: z15.string().optional(),
|
|
624
|
+
text: z15.string()
|
|
570
625
|
})
|
|
571
626
|
]);
|
|
572
627
|
|
|
573
628
|
// ../protocol/src/decisions.ts
|
|
574
|
-
import { z as
|
|
575
|
-
var DecisionSchema =
|
|
629
|
+
import { z as z16 } from "zod";
|
|
630
|
+
var DecisionSchema = z16.enum(["accept", "deny", "always"]);
|
|
576
631
|
var NOTE_MAX = 4e3;
|
|
577
632
|
var NOTE_NOT_TYPED = "note_not_typed";
|
|
578
633
|
var DECISION_OFFERS = {
|
|
@@ -602,12 +657,12 @@ function pendingKey(p) {
|
|
|
602
657
|
}
|
|
603
658
|
|
|
604
659
|
// ../protocol/src/mobile.ts
|
|
605
|
-
import { z as
|
|
660
|
+
import { z as z17 } from "zod";
|
|
606
661
|
var DEFAULT_RELAY_URL = "https://app.kl-ledge.dev";
|
|
607
|
-
var RelayUrlSchema =
|
|
662
|
+
var RelayUrlSchema = z17.string().transform((v, ctx) => {
|
|
608
663
|
const bad = () => {
|
|
609
|
-
ctx.addIssue({ code:
|
|
610
|
-
return
|
|
664
|
+
ctx.addIssue({ code: z17.ZodIssueCode.custom, message: "invalid relay URL" });
|
|
665
|
+
return z17.NEVER;
|
|
611
666
|
};
|
|
612
667
|
let u;
|
|
613
668
|
try {
|
|
@@ -620,236 +675,248 @@ var RelayUrlSchema = z16.string().transform((v, ctx) => {
|
|
|
620
675
|
if (u.username || u.password || u.pathname !== "/" || u.search || u.hash) return bad();
|
|
621
676
|
return u.origin;
|
|
622
677
|
});
|
|
623
|
-
var MobileConfigSchema =
|
|
624
|
-
var MobileLinkStateSchema =
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
678
|
+
var MobileConfigSchema = z17.object({ enabled: z17.boolean(), relayUrl: RelayUrlSchema });
|
|
679
|
+
var MobileLinkStateSchema = z17.discriminatedUnion("state", [
|
|
680
|
+
z17.object({ state: z17.literal("off") }),
|
|
681
|
+
z17.object({ state: z17.literal("connecting") }),
|
|
682
|
+
z17.object({ state: z17.literal("online") }),
|
|
683
|
+
z17.object({ state: z17.literal("offline"), retryAt: z17.string().datetime(), error: z17.string() }),
|
|
684
|
+
z17.object({ state: z17.literal("signed_out"), reason: z17.enum(["other_pc", "session_invalid"]) }),
|
|
630
685
|
/** The mobile service did not start (a broken mobile.json, a missing key store): nothing is linked until the daemon restarts. */
|
|
631
|
-
|
|
686
|
+
z17.object({ state: z17.literal("unavailable"), error: z17.string().max(200) })
|
|
632
687
|
]);
|
|
633
|
-
var MobilePairingSchema =
|
|
634
|
-
id:
|
|
635
|
-
label:
|
|
636
|
-
code:
|
|
637
|
-
expiresAt:
|
|
638
|
-
state:
|
|
688
|
+
var MobilePairingSchema = z17.object({
|
|
689
|
+
id: z17.string(),
|
|
690
|
+
label: z17.string(),
|
|
691
|
+
code: z17.string().nullable(),
|
|
692
|
+
expiresAt: z17.string().datetime(),
|
|
693
|
+
state: z17.enum(["waiting", "confirm", "approved", "linked", "expired", "refused"])
|
|
639
694
|
});
|
|
640
|
-
var MobileStateSchema =
|
|
641
|
-
enabled:
|
|
642
|
-
relayUrl:
|
|
643
|
-
account:
|
|
644
|
-
signin:
|
|
695
|
+
var MobileStateSchema = z17.object({
|
|
696
|
+
enabled: z17.boolean(),
|
|
697
|
+
relayUrl: z17.string(),
|
|
698
|
+
account: z17.object({ login: z17.string(), accountId: z17.string() }).nullable(),
|
|
699
|
+
signin: z17.object({ userCode: z17.string(), verificationUri: z17.string(), expiresAt: z17.string().datetime() }).nullable(),
|
|
645
700
|
/** The last sign-in that did not end with a session; cleared by the next one. */
|
|
646
|
-
signinError:
|
|
701
|
+
signinError: z17.enum(["expired", "denied", "not_allowed", "failed"]).nullable(),
|
|
647
702
|
link: MobileLinkStateSchema,
|
|
648
|
-
devices:
|
|
649
|
-
pairings:
|
|
703
|
+
devices: z17.array(z17.object({ id: z17.string(), label: z17.string(), approvedAt: z17.string(), online: z17.boolean(), lastSeenAt: z17.string().optional() })),
|
|
704
|
+
pairings: z17.array(MobilePairingSchema)
|
|
650
705
|
});
|
|
651
706
|
|
|
652
707
|
// ../protocol/src/teams.ts
|
|
653
|
-
import { z as
|
|
654
|
-
var RoleIdSchema =
|
|
708
|
+
import { z as z18 } from "zod";
|
|
709
|
+
var RoleIdSchema = z18.string().regex(/^[a-z0-9][a-z0-9_-]{0,39}$/);
|
|
655
710
|
var ROLE_LABEL_MAX = 40;
|
|
656
711
|
var ROLE_PROMPT_MAX = 8e3;
|
|
657
|
-
var RoleSchema =
|
|
712
|
+
var RoleSchema = z18.object({
|
|
658
713
|
id: RoleIdSchema,
|
|
659
|
-
label:
|
|
660
|
-
prompt:
|
|
714
|
+
label: z18.string().min(1).max(ROLE_LABEL_MAX),
|
|
715
|
+
prompt: z18.string().max(ROLE_PROMPT_MAX),
|
|
661
716
|
tool: ToolSchema.optional(),
|
|
662
717
|
model: ModelIdSchema.optional(),
|
|
663
718
|
effort: EffortSchema.optional(),
|
|
664
719
|
autonomy: AutonomySchema.optional(),
|
|
665
|
-
source:
|
|
666
|
-
path:
|
|
720
|
+
source: z18.enum(["repo", "home"]),
|
|
721
|
+
path: z18.string()
|
|
667
722
|
});
|
|
668
|
-
var DefinitionProblemSchema =
|
|
723
|
+
var DefinitionProblemSchema = z18.object({ path: z18.string(), reason: z18.string() });
|
|
669
724
|
var TEAM_SEATS_MAX = 8;
|
|
670
|
-
var SeatSchema =
|
|
725
|
+
var SeatSchema = z18.object({
|
|
671
726
|
role: RoleIdSchema,
|
|
672
727
|
tool: ToolSchema.optional(),
|
|
673
728
|
model: ModelIdSchema.optional(),
|
|
674
729
|
effort: EffortSchema.optional(),
|
|
675
|
-
name:
|
|
730
|
+
name: z18.string().min(1).max(40).optional()
|
|
676
731
|
});
|
|
677
732
|
var uniqueRoles = (seats) => new Set(seats.map((s) => s.role)).size === seats.length;
|
|
678
|
-
var SeatsSchema =
|
|
679
|
-
var TeamNameSchema =
|
|
680
|
-
var TeamTemplateSchema =
|
|
681
|
-
var TeamIdSchema =
|
|
682
|
-
var TeamStateSchema =
|
|
683
|
-
var TeamSchema =
|
|
733
|
+
var SeatsSchema = z18.array(SeatSchema).min(1).max(TEAM_SEATS_MAX).refine(uniqueRoles, "a role twice in one team");
|
|
734
|
+
var TeamNameSchema = z18.string().trim().min(1).max(60);
|
|
735
|
+
var TeamTemplateSchema = z18.object({ id: z18.string().min(1).max(64), name: TeamNameSchema, seats: SeatsSchema, source: z18.enum(["repo", "home"]), path: z18.string() });
|
|
736
|
+
var TeamIdSchema = z18.string().regex(/^team-[0-9a-f]{4,8}$/);
|
|
737
|
+
var TeamStateSchema = z18.enum(["active", "resting", "dissolved"]);
|
|
738
|
+
var TeamSchema = z18.object({
|
|
684
739
|
id: TeamIdSchema,
|
|
685
740
|
name: TeamNameSchema,
|
|
686
|
-
template:
|
|
687
|
-
project:
|
|
688
|
-
machine:
|
|
689
|
-
cwd:
|
|
741
|
+
template: z18.string().optional(),
|
|
742
|
+
project: z18.string().nullable(),
|
|
743
|
+
machine: z18.string(),
|
|
744
|
+
cwd: z18.string(),
|
|
690
745
|
state: TeamStateSchema,
|
|
691
|
-
seats:
|
|
692
|
-
createdAt:
|
|
693
|
-
updatedAt:
|
|
694
|
-
restingAt:
|
|
695
|
-
dissolvedAt:
|
|
746
|
+
seats: z18.array(z18.object({ role: RoleIdSchema, sessionId: z18.string().nullable() })).max(TEAM_SEATS_MAX * 2),
|
|
747
|
+
createdAt: z18.string(),
|
|
748
|
+
updatedAt: z18.string(),
|
|
749
|
+
restingAt: z18.string().optional(),
|
|
750
|
+
dissolvedAt: z18.string().optional()
|
|
696
751
|
});
|
|
697
|
-
var RolesListSchema =
|
|
698
|
-
var RolesListingSchema =
|
|
699
|
-
var TeamLaunchSchema =
|
|
700
|
-
type:
|
|
701
|
-
rid:
|
|
702
|
-
cwd:
|
|
703
|
-
template:
|
|
752
|
+
var RolesListSchema = z18.object({ type: z18.literal("roles.list"), cwd: z18.string().min(1).optional(), requestId: z18.string().max(100).optional(), machineId: z18.string().optional() });
|
|
753
|
+
var RolesListingSchema = z18.object({ type: z18.literal("roles.listing"), requestId: z18.string().optional(), roles: z18.array(RoleSchema), templates: z18.array(TeamTemplateSchema).default([]), problems: z18.array(DefinitionProblemSchema) });
|
|
754
|
+
var TeamLaunchSchema = z18.object({
|
|
755
|
+
type: z18.literal("team.launch"),
|
|
756
|
+
rid: z18.string().min(1).max(100),
|
|
757
|
+
cwd: z18.string().min(1).optional(),
|
|
758
|
+
template: z18.string().min(1).max(64).optional(),
|
|
704
759
|
seats: SeatsSchema.optional(),
|
|
705
760
|
name: TeamNameSchema.optional(),
|
|
706
|
-
qid:
|
|
707
|
-
machineId:
|
|
761
|
+
qid: z18.string().min(1).optional(),
|
|
762
|
+
machineId: z18.string().optional()
|
|
708
763
|
});
|
|
709
|
-
var TeamJoinSchema =
|
|
710
|
-
var TeamLeaveSchema =
|
|
711
|
-
var TeamResumeSchema =
|
|
712
|
-
var TeamDissolveSchema =
|
|
713
|
-
var TeamSaveSchema =
|
|
714
|
-
var TeamsMessageSchema =
|
|
715
|
-
var TeamUpdatedSchema =
|
|
716
|
-
var TeamLaunchedSchema =
|
|
717
|
-
var TeamFailedSchema =
|
|
718
|
-
var TeamSavedSchema =
|
|
764
|
+
var TeamJoinSchema = z18.object({ type: z18.literal("team.join"), team: TeamIdSchema, session: z18.string().min(1), role: RoleIdSchema });
|
|
765
|
+
var TeamLeaveSchema = z18.object({ type: z18.literal("team.leave"), team: TeamIdSchema, session: z18.string().min(1) });
|
|
766
|
+
var TeamResumeSchema = z18.object({ type: z18.literal("team.resume"), team: TeamIdSchema });
|
|
767
|
+
var TeamDissolveSchema = z18.object({ type: z18.literal("team.dissolve"), team: TeamIdSchema });
|
|
768
|
+
var TeamSaveSchema = z18.object({ type: z18.literal("team.save"), rid: z18.string().min(1).max(100), name: TeamNameSchema, seats: SeatsSchema, qid: z18.string().min(1).optional() });
|
|
769
|
+
var TeamsMessageSchema = z18.object({ type: z18.literal("teams"), teams: z18.array(TeamSchema) });
|
|
770
|
+
var TeamUpdatedSchema = z18.object({ type: z18.literal("team.updated"), team: TeamSchema });
|
|
771
|
+
var TeamLaunchedSchema = z18.object({ type: z18.literal("team.launched"), rid: z18.string(), team: TeamSchema });
|
|
772
|
+
var TeamFailedSchema = z18.object({ type: z18.literal("team.failed"), rid: z18.string(), reason: z18.string(), team: TeamSchema.optional() });
|
|
773
|
+
var TeamSavedSchema = z18.object({ type: z18.literal("team.saved"), rid: z18.string(), path: z18.string().optional(), reason: z18.string().optional() });
|
|
719
774
|
|
|
720
775
|
// ../protocol/src/messages.ts
|
|
721
776
|
var PROTOCOL_PORT = 47831;
|
|
722
|
-
var RefusalCodeSchema =
|
|
723
|
-
var SessionEventSchema =
|
|
724
|
-
name:
|
|
725
|
-
at:
|
|
726
|
-
source:
|
|
727
|
-
tool:
|
|
728
|
-
text:
|
|
729
|
-
options:
|
|
777
|
+
var RefusalCodeSchema = z19.enum(["stale", "read_only", "no_prompt", "not_taken", "busy", "unknown_session", "nothing_to_decide", "not_offered", "free_text", "note_not_typed", "unavailable", "invalid", "attachment_missing", "attachments_not_accepted"]);
|
|
778
|
+
var SessionEventSchema = z19.object({
|
|
779
|
+
name: z19.enum(["SessionStart", "UserPromptSubmit", "PreToolUse", "PermissionRequest", "Notification", "Stop", "SessionEnd", "PaneChanged", "PaneGone", "PanePrompt", "PaneIdle", "InjectFailed", "Decided", "PostToolUse", "PostToolUseFailure", "StopFailure", "SubagentStart", "SubagentStop", "PaneTitle", "Renamed", "NativeRequest", "AgentMessage", "QueueUpdate"]),
|
|
780
|
+
at: z19.string().datetime(),
|
|
781
|
+
source: z19.enum(["hook", "pane", "daemon"]),
|
|
782
|
+
tool: z19.string().optional(),
|
|
783
|
+
text: z19.string().optional(),
|
|
784
|
+
options: z19.array(z19.string()).optional(),
|
|
730
785
|
/** Each option's description, by index ('' when it has none); left out when no option has one. */
|
|
731
|
-
optionDetails:
|
|
732
|
-
kind:
|
|
786
|
+
optionDetails: z19.array(z19.string()).optional(),
|
|
787
|
+
kind: z19.enum(["question", "permission", "plan", "diff"]).optional(),
|
|
733
788
|
/** PanePrompt: what to review in full before deciding (a plan read in the terminal), when `text` is its summary. */
|
|
734
|
-
body:
|
|
735
|
-
exitCode:
|
|
736
|
-
helperId:
|
|
789
|
+
body: z19.string().optional(),
|
|
790
|
+
exitCode: z19.number().int().nullable().optional(),
|
|
791
|
+
helperId: z19.string().optional(),
|
|
737
792
|
/** The helper's description, once known (Claude Code: its `.meta.json`, written after SubagentStart). */
|
|
738
|
-
task:
|
|
793
|
+
task: z19.string().optional(),
|
|
739
794
|
/** PostToolUseFailure: the user interrupted the turn (Esc); Claude then waits for input with no Stop. */
|
|
740
|
-
interrupt:
|
|
795
|
+
interrupt: z19.boolean().optional(),
|
|
796
|
+
/** UserPromptSubmit: the images the prompt carried, by attachment id. */
|
|
797
|
+
attachments: z19.array(AttachmentIdSchema).max(ATTACHMENTS_MAX).optional(),
|
|
741
798
|
/** QueueUpdate: OMP's queue as it stands. */
|
|
742
|
-
queue:
|
|
799
|
+
queue: z19.array(z19.object({ text: z19.string(), mode: z19.enum(["steer", "follow_up"]) })).optional(),
|
|
743
800
|
/** AgentMessage: the harness's own message, its text so far (`streaming`) or whole. `messageId` is unique for the session's life. */
|
|
744
|
-
messageId:
|
|
745
|
-
streaming:
|
|
801
|
+
messageId: z19.string().optional(),
|
|
802
|
+
streaming: z19.boolean().optional(),
|
|
746
803
|
/** NativeRequest: the dialog's id, and OMP's `ask` questions when it is one. */
|
|
747
|
-
requestId:
|
|
748
|
-
questions:
|
|
804
|
+
requestId: z19.string().optional(),
|
|
805
|
+
questions: z19.array(AskQuestionSchema).optional(),
|
|
749
806
|
/** Stop: its text is already in the thread as AgentMessage cards, which the reply card must not repeat. */
|
|
750
|
-
streamed:
|
|
807
|
+
streamed: z19.boolean().optional(),
|
|
751
808
|
/** Native tracking (spec 2026-10-13 §2): the harness's id of the tool call, so its result lands on the same row. */
|
|
752
|
-
toolUseId:
|
|
809
|
+
toolUseId: z19.string().optional(),
|
|
753
810
|
/** The tool's input as the harness gave it, every string capped by the hook. */
|
|
754
|
-
toolInput:
|
|
811
|
+
toolInput: z19.record(z19.string(), z19.unknown()).optional(),
|
|
755
812
|
/** PostToolUse: the result as text; SubagentStop: nothing (the report travels in `text`). */
|
|
756
|
-
output:
|
|
757
|
-
durationMs:
|
|
813
|
+
output: z19.string().optional(),
|
|
814
|
+
durationMs: z19.number().nonnegative().optional(),
|
|
758
815
|
/** PostToolUseFailure: the harness's error message. */
|
|
759
|
-
error:
|
|
816
|
+
error: z19.string().optional(),
|
|
760
817
|
/** The session's transcript, or the helper's on SubagentStop; the daemon reads its tail for the agent's messages. */
|
|
761
|
-
transcriptPath:
|
|
818
|
+
transcriptPath: z19.string().optional(),
|
|
762
819
|
/** Decided: what was chosen when the daemon knows it. */
|
|
763
820
|
decision: DecisionSchema.optional(),
|
|
764
821
|
/** Decided: the request was refused by Ledge closing the session (its interrupt keys), not by the user's answer. */
|
|
765
|
-
byClose:
|
|
822
|
+
byClose: z19.literal(true).optional(),
|
|
766
823
|
/** The agent's own session id when the hook names it, so the daemon can resume that conversation. */
|
|
767
|
-
agentSessionId:
|
|
824
|
+
agentSessionId: z19.string().optional()
|
|
768
825
|
});
|
|
769
|
-
var RecentSchema =
|
|
826
|
+
var RecentSchema = z19.object({ cwd: z19.string().min(1), project: z19.string().min(1), lastAt: z19.string().datetime() });
|
|
770
827
|
var SEMVER = /^\d+\.\d+\.\d+$/;
|
|
771
|
-
var DaemonInfoSchema =
|
|
772
|
-
version:
|
|
773
|
-
install:
|
|
774
|
-
systemd:
|
|
775
|
-
manual:
|
|
776
|
-
routing:
|
|
777
|
-
archive:
|
|
828
|
+
var DaemonInfoSchema = z19.object({
|
|
829
|
+
version: z19.string(),
|
|
830
|
+
install: z19.enum(["npm", "git", "unknown"]),
|
|
831
|
+
systemd: z19.boolean(),
|
|
832
|
+
manual: z19.string().optional(),
|
|
833
|
+
routing: z19.boolean().optional(),
|
|
834
|
+
archive: z19.boolean().optional(),
|
|
778
835
|
/** Takes `model` and `effort` on `session.launch` and answers `models.list` (#58). */
|
|
779
|
-
models:
|
|
836
|
+
models: z19.boolean().optional(),
|
|
780
837
|
/** Drives OMP over its RPC: launching `omp` sessions is possible when the binary is there (`models.list` says so). */
|
|
781
|
-
omp:
|
|
838
|
+
omp: z19.boolean().optional(),
|
|
782
839
|
/** Takes `session.model`: a live session's model and effort changed (#58, lot 2). */
|
|
783
|
-
modelSwitch:
|
|
840
|
+
modelSwitch: z19.boolean().optional(),
|
|
784
841
|
/** Takes `approval` on an OMP `session.launch` (auto mode). */
|
|
785
|
-
ompApproval:
|
|
842
|
+
ompApproval: z19.boolean().optional(),
|
|
786
843
|
/** Its home folder, so a client shows the folders under it as `~` (absent from older daemons). */
|
|
787
|
-
home:
|
|
788
|
-
mobile:
|
|
844
|
+
home: z19.string().optional(),
|
|
845
|
+
mobile: z19.boolean().optional(),
|
|
789
846
|
/** Knows roles, teams and tasks given by Ledge (spec 2026-10-25 roles). */
|
|
790
|
-
teams:
|
|
847
|
+
teams: z19.boolean().optional()
|
|
791
848
|
});
|
|
792
|
-
var UpdateFailureSchema =
|
|
793
|
-
var ServerMessageSchema =
|
|
794
|
-
|
|
849
|
+
var UpdateFailureSchema = z19.enum(["git-install", "no-systemd", "sessions-at-risk", "npm-failed", "busy"]);
|
|
850
|
+
var ServerMessageSchema = z19.discriminatedUnion("type", [
|
|
851
|
+
z19.object({ type: z19.literal("chat.routed"), qid: z19.string(), result: RouteResultSchema }),
|
|
795
852
|
DocumentContentSchema,
|
|
796
853
|
DocumentErrorSchema,
|
|
854
|
+
AttachmentStoredSchema,
|
|
855
|
+
AttachmentDataSchema,
|
|
856
|
+
AttachmentErrorSchema,
|
|
797
857
|
ReposInfoSchema,
|
|
798
858
|
ReposFoundSchema,
|
|
799
859
|
ModelsListingSchema,
|
|
800
860
|
/** `recents`: the folders of past sessions, most recent first. `launcher`: the command that runs `ledge` inside WSL
|
|
801
861
|
* (`[node, cli]`), so the overlay can attach a terminal to a session with `<launcher> attach <id>`. `daemon`: absent
|
|
802
862
|
* from daemons older than the auto-update. */
|
|
803
|
-
|
|
804
|
-
|
|
863
|
+
z19.object({ type: z19.literal("snapshot"), sessions: z19.array(SessionSchema), recents: z19.array(RecentSchema).optional(), launcher: z19.array(z19.string()).optional(), daemon: DaemonInfoSchema.optional(), sshAlias: SshAliasSchema.optional() }),
|
|
864
|
+
z19.object({ type: z19.literal("session.updated"), session: SessionSchema }),
|
|
805
865
|
/** OMP: the instructions taken back from its queue by an interrupt that restores it; the asker puts them back in its draft. */
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
866
|
+
z19.object({
|
|
867
|
+
type: z19.literal("session.queue.restored"),
|
|
868
|
+
id: z19.string(),
|
|
869
|
+
texts: z19.array(z19.string()),
|
|
870
|
+
/** The same instructions with the images they carried; `imagesDropped`: some images could not be put back. */
|
|
871
|
+
entries: z19.array(z19.object({ text: z19.string(), attachments: z19.array(AttachmentIdSchema).optional() })).optional(),
|
|
872
|
+
imagesDropped: z19.boolean().optional()
|
|
873
|
+
}),
|
|
874
|
+
z19.object({ type: z19.literal("session.removed"), id: z19.string() }),
|
|
875
|
+
z19.object({ type: z19.literal("session.preview"), id: z19.string(), lines: z19.array(z19.string()) }),
|
|
809
876
|
/** A session's thread, on request (spec 2026-10-13 §5); then each created or updated item, broadcast. */
|
|
810
|
-
|
|
811
|
-
|
|
877
|
+
z19.object({ type: z19.literal("session.thread"), id: z19.string(), items: z19.array(ThreadItemSchema) }),
|
|
878
|
+
z19.object({ type: z19.literal("session.thread.item"), id: z19.string(), item: ThreadItemSchema }),
|
|
812
879
|
/** Answer to the requester of a `session.launch`: the session exists (its `session.updated` is broadcast as usual). */
|
|
813
|
-
|
|
880
|
+
z19.object({ type: z19.literal("session.launched"), id: z19.string() }),
|
|
814
881
|
/** Answer to the requester of a `session.close`, once per row closed: the session `id` and how it ended. */
|
|
815
|
-
|
|
816
|
-
|
|
882
|
+
z19.object({ type: z19.literal("session.closed"), qid: z19.string(), row: z19.number().int().min(0), id: z19.string(), how: z19.enum(["exit", "killed"]) }),
|
|
883
|
+
z19.object({ type: z19.literal("recents"), recents: z19.array(RecentSchema) }),
|
|
817
884
|
/** Answer to the requester of a `folder.list` or `folder.create`: `path` resolved (`~` expanded), `parent` null at the
|
|
818
885
|
* root, `entries` its subfolders by name (hidden ones left out). A failure keeps the asked path and says why in `error`,
|
|
819
886
|
* never in an `error` message, which the launch form reads as a failed launch. */
|
|
820
|
-
|
|
821
|
-
type:
|
|
822
|
-
path:
|
|
823
|
-
parent:
|
|
824
|
-
entries:
|
|
825
|
-
error:
|
|
887
|
+
z19.object({
|
|
888
|
+
type: z19.literal("folder.listing"),
|
|
889
|
+
path: z19.string(),
|
|
890
|
+
parent: z19.string().nullable(),
|
|
891
|
+
entries: z19.array(z19.string()),
|
|
892
|
+
error: z19.string().optional(),
|
|
826
893
|
/** The request this answers, when it carried one. */
|
|
827
|
-
requestId:
|
|
894
|
+
requestId: z19.string().optional(),
|
|
828
895
|
/** Those `entries` that are Git repositories, with their branch (the short commit when HEAD is detached). */
|
|
829
|
-
repos:
|
|
896
|
+
repos: z19.array(z19.object({ name: z19.string(), branch: z19.string() })).optional()
|
|
830
897
|
}),
|
|
831
898
|
/** The chat (spec 2026-10-11 §5): what Ledge reads, its words as they come, the final text, or why it stopped; the day's turns after each snapshot. */
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
899
|
+
z19.object({ type: z19.literal("chat.step"), qid: z19.string(), step: ChatStepSchema }),
|
|
900
|
+
z19.object({ type: z19.literal("chat.delta"), qid: z19.string(), text: z19.string() }),
|
|
901
|
+
z19.object({ type: z19.literal("chat.done"), qid: z19.string(), text: z19.string(), at: z19.string().datetime(), proposal: ChatProposalSchema.optional(), proposals: ChatProposalsSchema.optional(), relay: ChatRelaySchema.optional(), closes: ChatClosesSchema.optional(), projectProposal: ChatProjectProposalSchema.optional(), team: ChatTeamProposalSchema.optional(), tasks: ChatTasksSchema.optional() }),
|
|
902
|
+
z19.object({ type: z19.literal("chat.error"), qid: z19.string(), message: z19.string() }),
|
|
903
|
+
z19.object({ type: z19.literal("chat.history"), turns: z19.array(ChatTurnSchema) }),
|
|
837
904
|
/** The daemon updating itself: npm is running, then the service restarts (the socket closes right after). */
|
|
838
|
-
|
|
905
|
+
z19.object({ type: z19.literal("update.progress"), version: z19.string(), step: z19.enum(["installing", "restarting"]) }),
|
|
839
906
|
/** Nothing was changed. `detail`: the useful end of npm's output; `command`: what the person can run instead. */
|
|
840
|
-
|
|
907
|
+
z19.object({ type: z19.literal("update.failed"), version: z19.string(), reason: UpdateFailureSchema, detail: z19.string().optional(), command: z19.string().optional() }),
|
|
841
908
|
/** The shared machines list (spec 2026-10-14 §5), sent to local clients only. */
|
|
842
|
-
|
|
909
|
+
z19.object({ type: z19.literal("machines"), machines: MachinesSchema }),
|
|
843
910
|
/** The local daemon's projects and folder rules (spec 2026-10-16 build §5), sent to local clients only. */
|
|
844
|
-
|
|
911
|
+
z19.object({ type: z19.literal("projects"), projects: ProjectsSchema }),
|
|
845
912
|
/** The island's settings shared by the local fronts; null until a front sets them (the island then sends its own). Local clients only. */
|
|
846
|
-
|
|
913
|
+
z19.object({ type: z19.literal("island"), prefs: IslandPrefsSchema.nullable() }),
|
|
847
914
|
/** Mobile access (lot 3), after the island in each snapshot and on every change. Local clients only. */
|
|
848
|
-
|
|
915
|
+
z19.object({ type: z19.literal("mobile"), state: MobileStateSchema }),
|
|
849
916
|
/** The daemon's immediate answer to a `session.message`: delivered (`accepted`), held for later (`queued`), left to Claude's own SendMessage (`native`), or refused with a `reason`. */
|
|
850
|
-
|
|
917
|
+
z19.object({ type: z19.literal("message.ack"), rid: z19.string(), outcome: z19.enum(["accepted", "queued", "native", "refused"]), reason: z19.string().optional() }),
|
|
851
918
|
/** The answer to a `message.read`: the body with its sender, target and time, or the refusal's `reason`. */
|
|
852
|
-
|
|
919
|
+
z19.object({ type: z19.literal("message.body"), id: z19.string(), from: z19.string().optional(), to: z19.string().optional(), at: z19.string().optional(), text: z19.string().optional(), reason: z19.string().optional() }),
|
|
853
920
|
TaskResultSchema,
|
|
854
921
|
SessionHandoverResultSchema,
|
|
855
922
|
ContextPrefsMessageSchema,
|
|
@@ -861,22 +928,24 @@ var ServerMessageSchema = z18.discriminatedUnion("type", [
|
|
|
861
928
|
TeamLaunchedSchema,
|
|
862
929
|
TeamFailedSchema,
|
|
863
930
|
TeamSavedSchema,
|
|
864
|
-
|
|
865
|
-
type:
|
|
866
|
-
message:
|
|
867
|
-
id:
|
|
931
|
+
z19.object({
|
|
932
|
+
type: z19.literal("error"),
|
|
933
|
+
message: z19.string(),
|
|
934
|
+
id: z19.string().optional(),
|
|
868
935
|
/** Le type du message client refusé. */
|
|
869
|
-
request:
|
|
936
|
+
request: z19.string().optional(),
|
|
870
937
|
/** Ce que le front doit reconnaître au-delà du texte (NOTE_NOT_TYPED) ; une chaîne libre, qu'un front plus ancien ignore. */
|
|
871
|
-
code:
|
|
938
|
+
code: z19.string().optional()
|
|
872
939
|
})
|
|
873
940
|
]);
|
|
874
941
|
var MESSAGE_MAX = 2e4;
|
|
875
942
|
var SUMMARY_MAX = 500;
|
|
876
|
-
var launchRows =
|
|
877
|
-
var ClientMessageSchema =
|
|
878
|
-
|
|
943
|
+
var launchRows = z19.array(z19.number().int().min(0).max(MAX_PROPOSALS - 1)).min(1).max(MAX_PROPOSALS).refine((r) => new Set(r).size === r.length, "a row twice");
|
|
944
|
+
var ClientMessageSchema = z19.discriminatedUnion("type", [
|
|
945
|
+
z19.object({ type: z19.literal("chat.route"), qid: z19.string().min(1).max(100), text: z19.string().min(1).max(2e4), tool: ToolSchema.optional(), context: RoutingContextSchema }),
|
|
879
946
|
DocumentReadSchema,
|
|
947
|
+
AttachmentPutSchema,
|
|
948
|
+
AttachmentGetSchema,
|
|
880
949
|
ReposInspectSchema,
|
|
881
950
|
ReposScanSchema,
|
|
882
951
|
ModelsListSchema,
|
|
@@ -884,18 +953,18 @@ var ClientMessageSchema = z18.discriminatedUnion("type", [
|
|
|
884
953
|
* free one otherwise), `prompt` the agent's first instruction, `continue` resumes the folder's last conversation.
|
|
885
954
|
* With `qid` it is the chat card of that turn: the daemon launches the turn's proposal and ignores the other fields
|
|
886
955
|
* but `rows`, `model` and `effort`. */
|
|
887
|
-
|
|
888
|
-
type:
|
|
956
|
+
z19.object({
|
|
957
|
+
type: z19.literal("session.launch"),
|
|
889
958
|
tool: ToolSchema,
|
|
890
|
-
cwd:
|
|
891
|
-
name:
|
|
892
|
-
prompt:
|
|
893
|
-
continue:
|
|
894
|
-
qid:
|
|
959
|
+
cwd: z19.string().min(1),
|
|
960
|
+
name: z19.string().optional(),
|
|
961
|
+
prompt: z19.string().optional(),
|
|
962
|
+
continue: z19.boolean().optional(),
|
|
963
|
+
qid: z19.string().min(1).optional(),
|
|
895
964
|
/** With `qid`: the card's rows to launch (#24), indexes into the turn's `proposals`, each once; the first row without it. */
|
|
896
965
|
rows: launchRows.optional(),
|
|
897
966
|
/** Folders in addition to `cwd` (Claude: `--add-dir`); resolved like `cwd`. */
|
|
898
|
-
dirs:
|
|
967
|
+
dirs: z19.array(z19.string().min(1)).max(20).optional(),
|
|
899
968
|
/** The agent's model and effort (#58), the agent's own default when left out; with `qid`, for every row launched. */
|
|
900
969
|
model: ModelIdSchema.optional(),
|
|
901
970
|
effort: EffortSchema.optional(),
|
|
@@ -906,98 +975,98 @@ var ClientMessageSchema = z18.discriminatedUnion("type", [
|
|
|
906
975
|
/** A live team the new session joins at once, in `role`. */
|
|
907
976
|
team: TeamIdSchema.optional(),
|
|
908
977
|
/** Routing by the fleet, removed before the message reaches the daemon. */
|
|
909
|
-
machineId:
|
|
978
|
+
machineId: z19.string().optional()
|
|
910
979
|
}),
|
|
911
980
|
/** The launch form's folder browser: list a folder's subfolders (home when no `path`), or make `name` inside `parent`
|
|
912
981
|
* and list it. Both are answered with a `folder.listing`. */
|
|
913
|
-
|
|
914
|
-
type:
|
|
915
|
-
path:
|
|
982
|
+
z19.object({
|
|
983
|
+
type: z19.literal("folder.list"),
|
|
984
|
+
path: z19.string().optional(),
|
|
916
985
|
/** Routing by the fleet, removed before the message reaches the daemon. */
|
|
917
|
-
machineId:
|
|
986
|
+
machineId: z19.string().optional(),
|
|
918
987
|
/** Copied into the `folder.listing` that answers; the fleet relays only that listing, from the machine asked. */
|
|
919
|
-
requestId:
|
|
988
|
+
requestId: z19.string().min(1).max(100).optional()
|
|
920
989
|
}),
|
|
921
|
-
|
|
922
|
-
type:
|
|
923
|
-
parent:
|
|
924
|
-
name:
|
|
990
|
+
z19.object({
|
|
991
|
+
type: z19.literal("folder.create"),
|
|
992
|
+
parent: z19.string().min(1),
|
|
993
|
+
name: z19.string().min(1),
|
|
925
994
|
/** As for `folder.list`: routing by the fleet, and the request its `folder.listing` answers. */
|
|
926
|
-
machineId:
|
|
927
|
-
requestId:
|
|
995
|
+
machineId: z19.string().optional(),
|
|
996
|
+
requestId: z19.string().min(1).max(100).optional()
|
|
928
997
|
}),
|
|
929
998
|
/** `steer`: OMP only, redirect the turn running now instead of queueing the text after it. */
|
|
930
999
|
/** OMP's `ask`: the answers to every question of the dialog `requestId`, in order (`selected` labels, and/or free `text`); `cancel` declines it. */
|
|
931
|
-
|
|
932
|
-
|
|
1000
|
+
z19.object({ type: z19.literal("session.answer"), id: z19.string(), requestId: z19.string().min(1).max(200), answers: z19.array(z19.object({ id: z19.string(), selected: z19.array(z19.string().max(2e3)).max(100), text: z19.string().max(2e4).optional() })).max(50), cancel: z19.boolean().optional() }),
|
|
1001
|
+
z19.object({ type: z19.literal("session.reply"), id: z19.string(), text: z19.string(), attachments: z19.array(AttachmentIdSchema).max(ATTACHMENTS_MAX).optional(), steer: z19.boolean().optional() }),
|
|
933
1002
|
/** The chat card's instruction (spec 2026-10-12 relay §4): sent now if the session is free, else queued until it is. */
|
|
934
|
-
|
|
1003
|
+
z19.object({ type: z19.literal("session.relay"), qid: z19.string().min(1) }),
|
|
935
1004
|
/** Takes the card's queued instruction back out of the queue. */
|
|
936
|
-
|
|
1005
|
+
z19.object({ type: z19.literal("session.relay.cancel"), qid: z19.string().min(1) }),
|
|
937
1006
|
/** The chat's close card: closes the turn's sessions, `rows` (indexes into its `closes`) or all of them. */
|
|
938
|
-
|
|
1007
|
+
z19.object({ type: z19.literal("session.close"), qid: z19.string().min(1), rows: launchRows.optional() }),
|
|
939
1008
|
/** `always` and `note` only where the harness offers them (`offers`); a note goes with `deny`, for the agent to read. */
|
|
940
|
-
|
|
941
|
-
type:
|
|
942
|
-
id:
|
|
1009
|
+
z19.object({
|
|
1010
|
+
type: z19.literal("session.decide"),
|
|
1011
|
+
id: z19.string(),
|
|
943
1012
|
decision: DecisionSchema,
|
|
944
|
-
note:
|
|
1013
|
+
note: z19.string().trim().min(1).max(NOTE_MAX).optional(),
|
|
945
1014
|
/** The request the user saw when deciding: refused (the request changed) unless it is still the pending one. Left out by older fronts and the island.
|
|
946
1015
|
* `key` (pendingKey) covers its whole content; older fronts send kind and text only. */
|
|
947
|
-
expect: PendingSchema.pick({ kind: true, text: true }).extend({ key:
|
|
1016
|
+
expect: PendingSchema.pick({ kind: true, text: true }).extend({ key: z19.string().max(64).optional() }).optional()
|
|
948
1017
|
}),
|
|
949
|
-
|
|
950
|
-
|
|
1018
|
+
z19.object({ type: z19.literal("session.focus"), id: z19.string() }),
|
|
1019
|
+
z19.object({ type: z19.literal("session.kill"), id: z19.string() }),
|
|
951
1020
|
/** `restoreQueue` (OMP): also take back what waits in its queue, returned as `session.queue.restored` to put in the draft. */
|
|
952
|
-
|
|
1021
|
+
z19.object({ type: z19.literal("session.interrupt"), id: z19.string(), restoreQueue: z19.boolean().optional() }),
|
|
953
1022
|
/** Removes a finished (exited) or read-only (hook_only) session from the list; refused for a live launcher session. */
|
|
954
|
-
|
|
1023
|
+
z19.object({ type: z19.literal("session.dismiss"), id: z19.string() }),
|
|
955
1024
|
/** Puts a session in the archive: it leaves the live list but is kept. */
|
|
956
|
-
|
|
1025
|
+
z19.object({ type: z19.literal("session.archive"), id: z19.string() }),
|
|
957
1026
|
/** Takes an archived session back out of the archive, as it was. */
|
|
958
|
-
|
|
1027
|
+
z19.object({ type: z19.literal("session.restore"), id: z19.string() }),
|
|
959
1028
|
/** Starts the agent again on an archived session's conversation. */
|
|
960
|
-
|
|
1029
|
+
z19.object({ type: z19.literal("session.resume"), id: z19.string() }),
|
|
961
1030
|
/** Changes a live session's model and effort (#58, lot 2), `null` for the agent's own default: the daemon restarts the
|
|
962
1031
|
* agent on the same conversation with them, at once when the session is free, else at its next free moment. */
|
|
963
|
-
|
|
1032
|
+
z19.object({ type: z19.literal("session.model"), id: z19.string(), model: ModelIdSchema.nullable(), effort: EffortSchema.nullable() }),
|
|
964
1033
|
/** Deletes a session for good, archived or not. */
|
|
965
|
-
|
|
1034
|
+
z19.object({ type: z19.literal("session.delete"), id: z19.string() }),
|
|
966
1035
|
/** The user names the session's topic from the overlay (500 characters at most, the hook's prompt cap); an empty topic hands back to the automatic sources. */
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1036
|
+
z19.object({ type: z19.literal("session.rename"), id: z19.string(), topic: z19.string().max(500) }),
|
|
1037
|
+
z19.object({ type: z19.literal("session.thread"), id: z19.string() }),
|
|
1038
|
+
z19.object({ type: z19.literal("session.register"), session: SessionSchema }),
|
|
970
1039
|
/** `agent` and `cwd` describe the session when the daemon does not know it yet (a hook from an agent started without ledge). */
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
1040
|
+
z19.object({ type: z19.literal("session.event"), id: z19.string(), event: SessionEventSchema, agent: ToolSchema.optional(), cwd: z19.string().optional() }),
|
|
1041
|
+
z19.object({ type: z19.literal("session.unregister"), id: z19.string(), exitCode: z19.number().int().nullable() }),
|
|
1042
|
+
z19.object({ type: z19.literal("snapshot.request") }),
|
|
1043
|
+
z19.object({ type: z19.literal("chat.ask"), qid: z19.string().min(1), text: z19.string(), images: z19.array(ImageUploadSchema).max(ATTACHMENTS_MAX).optional(), tool: ToolSchema.optional() }),
|
|
1044
|
+
z19.object({ type: z19.literal("chat.cancel"), qid: z19.string().min(1) }),
|
|
976
1045
|
/** Starts a new conversation with Ledge: the day's turns are cleared and the next question opens a new harness session. */
|
|
977
|
-
|
|
1046
|
+
z19.object({ type: z19.literal("chat.reset") }),
|
|
978
1047
|
/** Installs `@paradow/ledge@version` and restarts the service (spec 2026-10-12 auto-update §6). */
|
|
979
|
-
|
|
1048
|
+
z19.object({ type: z19.literal("update.daemon"), version: z19.string().regex(SEMVER) }),
|
|
980
1049
|
/** Replaces the daemon's machines list (first connected front wins); refused unless valid. */
|
|
981
|
-
|
|
1050
|
+
z19.object({ type: z19.literal("machines.set"), machines: MachinesSchema }),
|
|
982
1051
|
/** Replaces the local daemon's projects and rules as a whole; refused unless valid. */
|
|
983
|
-
|
|
1052
|
+
z19.object({ type: z19.literal("projects.set"), projects: ProjectsSchema }),
|
|
984
1053
|
/** Replaces the island's settings as a whole; refused unless valid. */
|
|
985
|
-
|
|
1054
|
+
z19.object({ type: z19.literal("island.set"), prefs: IslandPrefsSchema }),
|
|
986
1055
|
/** Mobile access (lot 3), local fronts only. A changed `relayUrl` drops the relay session. */
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1056
|
+
z19.object({ type: z19.literal("mobile.set"), enabled: z19.boolean(), relayUrl: RelayUrlSchema }),
|
|
1057
|
+
z19.object({ type: z19.literal("mobile.signin") }),
|
|
1058
|
+
z19.object({ type: z19.literal("mobile.signin.cancel") }),
|
|
1059
|
+
z19.object({ type: z19.literal("mobile.signout") }),
|
|
991
1060
|
/** While the link is offline: try again now. */
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1061
|
+
z19.object({ type: z19.literal("mobile.retry") }),
|
|
1062
|
+
z19.object({ type: z19.literal("mobile.pairing.approve"), id: z19.string().min(1).max(100) }),
|
|
1063
|
+
z19.object({ type: z19.literal("mobile.pairing.deny"), id: z19.string().min(1).max(100) }),
|
|
995
1064
|
/** `id`: the device's fingerprint. */
|
|
996
|
-
|
|
1065
|
+
z19.object({ type: z19.literal("mobile.device.revoke"), id: z19.string().min(1).max(100) }),
|
|
997
1066
|
/** One session writing to another by Ledge name (`to` may end in ` [ref]`); `intercept` (the Claude hook): answer `native` unless `to` is a live non-Claude session. */
|
|
998
|
-
|
|
1067
|
+
z19.object({ type: z19.literal("session.message"), rid: z19.string().min(1), from: z19.string().min(1), to: z19.string().min(1), text: z19.string().min(1).max(MESSAGE_MAX), summary: z19.string().max(SUMMARY_MAX).optional(), intercept: z19.boolean().optional() }),
|
|
999
1068
|
/** `ledge read <id>`: a message's whole body, for its receiver or its sender (`by`, a session id). */
|
|
1000
|
-
|
|
1069
|
+
z19.object({ type: z19.literal("message.read"), id: z19.string().min(1).max(40), by: z19.string().min(1) }),
|
|
1001
1070
|
TaskCmdSchema,
|
|
1002
1071
|
SessionHandoverSchema,
|
|
1003
1072
|
ContextSetSchema,
|
|
@@ -1101,27 +1170,27 @@ function pickName(taken, preferred) {
|
|
|
1101
1170
|
}
|
|
1102
1171
|
|
|
1103
1172
|
// ../protocol/src/proposal.ts
|
|
1104
|
-
import { z as
|
|
1105
|
-
var ProposalBlockSchema =
|
|
1106
|
-
var RelayBlockSchema =
|
|
1107
|
-
var ProjectBlockSchema =
|
|
1108
|
-
name:
|
|
1109
|
-
description:
|
|
1110
|
-
repos:
|
|
1111
|
-
addTo:
|
|
1173
|
+
import { z as z20 } from "zod";
|
|
1174
|
+
var ProposalBlockSchema = z20.object({ cwd: z20.string().trim().min(1), prompt: z20.string().optional() });
|
|
1175
|
+
var RelayBlockSchema = z20.object({ session: z20.string().trim().min(1), text: z20.string().trim().min(1) });
|
|
1176
|
+
var ProjectBlockSchema = z20.object({
|
|
1177
|
+
name: z20.string().trim().min(1).max(80),
|
|
1178
|
+
description: z20.string().max(500).optional(),
|
|
1179
|
+
repos: z20.array(z20.object({ path: z20.string().min(1).max(4096), why: z20.string().trim().min(1).max(200) })).min(1).max(50),
|
|
1180
|
+
addTo: z20.string().trim().max(80).optional()
|
|
1112
1181
|
});
|
|
1113
|
-
var CloseBlockSchema =
|
|
1114
|
-
var TeamBlockSchema =
|
|
1115
|
-
cwd:
|
|
1116
|
-
template:
|
|
1117
|
-
name:
|
|
1118
|
-
seats:
|
|
1182
|
+
var CloseBlockSchema = z20.object({ session: z20.string().trim().min(1) });
|
|
1183
|
+
var TeamBlockSchema = z20.object({
|
|
1184
|
+
cwd: z20.string().trim().min(1),
|
|
1185
|
+
template: z20.string().trim().min(1).max(64).optional(),
|
|
1186
|
+
name: z20.string().trim().min(1).max(60).optional(),
|
|
1187
|
+
seats: z20.array(z20.object({ role: z20.string().trim().min(1).max(40), tool: z20.enum(["claude", "codex", "cursor", "omp"]).optional(), model: z20.string().max(200).optional(), effort: z20.string().max(20).optional(), name: z20.string().max(40).optional() })).min(1).max(8).optional()
|
|
1119
1188
|
}).refine((b) => !!b.template || !!b.seats?.length, "a template or seats");
|
|
1120
|
-
var TaskBlockSchema =
|
|
1121
|
-
to:
|
|
1122
|
-
team:
|
|
1123
|
-
title:
|
|
1124
|
-
text:
|
|
1189
|
+
var TaskBlockSchema = z20.object({
|
|
1190
|
+
to: z20.string().trim().min(1).max(80),
|
|
1191
|
+
team: z20.string().trim().max(40).optional(),
|
|
1192
|
+
title: z20.string().trim().min(1).max(200),
|
|
1193
|
+
text: z20.string().max(2e4).optional()
|
|
1125
1194
|
});
|
|
1126
1195
|
var BLOCK = /```ledge-(session|relay|project|close|team|task)[ \t]*\n?([\s\S]*?)(?:```|$)/g;
|
|
1127
1196
|
function extractProposal(answer) {
|
|
@@ -1194,80 +1263,80 @@ function sessionTitle(s) {
|
|
|
1194
1263
|
}
|
|
1195
1264
|
|
|
1196
1265
|
// ../protocol/src/relay.ts
|
|
1197
|
-
import { z as
|
|
1266
|
+
import { z as z21 } from "zod";
|
|
1198
1267
|
var SEALED_MAX = 1048576;
|
|
1199
|
-
var RelayPeerSchema =
|
|
1200
|
-
var RelayClientMessageSchema =
|
|
1201
|
-
type:
|
|
1268
|
+
var RelayPeerSchema = z21.union([z21.literal("pc"), z21.string().regex(/^d_[A-Za-z0-9_-]{16,40}$/)]);
|
|
1269
|
+
var RelayClientMessageSchema = z21.object({
|
|
1270
|
+
type: z21.literal("send"),
|
|
1202
1271
|
to: RelayPeerSchema,
|
|
1203
|
-
body:
|
|
1272
|
+
body: z21.string().max(SEALED_MAX)
|
|
1204
1273
|
});
|
|
1205
|
-
var RelayServerMessageSchema =
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1274
|
+
var RelayServerMessageSchema = z21.discriminatedUnion("type", [
|
|
1275
|
+
z21.object({ type: z21.literal("welcome"), accountId: z21.string(), self: RelayPeerSchema, online: z21.array(RelayPeerSchema) }),
|
|
1276
|
+
z21.object({ type: z21.literal("deliver"), from: RelayPeerSchema, body: z21.string() }),
|
|
1277
|
+
z21.object({ type: z21.literal("presence"), peer: RelayPeerSchema, online: z21.boolean() }),
|
|
1209
1278
|
/**
|
|
1210
1279
|
* A frame was refused; `to` names the target when it is known.
|
|
1211
1280
|
* Contract: an error concerning a sealed body (`offline`, `too_large`, or a socket closed with 4008
|
|
1212
1281
|
* `rate_limited`) means that body was not delivered, so the sequence on that channel is lost: the
|
|
1213
1282
|
* sender must re-handshake with that peer before sending to it again.
|
|
1214
1283
|
*/
|
|
1215
|
-
|
|
1216
|
-
type:
|
|
1217
|
-
code:
|
|
1284
|
+
z21.object({
|
|
1285
|
+
type: z21.literal("error"),
|
|
1286
|
+
code: z21.enum(["bad_frame", "too_large", "bad_target", "offline", "rate_limited"]),
|
|
1218
1287
|
to: RelayPeerSchema.optional()
|
|
1219
1288
|
})
|
|
1220
1289
|
]);
|
|
1221
1290
|
var PAIR_LABEL_MAX = 40;
|
|
1222
|
-
var KeyB64 =
|
|
1223
|
-
var Nonce =
|
|
1224
|
-
var Fingerprint =
|
|
1225
|
-
var SealedFrameSchema =
|
|
1291
|
+
var KeyB64 = z21.string().regex(/^[A-Za-z0-9_-]{87}$/);
|
|
1292
|
+
var Nonce = z21.string().regex(/^[A-Za-z0-9_-]{43}$/);
|
|
1293
|
+
var Fingerprint = z21.string().regex(/^[A-Za-z0-9_-]{22}$/);
|
|
1294
|
+
var SealedFrameSchema = z21.discriminatedUnion("k", [
|
|
1226
1295
|
/** `e` is the ephemeral key, `f` the fingerprint of the sender's static key. */
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1296
|
+
z21.object({ k: z21.literal("hello"), e: KeyB64, f: Fingerprint }),
|
|
1297
|
+
z21.object({ k: z21.literal("msg"), s: z21.string() }),
|
|
1298
|
+
z21.object({ k: z21.literal("pair_commit"), c: Nonce, label: z21.string().trim().min(1).max(PAIR_LABEL_MAX) }),
|
|
1299
|
+
z21.object({ k: z21.literal("pair_offer"), pc: KeyB64, n: Nonce }),
|
|
1300
|
+
z21.object({ k: z21.literal("pair_reveal"), d: KeyB64, n: Nonce }),
|
|
1301
|
+
z21.object({ k: z21.literal("pair_ok") }),
|
|
1302
|
+
z21.object({ k: z21.literal("pair_no") }),
|
|
1303
|
+
z21.object({ k: z21.literal("denied") }),
|
|
1304
|
+
z21.object({ k: z21.literal("rekey") })
|
|
1236
1305
|
]);
|
|
1237
1306
|
|
|
1238
1307
|
// ../protocol/src/relayAuth.ts
|
|
1239
|
-
import { z as
|
|
1308
|
+
import { z as z22 } from "zod";
|
|
1240
1309
|
var RELAY_CLOSE_SIGNED_OUT = 4001;
|
|
1241
|
-
var DeviceStartResponseSchema =
|
|
1242
|
-
deviceCode:
|
|
1243
|
-
userCode:
|
|
1244
|
-
verificationUri:
|
|
1245
|
-
expiresIn:
|
|
1246
|
-
interval:
|
|
1310
|
+
var DeviceStartResponseSchema = z22.object({
|
|
1311
|
+
deviceCode: z22.string().min(1),
|
|
1312
|
+
userCode: z22.string().min(1),
|
|
1313
|
+
verificationUri: z22.string().min(1),
|
|
1314
|
+
expiresIn: z22.number().int().positive(),
|
|
1315
|
+
interval: z22.number().int().positive()
|
|
1247
1316
|
});
|
|
1248
|
-
var DevicePollResponseSchema =
|
|
1249
|
-
|
|
1250
|
-
|
|
1317
|
+
var DevicePollResponseSchema = z22.discriminatedUnion("status", [
|
|
1318
|
+
z22.object({ status: z22.literal("pending") }),
|
|
1319
|
+
z22.object({ status: z22.literal("slow_down"), interval: z22.number().int().positive() }),
|
|
1251
1320
|
/** `token` is the relay session token, shown this once only. */
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1321
|
+
z22.object({ status: z22.literal("ok"), token: z22.string().min(1), accountId: z22.string().min(1), login: z22.string().min(1) }),
|
|
1322
|
+
z22.object({ status: z22.literal("expired") }),
|
|
1323
|
+
z22.object({ status: z22.literal("denied") }),
|
|
1324
|
+
z22.object({ status: z22.literal("not_allowed") })
|
|
1256
1325
|
]);
|
|
1257
|
-
var DeviceRevokeResponseSchema =
|
|
1258
|
-
var MeResponseSchema =
|
|
1259
|
-
accountId:
|
|
1260
|
-
login:
|
|
1326
|
+
var DeviceRevokeResponseSchema = z22.object({ revoked: z22.number().int().min(0) });
|
|
1327
|
+
var MeResponseSchema = z22.object({
|
|
1328
|
+
accountId: z22.string().min(1),
|
|
1329
|
+
login: z22.string().min(1),
|
|
1261
1330
|
peer: RelayPeerSchema,
|
|
1262
|
-
kind:
|
|
1331
|
+
kind: z22.enum(["pc", "device"])
|
|
1263
1332
|
});
|
|
1264
1333
|
|
|
1265
1334
|
// ../protocol/src/phone.ts
|
|
1266
|
-
import { z as
|
|
1335
|
+
import { z as z24 } from "zod";
|
|
1267
1336
|
|
|
1268
1337
|
// ../protocol/src/push.ts
|
|
1269
|
-
import { z as
|
|
1270
|
-
var B64U =
|
|
1338
|
+
import { z as z23 } from "zod";
|
|
1339
|
+
var B64U = z23.string().regex(/^[A-Za-z0-9_-]*$/);
|
|
1271
1340
|
var PUSH_HOSTS = ["*.push.apple.com", "fcm.googleapis.com", "updates.push.services.mozilla.com", "*.notify.windows.com"];
|
|
1272
1341
|
function pushEndpointAllowed(url) {
|
|
1273
1342
|
let u;
|
|
@@ -1284,29 +1353,29 @@ function pushEndpointAllowed(url) {
|
|
|
1284
1353
|
return host.length > suffix.length && host.endsWith(suffix);
|
|
1285
1354
|
});
|
|
1286
1355
|
}
|
|
1287
|
-
var PushSendSchema =
|
|
1288
|
-
endpoint:
|
|
1356
|
+
var PushSendSchema = z23.object({
|
|
1357
|
+
endpoint: z23.string().url().max(1024),
|
|
1289
1358
|
body: B64U.max(5462),
|
|
1290
|
-
ttl:
|
|
1291
|
-
urgency:
|
|
1292
|
-
topic:
|
|
1359
|
+
ttl: z23.number().int().min(0).max(86400),
|
|
1360
|
+
urgency: z23.enum(["normal", "high"]),
|
|
1361
|
+
topic: z23.string().regex(/^[A-Za-z0-9_-]{1,32}$/)
|
|
1293
1362
|
});
|
|
1294
|
-
var PushSendResultSchema =
|
|
1295
|
-
result:
|
|
1296
|
-
status:
|
|
1363
|
+
var PushSendResultSchema = z23.object({
|
|
1364
|
+
result: z23.enum(["sent", "gone", "failed"]),
|
|
1365
|
+
status: z23.number().int().optional()
|
|
1297
1366
|
});
|
|
1298
|
-
var PushSubscriptionSchema =
|
|
1299
|
-
endpoint:
|
|
1300
|
-
keys:
|
|
1367
|
+
var PushSubscriptionSchema = z23.object({
|
|
1368
|
+
endpoint: z23.string().url().max(1024).refine(pushEndpointAllowed),
|
|
1369
|
+
keys: z23.object({ p256dh: B64U.length(87), auth: B64U.length(22) })
|
|
1301
1370
|
});
|
|
1302
|
-
var PushPayloadSchema =
|
|
1303
|
-
v:
|
|
1304
|
-
kind:
|
|
1305
|
-
title:
|
|
1306
|
-
body:
|
|
1307
|
-
url:
|
|
1308
|
-
badge:
|
|
1309
|
-
tag:
|
|
1371
|
+
var PushPayloadSchema = z23.object({
|
|
1372
|
+
v: z23.literal(1),
|
|
1373
|
+
kind: z23.enum(["request", "question", "finished", "chat"]),
|
|
1374
|
+
title: z23.string().max(80),
|
|
1375
|
+
body: z23.string().max(120),
|
|
1376
|
+
url: z23.string().regex(/^\/#\/[A-Za-z0-9/%._~-]*$/).max(300),
|
|
1377
|
+
badge: z23.number().int().min(0).max(999),
|
|
1378
|
+
tag: z23.string().regex(/^[A-Za-z0-9_-]{1,32}$/)
|
|
1310
1379
|
});
|
|
1311
1380
|
|
|
1312
1381
|
// ../protocol/src/phone.ts
|
|
@@ -1327,22 +1396,22 @@ var THREAD_TEXT_MAX = 8192;
|
|
|
1327
1396
|
var TOOL_TEXT_MAX = 2048;
|
|
1328
1397
|
var PENDING_BODY_MAX = 65536;
|
|
1329
1398
|
var SNAPSHOT_BODY_MAX = 2048;
|
|
1330
|
-
var RiskSchema =
|
|
1331
|
-
var RiskReasonSchema =
|
|
1332
|
-
var OperationIdSchema =
|
|
1333
|
-
var OperationStatusSchema =
|
|
1334
|
-
var OperationReasonSchema =
|
|
1335
|
-
var CapabilitiesSchema =
|
|
1399
|
+
var RiskSchema = z24.enum(["low", "high"]);
|
|
1400
|
+
var RiskReasonSchema = z24.enum(["question", "read_only_command", "edit_inside_folder", "pushes", "destroys", "deploys", "publishes", "pipes_to_shell", "network", "writes_outside_folder", "sensitive_path", "unsafe_flag", "shell_syntax", "script", "plan", "unknown"]);
|
|
1401
|
+
var OperationIdSchema = z24.string().uuid();
|
|
1402
|
+
var OperationStatusSchema = z24.enum(["received", "applied", "rejected", "failed"]);
|
|
1403
|
+
var OperationReasonSchema = z24.enum([...RefusalCodeSchema.options, "untypable", "confirm_required", "conflict", "assertion_invalid", "assertion_expired"]);
|
|
1404
|
+
var CapabilitiesSchema = z24.object({
|
|
1336
1405
|
/** A question can be answered in free text. */
|
|
1337
|
-
freeTextAnswer:
|
|
1406
|
+
freeTextAnswer: z24.boolean(),
|
|
1338
1407
|
/** The session's accept/deny can be typed; absent = true. */
|
|
1339
|
-
decide:
|
|
1408
|
+
decide: z24.boolean().optional(),
|
|
1340
1409
|
/** OMP's dialog questions can be answered from the phone; absent = false. */
|
|
1341
|
-
questions:
|
|
1410
|
+
questions: z24.boolean().optional()
|
|
1342
1411
|
});
|
|
1343
1412
|
var UNTYPABLE = /[\u0000-\u001f\u007f-\u009f\u200b\u200e\u200f\u2028-\u202e\u2066-\u2069\ufeff]/;
|
|
1344
|
-
var CapabilitiesByToolSchema =
|
|
1345
|
-
var PhonePendingSchema = PendingSchema.extend({ key:
|
|
1413
|
+
var CapabilitiesByToolSchema = z24.object({ claude: CapabilitiesSchema, codex: CapabilitiesSchema, cursor: CapabilitiesSchema, omp: CapabilitiesSchema });
|
|
1414
|
+
var PhonePendingSchema = PendingSchema.extend({ key: z24.string().max(64), risk: RiskSchema, riskReason: RiskReasonSchema, cut: z24.literal(true).optional() });
|
|
1346
1415
|
var PhoneSessionSchema = SessionSchema.pick({
|
|
1347
1416
|
id: true,
|
|
1348
1417
|
name: true,
|
|
@@ -1365,202 +1434,210 @@ var PhoneSessionSchema = SessionSchema.pick({
|
|
|
1365
1434
|
/** Its context and its relief (context handover spec §3.2): the phone shows the gauge; the relief is started from the PC. */
|
|
1366
1435
|
context: true,
|
|
1367
1436
|
relieves: true
|
|
1368
|
-
}).extend({ pending: PhonePendingSchema.optional(), unread:
|
|
1369
|
-
var B64U2 =
|
|
1370
|
-
var CredentialSchema =
|
|
1437
|
+
}).extend({ pending: PhonePendingSchema.optional(), unread: z24.boolean(), handover: z24.object({ state: HandoverStateSchema, toName: z24.string().max(80).optional() }).strict().optional() });
|
|
1438
|
+
var B64U2 = z24.string().regex(/^[A-Za-z0-9_-]*$/);
|
|
1439
|
+
var CredentialSchema = z24.object({
|
|
1371
1440
|
id: B64U2.max(1366),
|
|
1372
1441
|
publicKey: B64U2.max(2048),
|
|
1373
|
-
alg:
|
|
1442
|
+
alg: z24.union([z24.literal(-7), z24.literal(-257)]),
|
|
1374
1443
|
clientDataJSON: B64U2.max(4096),
|
|
1375
1444
|
authenticatorData: B64U2.max(4096),
|
|
1376
|
-
transports:
|
|
1445
|
+
transports: z24.array(z24.string().max(20)).max(8).optional()
|
|
1377
1446
|
});
|
|
1378
|
-
var AssertionSchema =
|
|
1447
|
+
var AssertionSchema = z24.object({
|
|
1379
1448
|
id: B64U2.max(1366),
|
|
1380
1449
|
clientDataJSON: B64U2.max(4096),
|
|
1381
1450
|
authenticatorData: B64U2.max(4096),
|
|
1382
1451
|
signature: B64U2.max(1024)
|
|
1383
1452
|
});
|
|
1384
|
-
var ConfirmPurposeSchema =
|
|
1453
|
+
var ConfirmPurposeSchema = z24.enum(["register", "decide", "launch", "close"]);
|
|
1385
1454
|
var PhoneChatStepSchema = ChatStepSchema.pick({ kind: true, id: true, name: true }).strict();
|
|
1386
|
-
var PhoneChatProposalSchema =
|
|
1387
|
-
project:
|
|
1455
|
+
var PhoneChatProposalSchema = z24.object({
|
|
1456
|
+
project: z24.string().max(80),
|
|
1388
1457
|
tool: ToolSchema,
|
|
1389
|
-
prompt:
|
|
1390
|
-
launchedId:
|
|
1391
|
-
failed:
|
|
1458
|
+
prompt: z24.string().max(TOOL_TEXT_MAX).optional(),
|
|
1459
|
+
launchedId: z24.string().optional(),
|
|
1460
|
+
failed: z24.literal(true).optional()
|
|
1392
1461
|
}).strict();
|
|
1393
|
-
var PhoneChatRelaySchema =
|
|
1394
|
-
id:
|
|
1395
|
-
name:
|
|
1462
|
+
var PhoneChatRelaySchema = z24.object({
|
|
1463
|
+
id: z24.string().min(1),
|
|
1464
|
+
name: z24.string(),
|
|
1396
1465
|
tool: ToolSchema,
|
|
1397
|
-
text:
|
|
1398
|
-
status:
|
|
1399
|
-
sentAt:
|
|
1400
|
-
failed:
|
|
1466
|
+
text: z24.string().max(TOOL_TEXT_MAX),
|
|
1467
|
+
status: z24.enum(["queued", "sent"]).optional(),
|
|
1468
|
+
sentAt: z24.string().datetime().optional(),
|
|
1469
|
+
failed: z24.literal(true).optional()
|
|
1401
1470
|
}).strict();
|
|
1402
|
-
var PhoneChatCloseSchema =
|
|
1403
|
-
id:
|
|
1404
|
-
name:
|
|
1471
|
+
var PhoneChatCloseSchema = z24.object({
|
|
1472
|
+
id: z24.string().min(1),
|
|
1473
|
+
name: z24.string(),
|
|
1405
1474
|
tool: ToolSchema,
|
|
1406
|
-
how:
|
|
1407
|
-
closedAt:
|
|
1408
|
-
failed:
|
|
1475
|
+
how: z24.enum(["exit", "killed"]).optional(),
|
|
1476
|
+
closedAt: z24.string().datetime().optional(),
|
|
1477
|
+
failed: z24.literal(true).optional()
|
|
1409
1478
|
}).strict();
|
|
1410
|
-
var PhoneChatTeamSchema =
|
|
1411
|
-
project:
|
|
1412
|
-
name:
|
|
1413
|
-
template:
|
|
1414
|
-
seats:
|
|
1415
|
-
teamId:
|
|
1416
|
-
launchedAt:
|
|
1417
|
-
failed:
|
|
1479
|
+
var PhoneChatTeamSchema = z24.object({
|
|
1480
|
+
project: z24.string().max(80),
|
|
1481
|
+
name: z24.string().max(60),
|
|
1482
|
+
template: z24.string().max(64).optional(),
|
|
1483
|
+
seats: z24.array(z24.object({ role: z24.string().max(40), label: z24.string().max(40), tool: ToolSchema, model: z24.string().max(200).optional(), effort: z24.string().max(20).optional(), autonomy: AutonomySchema.optional() }).strict()).min(1).max(8),
|
|
1484
|
+
teamId: z24.string().max(40).optional(),
|
|
1485
|
+
launchedAt: z24.string().datetime().optional(),
|
|
1486
|
+
failed: z24.literal(true).optional()
|
|
1418
1487
|
}).strict();
|
|
1419
|
-
var PhoneChatTaskSchema =
|
|
1420
|
-
to:
|
|
1421
|
-
toName:
|
|
1422
|
-
title:
|
|
1423
|
-
text:
|
|
1424
|
-
taskId:
|
|
1425
|
-
ownerName:
|
|
1426
|
-
state:
|
|
1427
|
-
failed:
|
|
1488
|
+
var PhoneChatTaskSchema = z24.object({
|
|
1489
|
+
to: z24.string().max(80),
|
|
1490
|
+
toName: z24.string().max(80).optional(),
|
|
1491
|
+
title: z24.string().max(200),
|
|
1492
|
+
text: z24.string().max(TOOL_TEXT_MAX).optional(),
|
|
1493
|
+
taskId: z24.string().max(40).optional(),
|
|
1494
|
+
ownerName: z24.string().max(80).optional(),
|
|
1495
|
+
state: z24.enum(["open", "taken", "done", "refused", "dropped"]).optional(),
|
|
1496
|
+
failed: z24.literal(true).optional()
|
|
1428
1497
|
}).strict();
|
|
1429
|
-
var PhoneTeamSchema =
|
|
1430
|
-
id:
|
|
1431
|
-
name:
|
|
1432
|
-
project:
|
|
1433
|
-
state:
|
|
1434
|
-
seats:
|
|
1435
|
-
done:
|
|
1436
|
-
given:
|
|
1498
|
+
var PhoneTeamSchema = z24.object({
|
|
1499
|
+
id: z24.string().max(40),
|
|
1500
|
+
name: z24.string().max(60),
|
|
1501
|
+
project: z24.string().max(80).nullable(),
|
|
1502
|
+
state: z24.enum(["active", "resting"]),
|
|
1503
|
+
seats: z24.array(z24.object({ role: z24.string().max(40), sessionId: z24.string().max(100).nullable() }).strict()).max(16),
|
|
1504
|
+
done: z24.number().int().min(0),
|
|
1505
|
+
given: z24.number().int().min(0)
|
|
1437
1506
|
}).strict();
|
|
1438
|
-
var PhoneTaskSchema =
|
|
1439
|
-
id:
|
|
1440
|
-
title:
|
|
1441
|
-
owner:
|
|
1442
|
-
ownerName:
|
|
1443
|
-
ownerRole:
|
|
1444
|
-
team:
|
|
1445
|
-
teamName:
|
|
1446
|
-
state:
|
|
1447
|
-
result:
|
|
1448
|
-
cut:
|
|
1449
|
-
at:
|
|
1450
|
-
updatedAt:
|
|
1451
|
-
seen:
|
|
1507
|
+
var PhoneTaskSchema = z24.object({
|
|
1508
|
+
id: z24.string().max(40),
|
|
1509
|
+
title: z24.string().max(200),
|
|
1510
|
+
owner: z24.string().max(100),
|
|
1511
|
+
ownerName: z24.string().max(80),
|
|
1512
|
+
ownerRole: z24.string().max(40).optional(),
|
|
1513
|
+
team: z24.string().max(40).optional(),
|
|
1514
|
+
teamName: z24.string().max(60).optional(),
|
|
1515
|
+
state: z24.enum(["open", "taken", "done", "refused", "dropped"]),
|
|
1516
|
+
result: z24.string().max(TOOL_TEXT_MAX).optional(),
|
|
1517
|
+
cut: z24.literal(true).optional(),
|
|
1518
|
+
at: z24.string(),
|
|
1519
|
+
updatedAt: z24.string(),
|
|
1520
|
+
seen: z24.literal(true).optional()
|
|
1452
1521
|
}).strict();
|
|
1453
|
-
var ChatErrorCodeSchema =
|
|
1454
|
-
var PhoneChatTurnSchema =
|
|
1522
|
+
var ChatErrorCodeSchema = z24.enum(["busy", "timeout", "cancelled", "failed"]);
|
|
1523
|
+
var PhoneChatTurnSchema = z24.object({
|
|
1455
1524
|
qid: OperationIdSchema,
|
|
1456
|
-
question:
|
|
1457
|
-
askedAt:
|
|
1458
|
-
steps:
|
|
1459
|
-
answer:
|
|
1460
|
-
answeredAt:
|
|
1525
|
+
question: z24.string().max(MESSAGE_MAX),
|
|
1526
|
+
askedAt: z24.string().datetime(),
|
|
1527
|
+
steps: z24.array(PhoneChatStepSchema).max(50),
|
|
1528
|
+
answer: z24.string().max(THREAD_TEXT_MAX).optional(),
|
|
1529
|
+
answeredAt: z24.string().datetime().optional(),
|
|
1461
1530
|
error: ChatErrorCodeSchema.optional(),
|
|
1462
|
-
proposals:
|
|
1531
|
+
proposals: z24.array(PhoneChatProposalSchema).max(MAX_PROPOSALS).optional(),
|
|
1463
1532
|
relay: PhoneChatRelaySchema.optional(),
|
|
1464
|
-
closes:
|
|
1465
|
-
cut:
|
|
1533
|
+
closes: z24.array(PhoneChatCloseSchema).min(1).max(MAX_PROPOSALS).optional(),
|
|
1534
|
+
cut: z24.literal(true).optional(),
|
|
1466
1535
|
team: PhoneChatTeamSchema.optional(),
|
|
1467
|
-
tasks:
|
|
1536
|
+
tasks: z24.array(PhoneChatTaskSchema).min(1).max(MAX_PROPOSALS).optional(),
|
|
1537
|
+
attachments: z24.array(AttachmentRefSchema).max(ATTACHMENTS_MAX).optional()
|
|
1468
1538
|
}).strict();
|
|
1469
1539
|
var CHAT_HISTORY_BUDGET = 393216;
|
|
1470
|
-
var sessionId =
|
|
1471
|
-
var PhoneExpectSchema = PendingSchema.pick({ kind: true, text: true }).extend({ key:
|
|
1472
|
-
var CardRowsSchema =
|
|
1473
|
-
var PhoneClientMessageSchema =
|
|
1474
|
-
|
|
1475
|
-
|
|
1540
|
+
var sessionId = z24.string().min(1).max(100);
|
|
1541
|
+
var PhoneExpectSchema = PendingSchema.pick({ kind: true, text: true }).extend({ key: z24.string().min(1).max(64) });
|
|
1542
|
+
var CardRowsSchema = z24.array(z24.number().int().min(0).max(MAX_PROPOSALS - 1)).min(1).max(MAX_PROPOSALS).refine((r) => new Set(r).size === r.length, "a row twice");
|
|
1543
|
+
var PhoneClientMessageSchema = z24.discriminatedUnion("type", [
|
|
1544
|
+
z24.object({ type: z24.literal("snapshot.request") }),
|
|
1545
|
+
z24.object({ type: z24.literal("session.thread"), id: sessionId }),
|
|
1476
1546
|
/** The session's request with its whole body (up to `PENDING_BODY_MAX`). */
|
|
1477
|
-
|
|
1547
|
+
z24.object({ type: z24.literal("session.pending"), id: sessionId }),
|
|
1478
1548
|
/** The session whose terminal the phone shows; null when it shows none. */
|
|
1479
|
-
|
|
1480
|
-
|
|
1549
|
+
z24.object({ type: z24.literal("session.watch"), id: sessionId.nullable() }),
|
|
1550
|
+
z24.object({ type: z24.literal("session.read"), id: sessionId, at: z24.string().datetime() }),
|
|
1481
1551
|
/** Asks for a challenge. One object for both purposes: the gateway refuses a `decide` without `id` and `expect`. */
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
type:
|
|
1552
|
+
z24.object({ type: z24.literal("confirm.prepare"), purpose: ConfirmPurposeSchema, id: sessionId.optional(), expect: PhoneExpectSchema.optional(), qid: OperationIdSchema.optional() }),
|
|
1553
|
+
z24.object({ type: z24.literal("credential.register"), op: OperationIdSchema, credential: CredentialSchema }),
|
|
1554
|
+
z24.object({
|
|
1555
|
+
type: z24.literal("session.decide"),
|
|
1486
1556
|
op: OperationIdSchema,
|
|
1487
1557
|
id: sessionId,
|
|
1488
1558
|
decision: DecisionSchema,
|
|
1489
|
-
note:
|
|
1559
|
+
note: z24.string().trim().min(1).max(NOTE_MAX).optional(),
|
|
1490
1560
|
/** The request the phone showed: refused unless it is still the pending one. */
|
|
1491
1561
|
expect: PhoneExpectSchema,
|
|
1492
1562
|
/** The device check over the challenge of `confirm.prepare`; required by the daemon for a high-risk accept. */
|
|
1493
1563
|
assertion: AssertionSchema.optional()
|
|
1494
1564
|
}),
|
|
1495
|
-
|
|
1496
|
-
type:
|
|
1565
|
+
z24.object({
|
|
1566
|
+
type: z24.literal("session.reply"),
|
|
1497
1567
|
op: OperationIdSchema,
|
|
1498
1568
|
id: sessionId,
|
|
1499
|
-
text:
|
|
1569
|
+
text: z24.string().max(MESSAGE_MAX),
|
|
1570
|
+
attachments: z24.array(AttachmentIdSchema).max(ATTACHMENTS_MAX).optional(),
|
|
1500
1571
|
/** The request the reply answers, or null when the phone showed none: refused if the session's request is no longer that one. */
|
|
1501
1572
|
expect: PhoneExpectSchema.nullable(),
|
|
1502
1573
|
assertion: AssertionSchema.optional()
|
|
1503
1574
|
}),
|
|
1504
1575
|
/** OMP's `ask`: the answers to every question of the dialog `requestId`, in order; `cancel` declines it. Bounds as the local `session.answer`. */
|
|
1505
|
-
|
|
1506
|
-
type:
|
|
1576
|
+
z24.object({
|
|
1577
|
+
type: z24.literal("session.answer"),
|
|
1507
1578
|
op: OperationIdSchema,
|
|
1508
1579
|
id: sessionId,
|
|
1509
|
-
requestId:
|
|
1510
|
-
answers:
|
|
1511
|
-
cancel:
|
|
1580
|
+
requestId: z24.string().min(1).max(200),
|
|
1581
|
+
answers: z24.array(z24.object({ id: z24.string().max(200), selected: z24.array(z24.string().max(2e3)).max(100), text: z24.string().max(2e4).optional() })).max(50),
|
|
1582
|
+
cancel: z24.literal(true).optional(),
|
|
1512
1583
|
expect: PhoneExpectSchema
|
|
1513
1584
|
}),
|
|
1514
|
-
|
|
1585
|
+
z24.object({ type: z24.literal("session.interrupt"), op: OperationIdSchema, id: sessionId }),
|
|
1515
1586
|
/** The phone drops its passkey from the daemon. */
|
|
1516
|
-
|
|
1587
|
+
z24.object({ type: z24.literal("device.forget"), op: OperationIdSchema }),
|
|
1517
1588
|
/** The phone's push subscription, with the VAPID key it was made with (so a key change is seen). */
|
|
1518
|
-
|
|
1519
|
-
|
|
1589
|
+
z24.object({ type: z24.literal("push.subscribe"), op: OperationIdSchema, subscription: PushSubscriptionSchema, key: B64U2.length(87) }),
|
|
1590
|
+
z24.object({ type: z24.literal("push.unsubscribe"), op: OperationIdSchema }),
|
|
1520
1591
|
/** The phone's own chat with Ledge. */
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1592
|
+
z24.object({ type: z24.literal("chat.ask"), qid: OperationIdSchema, text: z24.string().trim().max(MESSAGE_MAX), attachments: z24.array(AttachmentIdSchema).max(ATTACHMENTS_MAX).optional() }),
|
|
1593
|
+
z24.object({ type: z24.literal("chat.cancel"), qid: OperationIdSchema }),
|
|
1594
|
+
z24.object({ type: z24.literal("chat.reset") }),
|
|
1595
|
+
z24.object({ type: z24.literal("chat.history") }),
|
|
1596
|
+
/** An image to store, sent alone before the message that names it; no `id`, and at most `ATTACHMENT_MAX` bytes. */
|
|
1597
|
+
AttachmentPutSchema.pick({ type: true, requestId: true }).extend({ image: ImageUploadSchema.extend({ data: z24.string().min(1).max(b64Max(ATTACHMENT_MAX)) }) }),
|
|
1598
|
+
AttachmentGetSchema.pick({ type: true, requestId: true, attachment: true, preview: true }),
|
|
1599
|
+
z24.object({ type: z24.literal("chat.relay"), op: OperationIdSchema, qid: OperationIdSchema }),
|
|
1600
|
+
z24.object({ type: z24.literal("chat.launch"), op: OperationIdSchema, qid: OperationIdSchema, rows: CardRowsSchema.optional(), assertion: AssertionSchema.optional() }),
|
|
1601
|
+
z24.object({ type: z24.literal("chat.close"), op: OperationIdSchema, qid: OperationIdSchema, rows: CardRowsSchema.optional(), assertion: AssertionSchema.optional() }),
|
|
1528
1602
|
/** The turn's team card (roles spec §3.8): launched like a session card, with the device check (purpose `launch`, the turn). */
|
|
1529
|
-
|
|
1603
|
+
z24.object({ type: z24.literal("chat.team"), op: OperationIdSchema, qid: OperationIdSchema, assertion: AssertionSchema.optional() }),
|
|
1530
1604
|
/** A row of the turn's task card: given by Ledge. */
|
|
1531
|
-
|
|
1605
|
+
z24.object({ type: z24.literal("chat.task"), op: OperationIdSchema, qid: OperationIdSchema, row: z24.number().int().min(0).max(MAX_PROPOSALS - 1) }),
|
|
1532
1606
|
/** « Reprendre » a resting team. */
|
|
1533
|
-
|
|
1607
|
+
z24.object({ type: z24.literal("team.resume"), op: OperationIdSchema, team: z24.string().min(1).max(40) }),
|
|
1534
1608
|
/** Puts a closed task Ledge gave away from « À traiter ». */
|
|
1535
|
-
|
|
1609
|
+
z24.object({ type: z24.literal("task.seen"), op: OperationIdSchema, task: z24.string().min(1).max(40) }),
|
|
1536
1610
|
/** Whether the phone's app is in front: a device that is visible gets no push. */
|
|
1537
|
-
|
|
1611
|
+
z24.object({ type: z24.literal("presence"), visible: z24.boolean() })
|
|
1538
1612
|
]);
|
|
1539
|
-
var PhoneServerMessageSchema =
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1613
|
+
var PhoneServerMessageSchema = z24.discriminatedUnion("type", [
|
|
1614
|
+
z24.object({ type: z24.literal("snapshot"), protocol: z24.literal(PHONE_PROTOCOL), sessions: z24.array(PhoneSessionSchema), capabilities: CapabilitiesByToolSchema, daemon: z24.object({ version: z24.string(), name: z24.string().max(40), boot: z24.string().uuid().optional() }), device: z24.object({ confirm: z24.boolean(), push: z24.enum(["on", "off", "stale", "unavailable"]).optional(), chat: z24.literal(true).optional(), contextNear: ContextPrefsSchema.shape.near.optional() }).optional() }),
|
|
1615
|
+
z24.object({ type: z24.literal("confirm.challenge"), purpose: ConfirmPurposeSchema, challenge: B64U2.max(64), rpId: z24.string().max(253), credentialId: B64U2.max(1366).optional(), expiresInMs: z24.number().int().positive() }),
|
|
1616
|
+
z24.object({ type: z24.literal("session.updated"), session: PhoneSessionSchema }),
|
|
1617
|
+
z24.object({ type: z24.literal("session.removed"), id: z24.string() }),
|
|
1544
1618
|
/** `pending.cut` is set when even this body was shortened. */
|
|
1545
|
-
|
|
1546
|
-
|
|
1619
|
+
z24.object({ type: z24.literal("session.pending"), id: z24.string(), pending: PhonePendingSchema }),
|
|
1620
|
+
z24.object({ type: z24.literal("session.preview"), id: z24.string(), lines: z24.array(z24.string()) }),
|
|
1547
1621
|
/** `cut`: the ids of the items shortened; `more`: older items were left out. */
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1622
|
+
z24.object({ type: z24.literal("session.thread"), id: z24.string(), items: z24.array(ThreadItemSchema), cut: z24.array(z24.string()), more: z24.boolean() }),
|
|
1623
|
+
z24.object({ type: z24.literal("session.thread.item"), id: z24.string(), item: ThreadItemSchema, cut: z24.literal(true).optional() }),
|
|
1624
|
+
z24.object({ type: z24.literal("operation.result"), op: OperationIdSchema, status: OperationStatusSchema, reason: OperationReasonSchema.optional() }),
|
|
1625
|
+
z24.object({ type: z24.literal("chat.history"), turns: z24.array(PhoneChatTurnSchema).max(50) }),
|
|
1626
|
+
z24.object({ type: z24.literal("chat.step"), qid: OperationIdSchema, step: PhoneChatStepSchema }),
|
|
1553
1627
|
/** The whole text so far, not an increment. */
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1628
|
+
z24.object({ type: z24.literal("chat.delta"), qid: OperationIdSchema, text: z24.string().max(THREAD_TEXT_MAX) }),
|
|
1629
|
+
z24.object({ type: z24.literal("chat.done"), qid: OperationIdSchema, turn: PhoneChatTurnSchema }),
|
|
1630
|
+
z24.object({ type: z24.literal("chat.error"), qid: OperationIdSchema, code: ChatErrorCodeSchema }),
|
|
1557
1631
|
/** The live teams, after each snapshot and on every change. */
|
|
1558
|
-
|
|
1632
|
+
z24.object({ type: z24.literal("teams"), teams: z24.array(PhoneTeamSchema).max(50) }),
|
|
1559
1633
|
/** The tasks Ledge gave, open or closed lately, after each snapshot; then each change. */
|
|
1560
|
-
|
|
1561
|
-
|
|
1634
|
+
z24.object({ type: z24.literal("tasks"), tasks: z24.array(PhoneTaskSchema).max(200) }),
|
|
1635
|
+
z24.object({ type: z24.literal("task.updated"), task: PhoneTaskSchema }),
|
|
1636
|
+
AttachmentStoredSchema,
|
|
1637
|
+
AttachmentDataSchema,
|
|
1638
|
+
AttachmentErrorSchema,
|
|
1562
1639
|
/** Never carries free text. */
|
|
1563
|
-
|
|
1640
|
+
z24.object({ type: z24.literal("error"), code: z24.enum(["invalid", "unknown_session", "too_large"]), request: z24.string().max(40).optional() })
|
|
1564
1641
|
]);
|
|
1565
1642
|
|
|
1566
1643
|
// src/auth.ts
|
|
@@ -1683,6 +1760,12 @@ function readDaemonToken() {
|
|
|
1683
1760
|
}
|
|
1684
1761
|
|
|
1685
1762
|
export {
|
|
1763
|
+
ATTACHMENT_ID,
|
|
1764
|
+
ATTACHMENT_MAX,
|
|
1765
|
+
ATTACHMENT_LOCAL_MAX,
|
|
1766
|
+
PREVIEW_MAX,
|
|
1767
|
+
ATTACHMENTS_MAX,
|
|
1768
|
+
AttachmentRefSchema,
|
|
1686
1769
|
CONTEXT_NEAR,
|
|
1687
1770
|
CONTEXT_NEAR_MIN,
|
|
1688
1771
|
CONTEXT_NEAR_MAX,
|
|
@@ -1711,13 +1794,14 @@ export {
|
|
|
1711
1794
|
ModelIdSchema,
|
|
1712
1795
|
EffortSchema,
|
|
1713
1796
|
RouteResultSchema,
|
|
1714
|
-
DEFAULT_RELAY_URL,
|
|
1715
|
-
MobileConfigSchema,
|
|
1716
1797
|
TASK_TITLE_MAX,
|
|
1717
1798
|
TASK_TEXT_MAX,
|
|
1718
1799
|
LEDGE_GIVER,
|
|
1800
|
+
transmissions,
|
|
1719
1801
|
givenByLedge,
|
|
1720
1802
|
taskClosed,
|
|
1803
|
+
DEFAULT_RELAY_URL,
|
|
1804
|
+
MobileConfigSchema,
|
|
1721
1805
|
ROLE_LABEL_MAX,
|
|
1722
1806
|
ROLE_PROMPT_MAX,
|
|
1723
1807
|
RoleSchema,
|