@paradow/ledge 0.25.1 → 0.27.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/{action-WNQ3NJGD.js → action-7SJJTIEA.js} +4 -4
- package/dist/cli/{attach-UHM7QQ4W.js → attach-V7UPHVB2.js} +8 -8
- package/dist/cli/{bridge-R37AHVXS.js → bridge-JK3PMG7T.js} +1 -1
- package/dist/cli/{chunk-RKV5KYKL.js → chunk-2N7PSP7C.js} +3 -3
- package/dist/cli/{chunk-ARB4BKZJ.js → chunk-37G5F75H.js} +755 -557
- package/dist/cli/{chunk-TZBI2RVU.js → chunk-7GIUG73R.js} +1 -1
- package/dist/cli/{chunk-RYUDIFSI.js → chunk-7JRQCKBP.js} +6 -2
- package/dist/cli/{chunk-5VFFJ3ZC.js → chunk-7OGFH6KJ.js} +2 -2
- package/dist/cli/{chunk-ZDEEHFU3.js → chunk-ADAGKOFO.js} +1 -1
- package/dist/cli/{chunk-KRFXWD5S.js → chunk-CVHX7GUB.js} +685 -89
- package/dist/cli/chunk-HMTOPOJG.js +6 -0
- package/dist/cli/{chunk-O6FTIYJV.js → chunk-IGAGJVRZ.js} +3 -3
- package/dist/cli/{chunk-7XMGYJTN.js → chunk-ISNHG5SJ.js} +5 -5
- package/dist/cli/{chunk-TOFVC6IV.js → chunk-RA3OIXEQ.js} +2 -2
- package/dist/cli/{chunk-PUJLMKZC.js → chunk-TOSPL5H2.js} +3 -3
- package/dist/cli/{chunk-AVKFQSRP.js → chunk-UPKJO3BZ.js} +45 -17
- package/dist/cli/{chunk-JNLARCUC.js → chunk-YLN3VOGV.js} +49 -19
- package/dist/cli/{daemon-ESBBZW7O.js → daemon-YUPB5NUG.js} +34 -15
- package/dist/cli/{decide-UWJMKDR4.js → decide-HFI2WQXI.js} +3 -3
- package/dist/cli/{handover-5JHFA5EF.js → handover-GKORMXZ2.js} +4 -4
- package/dist/cli/{hook-XBSMUMZ7.js → hook-TJJEFV54.js} +10 -10
- package/dist/cli/index.js +16 -16
- package/dist/cli/{launch-OVB66BZJ.js → launch-QKQZZSIM.js} +8 -8
- package/dist/cli/{send-Y2C3BIGK.js → send-RI7JOO5K.js} +4 -4
- package/dist/cli/{status-5YEORNTH.js → status-RQRS26S2.js} +2 -2
- package/dist/cli/{task-R44VWZHR.js → task-U2XHBUKW.js} +4 -4
- package/dist/cli/{team-F7B3IG3I.js → team-NFC4XEIA.js} +6 -6
- package/dist/cli/{tui-YK6TXFYX.js → tui-UWR7SDYF.js} +8 -8
- package/dist/cli/{version-NFURQHXH.js → version-YYNMMWKJ.js} +1 -1
- package/dist/cli/{who-YMSQI64I.js → who-WW6IL4KD.js} +3 -3
- package/package.json +1 -1
- package/dist/cli/chunk-PA2JU476.js +0 -6
|
@@ -176,7 +176,7 @@ function isArchived(s) {
|
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
// ../protocol/src/teams.ts
|
|
179
|
-
import { z as
|
|
179
|
+
import { z as z7 } from "zod";
|
|
180
180
|
|
|
181
181
|
// ../protocol/src/models.ts
|
|
182
182
|
import { z as z3 } from "zod";
|
|
@@ -204,118 +204,257 @@ var ModelsListingSchema = z3.object({
|
|
|
204
204
|
error: z3.string().optional()
|
|
205
205
|
});
|
|
206
206
|
|
|
207
|
+
// ../protocol/src/projects.ts
|
|
208
|
+
import { z as z6 } from "zod";
|
|
209
|
+
|
|
210
|
+
// ../protocol/src/machines.ts
|
|
211
|
+
import { z as z5 } from "zod";
|
|
212
|
+
|
|
213
|
+
// ../protocol/src/ssh.ts
|
|
214
|
+
import { z as z4 } from "zod";
|
|
215
|
+
var SshAliasSchema = z4.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/);
|
|
216
|
+
|
|
217
|
+
// ../protocol/src/machines.ts
|
|
218
|
+
var MachineIdSchema = z5.string().regex(/^[a-zA-Z0-9_-]{1,64}$/);
|
|
219
|
+
var MachineSchema = z5.object({
|
|
220
|
+
id: MachineIdSchema,
|
|
221
|
+
label: z5.string().trim().min(1).max(80),
|
|
222
|
+
ssh: SshAliasSchema.optional()
|
|
223
|
+
});
|
|
224
|
+
var MachinesSchema = z5.array(MachineSchema).min(1).max(20).superRefine((list, ctx) => {
|
|
225
|
+
if (list[0]?.id !== "local" || list[0].ssh !== void 0) ctx.addIssue({ code: "custom", message: "the first machine is local, without ssh", path: [0] });
|
|
226
|
+
const ids = /* @__PURE__ */ new Set(), aliases = /* @__PURE__ */ new Set();
|
|
227
|
+
list.forEach((m, i) => {
|
|
228
|
+
if (i > 0 && !m.ssh) ctx.addIssue({ code: "custom", message: "a remote machine needs an ssh alias", path: [i, "ssh"] });
|
|
229
|
+
if (ids.has(m.id)) ctx.addIssue({ code: "custom", message: `duplicate id ${m.id}`, path: [i, "id"] });
|
|
230
|
+
ids.add(m.id);
|
|
231
|
+
if (m.ssh) {
|
|
232
|
+
if (aliases.has(m.ssh)) ctx.addIssue({ code: "custom", message: `duplicate ssh alias ${m.ssh}`, path: [i, "ssh"] });
|
|
233
|
+
aliases.add(m.ssh);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
// ../protocol/src/projects.ts
|
|
239
|
+
var PROJECT_COLORS = { blue: "#3b82f6", green: "#10b981", amber: "#f59e0b", violet: "#8b5cf6", teal: "#14b8a6", pink: "#ec4899", red: "#ef4444", slate: "#64748b" };
|
|
240
|
+
var ProjectColorSchema = z6.enum(["blue", "green", "amber", "violet", "teal", "pink", "red", "slate"]);
|
|
241
|
+
var ProjectIdSchema = z6.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/);
|
|
242
|
+
function normalizePath(raw) {
|
|
243
|
+
const p = raw.trim().replace(/\/+/g, "/");
|
|
244
|
+
return p.length > 1 && p.endsWith("/") ? p.slice(0, -1) : p;
|
|
245
|
+
}
|
|
246
|
+
var PathSchema = z6.string().max(4096).refine((p) => p.startsWith("/") && p === normalizePath(p), "an absolute, normalized path");
|
|
247
|
+
var RepoSchema = z6.object({ machine: MachineIdSchema, path: PathSchema });
|
|
248
|
+
var ProjectSchema = z6.object({
|
|
249
|
+
id: ProjectIdSchema,
|
|
250
|
+
name: z6.string().trim().min(1).max(80),
|
|
251
|
+
color: ProjectColorSchema,
|
|
252
|
+
description: z6.string().max(500).default(""),
|
|
253
|
+
repos: z6.array(RepoSchema).max(50)
|
|
254
|
+
});
|
|
255
|
+
var RuleSchema = z6.object({ machine: MachineIdSchema, path: PathSchema, project: ProjectIdSchema });
|
|
256
|
+
function projectsProblems(p) {
|
|
257
|
+
const out = [];
|
|
258
|
+
const ids = /* @__PURE__ */ new Set(), names = /* @__PURE__ */ new Set(), repos = /* @__PURE__ */ new Set(), rules = /* @__PURE__ */ new Set();
|
|
259
|
+
p.projects.forEach((project, i) => {
|
|
260
|
+
if (ids.has(project.id)) out.push({ code: "duplicate_id", path: ["projects", i, "id"] });
|
|
261
|
+
ids.add(project.id);
|
|
262
|
+
const name = project.name.trim().toLocaleLowerCase();
|
|
263
|
+
if (names.has(name)) out.push({ code: "duplicate_name", path: ["projects", i, "name"] });
|
|
264
|
+
names.add(name);
|
|
265
|
+
project.repos.forEach((repo, j) => {
|
|
266
|
+
const key = `${repo.machine}
|
|
267
|
+
${repo.path}`;
|
|
268
|
+
if (repos.has(key)) out.push({ code: "duplicate_repo", path: ["projects", i, "repos", j] });
|
|
269
|
+
repos.add(key);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
p.rules.forEach((rule, i) => {
|
|
273
|
+
const key = `${rule.machine}
|
|
274
|
+
${rule.path}`;
|
|
275
|
+
if (rules.has(key)) out.push({ code: "duplicate_rule", path: ["rules", i] });
|
|
276
|
+
rules.add(key);
|
|
277
|
+
if (!ids.has(rule.project)) out.push({ code: "unknown_project", path: ["rules", i, "project"] });
|
|
278
|
+
});
|
|
279
|
+
return out;
|
|
280
|
+
}
|
|
281
|
+
var ProjectsSchema = z6.object({ projects: z6.array(ProjectSchema).max(100), rules: z6.array(RuleSchema).max(1e3) }).superRefine((p, ctx) => {
|
|
282
|
+
for (const problem of projectsProblems(p)) ctx.addIssue({ code: "custom", message: problem.code, path: problem.path });
|
|
283
|
+
});
|
|
284
|
+
var DEFAULT_PROJECTS = { projects: [], rules: [] };
|
|
285
|
+
var under = (cwd, path2) => path2 === "/" || cwd === path2 || cwd.startsWith(`${path2}/`);
|
|
286
|
+
function projectOf(session, state) {
|
|
287
|
+
const machine = session.machineId ?? "local";
|
|
288
|
+
const cwd = normalizePath(session.cwd);
|
|
289
|
+
const known = new Set(state.projects.map((p) => p.id));
|
|
290
|
+
const candidates = [
|
|
291
|
+
...state.projects.flatMap((p) => p.repos.filter((r) => r.machine === machine).map((r) => ({ project: p.id, path: r.path, rule: false }))),
|
|
292
|
+
...state.rules.filter((r) => r.machine === machine && known.has(r.project)).map((r) => ({ project: r.project, path: r.path, rule: true }))
|
|
293
|
+
].filter((c) => under(cwd, c.path));
|
|
294
|
+
candidates.sort((x, y) => y.path.length - x.path.length || Number(y.rule) - Number(x.rule));
|
|
295
|
+
return candidates[0]?.project ?? null;
|
|
296
|
+
}
|
|
297
|
+
|
|
207
298
|
// ../protocol/src/teams.ts
|
|
208
|
-
var RoleIdSchema =
|
|
299
|
+
var RoleIdSchema = z7.string().regex(/^[a-z0-9][a-z0-9_-]{0,39}$/);
|
|
209
300
|
var ROLE_LABEL_MAX = 40;
|
|
210
301
|
var ROLE_PROMPT_MAX = 8e3;
|
|
211
|
-
var
|
|
302
|
+
var DefinitionHashSchema = z7.string().regex(/^[0-9a-f]{16}$/);
|
|
303
|
+
var RoleSchema = z7.object({
|
|
212
304
|
id: RoleIdSchema,
|
|
213
|
-
label:
|
|
214
|
-
prompt:
|
|
305
|
+
label: z7.string().min(1).max(ROLE_LABEL_MAX),
|
|
306
|
+
prompt: z7.string().max(ROLE_PROMPT_MAX),
|
|
215
307
|
tool: ToolSchema.optional(),
|
|
216
308
|
model: ModelIdSchema.optional(),
|
|
217
309
|
effort: EffortSchema.optional(),
|
|
218
310
|
autonomy: AutonomySchema.optional(),
|
|
219
|
-
source:
|
|
220
|
-
path:
|
|
221
|
-
shadows:
|
|
311
|
+
source: z7.enum(["repo", "home"]),
|
|
312
|
+
path: z7.string(),
|
|
313
|
+
shadows: z7.string().optional(),
|
|
314
|
+
/** 16 hex chars of the file's text: what a write or delete must name as its base (absent from older daemons). */
|
|
315
|
+
hash: DefinitionHashSchema.optional()
|
|
222
316
|
});
|
|
223
|
-
var DefinitionProblemSchema =
|
|
317
|
+
var DefinitionProblemSchema = z7.object({ path: z7.string(), reason: z7.string() });
|
|
224
318
|
var TEAM_SEATS_MAX = 8;
|
|
225
|
-
var SeatSchema =
|
|
319
|
+
var SeatSchema = z7.object({
|
|
226
320
|
role: RoleIdSchema,
|
|
227
321
|
tool: ToolSchema.optional(),
|
|
228
322
|
model: ModelIdSchema.optional(),
|
|
229
323
|
effort: EffortSchema.optional(),
|
|
230
|
-
name:
|
|
324
|
+
name: z7.string().min(1).max(40).optional()
|
|
231
325
|
});
|
|
232
326
|
var uniqueRoles = (seats) => new Set(seats.map((s) => s.role)).size === seats.length;
|
|
233
|
-
var SeatsSchema =
|
|
234
|
-
var TeamNameSchema =
|
|
235
|
-
var
|
|
236
|
-
var
|
|
237
|
-
var
|
|
238
|
-
var
|
|
327
|
+
var SeatsSchema = z7.array(SeatSchema).min(1).max(TEAM_SEATS_MAX).refine(uniqueRoles, "a role twice in one team");
|
|
328
|
+
var TeamNameSchema = z7.string().trim().min(1).max(60);
|
|
329
|
+
var TemplateIdSchema = z7.string().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/);
|
|
330
|
+
var TeamTemplateSchema = z7.object({ id: z7.string().min(1).max(64), name: TeamNameSchema, seats: SeatsSchema, source: z7.enum(["repo", "home"]), path: z7.string(), hash: DefinitionHashSchema.optional() });
|
|
331
|
+
var TeamIdSchema = z7.string().regex(/^team-[0-9a-f]{4,8}$/);
|
|
332
|
+
var TeamStateSchema = z7.enum(["active", "resting", "dissolved"]);
|
|
333
|
+
var TeamSchema = z7.object({
|
|
239
334
|
id: TeamIdSchema,
|
|
240
335
|
name: TeamNameSchema,
|
|
241
|
-
template:
|
|
242
|
-
project:
|
|
243
|
-
machine:
|
|
244
|
-
cwd:
|
|
336
|
+
template: z7.string().optional(),
|
|
337
|
+
project: z7.string().nullable(),
|
|
338
|
+
machine: z7.string(),
|
|
339
|
+
cwd: z7.string(),
|
|
245
340
|
state: TeamStateSchema,
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
341
|
+
/** A live seat: `tool`, `model` and `effort` are what it was composed with over the role's defaults; `leaving` marks a seat removed
|
|
342
|
+
* from the composition that finishes its turn and then is closed. */
|
|
343
|
+
seats: z7.array(z7.object({
|
|
344
|
+
role: RoleIdSchema,
|
|
345
|
+
sessionId: z7.string().nullable(),
|
|
346
|
+
tool: ToolSchema.optional(),
|
|
347
|
+
model: ModelIdSchema.optional(),
|
|
348
|
+
effort: EffortSchema.optional(),
|
|
349
|
+
leaving: z7.literal(true).optional()
|
|
350
|
+
})).max(TEAM_SEATS_MAX * 2),
|
|
351
|
+
createdAt: z7.string(),
|
|
352
|
+
updatedAt: z7.string(),
|
|
353
|
+
restingAt: z7.string().optional(),
|
|
354
|
+
dissolvedAt: z7.string().optional()
|
|
251
355
|
});
|
|
252
|
-
var RolesListSchema =
|
|
253
|
-
var RolesListingSchema =
|
|
254
|
-
type:
|
|
255
|
-
requestId:
|
|
256
|
-
roles:
|
|
257
|
-
templates:
|
|
258
|
-
problems:
|
|
356
|
+
var RolesListSchema = z7.object({ type: z7.literal("roles.list"), cwd: z7.string().min(1).optional(), requestId: z7.string().max(100).optional(), machineId: z7.string().optional() });
|
|
357
|
+
var RolesListingSchema = z7.object({
|
|
358
|
+
type: z7.literal("roles.listing"),
|
|
359
|
+
requestId: z7.string().optional(),
|
|
360
|
+
roles: z7.array(RoleSchema),
|
|
361
|
+
templates: z7.array(TeamTemplateSchema).default([]),
|
|
362
|
+
problems: z7.array(DefinitionProblemSchema),
|
|
259
363
|
/** Set by the fleet when the project's machine could not answer (#99): 'offline', or 'outdated' for a daemon without roles.list. */
|
|
260
|
-
error:
|
|
364
|
+
error: z7.string().optional()
|
|
261
365
|
});
|
|
262
|
-
var TeamLaunchSchema =
|
|
263
|
-
type:
|
|
264
|
-
rid:
|
|
265
|
-
cwd:
|
|
266
|
-
template:
|
|
366
|
+
var TeamLaunchSchema = z7.object({
|
|
367
|
+
type: z7.literal("team.launch"),
|
|
368
|
+
rid: z7.string().min(1).max(100),
|
|
369
|
+
cwd: z7.string().min(1).optional(),
|
|
370
|
+
template: z7.string().min(1).max(64).optional(),
|
|
267
371
|
seats: SeatsSchema.optional(),
|
|
268
372
|
name: TeamNameSchema.optional(),
|
|
269
|
-
qid:
|
|
270
|
-
machineId:
|
|
373
|
+
qid: z7.string().min(1).optional(),
|
|
374
|
+
machineId: z7.string().optional(),
|
|
375
|
+
/** The project's name, for a client that holds no path (the phone): the daemon resolves its folder. */
|
|
376
|
+
project: ProjectIdSchema.optional()
|
|
377
|
+
});
|
|
378
|
+
var TeamJoinSchema = z7.object({ type: z7.literal("team.join"), team: TeamIdSchema, session: z7.string().min(1), role: RoleIdSchema });
|
|
379
|
+
var TeamLeaveSchema = z7.object({ type: z7.literal("team.leave"), team: TeamIdSchema, session: z7.string().min(1) });
|
|
380
|
+
var TeamResumeSchema = z7.object({ type: z7.literal("team.resume"), team: TeamIdSchema });
|
|
381
|
+
var TeamDissolveSchema = z7.object({ type: z7.literal("team.dissolve"), team: TeamIdSchema });
|
|
382
|
+
var TeamSaveSchema = z7.object({ type: z7.literal("team.save"), rid: z7.string().min(1).max(100), name: TeamNameSchema, seats: SeatsSchema, qid: z7.string().min(1).optional() });
|
|
383
|
+
var DefinitionScopeSchema = z7.enum(["home", "repo"]);
|
|
384
|
+
var RoleDraftSchema = RoleSchema.pick({ id: true, label: true, prompt: true, tool: true, model: true, effort: true, autonomy: true });
|
|
385
|
+
var DefinitionCodeSchema = z7.enum(["changed", "exists", "missing", "unknown_project", "invalid"]);
|
|
386
|
+
var scopeFields = { rid: z7.string().min(1).max(100), scope: DefinitionScopeSchema, project: ProjectIdSchema.optional() };
|
|
387
|
+
var scopeIssue = (m) => m.scope === void 0 || m.scope === "repo" === (m.project !== void 0) ? null : "a repo scope names a project, a home scope none";
|
|
388
|
+
var DefinitionBaseSchema = DefinitionHashSchema;
|
|
389
|
+
var DefinitionsListSchema = z7.object({ type: z7.literal("definitions.list"), requestId: z7.string().max(100).optional() });
|
|
390
|
+
var RoleWriteSchema = z7.object({ type: z7.literal("role.write"), ...scopeFields, role: RoleDraftSchema, base: DefinitionBaseSchema.nullable() });
|
|
391
|
+
var RoleDeleteSchema = z7.object({ type: z7.literal("role.delete"), ...scopeFields, id: RoleIdSchema, base: DefinitionBaseSchema });
|
|
392
|
+
var TemplateWriteSchema = z7.object({
|
|
393
|
+
type: z7.literal("template.write"),
|
|
394
|
+
...scopeFields,
|
|
395
|
+
id: TemplateIdSchema.optional(),
|
|
396
|
+
name: TeamNameSchema,
|
|
397
|
+
seats: SeatsSchema,
|
|
398
|
+
base: DefinitionBaseSchema.nullable()
|
|
399
|
+
});
|
|
400
|
+
var TemplateDeleteSchema = z7.object({ type: z7.literal("template.delete"), ...scopeFields, id: TemplateIdSchema, base: DefinitionBaseSchema });
|
|
401
|
+
var TeamComposeSchema = z7.object({ type: z7.literal("team.compose"), rid: z7.string().min(1).max(100), team: TeamIdSchema, seats: SeatsSchema });
|
|
402
|
+
var TeamSeatSchema = z7.object({ type: z7.literal("team.seat"), rid: z7.string().min(1).max(100), team: TeamIdSchema, role: RoleIdSchema, action: z7.enum(["start", "restart"]) });
|
|
403
|
+
var DefinitionsListingSchema = z7.object({
|
|
404
|
+
type: z7.literal("definitions.listing"),
|
|
405
|
+
requestId: z7.string().optional(),
|
|
406
|
+
scopes: z7.array(z7.object({
|
|
407
|
+
scope: DefinitionScopeSchema,
|
|
408
|
+
project: z7.string().nullable(),
|
|
409
|
+
roles: z7.array(RoleSchema),
|
|
410
|
+
templates: z7.array(TeamTemplateSchema),
|
|
411
|
+
problems: z7.array(DefinitionProblemSchema)
|
|
412
|
+
}))
|
|
271
413
|
});
|
|
272
|
-
var
|
|
273
|
-
var
|
|
274
|
-
var
|
|
275
|
-
var
|
|
276
|
-
var
|
|
277
|
-
var
|
|
278
|
-
var
|
|
279
|
-
var TeamLaunchedSchema = z4.object({ type: z4.literal("team.launched"), rid: z4.string(), team: TeamSchema });
|
|
280
|
-
var TeamFailedSchema = z4.object({ type: z4.literal("team.failed"), rid: z4.string(), reason: z4.string(), team: TeamSchema.optional() });
|
|
281
|
-
var TeamSavedSchema = z4.object({ type: z4.literal("team.saved"), rid: z4.string(), path: z4.string().optional(), reason: z4.string().optional() });
|
|
414
|
+
var DefinitionResultSchema = z7.object({ type: z7.literal("definition.result"), rid: z7.string(), id: z7.string().optional(), hash: DefinitionHashSchema.optional(), code: DefinitionCodeSchema.optional(), reason: z7.string().optional() });
|
|
415
|
+
var TeamChangedSchema = z7.object({ type: z7.literal("team.changed"), rid: z7.string(), team: TeamSchema.optional(), reason: z7.string().optional() });
|
|
416
|
+
var TeamsMessageSchema = z7.object({ type: z7.literal("teams"), teams: z7.array(TeamSchema) });
|
|
417
|
+
var TeamUpdatedSchema = z7.object({ type: z7.literal("team.updated"), team: TeamSchema });
|
|
418
|
+
var TeamLaunchedSchema = z7.object({ type: z7.literal("team.launched"), rid: z7.string(), team: TeamSchema });
|
|
419
|
+
var TeamFailedSchema = z7.object({ type: z7.literal("team.failed"), rid: z7.string(), reason: z7.string(), team: TeamSchema.optional() });
|
|
420
|
+
var TeamSavedSchema = z7.object({ type: z7.literal("team.saved"), rid: z7.string(), path: z7.string().optional(), reason: z7.string().optional() });
|
|
282
421
|
var isTeamLive = (t) => t.state !== "dissolved";
|
|
283
422
|
|
|
284
423
|
// ../protocol/src/tasks.ts
|
|
285
|
-
import { z as
|
|
424
|
+
import { z as z8 } from "zod";
|
|
286
425
|
var TASK_TITLE_MAX = 200;
|
|
287
426
|
var TASK_TEXT_MAX = 2e4;
|
|
288
427
|
var LEDGE_GIVER = "ledge";
|
|
289
428
|
var TASK_OPS = ["give", "take", "pass", "done", "refuse", "cancel", "drop"];
|
|
290
429
|
var TRANSMISSION_OPS = ["give", "pass", "done", "refuse", "cancel"];
|
|
291
|
-
var TaskLogEntrySchema =
|
|
292
|
-
at:
|
|
293
|
-
by:
|
|
294
|
-
what:
|
|
295
|
-
op:
|
|
296
|
-
from:
|
|
297
|
-
to:
|
|
298
|
-
fromName:
|
|
299
|
-
toName:
|
|
300
|
-
note:
|
|
430
|
+
var TaskLogEntrySchema = z8.object({
|
|
431
|
+
at: z8.string(),
|
|
432
|
+
by: z8.string(),
|
|
433
|
+
what: z8.string(),
|
|
434
|
+
op: z8.enum(TASK_OPS).optional(),
|
|
435
|
+
from: z8.string().optional(),
|
|
436
|
+
to: z8.string().optional(),
|
|
437
|
+
fromName: z8.string().optional(),
|
|
438
|
+
toName: z8.string().optional(),
|
|
439
|
+
note: z8.string().optional()
|
|
301
440
|
});
|
|
302
|
-
var TaskSchema =
|
|
303
|
-
id:
|
|
304
|
-
title:
|
|
305
|
-
text:
|
|
306
|
-
giver:
|
|
307
|
-
giverName:
|
|
308
|
-
owner:
|
|
309
|
-
ownerName:
|
|
310
|
-
state:
|
|
311
|
-
result:
|
|
441
|
+
var TaskSchema = z8.object({
|
|
442
|
+
id: z8.string(),
|
|
443
|
+
title: z8.string(),
|
|
444
|
+
text: z8.string().optional(),
|
|
445
|
+
giver: z8.string(),
|
|
446
|
+
giverName: z8.string(),
|
|
447
|
+
owner: z8.string(),
|
|
448
|
+
ownerName: z8.string(),
|
|
449
|
+
state: z8.enum(["open", "taken", "done", "refused", "dropped"]),
|
|
450
|
+
result: z8.string().optional(),
|
|
312
451
|
/** The live team its owner sat in when it was given (or passed), so a team's tasks can be listed. */
|
|
313
|
-
team:
|
|
452
|
+
team: z8.string().optional(),
|
|
314
453
|
/** A task Ledge gave and the user put away from « À toi » once closed. */
|
|
315
|
-
seen:
|
|
316
|
-
at:
|
|
317
|
-
updatedAt:
|
|
318
|
-
log:
|
|
454
|
+
seen: z8.boolean().optional(),
|
|
455
|
+
at: z8.string(),
|
|
456
|
+
updatedAt: z8.string(),
|
|
457
|
+
log: z8.array(TaskLogEntrySchema)
|
|
319
458
|
});
|
|
320
459
|
var handOver = (op) => TRANSMISSION_OPS.includes(op ?? "");
|
|
321
460
|
function transmissions(t) {
|
|
@@ -323,54 +462,54 @@ function transmissions(t) {
|
|
|
323
462
|
}
|
|
324
463
|
var givenByLedge = (t) => t.giver === LEDGE_GIVER;
|
|
325
464
|
var taskClosed = (t) => t.state === "done" || t.state === "refused" || t.state === "dropped";
|
|
326
|
-
var TaskCmdSchema =
|
|
327
|
-
type:
|
|
328
|
-
rid:
|
|
329
|
-
by:
|
|
330
|
-
op:
|
|
331
|
-
task:
|
|
332
|
-
to:
|
|
333
|
-
title:
|
|
334
|
-
text:
|
|
335
|
-
all:
|
|
336
|
-
team:
|
|
337
|
-
qid:
|
|
338
|
-
row:
|
|
465
|
+
var TaskCmdSchema = z8.object({
|
|
466
|
+
type: z8.literal("task.cmd"),
|
|
467
|
+
rid: z8.string().min(1),
|
|
468
|
+
by: z8.string().min(1),
|
|
469
|
+
op: z8.enum(["give", "take", "done", "refuse", "pass", "show", "list", "seen", "cancel"]),
|
|
470
|
+
task: z8.string().min(1).max(40).optional(),
|
|
471
|
+
to: z8.string().min(1).optional(),
|
|
472
|
+
title: z8.string().min(1).max(TASK_TITLE_MAX).optional(),
|
|
473
|
+
text: z8.string().max(TASK_TEXT_MAX).optional(),
|
|
474
|
+
all: z8.boolean().optional(),
|
|
475
|
+
team: z8.string().min(1).max(40).optional(),
|
|
476
|
+
qid: z8.string().min(1).optional(),
|
|
477
|
+
row: z8.number().int().min(0).max(7).optional()
|
|
339
478
|
});
|
|
340
|
-
var TaskUpdatedSchema =
|
|
341
|
-
var TaskResultSchema =
|
|
342
|
-
type:
|
|
343
|
-
rid:
|
|
479
|
+
var TaskUpdatedSchema = z8.object({ type: z8.literal("task.updated"), task: TaskSchema });
|
|
480
|
+
var TaskResultSchema = z8.object({
|
|
481
|
+
type: z8.literal("task.result"),
|
|
482
|
+
rid: z8.string(),
|
|
344
483
|
task: TaskSchema.optional(),
|
|
345
|
-
tasks:
|
|
346
|
-
reason:
|
|
484
|
+
tasks: z8.array(TaskSchema).optional(),
|
|
485
|
+
reason: z8.string().optional()
|
|
347
486
|
});
|
|
348
487
|
|
|
349
488
|
// ../protocol/src/actions.ts
|
|
350
|
-
import { z as
|
|
489
|
+
import { z as z11 } from "zod";
|
|
351
490
|
|
|
352
491
|
// ../protocol/src/proposal.ts
|
|
353
|
-
import { z as
|
|
354
|
-
var ProposalBlockSchema =
|
|
355
|
-
var RelayBlockSchema =
|
|
356
|
-
var ProjectBlockSchema =
|
|
357
|
-
name:
|
|
358
|
-
description:
|
|
359
|
-
repos:
|
|
360
|
-
addTo:
|
|
492
|
+
import { z as z9 } from "zod";
|
|
493
|
+
var ProposalBlockSchema = z9.object({ cwd: z9.string().trim().min(1), prompt: z9.string().optional() });
|
|
494
|
+
var RelayBlockSchema = z9.object({ session: z9.string().trim().min(1), text: z9.string().trim().min(1) });
|
|
495
|
+
var ProjectBlockSchema = z9.object({
|
|
496
|
+
name: z9.string().trim().min(1).max(80),
|
|
497
|
+
description: z9.string().max(500).optional(),
|
|
498
|
+
repos: z9.array(z9.object({ path: z9.string().min(1).max(4096), why: z9.string().trim().min(1).max(200) })).min(1).max(50),
|
|
499
|
+
addTo: z9.string().trim().max(80).optional()
|
|
361
500
|
});
|
|
362
|
-
var CloseBlockSchema =
|
|
363
|
-
var TeamBlockSchema =
|
|
364
|
-
cwd:
|
|
365
|
-
template:
|
|
366
|
-
name:
|
|
367
|
-
seats:
|
|
501
|
+
var CloseBlockSchema = z9.object({ session: z9.string().trim().min(1) });
|
|
502
|
+
var TeamBlockSchema = z9.object({
|
|
503
|
+
cwd: z9.string().trim().min(1),
|
|
504
|
+
template: z9.string().trim().min(1).max(64).optional(),
|
|
505
|
+
name: z9.string().trim().min(1).max(60).optional(),
|
|
506
|
+
seats: z9.array(z9.object({ role: z9.string().trim().min(1).max(40), tool: z9.enum(["claude", "codex", "cursor", "omp"]).optional(), model: z9.string().max(200).optional(), effort: z9.string().max(20).optional(), name: z9.string().max(40).optional() })).min(1).max(8).optional()
|
|
368
507
|
}).refine((b) => !!b.template || !!b.seats?.length, "a template or seats");
|
|
369
|
-
var TaskBlockSchema =
|
|
370
|
-
to:
|
|
371
|
-
team:
|
|
372
|
-
title:
|
|
373
|
-
text:
|
|
508
|
+
var TaskBlockSchema = z9.object({
|
|
509
|
+
to: z9.string().trim().min(1).max(80),
|
|
510
|
+
team: z9.string().trim().max(40).optional(),
|
|
511
|
+
title: z9.string().trim().min(1).max(200),
|
|
512
|
+
text: z9.string().max(2e4).optional()
|
|
374
513
|
});
|
|
375
514
|
var BLOCK = /```ledge-(session|relay|project|close|team|task|action)[ \t]*\n?([\s\S]*?)(?:```|$)/g;
|
|
376
515
|
function extractProposal(answer) {
|
|
@@ -424,8 +563,8 @@ function parseProjectBlock(raw) {
|
|
|
424
563
|
}
|
|
425
564
|
|
|
426
565
|
// ../protocol/src/decisions.ts
|
|
427
|
-
import { z as
|
|
428
|
-
var DecisionSchema =
|
|
566
|
+
import { z as z10 } from "zod";
|
|
567
|
+
var DecisionSchema = z10.enum(["accept", "deny", "always"]);
|
|
429
568
|
var NOTE_MAX = 4e3;
|
|
430
569
|
var NOTE_NOT_TYPED = "note_not_typed";
|
|
431
570
|
var DECISION_OFFERS = {
|
|
@@ -455,7 +594,7 @@ function pendingKey(p) {
|
|
|
455
594
|
}
|
|
456
595
|
|
|
457
596
|
// ../protocol/src/actions.ts
|
|
458
|
-
var ActionRiskSchema =
|
|
597
|
+
var ActionRiskSchema = z11.enum(["read", "reversible", "destructive"]);
|
|
459
598
|
var ACTION_IDS = [
|
|
460
599
|
"session.launch",
|
|
461
600
|
"session.relay",
|
|
@@ -477,11 +616,11 @@ var ACTION_IDS = [
|
|
|
477
616
|
"task.cancel",
|
|
478
617
|
"task.pass"
|
|
479
618
|
];
|
|
480
|
-
var ActionIdSchema =
|
|
619
|
+
var ActionIdSchema = z11.enum(ACTION_IDS);
|
|
481
620
|
var def = (d) => d;
|
|
482
|
-
var SessionRef =
|
|
483
|
-
var TeamRef =
|
|
484
|
-
var TaskRef =
|
|
621
|
+
var SessionRef = z11.string().trim().min(1).max(80);
|
|
622
|
+
var TeamRef = z11.string().trim().min(1).max(60);
|
|
623
|
+
var TaskRef = z11.string().trim().min(1).max(40);
|
|
485
624
|
var LaunchArgs = ProposalBlockSchema.extend({ model: ModelIdSchema.optional(), effort: EffortSchema.optional() });
|
|
486
625
|
var ACTIONS = [
|
|
487
626
|
def({
|
|
@@ -559,14 +698,14 @@ var ACTIONS = [
|
|
|
559
698
|
phone: null,
|
|
560
699
|
risk: "reversible",
|
|
561
700
|
max: 8,
|
|
562
|
-
args:
|
|
701
|
+
args: z11.object({ session: SessionRef, model: ModelIdSchema.nullable(), effort: EffortSchema.nullable() }),
|
|
563
702
|
summary: "changer le mod\xE8le et l'effort d'une session en cours (null : le d\xE9faut de l'agent) ; elle red\xE9marre sur la m\xEAme conversation, \xE0 son prochain moment libre",
|
|
564
703
|
when: "quand l'utilisateur demande de passer une session sur un autre mod\xE8le ou un autre effort",
|
|
565
704
|
example: { session: "Nova", model: "claude-opus-5-5", effort: "high" }
|
|
566
705
|
}),
|
|
567
706
|
def({
|
|
568
707
|
id: "session.interrupt",
|
|
569
|
-
args:
|
|
708
|
+
args: z11.object({ session: SessionRef }),
|
|
570
709
|
card: "generic",
|
|
571
710
|
phone: null,
|
|
572
711
|
risk: "reversible",
|
|
@@ -577,7 +716,7 @@ var ACTIONS = [
|
|
|
577
716
|
}),
|
|
578
717
|
def({
|
|
579
718
|
id: "session.archive",
|
|
580
|
-
args:
|
|
719
|
+
args: z11.object({ session: SessionRef }),
|
|
581
720
|
card: "generic",
|
|
582
721
|
phone: null,
|
|
583
722
|
risk: "reversible",
|
|
@@ -588,7 +727,7 @@ var ACTIONS = [
|
|
|
588
727
|
}),
|
|
589
728
|
def({
|
|
590
729
|
id: "session.restore",
|
|
591
|
-
args:
|
|
730
|
+
args: z11.object({ session: SessionRef }),
|
|
592
731
|
card: "generic",
|
|
593
732
|
phone: null,
|
|
594
733
|
risk: "reversible",
|
|
@@ -599,7 +738,7 @@ var ACTIONS = [
|
|
|
599
738
|
}),
|
|
600
739
|
def({
|
|
601
740
|
id: "session.resume",
|
|
602
|
-
args:
|
|
741
|
+
args: z11.object({ session: SessionRef }),
|
|
603
742
|
card: "generic",
|
|
604
743
|
phone: "act",
|
|
605
744
|
risk: "reversible",
|
|
@@ -613,7 +752,7 @@ var ACTIONS = [
|
|
|
613
752
|
card: "generic",
|
|
614
753
|
phone: "act",
|
|
615
754
|
max: 1,
|
|
616
|
-
args:
|
|
755
|
+
args: z11.object({ session: SessionRef, decision: z11.enum(["accept", "deny"]), note: z11.string().trim().min(1).max(NOTE_MAX).optional() }),
|
|
617
756
|
risk: (a) => a.decision === "accept" ? "destructive" : "reversible",
|
|
618
757
|
summary: "accepter ou refuser la demande en attente d'une session (permission, diff ou plan), note possible avec un refus ; jamais \xAB toujours \xBB",
|
|
619
758
|
when: "seulement quand l'utilisateur demande explicitement d'accepter ou de refuser la demande d'une session pr\xE9cise, et que sessions.md montre une demande en attente pour elle ; cite la demande telle quelle dans ta r\xE9ponse",
|
|
@@ -621,7 +760,7 @@ var ACTIONS = [
|
|
|
621
760
|
}),
|
|
622
761
|
def({
|
|
623
762
|
id: "team.join",
|
|
624
|
-
args:
|
|
763
|
+
args: z11.object({ team: TeamRef, session: SessionRef, role: RoleIdSchema }),
|
|
625
764
|
card: "generic",
|
|
626
765
|
phone: null,
|
|
627
766
|
risk: "reversible",
|
|
@@ -632,7 +771,7 @@ var ACTIONS = [
|
|
|
632
771
|
}),
|
|
633
772
|
def({
|
|
634
773
|
id: "team.leave",
|
|
635
|
-
args:
|
|
774
|
+
args: z11.object({ team: TeamRef, session: SessionRef }),
|
|
636
775
|
card: "generic",
|
|
637
776
|
phone: null,
|
|
638
777
|
risk: "reversible",
|
|
@@ -643,7 +782,7 @@ var ACTIONS = [
|
|
|
643
782
|
}),
|
|
644
783
|
def({
|
|
645
784
|
id: "team.resume",
|
|
646
|
-
args:
|
|
785
|
+
args: z11.object({ team: TeamRef }),
|
|
647
786
|
card: "generic",
|
|
648
787
|
phone: "act",
|
|
649
788
|
risk: "reversible",
|
|
@@ -654,7 +793,7 @@ var ACTIONS = [
|
|
|
654
793
|
}),
|
|
655
794
|
def({
|
|
656
795
|
id: "team.dissolve",
|
|
657
|
-
args:
|
|
796
|
+
args: z11.object({ team: TeamRef }),
|
|
658
797
|
card: "generic",
|
|
659
798
|
phone: "act",
|
|
660
799
|
risk: "destructive",
|
|
@@ -666,7 +805,7 @@ var ACTIONS = [
|
|
|
666
805
|
}),
|
|
667
806
|
def({
|
|
668
807
|
id: "team.save",
|
|
669
|
-
args:
|
|
808
|
+
args: z11.object({ team: TeamRef, name: TeamNameSchema }),
|
|
670
809
|
card: "generic",
|
|
671
810
|
phone: null,
|
|
672
811
|
risk: "reversible",
|
|
@@ -677,7 +816,7 @@ var ACTIONS = [
|
|
|
677
816
|
}),
|
|
678
817
|
def({
|
|
679
818
|
id: "task.cancel",
|
|
680
|
-
args:
|
|
819
|
+
args: z11.object({ task: TaskRef, reason: z11.string().trim().min(1).max(500).optional() }),
|
|
681
820
|
card: "generic",
|
|
682
821
|
phone: "act",
|
|
683
822
|
risk: "destructive",
|
|
@@ -688,7 +827,7 @@ var ACTIONS = [
|
|
|
688
827
|
}),
|
|
689
828
|
def({
|
|
690
829
|
id: "task.pass",
|
|
691
|
-
args:
|
|
830
|
+
args: z11.object({ task: TaskRef, to: SessionRef, note: z11.string().trim().min(1).max(TASK_TEXT_MAX).optional() }),
|
|
692
831
|
card: "generic",
|
|
693
832
|
phone: null,
|
|
694
833
|
risk: "reversible",
|
|
@@ -701,7 +840,7 @@ var ACTIONS = [
|
|
|
701
840
|
var byId = new Map(ACTIONS.map((a) => [a.id, a]));
|
|
702
841
|
var actionById = (id) => byId.get(id);
|
|
703
842
|
var riskOf = (a, args) => typeof a.risk === "function" ? a.risk(args) : a.risk;
|
|
704
|
-
var ActionBlockSchema =
|
|
843
|
+
var ActionBlockSchema = z11.object({ action: z11.string().trim().min(1).max(40), args: z11.record(z11.unknown()).default({}) });
|
|
705
844
|
var LEGACY_FENCE_ACTION = {
|
|
706
845
|
session: "session.launch",
|
|
707
846
|
relay: "session.relay",
|
|
@@ -747,119 +886,119 @@ var NEVER_PROPOSED = [
|
|
|
747
886
|
import { z as z21 } from "zod";
|
|
748
887
|
|
|
749
888
|
// ../protocol/src/chat.ts
|
|
750
|
-
import { z as
|
|
889
|
+
import { z as z13 } from "zod";
|
|
751
890
|
|
|
752
891
|
// ../protocol/src/attachments.ts
|
|
753
|
-
import { z as
|
|
892
|
+
import { z as z12 } from "zod";
|
|
754
893
|
var ATTACHMENT_ID = /^[0-9a-f]{64}$/;
|
|
755
|
-
var AttachmentIdSchema =
|
|
894
|
+
var AttachmentIdSchema = z12.string().regex(ATTACHMENT_ID);
|
|
756
895
|
var IMAGE_MIMES = ["image/webp", "image/jpeg", "image/png", "image/gif"];
|
|
757
|
-
var ImageMimeSchema =
|
|
896
|
+
var ImageMimeSchema = z12.enum(IMAGE_MIMES);
|
|
758
897
|
var ATTACHMENT_MAX = 4e5;
|
|
759
898
|
var ATTACHMENT_LOCAL_MAX = 2e6;
|
|
760
899
|
var PREVIEW_MAX = 4e4;
|
|
761
900
|
var ATTACHMENTS_MAX = 5;
|
|
762
901
|
var b64Max = (bytes) => Math.ceil(bytes / 3) * 4;
|
|
763
|
-
var AttachmentRefSchema =
|
|
902
|
+
var AttachmentRefSchema = z12.object({
|
|
764
903
|
id: AttachmentIdSchema,
|
|
765
904
|
mime: ImageMimeSchema,
|
|
766
|
-
width:
|
|
767
|
-
height:
|
|
768
|
-
bytes:
|
|
769
|
-
preview:
|
|
905
|
+
width: z12.number().int().positive(),
|
|
906
|
+
height: z12.number().int().positive(),
|
|
907
|
+
bytes: z12.number().int().positive(),
|
|
908
|
+
preview: z12.boolean()
|
|
770
909
|
});
|
|
771
|
-
var ImageUploadSchema =
|
|
910
|
+
var ImageUploadSchema = z12.object({
|
|
772
911
|
mime: ImageMimeSchema,
|
|
773
|
-
data:
|
|
774
|
-
preview:
|
|
912
|
+
data: z12.string().min(1).max(b64Max(ATTACHMENT_LOCAL_MAX)),
|
|
913
|
+
preview: z12.object({ mime: ImageMimeSchema, data: z12.string().min(1).max(b64Max(PREVIEW_MAX)) }).optional()
|
|
775
914
|
});
|
|
776
|
-
var AttachmentErrorReasonSchema =
|
|
777
|
-
var requestId =
|
|
778
|
-
var AttachmentPutSchema =
|
|
779
|
-
var AttachmentGetSchema =
|
|
780
|
-
var AttachmentStoredSchema =
|
|
781
|
-
var AttachmentDataSchema =
|
|
782
|
-
var AttachmentErrorSchema =
|
|
915
|
+
var AttachmentErrorReasonSchema = z12.enum(["too_large", "not_image", "unreadable", "not_found", "offline"]);
|
|
916
|
+
var requestId = z12.string().min(1).max(100);
|
|
917
|
+
var AttachmentPutSchema = z12.object({ type: z12.literal("attachment.put"), requestId, id: z12.string().optional(), image: ImageUploadSchema });
|
|
918
|
+
var AttachmentGetSchema = z12.object({ type: z12.literal("attachment.get"), requestId, attachment: AttachmentIdSchema, preview: z12.boolean().optional(), id: z12.string().optional(), machine: z12.string().optional() });
|
|
919
|
+
var AttachmentStoredSchema = z12.object({ type: z12.literal("attachment.stored"), requestId, ref: AttachmentRefSchema });
|
|
920
|
+
var AttachmentDataSchema = z12.object({ type: z12.literal("attachment.data"), requestId, attachment: AttachmentIdSchema, mime: ImageMimeSchema, data: z12.string() });
|
|
921
|
+
var AttachmentErrorSchema = z12.object({ type: z12.literal("attachment.error"), requestId, reason: AttachmentErrorReasonSchema });
|
|
783
922
|
|
|
784
923
|
// ../protocol/src/chat.ts
|
|
785
|
-
var ChatStepSchema =
|
|
786
|
-
kind:
|
|
787
|
-
id:
|
|
788
|
-
name:
|
|
789
|
-
path:
|
|
924
|
+
var ChatStepSchema = z13.object({
|
|
925
|
+
kind: z13.enum(["sessions", "pane", "reply", "git", "repo"]),
|
|
926
|
+
id: z13.string().optional(),
|
|
927
|
+
name: z13.string().optional(),
|
|
928
|
+
path: z13.string().optional()
|
|
790
929
|
});
|
|
791
|
-
var ChatProposalSchema =
|
|
792
|
-
cwd:
|
|
793
|
-
project:
|
|
794
|
-
prompt:
|
|
930
|
+
var ChatProposalSchema = z13.object({
|
|
931
|
+
cwd: z13.string().min(1),
|
|
932
|
+
project: z13.string(),
|
|
933
|
+
prompt: z13.string().optional(),
|
|
795
934
|
tool: ToolSchema,
|
|
796
935
|
/** What Ledge proposed on the card's picker (spec 2026-10-26 action registry §4), the agent's own default when left out. */
|
|
797
936
|
model: ModelIdSchema.optional(),
|
|
798
937
|
effort: EffortSchema.optional(),
|
|
799
|
-
launchedId:
|
|
800
|
-
error:
|
|
938
|
+
launchedId: z13.string().optional(),
|
|
939
|
+
error: z13.string().optional()
|
|
801
940
|
});
|
|
802
941
|
var MAX_PROPOSALS = 8;
|
|
803
|
-
var ChatProposalsSchema =
|
|
804
|
-
var ChatRelaySchema =
|
|
805
|
-
id:
|
|
806
|
-
name:
|
|
942
|
+
var ChatProposalsSchema = z13.array(ChatProposalSchema).min(1).max(MAX_PROPOSALS);
|
|
943
|
+
var ChatRelaySchema = z13.object({
|
|
944
|
+
id: z13.string().min(1),
|
|
945
|
+
name: z13.string(),
|
|
807
946
|
tool: ToolSchema,
|
|
808
|
-
text:
|
|
809
|
-
status:
|
|
810
|
-
sentAt:
|
|
811
|
-
error:
|
|
947
|
+
text: z13.string().min(1),
|
|
948
|
+
status: z13.enum(["queued", "sent"]).optional(),
|
|
949
|
+
sentAt: z13.string().datetime().optional(),
|
|
950
|
+
error: z13.string().optional()
|
|
812
951
|
});
|
|
813
|
-
var ChatCloseSchema =
|
|
814
|
-
id:
|
|
815
|
-
name:
|
|
952
|
+
var ChatCloseSchema = z13.object({
|
|
953
|
+
id: z13.string().min(1),
|
|
954
|
+
name: z13.string(),
|
|
816
955
|
tool: ToolSchema,
|
|
817
|
-
closedAt:
|
|
818
|
-
how:
|
|
819
|
-
error:
|
|
956
|
+
closedAt: z13.string().datetime().optional(),
|
|
957
|
+
how: z13.enum(["exit", "killed"]).optional(),
|
|
958
|
+
error: z13.string().optional()
|
|
820
959
|
});
|
|
821
|
-
var ChatClosesSchema =
|
|
822
|
-
var ChatProjectProposalSchema =
|
|
823
|
-
name:
|
|
824
|
-
description:
|
|
825
|
-
repos:
|
|
826
|
-
addTo:
|
|
960
|
+
var ChatClosesSchema = z13.array(ChatCloseSchema).min(1).max(MAX_PROPOSALS);
|
|
961
|
+
var ChatProjectProposalSchema = z13.object({
|
|
962
|
+
name: z13.string().min(1).max(80),
|
|
963
|
+
description: z13.string().max(500).optional(),
|
|
964
|
+
repos: z13.array(z13.object({ path: z13.string().min(1).max(4096), why: z13.string().min(1).max(200) })).min(1).max(50),
|
|
965
|
+
addTo: z13.string().min(1).max(80).optional()
|
|
827
966
|
});
|
|
828
|
-
var ChatTeamSeatSchema =
|
|
829
|
-
role:
|
|
830
|
-
label:
|
|
967
|
+
var ChatTeamSeatSchema = z13.object({
|
|
968
|
+
role: z13.string().min(1),
|
|
969
|
+
label: z13.string(),
|
|
831
970
|
tool: ToolSchema,
|
|
832
|
-
model:
|
|
833
|
-
effort:
|
|
971
|
+
model: z13.string().optional(),
|
|
972
|
+
effort: z13.string().optional(),
|
|
834
973
|
autonomy: AutonomySchema.optional(),
|
|
835
|
-
name:
|
|
974
|
+
name: z13.string().optional()
|
|
836
975
|
});
|
|
837
|
-
var ChatTeamProposalSchema =
|
|
838
|
-
cwd:
|
|
839
|
-
project:
|
|
840
|
-
projectName:
|
|
841
|
-
name:
|
|
842
|
-
template:
|
|
843
|
-
seats:
|
|
844
|
-
teamId:
|
|
845
|
-
launchedAt:
|
|
846
|
-
error:
|
|
847
|
-
savedPath:
|
|
976
|
+
var ChatTeamProposalSchema = z13.object({
|
|
977
|
+
cwd: z13.string().min(1),
|
|
978
|
+
project: z13.string(),
|
|
979
|
+
projectName: z13.string().optional(),
|
|
980
|
+
name: z13.string().min(1),
|
|
981
|
+
template: z13.string().optional(),
|
|
982
|
+
seats: z13.array(ChatTeamSeatSchema).min(1).max(8),
|
|
983
|
+
teamId: z13.string().optional(),
|
|
984
|
+
launchedAt: z13.string().datetime().optional(),
|
|
985
|
+
error: z13.string().optional(),
|
|
986
|
+
savedPath: z13.string().optional()
|
|
848
987
|
});
|
|
849
|
-
var ChatTaskProposalSchema =
|
|
850
|
-
to:
|
|
851
|
-
toName:
|
|
852
|
-
team:
|
|
853
|
-
title:
|
|
854
|
-
text:
|
|
855
|
-
taskId:
|
|
856
|
-
ownerName:
|
|
857
|
-
state:
|
|
858
|
-
givenAt:
|
|
859
|
-
error:
|
|
988
|
+
var ChatTaskProposalSchema = z13.object({
|
|
989
|
+
to: z13.string().min(1),
|
|
990
|
+
toName: z13.string().optional(),
|
|
991
|
+
team: z13.string().optional(),
|
|
992
|
+
title: z13.string().min(1).max(200),
|
|
993
|
+
text: z13.string().max(2e4).optional(),
|
|
994
|
+
taskId: z13.string().optional(),
|
|
995
|
+
ownerName: z13.string().optional(),
|
|
996
|
+
state: z13.enum(["open", "taken", "done", "refused", "dropped"]).optional(),
|
|
997
|
+
givenAt: z13.string().datetime().optional(),
|
|
998
|
+
error: z13.string().optional()
|
|
860
999
|
});
|
|
861
|
-
var ChatTasksSchema =
|
|
862
|
-
var ActionVarsSchema =
|
|
1000
|
+
var ChatTasksSchema = z13.array(ChatTaskProposalSchema).min(1).max(MAX_PROPOSALS);
|
|
1001
|
+
var ActionVarsSchema = z13.record(z13.string().max(40), z13.string().max(300));
|
|
863
1002
|
var DETAIL_MAX = 4e3;
|
|
864
1003
|
var ACTION_ERROR_CODES = [
|
|
865
1004
|
"unknown",
|
|
@@ -886,34 +1025,34 @@ var ACTION_ERROR_CODES = [
|
|
|
886
1025
|
"cut",
|
|
887
1026
|
"failed"
|
|
888
1027
|
];
|
|
889
|
-
var ChatActionStateSchema =
|
|
890
|
-
var ChatActionSchema =
|
|
891
|
-
action:
|
|
892
|
-
args:
|
|
893
|
-
summary:
|
|
1028
|
+
var ChatActionStateSchema = z13.enum(["running", "done", "denied", "failed", "refused"]);
|
|
1029
|
+
var ChatActionSchema = z13.object({
|
|
1030
|
+
action: z13.string().min(1).max(40),
|
|
1031
|
+
args: z13.record(z13.unknown()),
|
|
1032
|
+
summary: z13.string().min(1).max(300),
|
|
894
1033
|
vars: ActionVarsSchema.optional(),
|
|
895
|
-
detail:
|
|
896
|
-
detailCut:
|
|
1034
|
+
detail: z13.string().max(DETAIL_MAX).optional(),
|
|
1035
|
+
detailCut: z13.literal(true).optional(),
|
|
897
1036
|
risk: ActionRiskSchema,
|
|
898
|
-
session:
|
|
899
|
-
team:
|
|
1037
|
+
session: z13.string().optional(),
|
|
1038
|
+
team: z13.string().optional(),
|
|
900
1039
|
state: ChatActionStateSchema.optional(),
|
|
901
|
-
doneAt:
|
|
902
|
-
error:
|
|
903
|
-
code:
|
|
1040
|
+
doneAt: z13.string().datetime().optional(),
|
|
1041
|
+
error: z13.string().optional(),
|
|
1042
|
+
code: z13.string().max(40).optional()
|
|
904
1043
|
});
|
|
905
|
-
var ChatActionsSchema =
|
|
906
|
-
var ChatTurnSchema =
|
|
907
|
-
machineId:
|
|
908
|
-
machineName:
|
|
909
|
-
choices:
|
|
910
|
-
qid:
|
|
911
|
-
question:
|
|
912
|
-
askedAt:
|
|
913
|
-
steps:
|
|
914
|
-
answer:
|
|
915
|
-
answeredAt:
|
|
916
|
-
error:
|
|
1044
|
+
var ChatActionsSchema = z13.array(ChatActionSchema).min(1).max(MAX_PROPOSALS);
|
|
1045
|
+
var ChatTurnSchema = z13.object({
|
|
1046
|
+
machineId: z13.string().optional(),
|
|
1047
|
+
machineName: z13.string().optional(),
|
|
1048
|
+
choices: z13.array(z13.object({ id: z13.string(), label: z13.string() })).optional(),
|
|
1049
|
+
qid: z13.string().min(1),
|
|
1050
|
+
question: z13.string(),
|
|
1051
|
+
askedAt: z13.string().datetime(),
|
|
1052
|
+
steps: z13.array(ChatStepSchema),
|
|
1053
|
+
answer: z13.string().optional(),
|
|
1054
|
+
answeredAt: z13.string().datetime().optional(),
|
|
1055
|
+
error: z13.string().optional(),
|
|
917
1056
|
proposal: ChatProposalSchema.optional(),
|
|
918
1057
|
proposals: ChatProposalsSchema.optional(),
|
|
919
1058
|
relay: ChatRelaySchema.optional(),
|
|
@@ -922,50 +1061,50 @@ var ChatTurnSchema = z10.object({
|
|
|
922
1061
|
team: ChatTeamProposalSchema.optional(),
|
|
923
1062
|
tasks: ChatTasksSchema.optional(),
|
|
924
1063
|
actions: ChatActionsSchema.optional(),
|
|
925
|
-
ignoredAt:
|
|
926
|
-
attachments:
|
|
1064
|
+
ignoredAt: z13.string().datetime().optional(),
|
|
1065
|
+
attachments: z13.array(AttachmentRefSchema).optional()
|
|
927
1066
|
});
|
|
928
1067
|
var proposalRows = (t) => t?.proposals ?? (t?.proposal ? [t.proposal] : []);
|
|
929
1068
|
|
|
930
1069
|
// ../protocol/src/repos.ts
|
|
931
|
-
import { z as
|
|
932
|
-
var ReposInspectSchema =
|
|
933
|
-
type:
|
|
934
|
-
requestId:
|
|
935
|
-
paths:
|
|
936
|
-
machineId:
|
|
1070
|
+
import { z as z14 } from "zod";
|
|
1071
|
+
var ReposInspectSchema = z14.object({
|
|
1072
|
+
type: z14.literal("repos.inspect"),
|
|
1073
|
+
requestId: z14.string().min(1).max(100),
|
|
1074
|
+
paths: z14.array(z14.string().min(1)).min(1).max(50),
|
|
1075
|
+
machineId: z14.string().optional()
|
|
937
1076
|
});
|
|
938
|
-
var RepoInfoSchema =
|
|
939
|
-
var ReposInfoSchema =
|
|
1077
|
+
var RepoInfoSchema = z14.object({ path: z14.string(), exists: z14.boolean(), branch: z14.string().nullable() });
|
|
1078
|
+
var ReposInfoSchema = z14.object({ type: z14.literal("repos.info"), requestId: z14.string(), repos: z14.array(RepoInfoSchema) });
|
|
940
1079
|
|
|
941
1080
|
// ../protocol/src/scan.ts
|
|
942
|
-
import { z as
|
|
943
|
-
var ReposScanSchema =
|
|
944
|
-
var FoundRepoSchema =
|
|
945
|
-
var ReposFoundSchema =
|
|
1081
|
+
import { z as z15 } from "zod";
|
|
1082
|
+
var ReposScanSchema = z15.object({ type: z15.literal("repos.scan"), requestId: z15.string().min(1).max(100), machineId: z15.string().optional() });
|
|
1083
|
+
var FoundRepoSchema = z15.object({ path: z15.string(), branch: z15.string().nullable(), remote: z15.string().optional(), manifest: z15.string().max(200).optional() });
|
|
1084
|
+
var ReposFoundSchema = z15.object({ type: z15.literal("repos.found"), requestId: z15.string(), repos: z15.array(FoundRepoSchema).max(500), truncated: z15.boolean(), error: z15.string().optional() });
|
|
946
1085
|
|
|
947
1086
|
// ../protocol/src/documents.ts
|
|
948
|
-
import { z as
|
|
1087
|
+
import { z as z16 } from "zod";
|
|
949
1088
|
var DOCUMENT_MAX_BYTES = 1048576;
|
|
950
|
-
var path =
|
|
951
|
-
var requestId2 =
|
|
952
|
-
var DocumentReadSchema =
|
|
953
|
-
type:
|
|
1089
|
+
var path = z16.string().min(1).max(4096);
|
|
1090
|
+
var requestId2 = z16.string().min(1);
|
|
1091
|
+
var DocumentReadSchema = z16.object({
|
|
1092
|
+
type: z16.literal("document.read"),
|
|
954
1093
|
requestId: requestId2,
|
|
955
1094
|
path,
|
|
956
|
-
machineId:
|
|
957
|
-
sessionId:
|
|
1095
|
+
machineId: z16.string().optional(),
|
|
1096
|
+
sessionId: z16.string().min(1).optional(),
|
|
958
1097
|
basePath: path.optional()
|
|
959
1098
|
});
|
|
960
|
-
var DocumentContentSchema =
|
|
961
|
-
type:
|
|
1099
|
+
var DocumentContentSchema = z16.object({
|
|
1100
|
+
type: z16.literal("document.content"),
|
|
962
1101
|
requestId: requestId2,
|
|
963
1102
|
path,
|
|
964
|
-
text:
|
|
965
|
-
bytes:
|
|
966
|
-
modifiedAt:
|
|
1103
|
+
text: z16.string(),
|
|
1104
|
+
bytes: z16.number().int().nonnegative(),
|
|
1105
|
+
modifiedAt: z16.string().datetime()
|
|
967
1106
|
});
|
|
968
|
-
var DocumentErrorCodeSchema =
|
|
1107
|
+
var DocumentErrorCodeSchema = z16.enum([
|
|
969
1108
|
"not_found",
|
|
970
1109
|
"not_file",
|
|
971
1110
|
"unsupported_path",
|
|
@@ -977,150 +1116,63 @@ var DocumentErrorCodeSchema = z13.enum([
|
|
|
977
1116
|
"session_missing",
|
|
978
1117
|
"read_failed"
|
|
979
1118
|
]);
|
|
980
|
-
var DocumentErrorSchema =
|
|
981
|
-
type:
|
|
1119
|
+
var DocumentErrorSchema = z16.object({
|
|
1120
|
+
type: z16.literal("document.error"),
|
|
982
1121
|
requestId: requestId2,
|
|
983
1122
|
path,
|
|
984
1123
|
code: DocumentErrorCodeSchema
|
|
985
1124
|
});
|
|
986
1125
|
|
|
987
1126
|
// ../protocol/src/routing.ts
|
|
988
|
-
import { z as
|
|
989
|
-
var MachineInventorySchema =
|
|
990
|
-
id:
|
|
991
|
-
label:
|
|
992
|
-
online:
|
|
993
|
-
local:
|
|
994
|
-
sessions:
|
|
995
|
-
folders:
|
|
1127
|
+
import { z as z17 } from "zod";
|
|
1128
|
+
var MachineInventorySchema = z17.object({
|
|
1129
|
+
id: z17.string().min(1).max(80),
|
|
1130
|
+
label: z17.string().min(1).max(120),
|
|
1131
|
+
online: z17.boolean(),
|
|
1132
|
+
local: z17.boolean(),
|
|
1133
|
+
sessions: z17.array(z17.object({ id: z17.string(), name: z17.string(), project: z17.string(), cwd: z17.string(), topic: z17.string().optional(), state: z17.string(), readOnly: z17.boolean() })).max(500),
|
|
1134
|
+
folders: z17.array(z17.object({ project: z17.string(), cwd: z17.string() })).max(100)
|
|
996
1135
|
});
|
|
997
|
-
var RoutingContextSchema =
|
|
998
|
-
machines:
|
|
999
|
-
history:
|
|
1136
|
+
var RoutingContextSchema = z17.object({
|
|
1137
|
+
machines: z17.array(MachineInventorySchema).min(1).max(20),
|
|
1138
|
+
history: z17.array(z17.object({ question: z17.string().max(2e4), answer: z17.string().max(2e4).optional(), machineId: z17.string().optional() })).max(50)
|
|
1000
1139
|
});
|
|
1001
|
-
var RouteResultSchema =
|
|
1140
|
+
var RouteResultSchema = z17.object({
|
|
1002
1141
|
/** Null means an answer or a clarification, never an implicit local destination. */
|
|
1003
|
-
machineId:
|
|
1004
|
-
text:
|
|
1005
|
-
choices:
|
|
1006
|
-
});
|
|
1007
|
-
|
|
1008
|
-
// ../protocol/src/ssh.ts
|
|
1009
|
-
import { z as z15 } from "zod";
|
|
1010
|
-
var SshAliasSchema = z15.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/);
|
|
1011
|
-
|
|
1012
|
-
// ../protocol/src/machines.ts
|
|
1013
|
-
import { z as z16 } from "zod";
|
|
1014
|
-
var MachineIdSchema = z16.string().regex(/^[a-zA-Z0-9_-]{1,64}$/);
|
|
1015
|
-
var MachineSchema = z16.object({
|
|
1016
|
-
id: MachineIdSchema,
|
|
1017
|
-
label: z16.string().trim().min(1).max(80),
|
|
1018
|
-
ssh: SshAliasSchema.optional()
|
|
1019
|
-
});
|
|
1020
|
-
var MachinesSchema = z16.array(MachineSchema).min(1).max(20).superRefine((list, ctx) => {
|
|
1021
|
-
if (list[0]?.id !== "local" || list[0].ssh !== void 0) ctx.addIssue({ code: "custom", message: "the first machine is local, without ssh", path: [0] });
|
|
1022
|
-
const ids = /* @__PURE__ */ new Set(), aliases = /* @__PURE__ */ new Set();
|
|
1023
|
-
list.forEach((m, i) => {
|
|
1024
|
-
if (i > 0 && !m.ssh) ctx.addIssue({ code: "custom", message: "a remote machine needs an ssh alias", path: [i, "ssh"] });
|
|
1025
|
-
if (ids.has(m.id)) ctx.addIssue({ code: "custom", message: `duplicate id ${m.id}`, path: [i, "id"] });
|
|
1026
|
-
ids.add(m.id);
|
|
1027
|
-
if (m.ssh) {
|
|
1028
|
-
if (aliases.has(m.ssh)) ctx.addIssue({ code: "custom", message: `duplicate ssh alias ${m.ssh}`, path: [i, "ssh"] });
|
|
1029
|
-
aliases.add(m.ssh);
|
|
1030
|
-
}
|
|
1031
|
-
});
|
|
1142
|
+
machineId: z17.string().nullable(),
|
|
1143
|
+
text: z17.string().min(1).max(2e4),
|
|
1144
|
+
choices: z17.array(z17.string()).max(20).optional()
|
|
1032
1145
|
});
|
|
1033
1146
|
|
|
1034
1147
|
// ../protocol/src/island.ts
|
|
1035
|
-
import { z as
|
|
1036
|
-
var IslandScaleSchema =
|
|
1037
|
-
var IslandPrefsSchema =
|
|
1148
|
+
import { z as z18 } from "zod";
|
|
1149
|
+
var IslandScaleSchema = z18.union([z18.literal("auto"), z18.literal(1), z18.literal(1.25), z18.literal(1.5), z18.literal(2)]);
|
|
1150
|
+
var IslandPrefsSchema = z18.object({
|
|
1038
1151
|
/** Shown at the top of the screen; hidden, Desktop still notifies. */
|
|
1039
|
-
visible:
|
|
1152
|
+
visible: z18.boolean(),
|
|
1040
1153
|
/** `primary` (whichever it is after a reconfiguration), or a monitor's id as the shell lists it (`list_monitors`: the OS
|
|
1041
1154
|
* name, `#index` without one). `second`, written by older fronts, is the first monitor that is not the primary. */
|
|
1042
|
-
screen:
|
|
1043
|
-
position:
|
|
1155
|
+
screen: z18.string().trim().min(1).max(200),
|
|
1156
|
+
position: z18.enum(["center", "left", "right"]),
|
|
1044
1157
|
/** A strip under a maximised window. */
|
|
1045
|
-
discreet:
|
|
1158
|
+
discreet: z18.boolean(),
|
|
1046
1159
|
islandScale: IslandScaleSchema,
|
|
1047
1160
|
panelScale: IslandScaleSchema,
|
|
1048
1161
|
/** What the island shows besides asks and questions, which it always shows. */
|
|
1049
|
-
shows:
|
|
1162
|
+
shows: z18.object({
|
|
1050
1163
|
/** Allow, deny or answer in a line from the island; off, its cards only say « Open in Ledge ». */
|
|
1051
|
-
quick:
|
|
1164
|
+
quick: z18.boolean(),
|
|
1052
1165
|
/** The 6 s bubble when an agent finishes. */
|
|
1053
|
-
finished:
|
|
1166
|
+
finished: z18.boolean(),
|
|
1054
1167
|
/** An agent's sentence in a bubble. */
|
|
1055
|
-
say:
|
|
1168
|
+
say: z18.boolean(),
|
|
1056
1169
|
/** The sub-agents next to their main agent. */
|
|
1057
|
-
helpers:
|
|
1170
|
+
helpers: z18.boolean()
|
|
1058
1171
|
}),
|
|
1059
1172
|
/** The global shortcut that opens the island, as shown (`Ctrl Alt L`). */
|
|
1060
|
-
shortcut:
|
|
1173
|
+
shortcut: z18.string().trim().min(1).max(40)
|
|
1061
1174
|
});
|
|
1062
1175
|
|
|
1063
|
-
// ../protocol/src/projects.ts
|
|
1064
|
-
import { z as z18 } from "zod";
|
|
1065
|
-
var PROJECT_COLORS = { blue: "#3b82f6", green: "#10b981", amber: "#f59e0b", violet: "#8b5cf6", teal: "#14b8a6", pink: "#ec4899", red: "#ef4444", slate: "#64748b" };
|
|
1066
|
-
var ProjectColorSchema = z18.enum(["blue", "green", "amber", "violet", "teal", "pink", "red", "slate"]);
|
|
1067
|
-
var ProjectIdSchema = z18.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/);
|
|
1068
|
-
function normalizePath(raw) {
|
|
1069
|
-
const p = raw.trim().replace(/\/+/g, "/");
|
|
1070
|
-
return p.length > 1 && p.endsWith("/") ? p.slice(0, -1) : p;
|
|
1071
|
-
}
|
|
1072
|
-
var PathSchema = z18.string().max(4096).refine((p) => p.startsWith("/") && p === normalizePath(p), "an absolute, normalized path");
|
|
1073
|
-
var RepoSchema = z18.object({ machine: MachineIdSchema, path: PathSchema });
|
|
1074
|
-
var ProjectSchema = z18.object({
|
|
1075
|
-
id: ProjectIdSchema,
|
|
1076
|
-
name: z18.string().trim().min(1).max(80),
|
|
1077
|
-
color: ProjectColorSchema,
|
|
1078
|
-
description: z18.string().max(500).default(""),
|
|
1079
|
-
repos: z18.array(RepoSchema).max(50)
|
|
1080
|
-
});
|
|
1081
|
-
var RuleSchema = z18.object({ machine: MachineIdSchema, path: PathSchema, project: ProjectIdSchema });
|
|
1082
|
-
function projectsProblems(p) {
|
|
1083
|
-
const out = [];
|
|
1084
|
-
const ids = /* @__PURE__ */ new Set(), names = /* @__PURE__ */ new Set(), repos = /* @__PURE__ */ new Set(), rules = /* @__PURE__ */ new Set();
|
|
1085
|
-
p.projects.forEach((project, i) => {
|
|
1086
|
-
if (ids.has(project.id)) out.push({ code: "duplicate_id", path: ["projects", i, "id"] });
|
|
1087
|
-
ids.add(project.id);
|
|
1088
|
-
const name = project.name.trim().toLocaleLowerCase();
|
|
1089
|
-
if (names.has(name)) out.push({ code: "duplicate_name", path: ["projects", i, "name"] });
|
|
1090
|
-
names.add(name);
|
|
1091
|
-
project.repos.forEach((repo, j) => {
|
|
1092
|
-
const key = `${repo.machine}
|
|
1093
|
-
${repo.path}`;
|
|
1094
|
-
if (repos.has(key)) out.push({ code: "duplicate_repo", path: ["projects", i, "repos", j] });
|
|
1095
|
-
repos.add(key);
|
|
1096
|
-
});
|
|
1097
|
-
});
|
|
1098
|
-
p.rules.forEach((rule, i) => {
|
|
1099
|
-
const key = `${rule.machine}
|
|
1100
|
-
${rule.path}`;
|
|
1101
|
-
if (rules.has(key)) out.push({ code: "duplicate_rule", path: ["rules", i] });
|
|
1102
|
-
rules.add(key);
|
|
1103
|
-
if (!ids.has(rule.project)) out.push({ code: "unknown_project", path: ["rules", i, "project"] });
|
|
1104
|
-
});
|
|
1105
|
-
return out;
|
|
1106
|
-
}
|
|
1107
|
-
var ProjectsSchema = z18.object({ projects: z18.array(ProjectSchema).max(100), rules: z18.array(RuleSchema).max(1e3) }).superRefine((p, ctx) => {
|
|
1108
|
-
for (const problem of projectsProblems(p)) ctx.addIssue({ code: "custom", message: problem.code, path: problem.path });
|
|
1109
|
-
});
|
|
1110
|
-
var DEFAULT_PROJECTS = { projects: [], rules: [] };
|
|
1111
|
-
var under = (cwd, path2) => path2 === "/" || cwd === path2 || cwd.startsWith(`${path2}/`);
|
|
1112
|
-
function projectOf(session, state) {
|
|
1113
|
-
const machine = session.machineId ?? "local";
|
|
1114
|
-
const cwd = normalizePath(session.cwd);
|
|
1115
|
-
const known = new Set(state.projects.map((p) => p.id));
|
|
1116
|
-
const candidates = [
|
|
1117
|
-
...state.projects.flatMap((p) => p.repos.filter((r) => r.machine === machine).map((r) => ({ project: p.id, path: r.path, rule: false }))),
|
|
1118
|
-
...state.rules.filter((r) => r.machine === machine && known.has(r.project)).map((r) => ({ project: r.project, path: r.path, rule: true }))
|
|
1119
|
-
].filter((c) => under(cwd, c.path));
|
|
1120
|
-
candidates.sort((x, y) => y.path.length - x.path.length || Number(y.rule) - Number(x.rule));
|
|
1121
|
-
return candidates[0]?.project ?? null;
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
1176
|
// ../protocol/src/thread.ts
|
|
1125
1177
|
import { z as z19 } from "zod";
|
|
1126
1178
|
var ToolStatusSchema = z19.enum(["running", "success", "failed", "unknown"]);
|
|
@@ -1382,6 +1434,9 @@ var ServerMessageSchema = z21.discriminatedUnion("type", [
|
|
|
1382
1434
|
TeamLaunchedSchema,
|
|
1383
1435
|
TeamFailedSchema,
|
|
1384
1436
|
TeamSavedSchema,
|
|
1437
|
+
DefinitionsListingSchema,
|
|
1438
|
+
DefinitionResultSchema,
|
|
1439
|
+
TeamChangedSchema,
|
|
1385
1440
|
z21.object({
|
|
1386
1441
|
type: z21.literal("error"),
|
|
1387
1442
|
message: z21.string(),
|
|
@@ -1559,8 +1614,18 @@ var ClientMessageSchema = z21.discriminatedUnion("type", [
|
|
|
1559
1614
|
TeamLeaveSchema,
|
|
1560
1615
|
TeamResumeSchema,
|
|
1561
1616
|
TeamDissolveSchema,
|
|
1562
|
-
TeamSaveSchema
|
|
1563
|
-
|
|
1617
|
+
TeamSaveSchema,
|
|
1618
|
+
DefinitionsListSchema,
|
|
1619
|
+
RoleWriteSchema,
|
|
1620
|
+
RoleDeleteSchema,
|
|
1621
|
+
TemplateWriteSchema,
|
|
1622
|
+
TemplateDeleteSchema,
|
|
1623
|
+
TeamComposeSchema,
|
|
1624
|
+
TeamSeatSchema
|
|
1625
|
+
]).superRefine((m, ctx) => {
|
|
1626
|
+
const issue = "scope" in m ? scopeIssue(m) : null;
|
|
1627
|
+
if (issue) ctx.addIssue({ code: z21.ZodIssueCode.custom, message: issue, path: ["project"] });
|
|
1628
|
+
});
|
|
1564
1629
|
function parseClientMessage(raw) {
|
|
1565
1630
|
return ClientMessageSchema.parse(raw);
|
|
1566
1631
|
}
|
|
@@ -1731,7 +1796,7 @@ var MeResponseSchema = z23.object({
|
|
|
1731
1796
|
});
|
|
1732
1797
|
|
|
1733
1798
|
// ../protocol/src/phone.ts
|
|
1734
|
-
import { z as
|
|
1799
|
+
import { z as z26 } from "zod";
|
|
1735
1800
|
|
|
1736
1801
|
// ../protocol/src/push.ts
|
|
1737
1802
|
import { z as z24 } from "zod";
|
|
@@ -1777,6 +1842,51 @@ var PushPayloadSchema = z24.object({
|
|
|
1777
1842
|
tag: z24.string().regex(/^[A-Za-z0-9_-]{1,32}$/)
|
|
1778
1843
|
});
|
|
1779
1844
|
|
|
1845
|
+
// ../protocol/src/phoneTeams.ts
|
|
1846
|
+
import { z as z25 } from "zod";
|
|
1847
|
+
var scope = DefinitionScopeSchema;
|
|
1848
|
+
var PhoneSeatsSchema = z25.array(SeatSchema.strict()).min(1).max(TEAM_SEATS_MAX).refine(uniqueRoles, "a role twice in one team");
|
|
1849
|
+
var PhoneRoleDraftSchema = RoleDraftSchema.strict();
|
|
1850
|
+
var projectName = z25.string().max(80).nullable();
|
|
1851
|
+
var PhoneRoleSchema = z25.object({
|
|
1852
|
+
id: RoleIdSchema,
|
|
1853
|
+
label: z25.string().min(1).max(ROLE_LABEL_MAX),
|
|
1854
|
+
prompt: z25.string().max(ROLE_PROMPT_MAX),
|
|
1855
|
+
cut: z25.literal(true).optional(),
|
|
1856
|
+
tool: ToolSchema.optional(),
|
|
1857
|
+
model: ModelIdSchema.optional(),
|
|
1858
|
+
effort: EffortSchema.optional(),
|
|
1859
|
+
autonomy: AutonomySchema.optional(),
|
|
1860
|
+
scope,
|
|
1861
|
+
project: projectName,
|
|
1862
|
+
hash: DefinitionHashSchema,
|
|
1863
|
+
shadows: z25.literal(true).optional(),
|
|
1864
|
+
shadowed: z25.literal(true).optional(),
|
|
1865
|
+
shadowedIn: z25.array(z25.string().max(80)).min(1).max(8).optional()
|
|
1866
|
+
}).strict();
|
|
1867
|
+
var PhoneTemplateSchema = z25.object({ id: TemplateIdSchema, name: TeamNameSchema, seats: PhoneSeatsSchema, scope, project: projectName, hash: DefinitionHashSchema }).strict();
|
|
1868
|
+
var PhoneProblemSchema = z25.object({ file: z25.string().max(80), scope, project: projectName, reason: z25.string().max(200) }).strict();
|
|
1869
|
+
var PhoneCatalogSchema = z25.object({
|
|
1870
|
+
/** The names of the projects with a local repository: the ones a « Dépôt » scope or a « Lever » can name. */
|
|
1871
|
+
projects: z25.array(z25.string().max(80)).max(50),
|
|
1872
|
+
roles: z25.array(PhoneRoleSchema).max(200),
|
|
1873
|
+
templates: z25.array(PhoneTemplateSchema).max(100),
|
|
1874
|
+
problems: z25.array(PhoneProblemSchema).max(50)
|
|
1875
|
+
}).strict();
|
|
1876
|
+
var TEAMS_OPERATION_TYPES = ["role.write", "role.delete", "template.write", "template.delete", "team.launch", "team.compose", "team.seat", "team.dissolve"];
|
|
1877
|
+
var isTeamsOperation = (m) => TEAMS_OPERATION_TYPES.includes(m.type);
|
|
1878
|
+
function canonicalJson(v) {
|
|
1879
|
+
const sort = (x) => {
|
|
1880
|
+
if (Array.isArray(x)) return x.map(sort);
|
|
1881
|
+
if (x !== null && typeof x === "object") {
|
|
1882
|
+
const o = x;
|
|
1883
|
+
return Object.fromEntries(Object.keys(o).sort().filter((k) => o[k] !== void 0).map((k) => [k, sort(o[k])]));
|
|
1884
|
+
}
|
|
1885
|
+
return x;
|
|
1886
|
+
};
|
|
1887
|
+
return JSON.stringify(sort(v));
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1780
1890
|
// ../protocol/src/phone.ts
|
|
1781
1891
|
var PHONE_PROTOCOL = 1;
|
|
1782
1892
|
var PAD_TIERS = [1024, 4096, 16384, 65536, 262144, 655360];
|
|
@@ -1795,22 +1905,22 @@ var THREAD_TEXT_MAX = 8192;
|
|
|
1795
1905
|
var TOOL_TEXT_MAX = 2048;
|
|
1796
1906
|
var PENDING_BODY_MAX = 65536;
|
|
1797
1907
|
var SNAPSHOT_BODY_MAX = 2048;
|
|
1798
|
-
var RiskSchema =
|
|
1799
|
-
var RiskReasonSchema =
|
|
1800
|
-
var OperationIdSchema =
|
|
1801
|
-
var OperationStatusSchema =
|
|
1802
|
-
var OperationReasonSchema =
|
|
1803
|
-
var CapabilitiesSchema =
|
|
1908
|
+
var RiskSchema = z26.enum(["low", "high"]);
|
|
1909
|
+
var RiskReasonSchema = z26.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"]);
|
|
1910
|
+
var OperationIdSchema = z26.string().uuid();
|
|
1911
|
+
var OperationStatusSchema = z26.enum(["received", "applied", "rejected", "failed"]);
|
|
1912
|
+
var OperationReasonSchema = z26.enum([...RefusalCodeSchema.options, "untypable", "confirm_required", "conflict", "assertion_invalid", "assertion_expired", "changed", "exists", "unknown_project", "seat_failed"]);
|
|
1913
|
+
var CapabilitiesSchema = z26.object({
|
|
1804
1914
|
/** A question can be answered in free text. */
|
|
1805
|
-
freeTextAnswer:
|
|
1915
|
+
freeTextAnswer: z26.boolean(),
|
|
1806
1916
|
/** The session's accept/deny can be typed; absent = true. */
|
|
1807
|
-
decide:
|
|
1917
|
+
decide: z26.boolean().optional(),
|
|
1808
1918
|
/** OMP's dialog questions can be answered from the phone; absent = false. */
|
|
1809
|
-
questions:
|
|
1919
|
+
questions: z26.boolean().optional()
|
|
1810
1920
|
});
|
|
1811
1921
|
var UNTYPABLE = /[\u0000-\u001f\u007f-\u009f\u200b\u200e\u200f\u2028-\u202e\u2066-\u2069\ufeff]/;
|
|
1812
|
-
var CapabilitiesByToolSchema =
|
|
1813
|
-
var PhonePendingSchema = PendingSchema.extend({ key:
|
|
1922
|
+
var CapabilitiesByToolSchema = z26.object({ claude: CapabilitiesSchema, codex: CapabilitiesSchema, cursor: CapabilitiesSchema, omp: CapabilitiesSchema });
|
|
1923
|
+
var PhonePendingSchema = PendingSchema.extend({ key: z26.string().max(64), risk: RiskSchema, riskReason: RiskReasonSchema, cut: z26.literal(true).optional() });
|
|
1814
1924
|
var PhoneSessionSchema = SessionSchema.pick({
|
|
1815
1925
|
id: true,
|
|
1816
1926
|
name: true,
|
|
@@ -1833,240 +1943,318 @@ var PhoneSessionSchema = SessionSchema.pick({
|
|
|
1833
1943
|
/** Its context and its relief (context handover spec §3.2): the phone shows the gauge; the relief is started from the PC. */
|
|
1834
1944
|
context: true,
|
|
1835
1945
|
relieves: true
|
|
1836
|
-
}).extend({ pending: PhonePendingSchema.optional(), unread:
|
|
1837
|
-
var B64U2 =
|
|
1838
|
-
var CredentialSchema =
|
|
1946
|
+
}).extend({ pending: PhonePendingSchema.optional(), unread: z26.boolean(), handover: z26.object({ state: HandoverStateSchema, toName: z26.string().max(80).optional() }).strict().optional() });
|
|
1947
|
+
var B64U2 = z26.string().regex(/^[A-Za-z0-9_-]*$/);
|
|
1948
|
+
var CredentialSchema = z26.object({
|
|
1839
1949
|
id: B64U2.max(1366),
|
|
1840
1950
|
publicKey: B64U2.max(2048),
|
|
1841
|
-
alg:
|
|
1951
|
+
alg: z26.union([z26.literal(-7), z26.literal(-257)]),
|
|
1842
1952
|
clientDataJSON: B64U2.max(4096),
|
|
1843
1953
|
authenticatorData: B64U2.max(4096),
|
|
1844
|
-
transports:
|
|
1954
|
+
transports: z26.array(z26.string().max(20)).max(8).optional()
|
|
1845
1955
|
});
|
|
1846
|
-
var AssertionSchema =
|
|
1956
|
+
var AssertionSchema = z26.object({
|
|
1847
1957
|
id: B64U2.max(1366),
|
|
1848
1958
|
clientDataJSON: B64U2.max(4096),
|
|
1849
1959
|
authenticatorData: B64U2.max(4096),
|
|
1850
1960
|
signature: B64U2.max(1024)
|
|
1851
1961
|
});
|
|
1852
|
-
var
|
|
1962
|
+
var TeamsDigestSchema = z26.string().regex(/^[0-9a-f]{64}$/);
|
|
1963
|
+
var ConfirmPurposeSchema = z26.enum(["register", "decide", "launch", "close", "act", "define", "team", "pc"]);
|
|
1853
1964
|
var PhoneChatStepSchema = ChatStepSchema.pick({ kind: true, id: true, name: true }).strict();
|
|
1854
|
-
var PhoneChatProposalSchema =
|
|
1855
|
-
project:
|
|
1965
|
+
var PhoneChatProposalSchema = z26.object({
|
|
1966
|
+
project: z26.string().max(80),
|
|
1856
1967
|
tool: ToolSchema,
|
|
1857
|
-
prompt:
|
|
1858
|
-
launchedId:
|
|
1859
|
-
failed:
|
|
1968
|
+
prompt: z26.string().max(TOOL_TEXT_MAX).optional(),
|
|
1969
|
+
launchedId: z26.string().optional(),
|
|
1970
|
+
failed: z26.literal(true).optional()
|
|
1860
1971
|
}).strict();
|
|
1861
|
-
var PhoneChatRelaySchema =
|
|
1862
|
-
id:
|
|
1863
|
-
name:
|
|
1972
|
+
var PhoneChatRelaySchema = z26.object({
|
|
1973
|
+
id: z26.string().min(1),
|
|
1974
|
+
name: z26.string(),
|
|
1864
1975
|
tool: ToolSchema,
|
|
1865
|
-
text:
|
|
1866
|
-
status:
|
|
1867
|
-
sentAt:
|
|
1868
|
-
failed:
|
|
1976
|
+
text: z26.string().max(TOOL_TEXT_MAX),
|
|
1977
|
+
status: z26.enum(["queued", "sent"]).optional(),
|
|
1978
|
+
sentAt: z26.string().datetime().optional(),
|
|
1979
|
+
failed: z26.literal(true).optional()
|
|
1869
1980
|
}).strict();
|
|
1870
|
-
var PhoneChatCloseSchema =
|
|
1871
|
-
id:
|
|
1872
|
-
name:
|
|
1981
|
+
var PhoneChatCloseSchema = z26.object({
|
|
1982
|
+
id: z26.string().min(1),
|
|
1983
|
+
name: z26.string(),
|
|
1873
1984
|
tool: ToolSchema,
|
|
1874
|
-
how:
|
|
1875
|
-
closedAt:
|
|
1876
|
-
failed:
|
|
1985
|
+
how: z26.enum(["exit", "killed"]).optional(),
|
|
1986
|
+
closedAt: z26.string().datetime().optional(),
|
|
1987
|
+
failed: z26.literal(true).optional()
|
|
1877
1988
|
}).strict();
|
|
1878
|
-
var PhoneChatTeamSchema =
|
|
1879
|
-
project:
|
|
1880
|
-
name:
|
|
1881
|
-
template:
|
|
1882
|
-
seats:
|
|
1883
|
-
teamId:
|
|
1884
|
-
launchedAt:
|
|
1885
|
-
failed:
|
|
1989
|
+
var PhoneChatTeamSchema = z26.object({
|
|
1990
|
+
project: z26.string().max(80),
|
|
1991
|
+
name: z26.string().max(60),
|
|
1992
|
+
template: z26.string().max(64).optional(),
|
|
1993
|
+
seats: z26.array(z26.object({ role: z26.string().max(40), label: z26.string().max(40), tool: ToolSchema, model: z26.string().max(200).optional(), effort: z26.string().max(20).optional(), autonomy: AutonomySchema.optional() }).strict()).min(1).max(8),
|
|
1994
|
+
teamId: z26.string().max(40).optional(),
|
|
1995
|
+
launchedAt: z26.string().datetime().optional(),
|
|
1996
|
+
failed: z26.literal(true).optional()
|
|
1886
1997
|
}).strict();
|
|
1887
|
-
var PhoneChatTaskSchema =
|
|
1888
|
-
to:
|
|
1889
|
-
toName:
|
|
1890
|
-
title:
|
|
1891
|
-
text:
|
|
1892
|
-
taskId:
|
|
1893
|
-
ownerName:
|
|
1894
|
-
state:
|
|
1895
|
-
failed:
|
|
1998
|
+
var PhoneChatTaskSchema = z26.object({
|
|
1999
|
+
to: z26.string().max(80),
|
|
2000
|
+
toName: z26.string().max(80).optional(),
|
|
2001
|
+
title: z26.string().max(200),
|
|
2002
|
+
text: z26.string().max(TOOL_TEXT_MAX).optional(),
|
|
2003
|
+
taskId: z26.string().max(40).optional(),
|
|
2004
|
+
ownerName: z26.string().max(80).optional(),
|
|
2005
|
+
state: z26.enum(["open", "taken", "done", "refused", "dropped"]).optional(),
|
|
2006
|
+
failed: z26.literal(true).optional()
|
|
1896
2007
|
}).strict();
|
|
1897
|
-
var PhoneChatActionSchema =
|
|
1898
|
-
action:
|
|
1899
|
-
summary:
|
|
2008
|
+
var PhoneChatActionSchema = z26.object({
|
|
2009
|
+
action: z26.string().min(1).max(40),
|
|
2010
|
+
summary: z26.string().max(300),
|
|
1900
2011
|
vars: ActionVarsSchema.optional(),
|
|
1901
|
-
detail:
|
|
1902
|
-
detailCut:
|
|
2012
|
+
detail: z26.string().max(TOOL_TEXT_MAX).optional(),
|
|
2013
|
+
detailCut: z26.literal(true).optional(),
|
|
1903
2014
|
risk: ActionRiskSchema,
|
|
1904
|
-
session:
|
|
1905
|
-
team:
|
|
2015
|
+
session: z26.string().max(100).optional(),
|
|
2016
|
+
team: z26.string().max(40).optional(),
|
|
1906
2017
|
state: ChatActionStateSchema.optional(),
|
|
1907
|
-
doneAt:
|
|
1908
|
-
code:
|
|
2018
|
+
doneAt: z26.string().datetime().optional(),
|
|
2019
|
+
code: z26.string().max(40).optional()
|
|
1909
2020
|
}).strict();
|
|
1910
|
-
var PhoneTeamSchema =
|
|
1911
|
-
id:
|
|
1912
|
-
name:
|
|
1913
|
-
project:
|
|
1914
|
-
state:
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
2021
|
+
var PhoneTeamSchema = z26.object({
|
|
2022
|
+
id: z26.string().max(40),
|
|
2023
|
+
name: z26.string().max(60),
|
|
2024
|
+
project: z26.string().max(80).nullable(),
|
|
2025
|
+
state: z26.enum(["active", "resting"]),
|
|
2026
|
+
template: z26.string().max(64).optional(),
|
|
2027
|
+
/** Absent from a daemon older than the phone: the phone then says no start time. */
|
|
2028
|
+
createdAt: z26.string().optional(),
|
|
2029
|
+
/** `tool`, `model` and `effort` are what the seat was composed with; `leaving` is a seat that finishes its turn and is then closed. */
|
|
2030
|
+
seats: z26.array(z26.object({
|
|
2031
|
+
role: z26.string().max(40),
|
|
2032
|
+
sessionId: z26.string().max(100).nullable(),
|
|
2033
|
+
tool: ToolSchema.optional(),
|
|
2034
|
+
model: ModelIdSchema.optional(),
|
|
2035
|
+
effort: EffortSchema.optional(),
|
|
2036
|
+
leaving: z26.literal(true).optional()
|
|
2037
|
+
}).strict()).max(16),
|
|
2038
|
+
done: z26.number().int().min(0),
|
|
2039
|
+
given: z26.number().int().min(0)
|
|
1918
2040
|
}).strict();
|
|
1919
|
-
var PhoneTaskSchema =
|
|
1920
|
-
id:
|
|
1921
|
-
title:
|
|
1922
|
-
owner:
|
|
1923
|
-
ownerName:
|
|
1924
|
-
ownerRole:
|
|
1925
|
-
team:
|
|
1926
|
-
teamName:
|
|
1927
|
-
state:
|
|
1928
|
-
result:
|
|
1929
|
-
cut:
|
|
1930
|
-
at:
|
|
1931
|
-
updatedAt:
|
|
1932
|
-
seen:
|
|
2041
|
+
var PhoneTaskSchema = z26.object({
|
|
2042
|
+
id: z26.string().max(40),
|
|
2043
|
+
title: z26.string().max(200),
|
|
2044
|
+
owner: z26.string().max(100),
|
|
2045
|
+
ownerName: z26.string().max(80),
|
|
2046
|
+
ownerRole: z26.string().max(40).optional(),
|
|
2047
|
+
team: z26.string().max(40).optional(),
|
|
2048
|
+
teamName: z26.string().max(60).optional(),
|
|
2049
|
+
state: z26.enum(["open", "taken", "done", "refused", "dropped"]),
|
|
2050
|
+
result: z26.string().max(TOOL_TEXT_MAX).optional(),
|
|
2051
|
+
cut: z26.literal(true).optional(),
|
|
2052
|
+
at: z26.string(),
|
|
2053
|
+
updatedAt: z26.string(),
|
|
2054
|
+
seen: z26.literal(true).optional()
|
|
1933
2055
|
}).strict();
|
|
1934
|
-
var ChatErrorCodeSchema =
|
|
1935
|
-
var PhoneChatTurnSchema =
|
|
2056
|
+
var ChatErrorCodeSchema = z26.enum(["busy", "timeout", "cancelled", "failed"]);
|
|
2057
|
+
var PhoneChatTurnSchema = z26.object({
|
|
1936
2058
|
qid: OperationIdSchema,
|
|
1937
|
-
question:
|
|
1938
|
-
askedAt:
|
|
1939
|
-
steps:
|
|
1940
|
-
answer:
|
|
1941
|
-
answeredAt:
|
|
2059
|
+
question: z26.string().max(MESSAGE_MAX),
|
|
2060
|
+
askedAt: z26.string().datetime(),
|
|
2061
|
+
steps: z26.array(PhoneChatStepSchema).max(50),
|
|
2062
|
+
answer: z26.string().max(THREAD_TEXT_MAX).optional(),
|
|
2063
|
+
answeredAt: z26.string().datetime().optional(),
|
|
1942
2064
|
error: ChatErrorCodeSchema.optional(),
|
|
1943
|
-
proposals:
|
|
2065
|
+
proposals: z26.array(PhoneChatProposalSchema).max(MAX_PROPOSALS).optional(),
|
|
1944
2066
|
relay: PhoneChatRelaySchema.optional(),
|
|
1945
|
-
closes:
|
|
1946
|
-
cut:
|
|
2067
|
+
closes: z26.array(PhoneChatCloseSchema).min(1).max(MAX_PROPOSALS).optional(),
|
|
2068
|
+
cut: z26.literal(true).optional(),
|
|
1947
2069
|
team: PhoneChatTeamSchema.optional(),
|
|
1948
|
-
tasks:
|
|
1949
|
-
actions:
|
|
1950
|
-
ignoredAt:
|
|
1951
|
-
attachments:
|
|
2070
|
+
tasks: z26.array(PhoneChatTaskSchema).min(1).max(MAX_PROPOSALS).optional(),
|
|
2071
|
+
actions: z26.array(PhoneChatActionSchema).min(1).max(MAX_PROPOSALS).optional(),
|
|
2072
|
+
ignoredAt: z26.string().datetime().optional(),
|
|
2073
|
+
attachments: z26.array(AttachmentRefSchema).max(ATTACHMENTS_MAX).optional()
|
|
1952
2074
|
}).strict();
|
|
1953
2075
|
var CHAT_HISTORY_BUDGET = 393216;
|
|
1954
|
-
var sessionId =
|
|
1955
|
-
var PhoneExpectSchema = PendingSchema.pick({ kind: true, text: true }).extend({ key:
|
|
1956
|
-
var CardRowsSchema =
|
|
1957
|
-
var
|
|
1958
|
-
|
|
1959
|
-
|
|
2076
|
+
var sessionId = z26.string().min(1).max(100);
|
|
2077
|
+
var PhoneExpectSchema = PendingSchema.pick({ kind: true, text: true }).extend({ key: z26.string().min(1).max(64) });
|
|
2078
|
+
var CardRowsSchema = z26.array(z26.number().int().min(0).max(MAX_PROPOSALS - 1)).min(1).max(MAX_PROPOSALS).refine((r) => new Set(r).size === r.length, "a row twice");
|
|
2079
|
+
var teamsOp = { op: OperationIdSchema, assertion: AssertionSchema.optional() };
|
|
2080
|
+
var PcActionSchema = z26.enum(["update", "restart"]);
|
|
2081
|
+
var pcSubject = (action, version) => action === "update" ? `update@${version ?? ""}` : "restart";
|
|
2082
|
+
var teamsScope = { scope: DefinitionScopeSchema, project: z26.string().min(1).max(80).optional() };
|
|
2083
|
+
var PhoneClientMessageSchema = z26.discriminatedUnion("type", [
|
|
2084
|
+
z26.object({ type: z26.literal("snapshot.request") }),
|
|
2085
|
+
z26.object({ type: z26.literal("session.thread"), id: sessionId }),
|
|
1960
2086
|
/** The session's request with its whole body (up to `PENDING_BODY_MAX`). */
|
|
1961
|
-
|
|
2087
|
+
z26.object({ type: z26.literal("session.pending"), id: sessionId }),
|
|
1962
2088
|
/** The session whose terminal the phone shows; null when it shows none. */
|
|
1963
|
-
|
|
1964
|
-
|
|
2089
|
+
z26.object({ type: z26.literal("session.watch"), id: sessionId.nullable() }),
|
|
2090
|
+
z26.object({ type: z26.literal("session.read"), id: sessionId, at: z26.string().datetime() }),
|
|
1965
2091
|
/** Asks for a challenge. One object for both purposes: the gateway refuses a `decide` without `id` and `expect`. */
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
2092
|
+
z26.object({
|
|
2093
|
+
type: z26.literal("confirm.prepare"),
|
|
2094
|
+
purpose: ConfirmPurposeSchema,
|
|
2095
|
+
id: sessionId.optional(),
|
|
2096
|
+
expect: PhoneExpectSchema.optional(),
|
|
2097
|
+
qid: OperationIdSchema.optional(),
|
|
2098
|
+
/** sha256 of the `define` or `team` operation the challenge is for (`teamsDigest`). */
|
|
2099
|
+
digest: TeamsDigestSchema.optional(),
|
|
2100
|
+
/** A `pc` challenge: what it is for, and for an update the version it covers. */
|
|
2101
|
+
action: PcActionSchema.optional(),
|
|
2102
|
+
version: z26.string().regex(SEMVER).optional()
|
|
2103
|
+
}),
|
|
2104
|
+
z26.object({ type: z26.literal("credential.register"), op: OperationIdSchema, credential: CredentialSchema }),
|
|
2105
|
+
z26.object({
|
|
2106
|
+
type: z26.literal("session.decide"),
|
|
1970
2107
|
op: OperationIdSchema,
|
|
1971
2108
|
id: sessionId,
|
|
1972
2109
|
decision: DecisionSchema,
|
|
1973
|
-
note:
|
|
2110
|
+
note: z26.string().trim().min(1).max(NOTE_MAX).optional(),
|
|
1974
2111
|
/** The request the phone showed: refused unless it is still the pending one. */
|
|
1975
2112
|
expect: PhoneExpectSchema,
|
|
1976
2113
|
/** The device check over the challenge of `confirm.prepare`; required by the daemon for a high-risk accept. */
|
|
1977
2114
|
assertion: AssertionSchema.optional()
|
|
1978
2115
|
}),
|
|
1979
|
-
|
|
1980
|
-
type:
|
|
2116
|
+
z26.object({
|
|
2117
|
+
type: z26.literal("session.reply"),
|
|
1981
2118
|
op: OperationIdSchema,
|
|
1982
2119
|
id: sessionId,
|
|
1983
|
-
text:
|
|
1984
|
-
attachments:
|
|
2120
|
+
text: z26.string().max(MESSAGE_MAX),
|
|
2121
|
+
attachments: z26.array(AttachmentIdSchema).max(ATTACHMENTS_MAX).optional(),
|
|
1985
2122
|
/** The request the reply answers, or null when the phone showed none: refused if the session's request is no longer that one. */
|
|
1986
2123
|
expect: PhoneExpectSchema.nullable(),
|
|
1987
2124
|
assertion: AssertionSchema.optional()
|
|
1988
2125
|
}),
|
|
1989
2126
|
/** OMP's `ask`: the answers to every question of the dialog `requestId`, in order; `cancel` declines it. Bounds as the local `session.answer`. */
|
|
1990
|
-
|
|
1991
|
-
type:
|
|
2127
|
+
z26.object({
|
|
2128
|
+
type: z26.literal("session.answer"),
|
|
1992
2129
|
op: OperationIdSchema,
|
|
1993
2130
|
id: sessionId,
|
|
1994
|
-
requestId:
|
|
1995
|
-
answers:
|
|
1996
|
-
cancel:
|
|
2131
|
+
requestId: z26.string().min(1).max(200),
|
|
2132
|
+
answers: z26.array(z26.object({ id: z26.string().max(200), selected: z26.array(z26.string().max(2e3)).max(100), text: z26.string().max(2e4).optional() })).max(50),
|
|
2133
|
+
cancel: z26.literal(true).optional(),
|
|
1997
2134
|
expect: PhoneExpectSchema
|
|
1998
2135
|
}),
|
|
1999
|
-
|
|
2136
|
+
z26.object({ type: z26.literal("session.interrupt"), op: OperationIdSchema, id: sessionId }),
|
|
2000
2137
|
/** The phone drops its passkey from the daemon. */
|
|
2001
|
-
|
|
2138
|
+
z26.object({ type: z26.literal("device.forget"), op: OperationIdSchema }),
|
|
2002
2139
|
/** The phone's push subscription, with the VAPID key it was made with (so a key change is seen). */
|
|
2003
|
-
|
|
2004
|
-
|
|
2140
|
+
z26.object({ type: z26.literal("push.subscribe"), op: OperationIdSchema, subscription: PushSubscriptionSchema, key: B64U2.length(87) }),
|
|
2141
|
+
z26.object({ type: z26.literal("push.unsubscribe"), op: OperationIdSchema }),
|
|
2005
2142
|
/** The phone's own chat with Ledge. */
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2143
|
+
z26.object({ type: z26.literal("chat.ask"), qid: OperationIdSchema, text: z26.string().trim().max(MESSAGE_MAX), attachments: z26.array(AttachmentIdSchema).max(ATTACHMENTS_MAX).optional() }),
|
|
2144
|
+
z26.object({ type: z26.literal("chat.cancel"), qid: OperationIdSchema }),
|
|
2145
|
+
z26.object({ type: z26.literal("chat.reset") }),
|
|
2146
|
+
z26.object({ type: z26.literal("chat.history") }),
|
|
2010
2147
|
/** An image to store, sent alone before the message that names it; no `id`, and at most `ATTACHMENT_MAX` bytes. */
|
|
2011
|
-
AttachmentPutSchema.pick({ type: true, requestId: true }).extend({ image: ImageUploadSchema.extend({ data:
|
|
2148
|
+
AttachmentPutSchema.pick({ type: true, requestId: true }).extend({ image: ImageUploadSchema.extend({ data: z26.string().min(1).max(b64Max(ATTACHMENT_MAX)) }) }),
|
|
2012
2149
|
AttachmentGetSchema.pick({ type: true, requestId: true, attachment: true, preview: true }),
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2150
|
+
z26.object({ type: z26.literal("chat.relay"), op: OperationIdSchema, qid: OperationIdSchema }),
|
|
2151
|
+
z26.object({ type: z26.literal("chat.launch"), op: OperationIdSchema, qid: OperationIdSchema, rows: CardRowsSchema.optional(), assertion: AssertionSchema.optional() }),
|
|
2152
|
+
z26.object({ type: z26.literal("chat.close"), op: OperationIdSchema, qid: OperationIdSchema, rows: CardRowsSchema.optional(), assertion: AssertionSchema.optional() }),
|
|
2016
2153
|
/** The turn's team card (roles spec §3.8): launched like a session card, with the device check (purpose `launch`, the turn). */
|
|
2017
|
-
|
|
2154
|
+
z26.object({ type: z26.literal("chat.team"), op: OperationIdSchema, qid: OperationIdSchema, assertion: AssertionSchema.optional() }),
|
|
2018
2155
|
/** A row of the turn's task card: given by Ledge. */
|
|
2019
|
-
|
|
2156
|
+
z26.object({ type: z26.literal("chat.task"), op: OperationIdSchema, qid: OperationIdSchema, row: z26.number().int().min(0).max(MAX_PROPOSALS - 1) }),
|
|
2020
2157
|
/** Rows of the turn's generic card (action registry spec §5): `confirmed` as the local `chat.act`; a row whose action asks
|
|
2021
2158
|
* for a device check (`phone`) needs one assertion, purpose `act`, over the turn. */
|
|
2022
|
-
|
|
2023
|
-
type:
|
|
2159
|
+
z26.object({
|
|
2160
|
+
type: z26.literal("chat.act"),
|
|
2024
2161
|
op: OperationIdSchema,
|
|
2025
2162
|
qid: OperationIdSchema,
|
|
2026
2163
|
rows: CardRowsSchema.optional(),
|
|
2027
|
-
confirmed:
|
|
2164
|
+
confirmed: z26.literal(true).optional(),
|
|
2028
2165
|
assertion: AssertionSchema.optional(),
|
|
2029
2166
|
/** « Refuser », as the local `chat.act`: no passkey, no confirmation. */
|
|
2030
|
-
deny:
|
|
2167
|
+
deny: z26.literal(true).optional()
|
|
2031
2168
|
}),
|
|
2032
2169
|
/** « Ignorer » the turn's cards, or `undo` (« Revoir »), as the local `chat.ignore`. */
|
|
2033
|
-
|
|
2170
|
+
z26.object({ type: z26.literal("chat.ignore"), op: OperationIdSchema, qid: OperationIdSchema, undo: z26.literal(true).optional() }),
|
|
2034
2171
|
/** « Reprendre » a resting team. */
|
|
2035
|
-
|
|
2172
|
+
z26.object({ type: z26.literal("team.resume"), op: OperationIdSchema, team: z26.string().min(1).max(40) }),
|
|
2036
2173
|
/** Puts a closed task Ledge gave away from « À traiter ». */
|
|
2037
|
-
|
|
2174
|
+
z26.object({ type: z26.literal("task.seen"), op: OperationIdSchema, task: z26.string().min(1).max(40) }),
|
|
2038
2175
|
/** Whether the phone's app is in front: a device that is visible gets no push. */
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2176
|
+
z26.object({ type: z26.literal("presence"), visible: z26.boolean() }),
|
|
2177
|
+
/** The roles, templates and problems of every scope the phone may name; then one role whole, when the catalog cut its prompt. */
|
|
2178
|
+
z26.object({ type: z26.literal("teams.catalog") }),
|
|
2179
|
+
z26.object({ type: z26.literal("teams.role"), ...teamsScope, id: RoleIdSchema }).strict(),
|
|
2180
|
+
/** `base` is the hash the phone was shown, null to create. */
|
|
2181
|
+
z26.object({ type: z26.literal("role.write"), ...teamsOp, ...teamsScope, role: PhoneRoleDraftSchema, base: DefinitionHashSchema.nullable() }).strict(),
|
|
2182
|
+
z26.object({ type: z26.literal("role.delete"), ...teamsOp, ...teamsScope, id: RoleIdSchema, base: DefinitionHashSchema }).strict(),
|
|
2183
|
+
/** No `id`: create, the id comes from the name. */
|
|
2184
|
+
z26.object({ type: z26.literal("template.write"), ...teamsOp, ...teamsScope, id: TemplateIdSchema.optional(), name: TeamNameSchema, seats: PhoneSeatsSchema, base: DefinitionHashSchema.nullable() }).strict(),
|
|
2185
|
+
z26.object({ type: z26.literal("template.delete"), ...teamsOp, ...teamsScope, id: TemplateIdSchema, base: DefinitionHashSchema }).strict(),
|
|
2186
|
+
z26.object({ type: z26.literal("team.launch"), ...teamsOp, project: z26.string().min(1).max(80), name: TeamNameSchema, seats: PhoneSeatsSchema, template: z26.string().min(1).max(64).optional() }).strict(),
|
|
2187
|
+
z26.object({ type: z26.literal("team.compose"), ...teamsOp, team: TeamIdSchema, seats: PhoneSeatsSchema }).strict(),
|
|
2188
|
+
z26.object({ type: z26.literal("team.seat"), ...teamsOp, team: TeamIdSchema, role: RoleIdSchema, action: z26.enum(["start", "restart"]) }).strict(),
|
|
2189
|
+
z26.object({ type: z26.literal("team.dissolve"), ...teamsOp, team: TeamIdSchema }).strict(),
|
|
2190
|
+
/** Installs `version` on the PC, then restarts its daemon; the phone asks for its own build's version. Passkey, purpose `pc`. */
|
|
2191
|
+
z26.object({ type: z26.literal("daemon.update"), ...teamsOp, version: z26.string().regex(SEMVER) }).strict(),
|
|
2192
|
+
/** Restarts the PC's daemon without installing anything. Passkey, purpose `pc`. */
|
|
2193
|
+
z26.object({ type: z26.literal("daemon.restart"), ...teamsOp }).strict()
|
|
2194
|
+
]).superRefine((m, ctx) => {
|
|
2195
|
+
const issue = "scope" in m ? scopeIssue(m) : null;
|
|
2196
|
+
if (issue) ctx.addIssue({ code: z26.ZodIssueCode.custom, message: issue, path: ["project"] });
|
|
2197
|
+
});
|
|
2198
|
+
var PhoneServerMessageSchema = z26.discriminatedUnion("type", [
|
|
2199
|
+
z26.object({ type: z26.literal("snapshot"), protocol: z26.literal(PHONE_PROTOCOL), sessions: z26.array(PhoneSessionSchema), capabilities: CapabilitiesByToolSchema, daemon: z26.object({
|
|
2200
|
+
version: z26.string(),
|
|
2201
|
+
name: z26.string().max(40),
|
|
2202
|
+
boot: z26.string().uuid().optional(),
|
|
2203
|
+
teams: z26.literal(true).optional(),
|
|
2204
|
+
/** `update`: the daemon can install a version and restart (npm, systemd); `restart`: it can restart (systemd). */
|
|
2205
|
+
update: z26.literal(true).optional(),
|
|
2206
|
+
restart: z26.literal(true).optional()
|
|
2207
|
+
}), device: z26.object({ confirm: z26.boolean(), push: z26.enum(["on", "off", "stale", "unavailable"]).optional(), chat: z26.literal(true).optional(), contextNear: ContextPrefsSchema.shape.near.optional() }).optional() }),
|
|
2208
|
+
z26.object({
|
|
2209
|
+
type: z26.literal("confirm.challenge"),
|
|
2210
|
+
purpose: ConfirmPurposeSchema,
|
|
2211
|
+
challenge: B64U2.max(64),
|
|
2212
|
+
rpId: z26.string().max(253),
|
|
2213
|
+
credentialId: B64U2.max(1366).optional(),
|
|
2214
|
+
expiresInMs: z26.number().int().positive(),
|
|
2215
|
+
/** Echoed from the `confirm.prepare` of a `define` or `team` challenge, so the phone matches each challenge to its own call. Absent from an older gateway. */
|
|
2216
|
+
digest: TeamsDigestSchema.optional()
|
|
2217
|
+
}),
|
|
2218
|
+
z26.object({ type: z26.literal("session.updated"), session: PhoneSessionSchema }),
|
|
2219
|
+
z26.object({ type: z26.literal("session.removed"), id: z26.string() }),
|
|
2046
2220
|
/** `pending.cut` is set when even this body was shortened. */
|
|
2047
|
-
|
|
2048
|
-
|
|
2221
|
+
z26.object({ type: z26.literal("session.pending"), id: z26.string(), pending: PhonePendingSchema }),
|
|
2222
|
+
z26.object({ type: z26.literal("session.preview"), id: z26.string(), lines: z26.array(z26.string()) }),
|
|
2049
2223
|
/** `cut`: the ids of the items shortened; `more`: older items were left out. */
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2224
|
+
z26.object({ type: z26.literal("session.thread"), id: z26.string(), items: z26.array(ThreadItemSchema), cut: z26.array(z26.string()), more: z26.boolean() }),
|
|
2225
|
+
z26.object({ type: z26.literal("session.thread.item"), id: z26.string(), item: ThreadItemSchema, cut: z26.literal(true).optional() }),
|
|
2226
|
+
z26.object({ type: z26.literal("operation.result"), op: OperationIdSchema, status: OperationStatusSchema, reason: OperationReasonSchema.optional() }),
|
|
2227
|
+
z26.object({ type: z26.literal("chat.history"), turns: z26.array(PhoneChatTurnSchema).max(50) }),
|
|
2228
|
+
z26.object({ type: z26.literal("chat.step"), qid: OperationIdSchema, step: PhoneChatStepSchema }),
|
|
2055
2229
|
/** The whole text so far, not an increment. */
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2230
|
+
z26.object({ type: z26.literal("chat.delta"), qid: OperationIdSchema, text: z26.string().max(THREAD_TEXT_MAX) }),
|
|
2231
|
+
z26.object({ type: z26.literal("chat.done"), qid: OperationIdSchema, turn: PhoneChatTurnSchema }),
|
|
2232
|
+
z26.object({ type: z26.literal("chat.error"), qid: OperationIdSchema, code: ChatErrorCodeSchema }),
|
|
2233
|
+
z26.object({ type: z26.literal("teams.catalog"), catalog: PhoneCatalogSchema }),
|
|
2234
|
+
/** The daemon updating or restarting itself, whoever asked: npm runs, then the service restarts (the link drops right after). */
|
|
2235
|
+
z26.object({ type: z26.literal("daemon.progress"), version: z26.string().max(40), step: z26.enum(["installing", "restarting"]) }),
|
|
2236
|
+
/** Nothing was changed. Never npm's output nor a command: both hold the PC's paths. */
|
|
2237
|
+
z26.object({ type: z26.literal("daemon.failed"), version: z26.string().max(40), reason: UpdateFailureSchema }),
|
|
2238
|
+
z26.object({ type: z26.literal("teams.role"), role: PhoneRoleSchema }),
|
|
2059
2239
|
/** The live teams, after each snapshot and on every change. */
|
|
2060
|
-
|
|
2240
|
+
z26.object({ type: z26.literal("teams"), teams: z26.array(PhoneTeamSchema).max(50) }),
|
|
2061
2241
|
/** The tasks Ledge gave, open or closed lately, after each snapshot; then each change. */
|
|
2062
|
-
|
|
2063
|
-
|
|
2242
|
+
z26.object({ type: z26.literal("tasks"), tasks: z26.array(PhoneTaskSchema).max(200) }),
|
|
2243
|
+
z26.object({ type: z26.literal("task.updated"), task: PhoneTaskSchema }),
|
|
2064
2244
|
AttachmentStoredSchema,
|
|
2065
2245
|
AttachmentDataSchema,
|
|
2066
2246
|
AttachmentErrorSchema,
|
|
2067
2247
|
/** Never carries free text. */
|
|
2068
|
-
|
|
2248
|
+
z26.object({ type: z26.literal("error"), code: z26.enum(["invalid", "unknown_session", "too_large"]), request: z26.string().max(40).optional() })
|
|
2069
2249
|
]);
|
|
2250
|
+
var teamsPurpose = (type) => type.startsWith("team.") ? "team" : "define";
|
|
2251
|
+
var DIGEST_OP = "00000000-0000-4000-8000-000000000000";
|
|
2252
|
+
async function teamsDigest(m) {
|
|
2253
|
+
const { op: _op, assertion: _assertion, ...raw } = m;
|
|
2254
|
+
const { op: _parsedOp, assertion: _parsedAssertion, ...rest } = PhoneClientMessageSchema.parse({ ...raw, op: DIGEST_OP });
|
|
2255
|
+
const bytes = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(canonicalJson(rest))));
|
|
2256
|
+
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
2257
|
+
}
|
|
2070
2258
|
|
|
2071
2259
|
// src/auth.ts
|
|
2072
2260
|
import { createHash, createHmac, randomBytes, timingSafeEqual } from "crypto";
|
|
@@ -2218,12 +2406,19 @@ export {
|
|
|
2218
2406
|
parseTeamBlock,
|
|
2219
2407
|
parseTaskBlock,
|
|
2220
2408
|
parseProjectBlock,
|
|
2409
|
+
SshAliasSchema,
|
|
2410
|
+
MachinesSchema,
|
|
2411
|
+
PROJECT_COLORS,
|
|
2412
|
+
ProjectsSchema,
|
|
2413
|
+
DEFAULT_PROJECTS,
|
|
2414
|
+
projectOf,
|
|
2221
2415
|
RoleIdSchema,
|
|
2222
2416
|
ROLE_LABEL_MAX,
|
|
2223
2417
|
ROLE_PROMPT_MAX,
|
|
2224
2418
|
RoleSchema,
|
|
2225
2419
|
SeatsSchema,
|
|
2226
2420
|
TeamNameSchema,
|
|
2421
|
+
TemplateIdSchema,
|
|
2227
2422
|
TeamSchema,
|
|
2228
2423
|
isTeamLive,
|
|
2229
2424
|
NOTE_MAX,
|
|
@@ -2248,19 +2443,14 @@ export {
|
|
|
2248
2443
|
ChatTurnSchema,
|
|
2249
2444
|
proposalRows,
|
|
2250
2445
|
DOCUMENT_MAX_BYTES,
|
|
2251
|
-
SshAliasSchema,
|
|
2252
|
-
MachinesSchema,
|
|
2253
2446
|
IslandPrefsSchema,
|
|
2254
|
-
PROJECT_COLORS,
|
|
2255
|
-
ProjectsSchema,
|
|
2256
|
-
DEFAULT_PROJECTS,
|
|
2257
|
-
projectOf,
|
|
2258
2447
|
RouteResultSchema,
|
|
2259
2448
|
DEFAULT_RELAY_URL,
|
|
2260
2449
|
MobileConfigSchema,
|
|
2261
2450
|
PROTOCOL_PORT,
|
|
2262
2451
|
RefusalCodeSchema,
|
|
2263
2452
|
RecentSchema,
|
|
2453
|
+
SEMVER,
|
|
2264
2454
|
MESSAGE_MAX,
|
|
2265
2455
|
SUMMARY_MAX,
|
|
2266
2456
|
parseClientMessage,
|
|
@@ -2279,6 +2469,11 @@ export {
|
|
|
2279
2469
|
pushEndpointAllowed,
|
|
2280
2470
|
PushSendResultSchema,
|
|
2281
2471
|
PushPayloadSchema,
|
|
2472
|
+
PhoneRoleSchema,
|
|
2473
|
+
PhoneTemplateSchema,
|
|
2474
|
+
TEAMS_OPERATION_TYPES,
|
|
2475
|
+
isTeamsOperation,
|
|
2476
|
+
canonicalJson,
|
|
2282
2477
|
PHONE_PROTOCOL,
|
|
2283
2478
|
padPlain,
|
|
2284
2479
|
THREAD_ITEMS_MAX,
|
|
@@ -2290,7 +2485,10 @@ export {
|
|
|
2290
2485
|
OperationIdSchema,
|
|
2291
2486
|
UNTYPABLE,
|
|
2292
2487
|
CHAT_HISTORY_BUDGET,
|
|
2488
|
+
pcSubject,
|
|
2293
2489
|
PhoneClientMessageSchema,
|
|
2490
|
+
teamsPurpose,
|
|
2491
|
+
teamsDigest,
|
|
2294
2492
|
tokenEquals,
|
|
2295
2493
|
hostAllowed,
|
|
2296
2494
|
requestAuthorized,
|