@paradow/ledge 0.32.0 → 0.34.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-HUKZUHQ7.js → action-K42H5BDA.js} +5 -5
- package/dist/cli/{attach-ILMHKRUI.js → attach-KEE4A5YP.js} +28 -15
- package/dist/cli/{bridge-LFKUCKQP.js → bridge-X327AZY4.js} +2 -2
- package/dist/cli/{chunk-VGAPV4DC.js → chunk-25RVT5MR.js} +3 -103
- package/dist/cli/{chunk-Q6RMLRPI.js → chunk-3OJCWJAA.js} +2 -2
- package/dist/cli/chunk-4OYVM4MT.js +49 -0
- package/dist/cli/{chunk-IE52REEI.js → chunk-4TCSADFR.js} +5 -23
- package/dist/cli/{chunk-HOOHS3MX.js → chunk-53ISXX2R.js} +1 -1
- package/dist/cli/{chunk-6IYPRUQG.js → chunk-54KF5RBY.js} +1 -1
- package/dist/cli/{chunk-CXZETRPA.js → chunk-7NHQGP6J.js} +1 -1
- package/dist/cli/{chunk-U7J2AN3F.js → chunk-G7XPEVCG.js} +5 -5
- package/dist/cli/{chunk-2BLPGRLO.js → chunk-IWY7DSSO.js} +835 -1030
- package/dist/cli/{chunk-SUBKKCGA.js → chunk-KPDTYX7F.js} +3 -3
- package/dist/cli/chunk-RPH773TY.js +6 -0
- package/dist/cli/{chunk-YHZIHIGI.js → chunk-RX5CJ7YH.js} +3 -5
- package/dist/cli/{chunk-NLL2EQJ2.js → chunk-T547FLQN.js} +38 -4
- package/dist/cli/{chunk-K7UEKSB2.js → chunk-UJ2WBGLW.js} +2 -2
- package/dist/cli/{chunk-OPUIV6PR.js → chunk-ULOMKEB6.js} +4 -4
- package/dist/cli/{chunk-5JNJFBKZ.js → chunk-V4XKKL6K.js} +13 -40
- package/dist/cli/{chunk-EGXOBQZI.js → daemon-RO43S3S5.js} +4655 -2964
- package/dist/cli/{decide-3B6LGVNN.js → decide-KZFYL3HY.js} +5 -5
- package/dist/cli/{handover-IX7EFDIP.js → handover-BWNMI2RA.js} +5 -5
- package/dist/cli/{hook-G7UA6MB6.js → hook-ZLWXI5EQ.js} +21 -71
- package/dist/cli/index.js +18 -25
- package/dist/cli/launch-GCX7TXOH.js +28 -0
- package/dist/cli/{send-55RWY4LZ.js → send-SXZAPVRH.js} +5 -5
- package/dist/cli/{setup-K42IVMHS.js → setup-TJ32FMVJ.js} +4 -4
- package/dist/cli/{status-NT5ZUYM6.js → status-YDVRES4E.js} +3 -3
- package/dist/cli/{task-GABQ4SKY.js → task-TUSOVJK7.js} +5 -5
- package/dist/cli/{tui-AMW2XAH5.js → tui-TCVIRZCQ.js} +1411 -1277
- package/dist/cli/{uninstall-4IMMR55T.js → uninstall-QO7YMSLA.js} +4 -4
- package/dist/cli/{version-35XLTEMX.js → version-BAYSYWFP.js} +1 -1
- package/dist/cli/who-6AZYSP7T.js +12 -0
- package/dist/ledge-guide.md +26 -49
- package/package.json +2 -1
- package/dist/cli/chunk-5FKHISVK.js +0 -160
- package/dist/cli/chunk-M7364G3S.js +0 -6
- package/dist/cli/chunk-QQVWFOPU.js +0 -290
- package/dist/cli/daemon-UJTMG3D4.js +0 -2322
- package/dist/cli/launch-2GZIRF3A.js +0 -36
- package/dist/cli/team-IK2RYXW2.js +0 -205
- package/dist/cli/who-4FRIGYVT.js +0 -12
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
paths
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-53ISXX2R.js";
|
|
4
4
|
|
|
5
5
|
// ../protocol/src/handover.ts
|
|
6
6
|
import { z } from "zod";
|
|
@@ -19,7 +19,7 @@ var HandoverSchema = z.object({
|
|
|
19
19
|
to: z.string().optional(),
|
|
20
20
|
toName: z.string().optional(),
|
|
21
21
|
reason: z.string().optional(),
|
|
22
|
-
/** Started by Ledge itself (a
|
|
22
|
+
/** Started by Ledge itself (a session working without asking), not by the user. */
|
|
23
23
|
auto: z.literal(true).optional()
|
|
24
24
|
});
|
|
25
25
|
var RelievesSchema = z.object({ id: z.string(), name: z.string(), at: z.string().datetime() });
|
|
@@ -36,23 +36,6 @@ var HandoverResultSchema = z.object({ type: z.literal("handover.result"), rid: z
|
|
|
36
36
|
import { z as z2 } from "zod";
|
|
37
37
|
var ToolSchema = z2.enum(["claude", "codex", "cursor", "omp"]);
|
|
38
38
|
var OmpApprovalSchema = z2.enum(["always-ask", "write", "yolo"]);
|
|
39
|
-
var AutonomySchema = z2.enum(["ask", "edits", "auto"]);
|
|
40
|
-
function autonomyArgs(tool, autonomy) {
|
|
41
|
-
if (!autonomy || autonomy === "ask") return [];
|
|
42
|
-
switch (tool) {
|
|
43
|
-
case "claude":
|
|
44
|
-
return ["--permission-mode", autonomy === "edits" ? "acceptEdits" : "auto"];
|
|
45
|
-
case "codex":
|
|
46
|
-
return autonomy === "edits" ? ["--ask-for-approval", "on-request"] : ["--ask-for-approval", "never", "--sandbox", "workspace-write"];
|
|
47
|
-
case "cursor":
|
|
48
|
-
return autonomy === "auto" ? ["--force"] : [];
|
|
49
|
-
case "omp":
|
|
50
|
-
return [];
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
function ompApprovalFor(autonomy) {
|
|
54
|
-
return autonomy === "auto" ? "yolo" : autonomy ? "always-ask" : void 0;
|
|
55
|
-
}
|
|
56
39
|
var BackendSchema = z2.enum(["tmux", "omp-rpc"]);
|
|
57
40
|
var SessionStateSchema = z2.enum(["starting", "working", "waiting_input", "waiting_permission", "idle", "exited", "error"]);
|
|
58
41
|
var AskQuestionSchema = z2.object({
|
|
@@ -119,6 +102,8 @@ var SessionSchema = z2.object({
|
|
|
119
102
|
worktree: z2.boolean().optional(),
|
|
120
103
|
/** The folder the agent works in now, as its last hook reported it: `cwd` stays where it started, this follows a worktree it entered. */
|
|
121
104
|
workdir: z2.string().optional(),
|
|
105
|
+
/** The OpenRig seat this agent is: its session name (`dev-build@starter`), its rig, and its role (`dev.build`) once OpenRig named it. */
|
|
106
|
+
rig: z2.object({ seat: z2.string(), name: z2.string(), role: z2.string().optional() }).optional(),
|
|
122
107
|
tmuxSession: z2.string().nullable(),
|
|
123
108
|
/** Left out for a tmux session. `omp-rpc`: no pane, nothing to attach to; the daemon holds the process (see `agentSessionFile`). */
|
|
124
109
|
backend: BackendSchema.optional(),
|
|
@@ -138,17 +123,6 @@ var SessionSchema = z2.object({
|
|
|
138
123
|
effort: z2.string().optional(),
|
|
139
124
|
/** OMP: the approval mode it was launched with, kept by a resume; left out, `always-ask`. */
|
|
140
125
|
approval: OmpApprovalSchema.optional(),
|
|
141
|
-
/** The role it was launched with or took in a team (spec 2026-10-25 roles §3.3): its id, its label as it was then. */
|
|
142
|
-
role: z2.string().optional(),
|
|
143
|
-
roleLabel: z2.string().optional(),
|
|
144
|
-
/** The live team it sits in (`team-…`); left out, the project's common table. */
|
|
145
|
-
team: z2.string().optional(),
|
|
146
|
-
/** The name of the team it was last taken out of (a leave, a dissolution, a seat in another team): a refused `@role` says so. */
|
|
147
|
-
teamLeft: z2.string().optional(),
|
|
148
|
-
/** Its team as it was last told it (`seatKey`): its next turn is told again when the team has changed since. */
|
|
149
|
-
teamSeen: z2.string().optional(),
|
|
150
|
-
/** Its role's autonomy, as launched (kept by a resume); left out, `ask`. */
|
|
151
|
-
autonomy: AutonomySchema.optional(),
|
|
152
126
|
/** Its context as its agent last reported it, after a turn (context handover spec §3.1); left out, not measured. */
|
|
153
127
|
context: ContextSchema.optional(),
|
|
154
128
|
/** Its relief by a fresh session (§3.3): asked, launched, done or failed. */
|
|
@@ -166,7 +140,10 @@ var SessionSchema = z2.object({
|
|
|
166
140
|
exitCode: z2.number().int().nullable().optional(),
|
|
167
141
|
exitedAt: z2.string().datetime().optional(),
|
|
168
142
|
lastError: z2.string().optional(),
|
|
169
|
-
|
|
143
|
+
/** `launcher`: Ledge launched it; `hook_only`: only its hooks are known (read-only); `rig`: an OpenRig seat Ledge follows through
|
|
144
|
+
* its tmux pane on the user's default server, answered like its own, whose life stays OpenRig's (no close, kill, resume, model). */
|
|
145
|
+
// A kind a newer daemon adds reads as read-only here, never as a snapshot thrown away whole (« hors ligne »).
|
|
146
|
+
source: z2.enum(["launcher", "hook_only", "rig"]).catch("hook_only"),
|
|
170
147
|
/** When the session was put in the archive (session management): set, it leaves the live list and waits to be restored, resumed or deleted. */
|
|
171
148
|
archivedAt: z2.string().datetime().optional(),
|
|
172
149
|
/** When the session was last taken out of the archive: the poller's retirement clock restarts from it, not from `exitedAt`. */
|
|
@@ -179,290 +156,39 @@ function isArchived(s) {
|
|
|
179
156
|
return s.archivedAt !== void 0;
|
|
180
157
|
}
|
|
181
158
|
|
|
182
|
-
// ../protocol/src/teams.ts
|
|
183
|
-
import { z as z7 } from "zod";
|
|
184
|
-
|
|
185
|
-
// ../protocol/src/models.ts
|
|
186
|
-
import { z as z3 } from "zod";
|
|
187
|
-
var ModelIdSchema = z3.string().min(1).max(200).regex(/^[A-Za-z0-9][A-Za-z0-9._:/@[\]=,+-]*$/, "not a model id");
|
|
188
|
-
var EffortSchema = z3.string().min(1).max(20).regex(/^[a-z]+$/, "not an effort");
|
|
189
|
-
var ModelChoiceSchema = z3.object({
|
|
190
|
-
id: ModelIdSchema,
|
|
191
|
-
label: z3.string(),
|
|
192
|
-
description: z3.string().optional(),
|
|
193
|
-
efforts: z3.array(EffortSchema).optional(),
|
|
194
|
-
defaultEffort: EffortSchema.optional(),
|
|
195
|
-
isDefault: z3.boolean().optional()
|
|
196
|
-
});
|
|
197
|
-
var ModelsListSchema = z3.object({
|
|
198
|
-
type: z3.literal("models.list"),
|
|
199
|
-
requestId: z3.string().min(1).max(100),
|
|
200
|
-
tool: ToolSchema,
|
|
201
|
-
machineId: z3.string().optional()
|
|
202
|
-
});
|
|
203
|
-
var ModelsListingSchema = z3.object({
|
|
204
|
-
type: z3.literal("models.listing"),
|
|
205
|
-
requestId: z3.string(),
|
|
206
|
-
tool: ToolSchema,
|
|
207
|
-
models: z3.array(ModelChoiceSchema),
|
|
208
|
-
error: z3.string().optional()
|
|
209
|
-
});
|
|
210
|
-
var ModelRefusalSchema = z3.enum(["not_launched", "ended", "no_conversation", "not_running", "effort_in_model", "restart_failed", "refused"]);
|
|
211
|
-
var SessionModelAcceptedSchema = z3.object({ type: z3.literal("session.model.accepted"), id: z3.string(), when: z3.enum(["now", "turn", "none"]) });
|
|
212
|
-
|
|
213
|
-
// ../protocol/src/projects.ts
|
|
214
|
-
import { z as z6 } from "zod";
|
|
215
|
-
|
|
216
|
-
// ../protocol/src/machines.ts
|
|
217
|
-
import { z as z5 } from "zod";
|
|
218
|
-
|
|
219
|
-
// ../protocol/src/ssh.ts
|
|
220
|
-
import { z as z4 } from "zod";
|
|
221
|
-
var SshAliasSchema = z4.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/);
|
|
222
|
-
|
|
223
|
-
// ../protocol/src/machines.ts
|
|
224
|
-
var MachineIdSchema = z5.string().regex(/^[a-zA-Z0-9_-]{1,64}$/);
|
|
225
|
-
var MachineSchema = z5.object({
|
|
226
|
-
id: MachineIdSchema,
|
|
227
|
-
label: z5.string().trim().min(1).max(80),
|
|
228
|
-
ssh: SshAliasSchema.optional()
|
|
229
|
-
});
|
|
230
|
-
var MachinesSchema = z5.array(MachineSchema).min(1).max(20).superRefine((list, ctx) => {
|
|
231
|
-
if (list[0]?.id !== "local" || list[0].ssh !== void 0) ctx.addIssue({ code: "custom", message: "the first machine is local, without ssh", path: [0] });
|
|
232
|
-
const ids = /* @__PURE__ */ new Set(), aliases = /* @__PURE__ */ new Set();
|
|
233
|
-
list.forEach((m, i) => {
|
|
234
|
-
if (i > 0 && !m.ssh) ctx.addIssue({ code: "custom", message: "a remote machine needs an ssh alias", path: [i, "ssh"] });
|
|
235
|
-
if (ids.has(m.id)) ctx.addIssue({ code: "custom", message: `duplicate id ${m.id}`, path: [i, "id"] });
|
|
236
|
-
ids.add(m.id);
|
|
237
|
-
if (m.ssh) {
|
|
238
|
-
if (aliases.has(m.ssh)) ctx.addIssue({ code: "custom", message: `duplicate ssh alias ${m.ssh}`, path: [i, "ssh"] });
|
|
239
|
-
aliases.add(m.ssh);
|
|
240
|
-
}
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
// ../protocol/src/projects.ts
|
|
245
|
-
var PROJECT_COLORS = { blue: "#3b82f6", green: "#10b981", amber: "#f59e0b", violet: "#8b5cf6", teal: "#14b8a6", pink: "#ec4899", red: "#ef4444", slate: "#64748b" };
|
|
246
|
-
var ProjectColorSchema = z6.enum(["blue", "green", "amber", "violet", "teal", "pink", "red", "slate"]);
|
|
247
|
-
var ProjectIdSchema = z6.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/);
|
|
248
|
-
function normalizePath(raw) {
|
|
249
|
-
const p = raw.trim().replace(/\/+/g, "/");
|
|
250
|
-
return p.length > 1 && p.endsWith("/") ? p.slice(0, -1) : p;
|
|
251
|
-
}
|
|
252
|
-
var PathSchema = z6.string().max(4096).refine((p) => p.startsWith("/") && p === normalizePath(p), "an absolute, normalized path");
|
|
253
|
-
var RepoSchema = z6.object({ machine: MachineIdSchema, path: PathSchema });
|
|
254
|
-
var ProjectSchema = z6.object({
|
|
255
|
-
id: ProjectIdSchema,
|
|
256
|
-
name: z6.string().trim().min(1).max(80),
|
|
257
|
-
color: ProjectColorSchema,
|
|
258
|
-
description: z6.string().max(500).default(""),
|
|
259
|
-
repos: z6.array(RepoSchema).max(50)
|
|
260
|
-
});
|
|
261
|
-
var RuleSchema = z6.object({ machine: MachineIdSchema, path: PathSchema, project: ProjectIdSchema });
|
|
262
|
-
function projectsProblems(p) {
|
|
263
|
-
const out = [];
|
|
264
|
-
const ids = /* @__PURE__ */ new Set(), names = /* @__PURE__ */ new Set(), repos = /* @__PURE__ */ new Set(), rules = /* @__PURE__ */ new Set();
|
|
265
|
-
p.projects.forEach((project, i) => {
|
|
266
|
-
if (ids.has(project.id)) out.push({ code: "duplicate_id", path: ["projects", i, "id"] });
|
|
267
|
-
ids.add(project.id);
|
|
268
|
-
const name = project.name.trim().toLocaleLowerCase();
|
|
269
|
-
if (names.has(name)) out.push({ code: "duplicate_name", path: ["projects", i, "name"] });
|
|
270
|
-
names.add(name);
|
|
271
|
-
project.repos.forEach((repo, j) => {
|
|
272
|
-
const key = `${repo.machine}
|
|
273
|
-
${repo.path}`;
|
|
274
|
-
if (repos.has(key)) out.push({ code: "duplicate_repo", path: ["projects", i, "repos", j] });
|
|
275
|
-
repos.add(key);
|
|
276
|
-
});
|
|
277
|
-
});
|
|
278
|
-
p.rules.forEach((rule, i) => {
|
|
279
|
-
const key = `${rule.machine}
|
|
280
|
-
${rule.path}`;
|
|
281
|
-
if (rules.has(key)) out.push({ code: "duplicate_rule", path: ["rules", i] });
|
|
282
|
-
rules.add(key);
|
|
283
|
-
if (!ids.has(rule.project)) out.push({ code: "unknown_project", path: ["rules", i, "project"] });
|
|
284
|
-
});
|
|
285
|
-
return out;
|
|
286
|
-
}
|
|
287
|
-
var ProjectsSchema = z6.object({ projects: z6.array(ProjectSchema).max(100), rules: z6.array(RuleSchema).max(1e3) }).superRefine((p, ctx) => {
|
|
288
|
-
for (const problem of projectsProblems(p)) ctx.addIssue({ code: "custom", message: problem.code, path: problem.path });
|
|
289
|
-
});
|
|
290
|
-
var DEFAULT_PROJECTS = { projects: [], rules: [] };
|
|
291
|
-
var under = (cwd, path2) => path2 === "/" || cwd === path2 || cwd.startsWith(`${path2}/`);
|
|
292
|
-
function projectOf(session, state) {
|
|
293
|
-
const machine = session.machineId ?? "local";
|
|
294
|
-
const cwd = normalizePath(session.cwd);
|
|
295
|
-
const known = new Set(state.projects.map((p) => p.id));
|
|
296
|
-
const candidates = [
|
|
297
|
-
...state.projects.flatMap((p) => p.repos.filter((r) => r.machine === machine).map((r) => ({ project: p.id, path: r.path, rule: false }))),
|
|
298
|
-
...state.rules.filter((r) => r.machine === machine && known.has(r.project)).map((r) => ({ project: r.project, path: r.path, rule: true }))
|
|
299
|
-
].filter((c) => under(cwd, c.path));
|
|
300
|
-
candidates.sort((x, y) => y.path.length - x.path.length || Number(y.rule) - Number(x.rule));
|
|
301
|
-
return candidates[0]?.project ?? null;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// ../protocol/src/teams.ts
|
|
305
|
-
var RoleIdSchema = z7.string().regex(/^[a-z0-9][a-z0-9_-]{0,39}$/);
|
|
306
|
-
var ROLE_LABEL_MAX = 40;
|
|
307
|
-
var ROLE_PROMPT_MAX = 8e3;
|
|
308
|
-
var DefinitionHashSchema = z7.string().regex(/^[0-9a-f]{16}$/);
|
|
309
|
-
var RoleSchema = z7.object({
|
|
310
|
-
id: RoleIdSchema,
|
|
311
|
-
label: z7.string().min(1).max(ROLE_LABEL_MAX),
|
|
312
|
-
prompt: z7.string().max(ROLE_PROMPT_MAX),
|
|
313
|
-
tool: ToolSchema.optional(),
|
|
314
|
-
model: ModelIdSchema.optional(),
|
|
315
|
-
effort: EffortSchema.optional(),
|
|
316
|
-
autonomy: AutonomySchema.optional(),
|
|
317
|
-
source: z7.enum(["repo", "home"]),
|
|
318
|
-
path: z7.string(),
|
|
319
|
-
shadows: z7.string().optional(),
|
|
320
|
-
/** 16 hex chars of the file's text: what a write or delete must name as its base (absent from older daemons). */
|
|
321
|
-
hash: DefinitionHashSchema.optional()
|
|
322
|
-
});
|
|
323
|
-
var DefinitionProblemSchema = z7.object({ path: z7.string(), reason: z7.string() });
|
|
324
|
-
var TEAM_SEATS_MAX = 8;
|
|
325
|
-
var SeatSchema = z7.object({
|
|
326
|
-
role: RoleIdSchema,
|
|
327
|
-
tool: ToolSchema.optional(),
|
|
328
|
-
model: ModelIdSchema.optional(),
|
|
329
|
-
effort: EffortSchema.optional(),
|
|
330
|
-
name: z7.string().min(1).max(40).optional()
|
|
331
|
-
});
|
|
332
|
-
var uniqueRoles = (seats) => new Set(seats.map((s) => s.role)).size === seats.length;
|
|
333
|
-
var SeatsSchema = z7.array(SeatSchema).min(1).max(TEAM_SEATS_MAX).refine(uniqueRoles, "a role twice in one team");
|
|
334
|
-
var TeamNameSchema = z7.string().trim().min(1).max(60);
|
|
335
|
-
var TemplateIdSchema = z7.string().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/);
|
|
336
|
-
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() });
|
|
337
|
-
var TeamIdSchema = z7.string().regex(/^team-[0-9a-f]{4,8}$/);
|
|
338
|
-
var TeamStateSchema = z7.enum(["active", "resting", "dissolved"]);
|
|
339
|
-
var TeamSchema = z7.object({
|
|
340
|
-
id: TeamIdSchema,
|
|
341
|
-
name: TeamNameSchema,
|
|
342
|
-
template: z7.string().optional(),
|
|
343
|
-
project: z7.string().nullable(),
|
|
344
|
-
machine: z7.string(),
|
|
345
|
-
cwd: z7.string(),
|
|
346
|
-
state: TeamStateSchema,
|
|
347
|
-
/** A live seat: `tool`, `model` and `effort` are what it was composed with over the role's defaults, `name` the bot name it asks
|
|
348
|
-
* for (its template's or its composition's); `leaving` marks a seat removed from the composition that finishes its turn and then is closed. */
|
|
349
|
-
seats: z7.array(z7.object({
|
|
350
|
-
role: RoleIdSchema,
|
|
351
|
-
sessionId: z7.string().nullable(),
|
|
352
|
-
tool: ToolSchema.optional(),
|
|
353
|
-
model: ModelIdSchema.optional(),
|
|
354
|
-
effort: EffortSchema.optional(),
|
|
355
|
-
name: SeatSchema.shape.name,
|
|
356
|
-
leaving: z7.literal(true).optional()
|
|
357
|
-
})).max(TEAM_SEATS_MAX * 2),
|
|
358
|
-
createdAt: z7.string(),
|
|
359
|
-
updatedAt: z7.string(),
|
|
360
|
-
restingAt: z7.string().optional(),
|
|
361
|
-
dissolvedAt: z7.string().optional()
|
|
362
|
-
});
|
|
363
|
-
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() });
|
|
364
|
-
var RolesListingSchema = z7.object({
|
|
365
|
-
type: z7.literal("roles.listing"),
|
|
366
|
-
requestId: z7.string().optional(),
|
|
367
|
-
roles: z7.array(RoleSchema),
|
|
368
|
-
templates: z7.array(TeamTemplateSchema).default([]),
|
|
369
|
-
problems: z7.array(DefinitionProblemSchema),
|
|
370
|
-
/** Set by the fleet when the project's machine could not answer (#99): 'offline', or 'outdated' for a daemon without roles.list. */
|
|
371
|
-
error: z7.string().optional()
|
|
372
|
-
});
|
|
373
|
-
var TeamLaunchSchema = z7.object({
|
|
374
|
-
type: z7.literal("team.launch"),
|
|
375
|
-
rid: z7.string().min(1).max(100),
|
|
376
|
-
cwd: z7.string().min(1).optional(),
|
|
377
|
-
template: z7.string().min(1).max(64).optional(),
|
|
378
|
-
seats: SeatsSchema.optional(),
|
|
379
|
-
name: TeamNameSchema.optional(),
|
|
380
|
-
qid: z7.string().min(1).optional(),
|
|
381
|
-
machineId: z7.string().optional(),
|
|
382
|
-
/** The project's name, for a client that holds no path (the phone): the daemon resolves its folder. */
|
|
383
|
-
project: ProjectIdSchema.optional()
|
|
384
|
-
});
|
|
385
|
-
var TeamJoinSchema = z7.object({ type: z7.literal("team.join"), team: TeamIdSchema, session: z7.string().min(1), role: RoleIdSchema });
|
|
386
|
-
var TeamLeaveSchema = z7.object({ type: z7.literal("team.leave"), team: TeamIdSchema, session: z7.string().min(1) });
|
|
387
|
-
var TeamResumeSchema = z7.object({ type: z7.literal("team.resume"), team: TeamIdSchema });
|
|
388
|
-
var TeamDissolveSchema = z7.object({ type: z7.literal("team.dissolve"), team: TeamIdSchema });
|
|
389
|
-
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(), base: DefinitionHashSchema.optional() });
|
|
390
|
-
var DefinitionScopeSchema = z7.enum(["home", "repo"]);
|
|
391
|
-
var RoleDraftSchema = RoleSchema.pick({ id: true, label: true, prompt: true, tool: true, model: true, effort: true, autonomy: true });
|
|
392
|
-
var DefinitionCodeSchema = z7.enum(["changed", "exists", "missing", "unknown_project", "invalid"]);
|
|
393
|
-
var scopeFields = { rid: z7.string().min(1).max(100), scope: DefinitionScopeSchema, project: ProjectIdSchema.optional() };
|
|
394
|
-
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";
|
|
395
|
-
var DefinitionBaseSchema = DefinitionHashSchema;
|
|
396
|
-
var DefinitionsListSchema = z7.object({ type: z7.literal("definitions.list"), requestId: z7.string().max(100).optional() });
|
|
397
|
-
var RoleWriteSchema = z7.object({ type: z7.literal("role.write"), ...scopeFields, role: RoleDraftSchema, base: DefinitionBaseSchema.nullable() });
|
|
398
|
-
var RoleDeleteSchema = z7.object({ type: z7.literal("role.delete"), ...scopeFields, id: RoleIdSchema, base: DefinitionBaseSchema });
|
|
399
|
-
var TemplateWriteSchema = z7.object({
|
|
400
|
-
type: z7.literal("template.write"),
|
|
401
|
-
...scopeFields,
|
|
402
|
-
id: TemplateIdSchema.optional(),
|
|
403
|
-
name: TeamNameSchema,
|
|
404
|
-
seats: SeatsSchema,
|
|
405
|
-
base: DefinitionBaseSchema.nullable()
|
|
406
|
-
});
|
|
407
|
-
var TemplateDeleteSchema = z7.object({ type: z7.literal("template.delete"), ...scopeFields, id: TemplateIdSchema, base: DefinitionBaseSchema });
|
|
408
|
-
var TeamComposeSchema = z7.object({ type: z7.literal("team.compose"), rid: z7.string().min(1).max(100), team: TeamIdSchema, seats: SeatsSchema });
|
|
409
|
-
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"]) });
|
|
410
|
-
var DefinitionsListingSchema = z7.object({
|
|
411
|
-
type: z7.literal("definitions.listing"),
|
|
412
|
-
requestId: z7.string().optional(),
|
|
413
|
-
scopes: z7.array(z7.object({
|
|
414
|
-
scope: DefinitionScopeSchema,
|
|
415
|
-
project: z7.string().nullable(),
|
|
416
|
-
roles: z7.array(RoleSchema),
|
|
417
|
-
templates: z7.array(TeamTemplateSchema),
|
|
418
|
-
problems: z7.array(DefinitionProblemSchema)
|
|
419
|
-
}))
|
|
420
|
-
});
|
|
421
|
-
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() });
|
|
422
|
-
var SeatModelOutcomeSchema = z7.object({ role: z7.string(), session: z7.string(), when: z7.enum(["now", "turn"]).optional(), code: ModelRefusalSchema.optional() });
|
|
423
|
-
var TeamChangedSchema = z7.object({ type: z7.literal("team.changed"), rid: z7.string(), team: TeamSchema.optional(), reason: z7.string().optional(), models: z7.array(SeatModelOutcomeSchema).max(16).optional() });
|
|
424
|
-
var TeamsMessageSchema = z7.object({ type: z7.literal("teams"), teams: z7.array(TeamSchema) });
|
|
425
|
-
var TeamUpdatedSchema = z7.object({ type: z7.literal("team.updated"), team: TeamSchema });
|
|
426
|
-
var TeamLaunchedSchema = z7.object({ type: z7.literal("team.launched"), rid: z7.string(), team: TeamSchema });
|
|
427
|
-
var TeamFailedSchema = z7.object({ type: z7.literal("team.failed"), rid: z7.string(), reason: z7.string(), team: TeamSchema.optional() });
|
|
428
|
-
var TeamSavedSchema = z7.object({ type: z7.literal("team.saved"), rid: z7.string(), path: z7.string().optional(), reason: z7.string().optional(), code: z7.enum(["exists", "changed"]).optional() });
|
|
429
|
-
var isTeamLive = (t) => t.state !== "dissolved";
|
|
430
|
-
|
|
431
159
|
// ../protocol/src/tasks.ts
|
|
432
|
-
import { z as
|
|
160
|
+
import { z as z3 } from "zod";
|
|
433
161
|
var TASK_TITLE_MAX = 200;
|
|
434
162
|
var TASK_TEXT_MAX = 2e4;
|
|
435
163
|
var LEDGE_GIVER = "ledge";
|
|
436
164
|
var TASK_OPS = ["give", "take", "pass", "done", "refuse", "cancel", "drop"];
|
|
437
165
|
var TRANSMISSION_OPS = ["give", "pass", "done", "refuse", "cancel"];
|
|
438
|
-
var TaskLogEntrySchema =
|
|
439
|
-
at:
|
|
440
|
-
by:
|
|
441
|
-
what:
|
|
442
|
-
op:
|
|
443
|
-
from:
|
|
444
|
-
to:
|
|
445
|
-
fromName:
|
|
446
|
-
toName:
|
|
447
|
-
note:
|
|
448
|
-
});
|
|
449
|
-
var TaskSchema =
|
|
450
|
-
id:
|
|
451
|
-
title:
|
|
452
|
-
text:
|
|
453
|
-
giver:
|
|
454
|
-
giverName:
|
|
455
|
-
owner:
|
|
456
|
-
ownerName:
|
|
457
|
-
state:
|
|
458
|
-
result:
|
|
459
|
-
/** The live team its owner sat in when it was given (or passed), so a team's tasks can be listed. */
|
|
460
|
-
team: z8.string().optional(),
|
|
166
|
+
var TaskLogEntrySchema = z3.object({
|
|
167
|
+
at: z3.string(),
|
|
168
|
+
by: z3.string(),
|
|
169
|
+
what: z3.string(),
|
|
170
|
+
op: z3.enum(TASK_OPS).optional(),
|
|
171
|
+
from: z3.string().optional(),
|
|
172
|
+
to: z3.string().optional(),
|
|
173
|
+
fromName: z3.string().optional(),
|
|
174
|
+
toName: z3.string().optional(),
|
|
175
|
+
note: z3.string().optional()
|
|
176
|
+
});
|
|
177
|
+
var TaskSchema = z3.object({
|
|
178
|
+
id: z3.string(),
|
|
179
|
+
title: z3.string(),
|
|
180
|
+
text: z3.string().optional(),
|
|
181
|
+
giver: z3.string(),
|
|
182
|
+
giverName: z3.string(),
|
|
183
|
+
owner: z3.string(),
|
|
184
|
+
ownerName: z3.string(),
|
|
185
|
+
state: z3.enum(["open", "taken", "done", "refused", "dropped"]),
|
|
186
|
+
result: z3.string().optional(),
|
|
461
187
|
/** A task Ledge gave and the user put away from « À toi » once closed. */
|
|
462
|
-
seen:
|
|
463
|
-
at:
|
|
464
|
-
updatedAt:
|
|
465
|
-
log:
|
|
188
|
+
seen: z3.boolean().optional(),
|
|
189
|
+
at: z3.string(),
|
|
190
|
+
updatedAt: z3.string(),
|
|
191
|
+
log: z3.array(TaskLogEntrySchema)
|
|
466
192
|
});
|
|
467
193
|
var handOver = (op) => TRANSMISSION_OPS.includes(op ?? "");
|
|
468
194
|
function transmissions(t) {
|
|
@@ -471,56 +197,48 @@ function transmissions(t) {
|
|
|
471
197
|
var givenByLedge = (t) => t.giver === LEDGE_GIVER;
|
|
472
198
|
var taskClosed = (t) => t.state === "done" || t.state === "refused" || t.state === "dropped";
|
|
473
199
|
var openDecision = (t) => t.owner === LEDGE_GIVER && !taskClosed(t);
|
|
474
|
-
var TaskCmdSchema =
|
|
475
|
-
type:
|
|
476
|
-
rid:
|
|
477
|
-
by:
|
|
478
|
-
op:
|
|
479
|
-
task:
|
|
480
|
-
to:
|
|
481
|
-
title:
|
|
482
|
-
text:
|
|
483
|
-
all:
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
});
|
|
488
|
-
var
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
rid: z8.string(),
|
|
200
|
+
var TaskCmdSchema = z3.object({
|
|
201
|
+
type: z3.literal("task.cmd"),
|
|
202
|
+
rid: z3.string().min(1),
|
|
203
|
+
by: z3.string().min(1),
|
|
204
|
+
op: z3.enum(["give", "take", "done", "refuse", "pass", "show", "list", "seen", "cancel"]),
|
|
205
|
+
task: z3.string().min(1).max(40).optional(),
|
|
206
|
+
to: z3.string().min(1).optional(),
|
|
207
|
+
title: z3.string().min(1).max(TASK_TITLE_MAX).optional(),
|
|
208
|
+
text: z3.string().max(TASK_TEXT_MAX).optional(),
|
|
209
|
+
all: z3.boolean().optional(),
|
|
210
|
+
qid: z3.string().min(1).optional(),
|
|
211
|
+
row: z3.number().int().min(0).max(7).optional()
|
|
212
|
+
});
|
|
213
|
+
var TaskUpdatedSchema = z3.object({ type: z3.literal("task.updated"), task: TaskSchema });
|
|
214
|
+
var TaskResultSchema = z3.object({
|
|
215
|
+
type: z3.literal("task.result"),
|
|
216
|
+
rid: z3.string(),
|
|
492
217
|
task: TaskSchema.optional(),
|
|
493
|
-
tasks:
|
|
494
|
-
reason:
|
|
218
|
+
tasks: z3.array(TaskSchema).optional(),
|
|
219
|
+
reason: z3.string().optional()
|
|
495
220
|
});
|
|
496
221
|
|
|
497
222
|
// ../protocol/src/actions.ts
|
|
498
|
-
import { z as
|
|
223
|
+
import { z as z7 } from "zod";
|
|
499
224
|
|
|
500
225
|
// ../protocol/src/proposal.ts
|
|
501
|
-
import { z as
|
|
502
|
-
var ProposalBlockSchema =
|
|
503
|
-
var RelayBlockSchema =
|
|
504
|
-
var ProjectBlockSchema =
|
|
505
|
-
name:
|
|
506
|
-
description:
|
|
507
|
-
repos:
|
|
508
|
-
addTo:
|
|
509
|
-
});
|
|
510
|
-
var CloseBlockSchema =
|
|
511
|
-
var
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
var TaskBlockSchema = z9.object({
|
|
518
|
-
to: z9.string().trim().min(1).max(80),
|
|
519
|
-
team: z9.string().trim().max(40).optional(),
|
|
520
|
-
title: z9.string().trim().min(1).max(200),
|
|
521
|
-
text: z9.string().max(2e4).optional()
|
|
522
|
-
});
|
|
523
|
-
var BLOCK = /```ledge-(session|relay|project|close|team|task|action)[ \t]*\n?([\s\S]*?)(?:```|$)/g;
|
|
226
|
+
import { z as z4 } from "zod";
|
|
227
|
+
var ProposalBlockSchema = z4.object({ cwd: z4.string().trim().min(1), prompt: z4.string().optional() });
|
|
228
|
+
var RelayBlockSchema = z4.object({ session: z4.string().trim().min(1), text: z4.string().trim().min(1) });
|
|
229
|
+
var ProjectBlockSchema = z4.object({
|
|
230
|
+
name: z4.string().trim().min(1).max(80),
|
|
231
|
+
description: z4.string().max(500).optional(),
|
|
232
|
+
repos: z4.array(z4.object({ path: z4.string().min(1).max(4096), why: z4.string().trim().min(1).max(200) })).min(1).max(50),
|
|
233
|
+
addTo: z4.string().trim().max(80).optional()
|
|
234
|
+
});
|
|
235
|
+
var CloseBlockSchema = z4.object({ session: z4.string().trim().min(1) });
|
|
236
|
+
var TaskBlockSchema = z4.object({
|
|
237
|
+
to: z4.string().trim().min(1).max(80),
|
|
238
|
+
title: z4.string().trim().min(1).max(200),
|
|
239
|
+
text: z4.string().max(2e4).optional()
|
|
240
|
+
});
|
|
241
|
+
var BLOCK = /```ledge-(session|relay|project|close|task|action)[ \t]*\n?([\s\S]*?)(?:```|$)/g;
|
|
524
242
|
function extractProposal(answer) {
|
|
525
243
|
const found = [];
|
|
526
244
|
const text2 = answer.replace(BLOCK, (_m, kind, body) => {
|
|
@@ -546,14 +264,6 @@ function parseCloseBlock(raw) {
|
|
|
546
264
|
return null;
|
|
547
265
|
}
|
|
548
266
|
}
|
|
549
|
-
function parseTeamBlock(raw) {
|
|
550
|
-
try {
|
|
551
|
-
const r = TeamBlockSchema.safeParse(JSON.parse(raw));
|
|
552
|
-
return r.success ? r.data : null;
|
|
553
|
-
} catch {
|
|
554
|
-
return null;
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
267
|
function parseTaskBlock(raw) {
|
|
558
268
|
try {
|
|
559
269
|
const r = TaskBlockSchema.safeParse(JSON.parse(raw));
|
|
@@ -571,9 +281,37 @@ function parseProjectBlock(raw) {
|
|
|
571
281
|
}
|
|
572
282
|
}
|
|
573
283
|
|
|
284
|
+
// ../protocol/src/models.ts
|
|
285
|
+
import { z as z5 } from "zod";
|
|
286
|
+
var ModelIdSchema = z5.string().min(1).max(200).regex(/^[A-Za-z0-9][A-Za-z0-9._:/@[\]=,+-]*$/, "not a model id");
|
|
287
|
+
var EffortSchema = z5.string().min(1).max(20).regex(/^[a-z]+$/, "not an effort");
|
|
288
|
+
var ModelChoiceSchema = z5.object({
|
|
289
|
+
id: ModelIdSchema,
|
|
290
|
+
label: z5.string(),
|
|
291
|
+
description: z5.string().optional(),
|
|
292
|
+
efforts: z5.array(EffortSchema).optional(),
|
|
293
|
+
defaultEffort: EffortSchema.optional(),
|
|
294
|
+
isDefault: z5.boolean().optional()
|
|
295
|
+
});
|
|
296
|
+
var ModelsListSchema = z5.object({
|
|
297
|
+
type: z5.literal("models.list"),
|
|
298
|
+
requestId: z5.string().min(1).max(100),
|
|
299
|
+
tool: ToolSchema,
|
|
300
|
+
machineId: z5.string().optional()
|
|
301
|
+
});
|
|
302
|
+
var ModelsListingSchema = z5.object({
|
|
303
|
+
type: z5.literal("models.listing"),
|
|
304
|
+
requestId: z5.string(),
|
|
305
|
+
tool: ToolSchema,
|
|
306
|
+
models: z5.array(ModelChoiceSchema),
|
|
307
|
+
error: z5.string().optional()
|
|
308
|
+
});
|
|
309
|
+
var ModelRefusalSchema = z5.enum(["not_launched", "ended", "no_conversation", "not_running", "effort_in_model", "restart_failed", "refused"]);
|
|
310
|
+
var SessionModelAcceptedSchema = z5.object({ type: z5.literal("session.model.accepted"), id: z5.string(), when: z5.enum(["now", "turn", "none"]) });
|
|
311
|
+
|
|
574
312
|
// ../protocol/src/decisions.ts
|
|
575
|
-
import { z as
|
|
576
|
-
var DecisionSchema =
|
|
313
|
+
import { z as z6 } from "zod";
|
|
314
|
+
var DecisionSchema = z6.enum(["accept", "deny", "always"]);
|
|
577
315
|
var NOTE_MAX = 4e3;
|
|
578
316
|
var NOTE_NOT_TYPED = "note_not_typed";
|
|
579
317
|
var DECISION_OFFERS = {
|
|
@@ -603,13 +341,12 @@ function pendingKey(p) {
|
|
|
603
341
|
}
|
|
604
342
|
|
|
605
343
|
// ../protocol/src/actions.ts
|
|
606
|
-
var ActionRiskSchema =
|
|
344
|
+
var ActionRiskSchema = z7.enum(["read", "reversible", "destructive"]);
|
|
607
345
|
var ACTION_IDS = [
|
|
608
346
|
"session.launch",
|
|
609
347
|
"session.relay",
|
|
610
348
|
"session.close",
|
|
611
349
|
"project.propose",
|
|
612
|
-
"team.launch",
|
|
613
350
|
"task.give",
|
|
614
351
|
"session.model",
|
|
615
352
|
"session.interrupt",
|
|
@@ -617,20 +354,14 @@ var ACTION_IDS = [
|
|
|
617
354
|
"session.restore",
|
|
618
355
|
"session.resume",
|
|
619
356
|
"session.decide",
|
|
620
|
-
"team.join",
|
|
621
|
-
"team.leave",
|
|
622
|
-
"team.resume",
|
|
623
|
-
"team.dissolve",
|
|
624
|
-
"team.save",
|
|
625
357
|
"task.cancel",
|
|
626
358
|
"task.pass",
|
|
627
359
|
"task.answer"
|
|
628
360
|
];
|
|
629
|
-
var ActionIdSchema =
|
|
361
|
+
var ActionIdSchema = z7.enum(ACTION_IDS);
|
|
630
362
|
var def = (d) => d;
|
|
631
|
-
var SessionRef =
|
|
632
|
-
var
|
|
633
|
-
var TaskRef = z11.string().trim().min(1).max(40);
|
|
363
|
+
var SessionRef = z7.string().trim().min(1).max(80);
|
|
364
|
+
var TaskRef = z7.string().trim().min(1).max(40);
|
|
634
365
|
var LaunchArgs = ProposalBlockSchema.extend({ model: ModelIdSchema.optional(), effort: EffortSchema.optional() });
|
|
635
366
|
var ACTIONS = [
|
|
636
367
|
def({
|
|
@@ -678,18 +409,6 @@ var ACTIONS = [
|
|
|
678
409
|
when: "seulement si l'utilisateur demande explicitement de cr\xE9er ou de compl\xE9ter un projet : lis projects.md, ne cite que des chemins absolus lus dans sessions.md, folders.md ou projects.md, jamais un d\xE9p\xF4t qui appartient d\xE9j\xE0 \xE0 un projet ; ta r\xE9ponse dit le nom, chaque d\xE9p\xF4t et pourquoi",
|
|
679
410
|
example: { name: "Facturation", description: "Le service et son front", repos: [{ path: "/home/alice/projets/billing-api", why: "le service" }] }
|
|
680
411
|
}),
|
|
681
|
-
def({
|
|
682
|
-
id: "team.launch",
|
|
683
|
-
args: TeamBlockSchema,
|
|
684
|
-
card: "team",
|
|
685
|
-
phone: "launch",
|
|
686
|
-
risk: "reversible",
|
|
687
|
-
max: 1,
|
|
688
|
-
cli: "ledge team up <mod\xE8le> --cwd <dossier>",
|
|
689
|
-
summary: "monter une \xE9quipe dans un dossier : un mod\xE8le de teams.md (template), ou des si\xE8ges (r\xF4le de roles.md, agent, et si demand\xE9 model, effort)",
|
|
690
|
-
when: "quand l'utilisateur demande explicitement de monter, lancer ou composer une \xE9quipe, avec la m\xEAme r\xE8gle de dossier s\xFBr qu'une session ; 8 si\xE8ges au plus, un r\xF4le une seule fois, seulement des r\xF4les de roles.md disponibles dans ce dossier (s'il en manque un, dis lequel et le fichier \xE0 \xE9crire, ~/.ledge/roles/<id>.md). Ne choisis jamais l'autonomie : c'est celle du r\xF4le",
|
|
691
|
-
example: { cwd: "/home/alice/projets/api", name: "api", seats: [{ role: "dev-back", tool: "claude" }, { role: "rev-back", tool: "codex" }] }
|
|
692
|
-
}),
|
|
693
412
|
def({
|
|
694
413
|
id: "task.give",
|
|
695
414
|
args: TaskBlockSchema,
|
|
@@ -697,10 +416,10 @@ var ACTIONS = [
|
|
|
697
416
|
phone: null,
|
|
698
417
|
risk: "reversible",
|
|
699
418
|
max: 8,
|
|
700
|
-
cli: 'ledge task give <session
|
|
701
|
-
summary: "confier une t\xE2che \xE0 une session
|
|
702
|
-
when: "quand l'utilisateur demande explicitement de confier une t\xE2che
|
|
703
|
-
example: { to: "
|
|
419
|
+
cli: 'ledge task give <session> "<titre>" "<d\xE9tail>"',
|
|
420
|
+
summary: "confier une t\xE2che \xE0 une session (son id ou son nom, tels que sessions.md les donne)",
|
|
421
|
+
when: "quand l'utilisateur demande explicitement de confier une t\xE2che \xE0 une session ; ne propose rien pour ce que les sessions se confient entre elles",
|
|
422
|
+
example: { to: "Nova", title: "Pagination de /invoices", text: "Ajoute la pagination par curseur et ses tests" }
|
|
704
423
|
}),
|
|
705
424
|
def({
|
|
706
425
|
id: "session.model",
|
|
@@ -708,14 +427,14 @@ var ACTIONS = [
|
|
|
708
427
|
phone: null,
|
|
709
428
|
risk: "reversible",
|
|
710
429
|
max: 8,
|
|
711
|
-
args:
|
|
430
|
+
args: z7.object({ session: SessionRef, model: ModelIdSchema.nullable(), effort: EffortSchema.nullable() }),
|
|
712
431
|
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",
|
|
713
432
|
when: "quand l'utilisateur demande de passer une session sur un autre mod\xE8le ou un autre effort",
|
|
714
433
|
example: { session: "Nova", model: "claude-opus-5-5", effort: "high" }
|
|
715
434
|
}),
|
|
716
435
|
def({
|
|
717
436
|
id: "session.interrupt",
|
|
718
|
-
args:
|
|
437
|
+
args: z7.object({ session: SessionRef }),
|
|
719
438
|
card: "generic",
|
|
720
439
|
phone: null,
|
|
721
440
|
risk: "reversible",
|
|
@@ -726,7 +445,7 @@ var ACTIONS = [
|
|
|
726
445
|
}),
|
|
727
446
|
def({
|
|
728
447
|
id: "session.archive",
|
|
729
|
-
args:
|
|
448
|
+
args: z7.object({ session: SessionRef }),
|
|
730
449
|
card: "generic",
|
|
731
450
|
phone: null,
|
|
732
451
|
risk: "reversible",
|
|
@@ -737,7 +456,7 @@ var ACTIONS = [
|
|
|
737
456
|
}),
|
|
738
457
|
def({
|
|
739
458
|
id: "session.restore",
|
|
740
|
-
args:
|
|
459
|
+
args: z7.object({ session: SessionRef }),
|
|
741
460
|
card: "generic",
|
|
742
461
|
phone: null,
|
|
743
462
|
risk: "reversible",
|
|
@@ -748,7 +467,7 @@ var ACTIONS = [
|
|
|
748
467
|
}),
|
|
749
468
|
def({
|
|
750
469
|
id: "session.resume",
|
|
751
|
-
args:
|
|
470
|
+
args: z7.object({ session: SessionRef }),
|
|
752
471
|
card: "generic",
|
|
753
472
|
phone: "act",
|
|
754
473
|
risk: "reversible",
|
|
@@ -762,71 +481,15 @@ var ACTIONS = [
|
|
|
762
481
|
card: "generic",
|
|
763
482
|
phone: "act",
|
|
764
483
|
max: 1,
|
|
765
|
-
args:
|
|
484
|
+
args: z7.object({ session: SessionRef, decision: z7.enum(["accept", "deny"]), note: z7.string().trim().min(1).max(NOTE_MAX).optional() }),
|
|
766
485
|
risk: (a) => a.decision === "accept" ? "destructive" : "reversible",
|
|
767
486
|
summary: "accepter ou refuser la demande en attente d'une session (permission, diff ou plan), note possible avec un refus ; jamais \xAB toujours \xBB",
|
|
768
487
|
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",
|
|
769
488
|
example: { session: "Nova", decision: "deny", note: "Pas sur main : cr\xE9e une branche" }
|
|
770
489
|
}),
|
|
771
|
-
def({
|
|
772
|
-
id: "team.join",
|
|
773
|
-
args: z11.object({ team: TeamRef, session: SessionRef, role: RoleIdSchema }),
|
|
774
|
-
card: "generic",
|
|
775
|
-
phone: null,
|
|
776
|
-
risk: "reversible",
|
|
777
|
-
max: 8,
|
|
778
|
-
summary: "faire entrer une session dans une \xE9quipe en cours, \xE0 un r\xF4le de roles.md",
|
|
779
|
-
when: "quand l'utilisateur demande d'ajouter une session existante \xE0 une \xE9quipe",
|
|
780
|
-
example: { team: "team-3fa2", session: "Nova", role: "dev-back" }
|
|
781
|
-
}),
|
|
782
|
-
def({
|
|
783
|
-
id: "team.leave",
|
|
784
|
-
args: z11.object({ team: TeamRef, session: SessionRef }),
|
|
785
|
-
card: "generic",
|
|
786
|
-
phone: null,
|
|
787
|
-
risk: "reversible",
|
|
788
|
-
max: 8,
|
|
789
|
-
summary: "faire sortir une session d'une \xE9quipe (la session continue)",
|
|
790
|
-
when: "quand l'utilisateur demande de retirer une session d'une \xE9quipe",
|
|
791
|
-
example: { team: "team-3fa2", session: "Nova" }
|
|
792
|
-
}),
|
|
793
|
-
def({
|
|
794
|
-
id: "team.resume",
|
|
795
|
-
args: z11.object({ team: TeamRef }),
|
|
796
|
-
card: "generic",
|
|
797
|
-
phone: "act",
|
|
798
|
-
risk: "reversible",
|
|
799
|
-
max: 1,
|
|
800
|
-
summary: "reprendre une \xE9quipe au repos : chaque si\xE8ge reprend sa conversation",
|
|
801
|
-
when: "quand l'utilisateur demande de reprendre ou relancer une \xE9quipe au repos",
|
|
802
|
-
example: { team: "team-3fa2" }
|
|
803
|
-
}),
|
|
804
|
-
def({
|
|
805
|
-
id: "team.dissolve",
|
|
806
|
-
args: z11.object({ team: TeamRef }),
|
|
807
|
-
card: "generic",
|
|
808
|
-
phone: "act",
|
|
809
|
-
risk: "destructive",
|
|
810
|
-
max: 8,
|
|
811
|
-
cli: "ledge team dissolve <\xE9quipe>",
|
|
812
|
-
summary: "dissoudre une \xE9quipe : elle dispara\xEEt, ses sessions restent ; irr\xE9versible",
|
|
813
|
-
when: "seulement quand l'utilisateur demande explicitement de dissoudre une \xE9quipe pr\xE9cise",
|
|
814
|
-
example: { team: "team-3fa2" }
|
|
815
|
-
}),
|
|
816
|
-
def({
|
|
817
|
-
id: "team.save",
|
|
818
|
-
args: z11.object({ team: TeamRef, name: TeamNameSchema }),
|
|
819
|
-
card: "generic",
|
|
820
|
-
phone: null,
|
|
821
|
-
risk: "reversible",
|
|
822
|
-
max: 1,
|
|
823
|
-
summary: "enregistrer une \xE9quipe en cours comme mod\xE8le (~/.ledge/teams/<nom>.yaml)",
|
|
824
|
-
when: "quand l'utilisateur demande d'enregistrer ou de garder la composition d'une \xE9quipe",
|
|
825
|
-
example: { team: "team-3fa2", name: "api" }
|
|
826
|
-
}),
|
|
827
490
|
def({
|
|
828
491
|
id: "task.cancel",
|
|
829
|
-
args:
|
|
492
|
+
args: z7.object({ task: TaskRef, reason: z7.string().trim().min(1).max(500).optional() }),
|
|
830
493
|
card: "generic",
|
|
831
494
|
phone: "act",
|
|
832
495
|
risk: "destructive",
|
|
@@ -837,7 +500,7 @@ var ACTIONS = [
|
|
|
837
500
|
}),
|
|
838
501
|
def({
|
|
839
502
|
id: "task.pass",
|
|
840
|
-
args:
|
|
503
|
+
args: z7.object({ task: TaskRef, to: SessionRef, note: z7.string().trim().min(1).max(TASK_TEXT_MAX).optional() }),
|
|
841
504
|
card: "generic",
|
|
842
505
|
phone: null,
|
|
843
506
|
risk: "reversible",
|
|
@@ -848,7 +511,7 @@ var ACTIONS = [
|
|
|
848
511
|
}),
|
|
849
512
|
def({
|
|
850
513
|
id: "task.answer",
|
|
851
|
-
args:
|
|
514
|
+
args: z7.object({ task: TaskRef, answer: z7.string().trim().min(1).max(TASK_TEXT_MAX) }),
|
|
852
515
|
card: "generic",
|
|
853
516
|
phone: "act",
|
|
854
517
|
risk: "destructive",
|
|
@@ -861,13 +524,12 @@ var ACTIONS = [
|
|
|
861
524
|
var byId = new Map(ACTIONS.map((a) => [a.id, a]));
|
|
862
525
|
var actionById = (id) => byId.get(id);
|
|
863
526
|
var riskOf = (a, args) => typeof a.risk === "function" ? a.risk(args) : a.risk;
|
|
864
|
-
var ActionBlockSchema =
|
|
527
|
+
var ActionBlockSchema = z7.object({ action: z7.string().trim().min(1).max(40), args: z7.record(z7.unknown()).default({}) });
|
|
865
528
|
var LEGACY_FENCE_ACTION = {
|
|
866
529
|
session: "session.launch",
|
|
867
530
|
relay: "session.relay",
|
|
868
531
|
close: "session.close",
|
|
869
532
|
project: "project.propose",
|
|
870
|
-
team: "team.launch",
|
|
871
533
|
task: "task.give"
|
|
872
534
|
};
|
|
873
535
|
function parseActionBlock(kind, raw) {
|
|
@@ -903,126 +565,345 @@ var NEVER_PROPOSED = [
|
|
|
903
565
|
"r\xE9pondre \xAB toujours \xBB \xE0 une demande, ou r\xE9pondre aux questions \xE0 choix d'OMP"
|
|
904
566
|
];
|
|
905
567
|
|
|
568
|
+
// ../protocol/src/openrig.ts
|
|
569
|
+
import { z as z8 } from "zod";
|
|
570
|
+
var RigNameSchema = z8.string().min(1).max(100).regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/, "not a rig name");
|
|
571
|
+
var RigSeatNameSchema = z8.string().min(3).max(200).regex(/^[A-Za-z0-9][A-Za-z0-9._-]*@[A-Za-z0-9][A-Za-z0-9._-]*$/, "not a seat");
|
|
572
|
+
var SeatPermissionsSchema = z8.enum(["inherit", "floor", "auto", "full_bypass"]);
|
|
573
|
+
var KERNEL_RIG = "kernel";
|
|
574
|
+
var RigSeatSchema = z8.object({
|
|
575
|
+
logicalId: z8.string(),
|
|
576
|
+
session: z8.string(),
|
|
577
|
+
runtime: z8.string(),
|
|
578
|
+
model: z8.string().nullable(),
|
|
579
|
+
sessionStatus: z8.string(),
|
|
580
|
+
lifecycleState: z8.string(),
|
|
581
|
+
activity: z8.string(),
|
|
582
|
+
stopped: z8.boolean(),
|
|
583
|
+
work: z8.number().int().min(0)
|
|
584
|
+
});
|
|
585
|
+
var RigSchema = z8.object({
|
|
586
|
+
id: z8.string(),
|
|
587
|
+
name: z8.string(),
|
|
588
|
+
status: z8.string(),
|
|
589
|
+
lifecycleState: z8.string(),
|
|
590
|
+
seats: z8.number().int().min(0),
|
|
591
|
+
running: z8.number().int().min(0),
|
|
592
|
+
attention: z8.number().int().min(0),
|
|
593
|
+
uptime: z8.string().nullable(),
|
|
594
|
+
snapshot: z8.string().nullable(),
|
|
595
|
+
nodes: z8.array(RigSeatSchema)
|
|
596
|
+
});
|
|
597
|
+
var RigDaemonStateSchema = z8.enum(["running", "stopped", "stale", "unknown"]);
|
|
598
|
+
var RigKernelStateSchema = z8.enum(["ready", "starting", "stopped", "skipped", "absent", "unknown"]);
|
|
599
|
+
var OpenRigStateSchema = z8.object({
|
|
600
|
+
installed: z8.boolean(),
|
|
601
|
+
version: z8.string().optional(),
|
|
602
|
+
daemon: z8.object({ state: RigDaemonStateSchema, pid: z8.number().int().optional(), port: z8.number().int().optional(), message: z8.string().optional() }),
|
|
603
|
+
kernel: z8.object({ state: RigKernelStateSchema }),
|
|
604
|
+
rigs: z8.array(RigSchema),
|
|
605
|
+
/** When it was read (ISO). */
|
|
606
|
+
at: z8.string()
|
|
607
|
+
});
|
|
608
|
+
var OpenRigActionSchema = z8.discriminatedUnion("kind", [
|
|
609
|
+
/** `restore` `last`: `rig start --last` (the rigs that were running come back); `none`: `rig daemon start`. */
|
|
610
|
+
z8.object({ kind: z8.literal("daemon.start"), restore: z8.enum(["last", "none"]).optional(), noKernel: z8.boolean().optional() }),
|
|
611
|
+
z8.object({ kind: z8.literal("daemon.stop") }),
|
|
612
|
+
z8.object({ kind: z8.literal("daemon.restart"), restore: z8.enum(["last", "none"]).optional() }),
|
|
613
|
+
z8.object({ kind: z8.literal("kernel.start") }),
|
|
614
|
+
z8.object({ kind: z8.literal("kernel.stop") }),
|
|
615
|
+
z8.object({ kind: z8.literal("kernel.restart") }),
|
|
616
|
+
z8.object({ kind: z8.literal("rig.start"), rig: RigNameSchema }),
|
|
617
|
+
z8.object({ kind: z8.literal("rig.stop"), rig: RigNameSchema, snapshot: z8.boolean().optional(), force: z8.boolean().optional(), delete: z8.boolean().optional() }),
|
|
618
|
+
z8.object({ kind: z8.literal("rig.restart"), rig: RigNameSchema }),
|
|
619
|
+
/** A seat's settings (docs/mockups/ledge-openrig-groups.html, view 2). `runtime`: moves it now to the other harness (a successor
|
|
620
|
+
* takes its context, `rig seat set-runtime`), `model` and `effort` going with it; without it, `model`, `effort` and `permissions`
|
|
621
|
+
* apply at its next resume. `dryRun`: the move's plan only. */
|
|
622
|
+
z8.object({
|
|
623
|
+
kind: z8.literal("seat.set"),
|
|
624
|
+
seat: RigSeatNameSchema,
|
|
625
|
+
runtime: z8.enum(["claude-code", "codex"]).optional(),
|
|
626
|
+
model: ModelIdSchema.optional(),
|
|
627
|
+
effort: EffortSchema.optional(),
|
|
628
|
+
permissions: SeatPermissionsSchema.optional(),
|
|
629
|
+
dryRun: z8.boolean().optional()
|
|
630
|
+
})
|
|
631
|
+
]);
|
|
632
|
+
var OpenRigStatusSchema = z8.object({ type: z8.literal("openrig.status"), requestId: z8.string().min(1).max(100), machineId: z8.string().optional() });
|
|
633
|
+
var OpenRigActSchema = z8.object({ type: z8.literal("openrig.act"), requestId: z8.string().min(1).max(100), action: OpenRigActionSchema, machineId: z8.string().optional() });
|
|
634
|
+
var OpenRigUnreachableSchema = z8.enum(["offline", "outdated"]);
|
|
635
|
+
var OpenRigStateMessageSchema = z8.object({
|
|
636
|
+
type: z8.literal("openrig.state"),
|
|
637
|
+
requestId: z8.string().optional(),
|
|
638
|
+
machineId: z8.string().optional(),
|
|
639
|
+
state: OpenRigStateSchema.optional(),
|
|
640
|
+
error: OpenRigUnreachableSchema.optional()
|
|
641
|
+
});
|
|
642
|
+
var OpenRigDoneSchema = z8.object({
|
|
643
|
+
type: z8.literal("openrig.done"),
|
|
644
|
+
requestId: z8.string(),
|
|
645
|
+
machineId: z8.string().optional(),
|
|
646
|
+
ok: z8.boolean(),
|
|
647
|
+
commands: z8.array(z8.string()),
|
|
648
|
+
output: z8.string().optional(),
|
|
649
|
+
error: z8.string().optional()
|
|
650
|
+
});
|
|
651
|
+
function rigCommands(a) {
|
|
652
|
+
const start = (restore, noKernel) => restore === "last" ? ["start", "--last", "--json"] : ["daemon", "start", ...noKernel ? ["--no-kernel"] : []];
|
|
653
|
+
const up = (rig) => ["up", rig, "--existing", "--yes", "--json"];
|
|
654
|
+
const down = (rig, o = {}) => ["down", rig, ...o.snapshot ? ["--snapshot"] : [], ...o.force ? ["--force"] : [], ...o.delete ? ["--delete"] : [], "--json"];
|
|
655
|
+
switch (a.kind) {
|
|
656
|
+
case "daemon.start":
|
|
657
|
+
return [start(a.restore, a.noKernel)];
|
|
658
|
+
case "daemon.stop":
|
|
659
|
+
return [["daemon", "stop"]];
|
|
660
|
+
case "daemon.restart":
|
|
661
|
+
return [["daemon", "stop"], start(a.restore)];
|
|
662
|
+
case "kernel.start":
|
|
663
|
+
return [up(KERNEL_RIG)];
|
|
664
|
+
case "kernel.stop":
|
|
665
|
+
return [down(KERNEL_RIG)];
|
|
666
|
+
case "kernel.restart":
|
|
667
|
+
return [down(KERNEL_RIG, { snapshot: true }), up(KERNEL_RIG)];
|
|
668
|
+
case "rig.start":
|
|
669
|
+
return [up(a.rig)];
|
|
670
|
+
case "rig.stop":
|
|
671
|
+
return [down(a.rig, a)];
|
|
672
|
+
case "rig.restart":
|
|
673
|
+
return [down(a.rig, { snapshot: true }), up(a.rig)];
|
|
674
|
+
case "seat.set": {
|
|
675
|
+
const why = ["--reason", "Ledge"];
|
|
676
|
+
if (a.runtime) return [[
|
|
677
|
+
"seat",
|
|
678
|
+
"set-runtime",
|
|
679
|
+
a.seat,
|
|
680
|
+
"--runtime",
|
|
681
|
+
a.runtime,
|
|
682
|
+
...a.model ? ["--model", a.model] : [],
|
|
683
|
+
...a.effort ? ["--effort", a.effort] : [],
|
|
684
|
+
...a.permissions && a.permissions !== "inherit" ? ["--permission-mode", a.permissions] : [],
|
|
685
|
+
...a.dryRun ? ["--dry-run"] : [],
|
|
686
|
+
...why
|
|
687
|
+
]];
|
|
688
|
+
return [
|
|
689
|
+
...a.model ? [["seat", "set-model", a.seat, "--model", a.model, ...why, "--json"]] : [],
|
|
690
|
+
...a.effort ? [["seat", "set-effort", a.seat, "--effort", a.effort, ...why, "--json"]] : [],
|
|
691
|
+
...a.permissions ? [["seat", "set-permissions", a.seat, "--mode", a.permissions, ...why, "--json"]] : []
|
|
692
|
+
];
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
var showRigCommand = (args) => ["rig", ...args.filter((x) => x !== "--json")].join(" ");
|
|
697
|
+
var RigSpecMemberSchema = z8.object({
|
|
698
|
+
id: z8.string(),
|
|
699
|
+
runtime: z8.string(),
|
|
700
|
+
model: z8.string().optional(),
|
|
701
|
+
agent: z8.string(),
|
|
702
|
+
/** Its `permission_policy`, as written. */
|
|
703
|
+
policy: z8.string().optional()
|
|
704
|
+
});
|
|
705
|
+
var RigSpecPodSchema = z8.object({ id: z8.string(), label: z8.string().optional(), members: z8.array(RigSpecMemberSchema) });
|
|
706
|
+
var RigSpecSchema = z8.object({
|
|
707
|
+
name: z8.string(),
|
|
708
|
+
source: z8.string(),
|
|
709
|
+
summary: z8.string().optional(),
|
|
710
|
+
path: z8.string(),
|
|
711
|
+
/** The rig's `permission_policy`, as written (`builtin:auto`, a file…). */
|
|
712
|
+
policy: z8.string().optional(),
|
|
713
|
+
pods: z8.array(RigSpecPodSchema),
|
|
714
|
+
edges: z8.number().int().min(0)
|
|
715
|
+
});
|
|
716
|
+
var OpenRigSpecsSchema = z8.object({ type: z8.literal("openrig.specs"), requestId: z8.string().min(1).max(100), machineId: z8.string().optional() });
|
|
717
|
+
var OpenRigSpecListSchema = z8.object({
|
|
718
|
+
type: z8.literal("openrig.specList"),
|
|
719
|
+
requestId: z8.string(),
|
|
720
|
+
machineId: z8.string().optional(),
|
|
721
|
+
specs: z8.array(RigSpecSchema),
|
|
722
|
+
error: z8.string().optional()
|
|
723
|
+
});
|
|
724
|
+
var RigRoleSchema = z8.string().min(3).max(201).regex(/^[A-Za-z0-9][A-Za-z0-9_-]*\.[A-Za-z0-9][A-Za-z0-9_-]*$/, "not a role");
|
|
725
|
+
var RuntimeSchema = z8.enum(["claude-code", "codex"]);
|
|
726
|
+
var RigPolicySchema = z8.enum(["auto", "standard", "open", "yolo", "locked"]);
|
|
727
|
+
var RIG_POLICIES = RigPolicySchema.options;
|
|
728
|
+
var RigLaunchSchema = z8.object({
|
|
729
|
+
spec: RigNameSchema,
|
|
730
|
+
cwd: z8.string().min(1).max(4096),
|
|
731
|
+
name: RigNameSchema,
|
|
732
|
+
seats: z8.record(RigRoleSchema, z8.number().int().min(0).max(9)).optional(),
|
|
733
|
+
runtimes: z8.record(RigRoleSchema, RuntimeSchema).optional(),
|
|
734
|
+
models: z8.record(RigRoleSchema, z8.string().min(1).max(200).regex(/^[A-Za-z0-9][A-Za-z0-9._:/@[\]=,+-]*$/)).optional(),
|
|
735
|
+
delegation: z8.enum(["pairs", "all"]).optional(),
|
|
736
|
+
save: z8.boolean().optional(),
|
|
737
|
+
plan: z8.boolean().optional(),
|
|
738
|
+
/** The rig's permission policy, in place of the spec's; `policies`: a role's, over the rig's. */
|
|
739
|
+
policy: RigPolicySchema.optional(),
|
|
740
|
+
policies: z8.record(RigRoleSchema, RigPolicySchema).optional(),
|
|
741
|
+
/** Accept the harnesses' first-launch warnings (`rig up --non-interruptive`), so a bypassing seat does not stop on Claude's dialog. */
|
|
742
|
+
nonInterruptive: z8.boolean().optional()
|
|
743
|
+
});
|
|
744
|
+
var OpenRigLaunchSchema = z8.object({ type: z8.literal("openrig.launch"), requestId: z8.string().min(1).max(100), launch: RigLaunchSchema, machineId: z8.string().optional() });
|
|
745
|
+
var OpenRigLaunchedSchema = z8.object({
|
|
746
|
+
type: z8.literal("openrig.launched"),
|
|
747
|
+
requestId: z8.string(),
|
|
748
|
+
machineId: z8.string().optional(),
|
|
749
|
+
ok: z8.boolean(),
|
|
750
|
+
plan: z8.boolean(),
|
|
751
|
+
commands: z8.array(z8.string()),
|
|
752
|
+
yaml: z8.string().optional(),
|
|
753
|
+
seats: z8.number().int().optional(),
|
|
754
|
+
output: z8.string().optional(),
|
|
755
|
+
error: z8.string().optional(),
|
|
756
|
+
/** What `rig up --plan` concluded: its status (`planned`…), its errors and its warnings (one per seat without a permission policy…). */
|
|
757
|
+
check: z8.object({ status: z8.string(), errors: z8.array(z8.string()), warnings: z8.array(z8.string()) }).optional()
|
|
758
|
+
});
|
|
759
|
+
var roleOf = (logicalId) => logicalId.replace(/-\d+$/, "");
|
|
760
|
+
var copyOf = (logicalId) => {
|
|
761
|
+
const m = /-(\d+)$/.exec(logicalId);
|
|
762
|
+
return m ? Number(m[1]) : 1;
|
|
763
|
+
};
|
|
764
|
+
function seatsByRole(nodes) {
|
|
765
|
+
const out = /* @__PURE__ */ new Map();
|
|
766
|
+
for (const n of nodes) out.set(roleOf(n.logicalId), [...out.get(roleOf(n.logicalId)) ?? [], n.logicalId]);
|
|
767
|
+
for (const [role, ids] of out) out.set(role, ids.sort((a, b) => copyOf(a) - copyOf(b)));
|
|
768
|
+
return out;
|
|
769
|
+
}
|
|
770
|
+
function seatPlan(nodes, seats) {
|
|
771
|
+
const by = seatsByRole(nodes);
|
|
772
|
+
const add = [], remove = [];
|
|
773
|
+
for (const [role, want] of Object.entries(seats)) {
|
|
774
|
+
const have = by.get(role) ?? [];
|
|
775
|
+
if (have.length === 0) continue;
|
|
776
|
+
if (want < have.length) {
|
|
777
|
+
remove.push(...have.slice(want).reverse());
|
|
778
|
+
continue;
|
|
779
|
+
}
|
|
780
|
+
const [pod, member] = role.split(".");
|
|
781
|
+
let next = Math.max(...have.map(copyOf));
|
|
782
|
+
for (let i = have.length; i < want; i++) add.push({ role, pod, id: `${member}-${++next}`, from: have[0] });
|
|
783
|
+
}
|
|
784
|
+
return { add, remove };
|
|
785
|
+
}
|
|
786
|
+
var OpenRigSeatsSchema = z8.object({
|
|
787
|
+
type: z8.literal("openrig.seats"),
|
|
788
|
+
requestId: z8.string().min(1).max(100),
|
|
789
|
+
machineId: z8.string().optional(),
|
|
790
|
+
rig: RigNameSchema,
|
|
791
|
+
seats: z8.record(RigRoleSchema, z8.number().int().min(0).max(9)),
|
|
792
|
+
/** How the added seats are linked, where OpenRig can add links to a running rig (0.7+): like a launch's. */
|
|
793
|
+
delegation: z8.enum(["pairs", "all"]).optional()
|
|
794
|
+
});
|
|
795
|
+
var OpenRigReseatedSchema = z8.object({
|
|
796
|
+
type: z8.literal("openrig.reseated"),
|
|
797
|
+
requestId: z8.string(),
|
|
798
|
+
machineId: z8.string().optional(),
|
|
799
|
+
ok: z8.boolean(),
|
|
800
|
+
commands: z8.array(z8.string()),
|
|
801
|
+
added: z8.array(z8.string()),
|
|
802
|
+
removed: z8.array(z8.string()),
|
|
803
|
+
output: z8.string().optional(),
|
|
804
|
+
error: z8.string().optional(),
|
|
805
|
+
/** The links ensured between the seats; `linksUnsupported`: this OpenRig cannot add links to a running rig (before 0.7). */
|
|
806
|
+
links: z8.number().int().optional(),
|
|
807
|
+
linksUnsupported: z8.boolean().optional()
|
|
808
|
+
});
|
|
809
|
+
|
|
906
810
|
// ../protocol/src/messages.ts
|
|
907
811
|
import { z as z21 } from "zod";
|
|
908
812
|
|
|
909
813
|
// ../protocol/src/chat.ts
|
|
910
|
-
import { z as
|
|
814
|
+
import { z as z10 } from "zod";
|
|
911
815
|
|
|
912
816
|
// ../protocol/src/attachments.ts
|
|
913
|
-
import { z as
|
|
817
|
+
import { z as z9 } from "zod";
|
|
914
818
|
var ATTACHMENT_ID = /^[0-9a-f]{64}$/;
|
|
915
|
-
var AttachmentIdSchema =
|
|
819
|
+
var AttachmentIdSchema = z9.string().regex(ATTACHMENT_ID);
|
|
916
820
|
var IMAGE_MIMES = ["image/webp", "image/jpeg", "image/png", "image/gif"];
|
|
917
|
-
var ImageMimeSchema =
|
|
821
|
+
var ImageMimeSchema = z9.enum(IMAGE_MIMES);
|
|
918
822
|
var ATTACHMENT_MAX = 4e5;
|
|
919
823
|
var ATTACHMENT_LOCAL_MAX = 2e6;
|
|
920
824
|
var PREVIEW_MAX = 4e4;
|
|
921
825
|
var ATTACHMENTS_MAX = 5;
|
|
922
826
|
var b64Max = (bytes) => Math.ceil(bytes / 3) * 4;
|
|
923
|
-
var AttachmentRefSchema =
|
|
827
|
+
var AttachmentRefSchema = z9.object({
|
|
924
828
|
id: AttachmentIdSchema,
|
|
925
829
|
mime: ImageMimeSchema,
|
|
926
|
-
width:
|
|
927
|
-
height:
|
|
928
|
-
bytes:
|
|
929
|
-
preview:
|
|
830
|
+
width: z9.number().int().positive(),
|
|
831
|
+
height: z9.number().int().positive(),
|
|
832
|
+
bytes: z9.number().int().positive(),
|
|
833
|
+
preview: z9.boolean()
|
|
930
834
|
});
|
|
931
|
-
var ImageUploadSchema =
|
|
835
|
+
var ImageUploadSchema = z9.object({
|
|
932
836
|
mime: ImageMimeSchema,
|
|
933
|
-
data:
|
|
934
|
-
preview:
|
|
935
|
-
});
|
|
936
|
-
var AttachmentErrorReasonSchema =
|
|
937
|
-
var requestId =
|
|
938
|
-
var AttachmentPutSchema =
|
|
939
|
-
var AttachmentGetSchema =
|
|
940
|
-
var AttachmentStoredSchema =
|
|
941
|
-
var AttachmentDataSchema =
|
|
942
|
-
var AttachmentErrorSchema =
|
|
837
|
+
data: z9.string().min(1).max(b64Max(ATTACHMENT_LOCAL_MAX)),
|
|
838
|
+
preview: z9.object({ mime: ImageMimeSchema, data: z9.string().min(1).max(b64Max(PREVIEW_MAX)) }).optional()
|
|
839
|
+
});
|
|
840
|
+
var AttachmentErrorReasonSchema = z9.enum(["too_large", "not_image", "unreadable", "not_found", "offline"]);
|
|
841
|
+
var requestId = z9.string().min(1).max(100);
|
|
842
|
+
var AttachmentPutSchema = z9.object({ type: z9.literal("attachment.put"), requestId, id: z9.string().optional(), image: ImageUploadSchema });
|
|
843
|
+
var AttachmentGetSchema = z9.object({ type: z9.literal("attachment.get"), requestId, attachment: AttachmentIdSchema, preview: z9.boolean().optional(), id: z9.string().optional(), machine: z9.string().optional() });
|
|
844
|
+
var AttachmentStoredSchema = z9.object({ type: z9.literal("attachment.stored"), requestId, ref: AttachmentRefSchema });
|
|
845
|
+
var AttachmentDataSchema = z9.object({ type: z9.literal("attachment.data"), requestId, attachment: AttachmentIdSchema, mime: ImageMimeSchema, data: z9.string() });
|
|
846
|
+
var AttachmentErrorSchema = z9.object({ type: z9.literal("attachment.error"), requestId, reason: AttachmentErrorReasonSchema });
|
|
943
847
|
|
|
944
848
|
// ../protocol/src/chat.ts
|
|
945
|
-
var ChatStepSchema =
|
|
946
|
-
kind:
|
|
947
|
-
id:
|
|
948
|
-
name:
|
|
949
|
-
path:
|
|
950
|
-
});
|
|
951
|
-
var ChatProposalSchema =
|
|
952
|
-
cwd:
|
|
953
|
-
project:
|
|
954
|
-
prompt:
|
|
849
|
+
var ChatStepSchema = z10.object({
|
|
850
|
+
kind: z10.enum(["sessions", "pane", "reply", "git", "repo"]),
|
|
851
|
+
id: z10.string().optional(),
|
|
852
|
+
name: z10.string().optional(),
|
|
853
|
+
path: z10.string().optional()
|
|
854
|
+
});
|
|
855
|
+
var ChatProposalSchema = z10.object({
|
|
856
|
+
cwd: z10.string().min(1),
|
|
857
|
+
project: z10.string(),
|
|
858
|
+
prompt: z10.string().optional(),
|
|
955
859
|
tool: ToolSchema,
|
|
956
860
|
/** What Ledge proposed on the card's picker (spec 2026-10-26 action registry §4), the agent's own default when left out. */
|
|
957
861
|
model: ModelIdSchema.optional(),
|
|
958
862
|
effort: EffortSchema.optional(),
|
|
959
|
-
launchedId:
|
|
960
|
-
error:
|
|
863
|
+
launchedId: z10.string().optional(),
|
|
864
|
+
error: z10.string().optional()
|
|
961
865
|
});
|
|
962
866
|
var MAX_PROPOSALS = 8;
|
|
963
|
-
var ChatProposalsSchema =
|
|
964
|
-
var ChatRelaySchema =
|
|
965
|
-
id:
|
|
966
|
-
name:
|
|
867
|
+
var ChatProposalsSchema = z10.array(ChatProposalSchema).min(1).max(MAX_PROPOSALS);
|
|
868
|
+
var ChatRelaySchema = z10.object({
|
|
869
|
+
id: z10.string().min(1),
|
|
870
|
+
name: z10.string(),
|
|
967
871
|
tool: ToolSchema,
|
|
968
|
-
text:
|
|
969
|
-
status:
|
|
970
|
-
sentAt:
|
|
971
|
-
error:
|
|
872
|
+
text: z10.string().min(1),
|
|
873
|
+
status: z10.enum(["queued", "sent"]).optional(),
|
|
874
|
+
sentAt: z10.string().datetime().optional(),
|
|
875
|
+
error: z10.string().optional(),
|
|
972
876
|
/** Why it failed, as a code a front words itself (a RefusalCode, `ended`, or `failed` for the machinery); goes with `error`. */
|
|
973
|
-
code:
|
|
877
|
+
code: z10.string().max(40).optional()
|
|
974
878
|
});
|
|
975
|
-
var ChatCloseSchema =
|
|
976
|
-
id:
|
|
977
|
-
name:
|
|
879
|
+
var ChatCloseSchema = z10.object({
|
|
880
|
+
id: z10.string().min(1),
|
|
881
|
+
name: z10.string(),
|
|
978
882
|
tool: ToolSchema,
|
|
979
|
-
closedAt:
|
|
980
|
-
how:
|
|
981
|
-
error:
|
|
982
|
-
});
|
|
983
|
-
var ChatClosesSchema =
|
|
984
|
-
var ChatProjectProposalSchema =
|
|
985
|
-
name:
|
|
986
|
-
description:
|
|
987
|
-
repos:
|
|
988
|
-
addTo:
|
|
989
|
-
});
|
|
990
|
-
var
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
name: z13.string().min(1),
|
|
1004
|
-
template: z13.string().optional(),
|
|
1005
|
-
seats: z13.array(ChatTeamSeatSchema).min(1).max(8),
|
|
1006
|
-
teamId: z13.string().optional(),
|
|
1007
|
-
launchedAt: z13.string().datetime().optional(),
|
|
1008
|
-
error: z13.string().optional(),
|
|
1009
|
-
savedPath: z13.string().optional(),
|
|
1010
|
-
saveError: z13.string().optional()
|
|
1011
|
-
});
|
|
1012
|
-
var ChatTaskProposalSchema = z13.object({
|
|
1013
|
-
to: z13.string().min(1),
|
|
1014
|
-
toName: z13.string().optional(),
|
|
1015
|
-
team: z13.string().optional(),
|
|
1016
|
-
title: z13.string().min(1).max(200),
|
|
1017
|
-
text: z13.string().max(2e4).optional(),
|
|
1018
|
-
taskId: z13.string().optional(),
|
|
1019
|
-
ownerName: z13.string().optional(),
|
|
1020
|
-
state: z13.enum(["open", "taken", "done", "refused", "dropped"]).optional(),
|
|
1021
|
-
givenAt: z13.string().datetime().optional(),
|
|
1022
|
-
error: z13.string().optional()
|
|
1023
|
-
});
|
|
1024
|
-
var ChatTasksSchema = z13.array(ChatTaskProposalSchema).min(1).max(MAX_PROPOSALS);
|
|
1025
|
-
var ActionVarsSchema = z13.record(z13.string().max(40), z13.string().max(300));
|
|
883
|
+
closedAt: z10.string().datetime().optional(),
|
|
884
|
+
how: z10.enum(["exit", "killed"]).optional(),
|
|
885
|
+
error: z10.string().optional()
|
|
886
|
+
});
|
|
887
|
+
var ChatClosesSchema = z10.array(ChatCloseSchema).min(1).max(MAX_PROPOSALS);
|
|
888
|
+
var ChatProjectProposalSchema = z10.object({
|
|
889
|
+
name: z10.string().min(1).max(80),
|
|
890
|
+
description: z10.string().max(500).optional(),
|
|
891
|
+
repos: z10.array(z10.object({ path: z10.string().min(1).max(4096), why: z10.string().min(1).max(200) })).min(1).max(50),
|
|
892
|
+
addTo: z10.string().min(1).max(80).optional()
|
|
893
|
+
});
|
|
894
|
+
var ChatTaskProposalSchema = z10.object({
|
|
895
|
+
to: z10.string().min(1),
|
|
896
|
+
toName: z10.string().optional(),
|
|
897
|
+
title: z10.string().min(1).max(200),
|
|
898
|
+
text: z10.string().max(2e4).optional(),
|
|
899
|
+
taskId: z10.string().optional(),
|
|
900
|
+
ownerName: z10.string().optional(),
|
|
901
|
+
state: z10.enum(["open", "taken", "done", "refused", "dropped"]).optional(),
|
|
902
|
+
givenAt: z10.string().datetime().optional(),
|
|
903
|
+
error: z10.string().optional()
|
|
904
|
+
});
|
|
905
|
+
var ChatTasksSchema = z10.array(ChatTaskProposalSchema).min(1).max(MAX_PROPOSALS);
|
|
906
|
+
var ActionVarsSchema = z10.record(z10.string().max(40), z10.string().max(300));
|
|
1026
907
|
var DETAIL_MAX = 4e3;
|
|
1027
908
|
var ACTION_ERROR_CODES = [
|
|
1028
909
|
"unknown",
|
|
@@ -1037,12 +918,6 @@ var ACTION_ERROR_CODES = [
|
|
|
1037
918
|
"no_request",
|
|
1038
919
|
"in_session",
|
|
1039
920
|
"no_note",
|
|
1040
|
-
"member",
|
|
1041
|
-
"not_member",
|
|
1042
|
-
"unknown_role",
|
|
1043
|
-
"not_resting",
|
|
1044
|
-
"dissolved",
|
|
1045
|
-
"no_seat",
|
|
1046
921
|
"closed",
|
|
1047
922
|
"holder",
|
|
1048
923
|
"changed",
|
|
@@ -1050,86 +925,84 @@ var ACTION_ERROR_CODES = [
|
|
|
1050
925
|
"not_decision",
|
|
1051
926
|
"failed"
|
|
1052
927
|
];
|
|
1053
|
-
var ChatActionStateSchema =
|
|
1054
|
-
var ChatActionSchema =
|
|
1055
|
-
action:
|
|
1056
|
-
args:
|
|
1057
|
-
summary:
|
|
928
|
+
var ChatActionStateSchema = z10.enum(["running", "done", "denied", "failed", "refused"]);
|
|
929
|
+
var ChatActionSchema = z10.object({
|
|
930
|
+
action: z10.string().min(1).max(40),
|
|
931
|
+
args: z10.record(z10.unknown()),
|
|
932
|
+
summary: z10.string().min(1).max(300),
|
|
1058
933
|
vars: ActionVarsSchema.optional(),
|
|
1059
|
-
detail:
|
|
1060
|
-
detailCut:
|
|
934
|
+
detail: z10.string().max(DETAIL_MAX).optional(),
|
|
935
|
+
detailCut: z10.literal(true).optional(),
|
|
1061
936
|
risk: ActionRiskSchema,
|
|
1062
|
-
session:
|
|
1063
|
-
team: z13.string().optional(),
|
|
937
|
+
session: z10.string().optional(),
|
|
1064
938
|
state: ChatActionStateSchema.optional(),
|
|
1065
|
-
doneAt:
|
|
1066
|
-
error:
|
|
1067
|
-
code:
|
|
1068
|
-
});
|
|
1069
|
-
var ChatActionsSchema =
|
|
1070
|
-
var ChatTurnSchema =
|
|
1071
|
-
machineId:
|
|
1072
|
-
machineName:
|
|
1073
|
-
choices:
|
|
1074
|
-
qid:
|
|
1075
|
-
question:
|
|
1076
|
-
askedAt:
|
|
1077
|
-
steps:
|
|
1078
|
-
answer:
|
|
1079
|
-
answeredAt:
|
|
1080
|
-
error:
|
|
939
|
+
doneAt: z10.string().datetime().optional(),
|
|
940
|
+
error: z10.string().optional(),
|
|
941
|
+
code: z10.string().max(40).optional()
|
|
942
|
+
});
|
|
943
|
+
var ChatActionsSchema = z10.array(ChatActionSchema).min(1).max(MAX_PROPOSALS);
|
|
944
|
+
var ChatTurnSchema = z10.object({
|
|
945
|
+
machineId: z10.string().optional(),
|
|
946
|
+
machineName: z10.string().optional(),
|
|
947
|
+
choices: z10.array(z10.object({ id: z10.string(), label: z10.string() })).optional(),
|
|
948
|
+
qid: z10.string().min(1),
|
|
949
|
+
question: z10.string(),
|
|
950
|
+
askedAt: z10.string().datetime(),
|
|
951
|
+
steps: z10.array(ChatStepSchema),
|
|
952
|
+
answer: z10.string().optional(),
|
|
953
|
+
answeredAt: z10.string().datetime().optional(),
|
|
954
|
+
error: z10.string().optional(),
|
|
1081
955
|
proposal: ChatProposalSchema.optional(),
|
|
1082
956
|
proposals: ChatProposalsSchema.optional(),
|
|
1083
957
|
relay: ChatRelaySchema.optional(),
|
|
1084
958
|
closes: ChatClosesSchema.optional(),
|
|
1085
959
|
projectProposal: ChatProjectProposalSchema.optional(),
|
|
1086
|
-
team: ChatTeamProposalSchema.optional(),
|
|
1087
960
|
tasks: ChatTasksSchema.optional(),
|
|
1088
961
|
actions: ChatActionsSchema.optional(),
|
|
1089
|
-
ignoredAt:
|
|
1090
|
-
attachments:
|
|
962
|
+
ignoredAt: z10.string().datetime().optional(),
|
|
963
|
+
attachments: z10.array(AttachmentRefSchema).optional()
|
|
1091
964
|
});
|
|
1092
965
|
var proposalRows = (t) => t?.proposals ?? (t?.proposal ? [t.proposal] : []);
|
|
1093
966
|
|
|
1094
967
|
// ../protocol/src/repos.ts
|
|
1095
|
-
import { z as
|
|
1096
|
-
var ReposInspectSchema =
|
|
1097
|
-
type:
|
|
1098
|
-
requestId:
|
|
1099
|
-
paths:
|
|
1100
|
-
machineId:
|
|
1101
|
-
});
|
|
1102
|
-
var RepoInfoSchema =
|
|
1103
|
-
var ReposInfoSchema =
|
|
968
|
+
import { z as z11 } from "zod";
|
|
969
|
+
var ReposInspectSchema = z11.object({
|
|
970
|
+
type: z11.literal("repos.inspect"),
|
|
971
|
+
requestId: z11.string().min(1).max(100),
|
|
972
|
+
paths: z11.array(z11.string().min(1)).min(1).max(50),
|
|
973
|
+
machineId: z11.string().optional()
|
|
974
|
+
});
|
|
975
|
+
var RepoInfoSchema = z11.object({ path: z11.string(), exists: z11.boolean(), branch: z11.string().nullable() });
|
|
976
|
+
var ReposInfoSchema = z11.object({ type: z11.literal("repos.info"), requestId: z11.string(), repos: z11.array(RepoInfoSchema) });
|
|
1104
977
|
|
|
1105
978
|
// ../protocol/src/scan.ts
|
|
1106
|
-
import { z as
|
|
1107
|
-
var ReposScanSchema =
|
|
1108
|
-
var FoundRepoSchema =
|
|
1109
|
-
var ReposFoundSchema =
|
|
979
|
+
import { z as z12 } from "zod";
|
|
980
|
+
var ReposScanSchema = z12.object({ type: z12.literal("repos.scan"), requestId: z12.string().min(1).max(100), machineId: z12.string().optional() });
|
|
981
|
+
var FoundRepoSchema = z12.object({ path: z12.string(), branch: z12.string().nullable(), remote: z12.string().optional(), manifest: z12.string().max(200).optional() });
|
|
982
|
+
var ReposFoundSchema = z12.object({ type: z12.literal("repos.found"), requestId: z12.string(), repos: z12.array(FoundRepoSchema).max(500), truncated: z12.boolean(), error: z12.string().optional() });
|
|
1110
983
|
|
|
1111
984
|
// ../protocol/src/documents.ts
|
|
1112
|
-
import { z as
|
|
985
|
+
import { z as z13 } from "zod";
|
|
1113
986
|
var DOCUMENT_MAX_BYTES = 1048576;
|
|
1114
|
-
var path =
|
|
1115
|
-
var requestId2 =
|
|
1116
|
-
var DocumentReadSchema =
|
|
1117
|
-
type:
|
|
987
|
+
var path = z13.string().min(1).max(4096);
|
|
988
|
+
var requestId2 = z13.string().min(1);
|
|
989
|
+
var DocumentReadSchema = z13.object({
|
|
990
|
+
type: z13.literal("document.read"),
|
|
1118
991
|
requestId: requestId2,
|
|
1119
992
|
path,
|
|
1120
|
-
machineId:
|
|
1121
|
-
sessionId:
|
|
993
|
+
machineId: z13.string().optional(),
|
|
994
|
+
sessionId: z13.string().min(1).optional(),
|
|
1122
995
|
basePath: path.optional()
|
|
1123
996
|
});
|
|
1124
|
-
var DocumentContentSchema =
|
|
1125
|
-
type:
|
|
997
|
+
var DocumentContentSchema = z13.object({
|
|
998
|
+
type: z13.literal("document.content"),
|
|
1126
999
|
requestId: requestId2,
|
|
1127
1000
|
path,
|
|
1128
|
-
text:
|
|
1129
|
-
bytes:
|
|
1130
|
-
modifiedAt:
|
|
1001
|
+
text: z13.string(),
|
|
1002
|
+
bytes: z13.number().int().nonnegative(),
|
|
1003
|
+
modifiedAt: z13.string().datetime()
|
|
1131
1004
|
});
|
|
1132
|
-
var DocumentErrorCodeSchema =
|
|
1005
|
+
var DocumentErrorCodeSchema = z13.enum([
|
|
1133
1006
|
"not_found",
|
|
1134
1007
|
"not_file",
|
|
1135
1008
|
"unsupported_path",
|
|
@@ -1141,63 +1014,153 @@ var DocumentErrorCodeSchema = z16.enum([
|
|
|
1141
1014
|
"session_missing",
|
|
1142
1015
|
"read_failed"
|
|
1143
1016
|
]);
|
|
1144
|
-
var DocumentErrorSchema =
|
|
1145
|
-
type:
|
|
1017
|
+
var DocumentErrorSchema = z13.object({
|
|
1018
|
+
type: z13.literal("document.error"),
|
|
1146
1019
|
requestId: requestId2,
|
|
1147
1020
|
path,
|
|
1148
1021
|
code: DocumentErrorCodeSchema
|
|
1149
1022
|
});
|
|
1150
1023
|
|
|
1151
1024
|
// ../protocol/src/routing.ts
|
|
1152
|
-
import { z as
|
|
1153
|
-
var MachineInventorySchema =
|
|
1154
|
-
id:
|
|
1155
|
-
label:
|
|
1156
|
-
online:
|
|
1157
|
-
local:
|
|
1158
|
-
sessions:
|
|
1159
|
-
folders:
|
|
1160
|
-
});
|
|
1161
|
-
var RoutingContextSchema =
|
|
1162
|
-
machines:
|
|
1163
|
-
history:
|
|
1164
|
-
});
|
|
1165
|
-
var RouteResultSchema =
|
|
1025
|
+
import { z as z14 } from "zod";
|
|
1026
|
+
var MachineInventorySchema = z14.object({
|
|
1027
|
+
id: z14.string().min(1).max(80),
|
|
1028
|
+
label: z14.string().min(1).max(120),
|
|
1029
|
+
online: z14.boolean(),
|
|
1030
|
+
local: z14.boolean(),
|
|
1031
|
+
sessions: z14.array(z14.object({ id: z14.string(), name: z14.string(), project: z14.string(), cwd: z14.string(), topic: z14.string().optional(), state: z14.string(), readOnly: z14.boolean() })).max(500),
|
|
1032
|
+
folders: z14.array(z14.object({ project: z14.string(), cwd: z14.string() })).max(100)
|
|
1033
|
+
});
|
|
1034
|
+
var RoutingContextSchema = z14.object({
|
|
1035
|
+
machines: z14.array(MachineInventorySchema).min(1).max(20),
|
|
1036
|
+
history: z14.array(z14.object({ question: z14.string().max(2e4), answer: z14.string().max(2e4).optional(), machineId: z14.string().optional() })).max(50)
|
|
1037
|
+
});
|
|
1038
|
+
var RouteResultSchema = z14.object({
|
|
1166
1039
|
/** Null means an answer or a clarification, never an implicit local destination. */
|
|
1167
|
-
machineId:
|
|
1168
|
-
text:
|
|
1169
|
-
choices:
|
|
1040
|
+
machineId: z14.string().nullable(),
|
|
1041
|
+
text: z14.string().min(1).max(2e4),
|
|
1042
|
+
choices: z14.array(z14.string()).max(20).optional()
|
|
1043
|
+
});
|
|
1044
|
+
|
|
1045
|
+
// ../protocol/src/ssh.ts
|
|
1046
|
+
import { z as z15 } from "zod";
|
|
1047
|
+
var SshAliasSchema = z15.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/);
|
|
1048
|
+
|
|
1049
|
+
// ../protocol/src/machines.ts
|
|
1050
|
+
import { z as z16 } from "zod";
|
|
1051
|
+
var MachineIdSchema = z16.string().regex(/^[a-zA-Z0-9_-]{1,64}$/);
|
|
1052
|
+
var MachineSchema = z16.object({
|
|
1053
|
+
id: MachineIdSchema,
|
|
1054
|
+
label: z16.string().trim().min(1).max(80),
|
|
1055
|
+
ssh: SshAliasSchema.optional(),
|
|
1056
|
+
/** Kept in the list but never connected to: no peer, no retry, no session shown until it is enabled again. */
|
|
1057
|
+
disabled: z16.boolean().optional()
|
|
1058
|
+
});
|
|
1059
|
+
var MachinesSchema = z16.array(MachineSchema).min(1).max(20).superRefine((list, ctx) => {
|
|
1060
|
+
if (list[0]?.id !== "local" || list[0].ssh !== void 0) ctx.addIssue({ code: "custom", message: "the first machine is local, without ssh", path: [0] });
|
|
1061
|
+
const ids = /* @__PURE__ */ new Set(), aliases = /* @__PURE__ */ new Set();
|
|
1062
|
+
list.forEach((m, i) => {
|
|
1063
|
+
if (i === 0 && m.disabled) ctx.addIssue({ code: "custom", message: "the local machine cannot be disabled", path: [0, "disabled"] });
|
|
1064
|
+
if (i > 0 && !m.ssh) ctx.addIssue({ code: "custom", message: "a remote machine needs an ssh alias", path: [i, "ssh"] });
|
|
1065
|
+
if (ids.has(m.id)) ctx.addIssue({ code: "custom", message: `duplicate id ${m.id}`, path: [i, "id"] });
|
|
1066
|
+
ids.add(m.id);
|
|
1067
|
+
if (m.ssh) {
|
|
1068
|
+
if (aliases.has(m.ssh)) ctx.addIssue({ code: "custom", message: `duplicate ssh alias ${m.ssh}`, path: [i, "ssh"] });
|
|
1069
|
+
aliases.add(m.ssh);
|
|
1070
|
+
}
|
|
1071
|
+
});
|
|
1170
1072
|
});
|
|
1171
1073
|
|
|
1172
1074
|
// ../protocol/src/island.ts
|
|
1173
|
-
import { z as
|
|
1174
|
-
var IslandScaleSchema =
|
|
1175
|
-
var IslandPrefsSchema =
|
|
1075
|
+
import { z as z17 } from "zod";
|
|
1076
|
+
var IslandScaleSchema = z17.union([z17.literal("auto"), z17.literal(1), z17.literal(1.25), z17.literal(1.5), z17.literal(2)]);
|
|
1077
|
+
var IslandPrefsSchema = z17.object({
|
|
1176
1078
|
/** Shown at the top of the screen; hidden, Desktop still notifies. */
|
|
1177
|
-
visible:
|
|
1079
|
+
visible: z17.boolean(),
|
|
1178
1080
|
/** `primary` (whichever it is after a reconfiguration), or a monitor's id as the shell lists it (`list_monitors`: the OS
|
|
1179
1081
|
* name, `#index` without one). `second`, written by older fronts, is the first monitor that is not the primary. */
|
|
1180
|
-
screen:
|
|
1181
|
-
position:
|
|
1082
|
+
screen: z17.string().trim().min(1).max(200),
|
|
1083
|
+
position: z17.enum(["center", "left", "right"]),
|
|
1182
1084
|
/** A strip under a maximised window. */
|
|
1183
|
-
discreet:
|
|
1085
|
+
discreet: z17.boolean(),
|
|
1184
1086
|
islandScale: IslandScaleSchema,
|
|
1185
1087
|
panelScale: IslandScaleSchema,
|
|
1186
1088
|
/** What the island shows besides asks and questions, which it always shows. */
|
|
1187
|
-
shows:
|
|
1089
|
+
shows: z17.object({
|
|
1188
1090
|
/** Allow, deny or answer in a line from the island; off, its cards only say « Open in Ledge ». */
|
|
1189
|
-
quick:
|
|
1091
|
+
quick: z17.boolean(),
|
|
1190
1092
|
/** The 6 s bubble when an agent finishes. */
|
|
1191
|
-
finished:
|
|
1093
|
+
finished: z17.boolean(),
|
|
1192
1094
|
/** An agent's sentence in a bubble. */
|
|
1193
|
-
say:
|
|
1095
|
+
say: z17.boolean(),
|
|
1194
1096
|
/** The sub-agents next to their main agent. */
|
|
1195
|
-
helpers:
|
|
1097
|
+
helpers: z17.boolean()
|
|
1196
1098
|
}),
|
|
1197
1099
|
/** The global shortcut that opens the island, as shown (`Ctrl Alt L`). */
|
|
1198
|
-
shortcut:
|
|
1100
|
+
shortcut: z17.string().trim().min(1).max(40)
|
|
1199
1101
|
});
|
|
1200
1102
|
|
|
1103
|
+
// ../protocol/src/projects.ts
|
|
1104
|
+
import { z as z18 } from "zod";
|
|
1105
|
+
var PROJECT_COLORS = { blue: "#3b82f6", green: "#10b981", amber: "#f59e0b", violet: "#8b5cf6", teal: "#14b8a6", pink: "#ec4899", red: "#ef4444", slate: "#64748b" };
|
|
1106
|
+
var ProjectColorSchema = z18.enum(["blue", "green", "amber", "violet", "teal", "pink", "red", "slate"]);
|
|
1107
|
+
var ProjectIdSchema = z18.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/);
|
|
1108
|
+
function normalizePath(raw) {
|
|
1109
|
+
const p = raw.trim().replace(/\/+/g, "/");
|
|
1110
|
+
return p.length > 1 && p.endsWith("/") ? p.slice(0, -1) : p;
|
|
1111
|
+
}
|
|
1112
|
+
var PathSchema = z18.string().max(4096).refine((p) => p.startsWith("/") && p === normalizePath(p), "an absolute, normalized path");
|
|
1113
|
+
var RepoSchema = z18.object({ machine: MachineIdSchema, path: PathSchema });
|
|
1114
|
+
var ProjectSchema = z18.object({
|
|
1115
|
+
id: ProjectIdSchema,
|
|
1116
|
+
name: z18.string().trim().min(1).max(80),
|
|
1117
|
+
color: ProjectColorSchema,
|
|
1118
|
+
description: z18.string().max(500).default(""),
|
|
1119
|
+
repos: z18.array(RepoSchema).max(50)
|
|
1120
|
+
});
|
|
1121
|
+
var RuleSchema = z18.object({ machine: MachineIdSchema, path: PathSchema, project: ProjectIdSchema });
|
|
1122
|
+
function projectsProblems(p) {
|
|
1123
|
+
const out = [];
|
|
1124
|
+
const ids = /* @__PURE__ */ new Set(), names = /* @__PURE__ */ new Set(), repos = /* @__PURE__ */ new Set(), rules = /* @__PURE__ */ new Set();
|
|
1125
|
+
p.projects.forEach((project, i) => {
|
|
1126
|
+
if (ids.has(project.id)) out.push({ code: "duplicate_id", path: ["projects", i, "id"] });
|
|
1127
|
+
ids.add(project.id);
|
|
1128
|
+
const name = project.name.trim().toLocaleLowerCase();
|
|
1129
|
+
if (names.has(name)) out.push({ code: "duplicate_name", path: ["projects", i, "name"] });
|
|
1130
|
+
names.add(name);
|
|
1131
|
+
project.repos.forEach((repo, j) => {
|
|
1132
|
+
const key = `${repo.machine}
|
|
1133
|
+
${repo.path}`;
|
|
1134
|
+
if (repos.has(key)) out.push({ code: "duplicate_repo", path: ["projects", i, "repos", j] });
|
|
1135
|
+
repos.add(key);
|
|
1136
|
+
});
|
|
1137
|
+
});
|
|
1138
|
+
p.rules.forEach((rule, i) => {
|
|
1139
|
+
const key = `${rule.machine}
|
|
1140
|
+
${rule.path}`;
|
|
1141
|
+
if (rules.has(key)) out.push({ code: "duplicate_rule", path: ["rules", i] });
|
|
1142
|
+
rules.add(key);
|
|
1143
|
+
if (!ids.has(rule.project)) out.push({ code: "unknown_project", path: ["rules", i, "project"] });
|
|
1144
|
+
});
|
|
1145
|
+
return out;
|
|
1146
|
+
}
|
|
1147
|
+
var ProjectsSchema = z18.object({ projects: z18.array(ProjectSchema).max(100), rules: z18.array(RuleSchema).max(1e3) }).superRefine((p, ctx) => {
|
|
1148
|
+
for (const problem of projectsProblems(p)) ctx.addIssue({ code: "custom", message: problem.code, path: problem.path });
|
|
1149
|
+
});
|
|
1150
|
+
var DEFAULT_PROJECTS = { projects: [], rules: [] };
|
|
1151
|
+
var under = (cwd, path2) => path2 === "/" || cwd === path2 || cwd.startsWith(`${path2}/`);
|
|
1152
|
+
function projectOf(session, state) {
|
|
1153
|
+
const machine = session.machineId ?? "local";
|
|
1154
|
+
const cwd = normalizePath(session.cwd);
|
|
1155
|
+
const known = new Set(state.projects.map((p) => p.id));
|
|
1156
|
+
const candidates = [
|
|
1157
|
+
...state.projects.flatMap((p) => p.repos.filter((r) => r.machine === machine).map((r) => ({ project: p.id, path: r.path, rule: false }))),
|
|
1158
|
+
...state.rules.filter((r) => r.machine === machine && known.has(r.project)).map((r) => ({ project: r.project, path: r.path, rule: true }))
|
|
1159
|
+
].filter((c) => under(cwd, c.path));
|
|
1160
|
+
candidates.sort((x, y) => y.path.length - x.path.length || Number(y.rule) - Number(x.rule));
|
|
1161
|
+
return candidates[0]?.project ?? null;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1201
1164
|
// ../protocol/src/thread.ts
|
|
1202
1165
|
import { z as z19 } from "zod";
|
|
1203
1166
|
var ToolStatusSchema = z19.enum(["running", "success", "failed", "unknown"]);
|
|
@@ -1225,10 +1188,8 @@ var ThreadItemSchema = z19.discriminatedUnion("kind", [
|
|
|
1225
1188
|
kind: z19.literal("notice"),
|
|
1226
1189
|
...base,
|
|
1227
1190
|
notice: z19.enum(["idle", "exited", "unavailable", "expired", "delivery", "other"]),
|
|
1228
|
-
/** An `other` notice from Ledge: `task`, the task a `<ledge-task>` is about
|
|
1229
|
-
* session in (roles spec §3.3). An older front, which knows neither, shows it as any other notice. */
|
|
1191
|
+
/** An `other` notice from Ledge: `task`, the task a `<ledge-task>` is about. An older front, which does not know it, shows it as any other notice. */
|
|
1230
1192
|
task: z19.string().optional(),
|
|
1231
|
-
team: z19.string().optional(),
|
|
1232
1193
|
/** A task this session handed over (`outgoing`), and how (issue #92). */
|
|
1233
1194
|
taskOp: z19.enum(TRANSMISSION_OPS).optional(),
|
|
1234
1195
|
outgoing: z19.literal(true).optional(),
|
|
@@ -1363,8 +1324,8 @@ var DaemonInfoSchema = z21.object({
|
|
|
1363
1324
|
/** Its home folder, so a client shows the folders under it as `~` (absent from older daemons). */
|
|
1364
1325
|
home: z21.string().optional(),
|
|
1365
1326
|
mobile: z21.boolean().optional(),
|
|
1366
|
-
/**
|
|
1367
|
-
|
|
1327
|
+
/** Answers `openrig.status` and `openrig.act`: drives OpenRig on its machine. */
|
|
1328
|
+
openrig: z21.boolean().optional()
|
|
1368
1329
|
});
|
|
1369
1330
|
var UpdateFailureSchema = z21.enum(["git-install", "no-systemd", "sessions-at-risk", "npm-failed", "busy"]);
|
|
1370
1331
|
var ServerMessageSchema = z21.discriminatedUnion("type", [
|
|
@@ -1378,6 +1339,11 @@ var ServerMessageSchema = z21.discriminatedUnion("type", [
|
|
|
1378
1339
|
ReposInfoSchema,
|
|
1379
1340
|
ReposFoundSchema,
|
|
1380
1341
|
ModelsListingSchema,
|
|
1342
|
+
OpenRigStateMessageSchema,
|
|
1343
|
+
OpenRigDoneSchema,
|
|
1344
|
+
OpenRigSpecListSchema,
|
|
1345
|
+
OpenRigLaunchedSchema,
|
|
1346
|
+
OpenRigReseatedSchema,
|
|
1381
1347
|
/** `recents`: the folders of past sessions, most recent first. `launcher`: the command that runs `ledge` inside WSL
|
|
1382
1348
|
* (`[node, cli]`), so the overlay can attach a terminal to a session with `<launcher> attach <id>`. `daemon`: absent
|
|
1383
1349
|
* from daemons older than the auto-update. */
|
|
@@ -1419,7 +1385,7 @@ var ServerMessageSchema = z21.discriminatedUnion("type", [
|
|
|
1419
1385
|
/** 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. */
|
|
1420
1386
|
z21.object({ type: z21.literal("chat.step"), qid: z21.string(), step: ChatStepSchema }),
|
|
1421
1387
|
z21.object({ type: z21.literal("chat.delta"), qid: z21.string(), text: z21.string() }),
|
|
1422
|
-
z21.object({ type: z21.literal("chat.done"), qid: z21.string(), text: z21.string(), at: z21.string().datetime(), proposal: ChatProposalSchema.optional(), proposals: ChatProposalsSchema.optional(), relay: ChatRelaySchema.optional(), closes: ChatClosesSchema.optional(), projectProposal: ChatProjectProposalSchema.optional(),
|
|
1388
|
+
z21.object({ type: z21.literal("chat.done"), qid: z21.string(), text: z21.string(), at: z21.string().datetime(), proposal: ChatProposalSchema.optional(), proposals: ChatProposalsSchema.optional(), relay: ChatRelaySchema.optional(), closes: ChatClosesSchema.optional(), projectProposal: ChatProjectProposalSchema.optional(), tasks: ChatTasksSchema.optional(), actions: ChatActionsSchema.optional() }),
|
|
1423
1389
|
/** What a `chat.act` applied: the rows done, and the one that failed with why (the rows after it stay proposed). */
|
|
1424
1390
|
z21.object({ type: z21.literal("chat.acted"), rid: z21.string(), qid: z21.string(), done: z21.array(z21.number().int().min(0)), failed: z21.array(z21.object({
|
|
1425
1391
|
row: z21.number().int().min(0),
|
|
@@ -1429,8 +1395,8 @@ var ServerMessageSchema = z21.discriminatedUnion("type", [
|
|
|
1429
1395
|
})) }),
|
|
1430
1396
|
/** What an `action.run` came to: `row` the action as the daemon resolved it (its summary, its risk); `reason` why it was not
|
|
1431
1397
|
* done, with `code` (`refused`: not possible now; `agent`: a session may not run it; `confirm_required`: destructive, ask
|
|
1432
|
-
* again; `failed`: the handler turned it down; a free string, as an `error`'s)
|
|
1433
|
-
z21.object({ type: z21.literal("action.result"), rid: z21.string(), action: z21.string().min(1).max(40), row: ChatActionSchema.optional(), reason: z21.string().optional(), code: z21.string().optional()
|
|
1398
|
+
* again; `failed`: the handler turned it down; a free string, as an `error`'s). */
|
|
1399
|
+
z21.object({ type: z21.literal("action.result"), rid: z21.string(), action: z21.string().min(1).max(40), row: ChatActionSchema.optional(), reason: z21.string().optional(), code: z21.string().optional() }),
|
|
1434
1400
|
z21.object({ type: z21.literal("chat.error"), qid: z21.string(), message: z21.string() }),
|
|
1435
1401
|
z21.object({ type: z21.literal("chat.history"), turns: z21.array(ChatTurnSchema) }),
|
|
1436
1402
|
/** The daemon updating itself: npm is running, then the service restarts (the socket closes right after). */
|
|
@@ -1454,15 +1420,6 @@ var ServerMessageSchema = z21.discriminatedUnion("type", [
|
|
|
1454
1420
|
ContextPrefsMessageSchema,
|
|
1455
1421
|
HandoverResultSchema,
|
|
1456
1422
|
TaskUpdatedSchema,
|
|
1457
|
-
RolesListingSchema,
|
|
1458
|
-
TeamsMessageSchema,
|
|
1459
|
-
TeamUpdatedSchema,
|
|
1460
|
-
TeamLaunchedSchema,
|
|
1461
|
-
TeamFailedSchema,
|
|
1462
|
-
TeamSavedSchema,
|
|
1463
|
-
DefinitionsListingSchema,
|
|
1464
|
-
DefinitionResultSchema,
|
|
1465
|
-
TeamChangedSchema,
|
|
1466
1423
|
z21.object({
|
|
1467
1424
|
type: z21.literal("error"),
|
|
1468
1425
|
message: z21.string(),
|
|
@@ -1484,6 +1441,11 @@ var ClientMessageSchema = z21.discriminatedUnion("type", [
|
|
|
1484
1441
|
ReposInspectSchema,
|
|
1485
1442
|
ReposScanSchema,
|
|
1486
1443
|
ModelsListSchema,
|
|
1444
|
+
OpenRigStatusSchema,
|
|
1445
|
+
OpenRigActSchema,
|
|
1446
|
+
OpenRigSpecsSchema,
|
|
1447
|
+
OpenRigLaunchSchema,
|
|
1448
|
+
OpenRigSeatsSchema,
|
|
1487
1449
|
/** The overlay starts a session: `cwd` is a WSL path (`~` allowed), `name` a preferred bot name (the daemon picks a
|
|
1488
1450
|
* free one otherwise), `prompt` the agent's first instruction, `continue` resumes the folder's last conversation.
|
|
1489
1451
|
* With `qid` it is the chat card of that turn: the daemon launches the turn's proposal and ignores the other fields
|
|
@@ -1505,10 +1467,6 @@ var ClientMessageSchema = z21.discriminatedUnion("type", [
|
|
|
1505
1467
|
effort: EffortSchema.optional(),
|
|
1506
1468
|
/** OMP only: its approval mode, `always-ask` when left out. */
|
|
1507
1469
|
approval: OmpApprovalSchema.optional(),
|
|
1508
|
-
/** A role (spec 2026-10-25 roles §3.4): its prompt reaches the agent at every start, its defaults fill what is left out. */
|
|
1509
|
-
role: RoleIdSchema.optional(),
|
|
1510
|
-
/** A live team the new session joins at once, in `role`. */
|
|
1511
|
-
team: TeamIdSchema.optional(),
|
|
1512
1470
|
/** Routing by the fleet, removed before the message reaches the daemon. */
|
|
1513
1471
|
machineId: z21.string().optional()
|
|
1514
1472
|
}),
|
|
@@ -1596,12 +1554,18 @@ var ClientMessageSchema = z21.discriminatedUnion("type", [
|
|
|
1596
1554
|
z21.object({ type: z21.literal("session.delete"), id: z21.string() }),
|
|
1597
1555
|
/** 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. */
|
|
1598
1556
|
z21.object({ type: z21.literal("session.rename"), id: z21.string(), topic: z21.string().max(500) }),
|
|
1599
|
-
/** A seat's hook told it its team as `key` names it (`seatKey`): at its start, or at a turn after the team changed. */
|
|
1600
|
-
z21.object({ type: z21.literal("seat.seen"), id: z21.string(), key: z21.string().max(4e3) }),
|
|
1601
1557
|
z21.object({ type: z21.literal("session.thread"), id: z21.string() }),
|
|
1602
1558
|
z21.object({ type: z21.literal("session.register"), session: SessionSchema }),
|
|
1603
1559
|
/** `agent` and `cwd` describe the session when the daemon does not know it yet (a hook from an agent started without ledge). */
|
|
1604
|
-
z21.object({
|
|
1560
|
+
z21.object({
|
|
1561
|
+
type: z21.literal("session.event"),
|
|
1562
|
+
id: z21.string(),
|
|
1563
|
+
event: SessionEventSchema,
|
|
1564
|
+
agent: ToolSchema.optional(),
|
|
1565
|
+
cwd: z21.string().optional(),
|
|
1566
|
+
/** The OpenRig seat the agent runs in (`OPENRIG_SESSION_NAME`, `pod-member@rig`), when OpenRig launched it. */
|
|
1567
|
+
rigSeat: RigSeatNameSchema.optional()
|
|
1568
|
+
}),
|
|
1605
1569
|
z21.object({ type: z21.literal("session.unregister"), id: z21.string(), exitCode: z21.number().int().nullable() }),
|
|
1606
1570
|
z21.object({ type: z21.literal("snapshot.request") }),
|
|
1607
1571
|
z21.object({ type: z21.literal("chat.ask"), qid: z21.string().min(1), text: z21.string(), images: z21.array(ImageUploadSchema).max(ATTACHMENTS_MAX).optional(), tool: ToolSchema.optional() }),
|
|
@@ -1635,25 +1599,8 @@ var ClientMessageSchema = z21.discriminatedUnion("type", [
|
|
|
1635
1599
|
SessionHandoverSchema,
|
|
1636
1600
|
ContextSetSchema,
|
|
1637
1601
|
HandoverBriefSchema,
|
|
1638
|
-
HandoverShowSchema
|
|
1639
|
-
|
|
1640
|
-
TeamLaunchSchema,
|
|
1641
|
-
TeamJoinSchema,
|
|
1642
|
-
TeamLeaveSchema,
|
|
1643
|
-
TeamResumeSchema,
|
|
1644
|
-
TeamDissolveSchema,
|
|
1645
|
-
TeamSaveSchema,
|
|
1646
|
-
DefinitionsListSchema,
|
|
1647
|
-
RoleWriteSchema,
|
|
1648
|
-
RoleDeleteSchema,
|
|
1649
|
-
TemplateWriteSchema,
|
|
1650
|
-
TemplateDeleteSchema,
|
|
1651
|
-
TeamComposeSchema,
|
|
1652
|
-
TeamSeatSchema
|
|
1653
|
-
]).superRefine((m, ctx) => {
|
|
1654
|
-
const issue = "scope" in m ? scopeIssue(m) : null;
|
|
1655
|
-
if (issue) ctx.addIssue({ code: z21.ZodIssueCode.custom, message: issue, path: ["project"] });
|
|
1656
|
-
});
|
|
1602
|
+
HandoverShowSchema
|
|
1603
|
+
]);
|
|
1657
1604
|
function parseClientMessage(raw) {
|
|
1658
1605
|
return ClientMessageSchema.parse(raw);
|
|
1659
1606
|
}
|
|
@@ -1742,6 +1689,7 @@ function pickName(taken, preferred) {
|
|
|
1742
1689
|
if (first) return first;
|
|
1743
1690
|
for (let i = 2; ; i++) if (free(`${NAMES[0]}-${i}`)) return `${NAMES[0]}-${i}`;
|
|
1744
1691
|
}
|
|
1692
|
+
var namesInUse = (sessions) => [...sessions].filter((s) => s.state !== "exited" && !s.archivedAt).map((s) => s.name);
|
|
1745
1693
|
|
|
1746
1694
|
// ../protocol/src/topic.ts
|
|
1747
1695
|
var TOPIC_MAX = 80;
|
|
@@ -1824,7 +1772,7 @@ var MeResponseSchema = z23.object({
|
|
|
1824
1772
|
});
|
|
1825
1773
|
|
|
1826
1774
|
// ../protocol/src/phone.ts
|
|
1827
|
-
import { z as
|
|
1775
|
+
import { z as z25 } from "zod";
|
|
1828
1776
|
|
|
1829
1777
|
// ../protocol/src/push.ts
|
|
1830
1778
|
import { z as z24 } from "zod";
|
|
@@ -1870,51 +1818,6 @@ var PushPayloadSchema = z24.object({
|
|
|
1870
1818
|
tag: z24.string().regex(/^[A-Za-z0-9_-]{1,32}$/)
|
|
1871
1819
|
});
|
|
1872
1820
|
|
|
1873
|
-
// ../protocol/src/phoneTeams.ts
|
|
1874
|
-
import { z as z25 } from "zod";
|
|
1875
|
-
var scope = DefinitionScopeSchema;
|
|
1876
|
-
var PhoneSeatsSchema = z25.array(SeatSchema.strict()).min(1).max(TEAM_SEATS_MAX).refine(uniqueRoles, "a role twice in one team");
|
|
1877
|
-
var PhoneRoleDraftSchema = RoleDraftSchema.strict();
|
|
1878
|
-
var projectName = z25.string().max(80).nullable();
|
|
1879
|
-
var PhoneRoleSchema = z25.object({
|
|
1880
|
-
id: RoleIdSchema,
|
|
1881
|
-
label: z25.string().min(1).max(ROLE_LABEL_MAX),
|
|
1882
|
-
prompt: z25.string().max(ROLE_PROMPT_MAX),
|
|
1883
|
-
cut: z25.literal(true).optional(),
|
|
1884
|
-
tool: ToolSchema.optional(),
|
|
1885
|
-
model: ModelIdSchema.optional(),
|
|
1886
|
-
effort: EffortSchema.optional(),
|
|
1887
|
-
autonomy: AutonomySchema.optional(),
|
|
1888
|
-
scope,
|
|
1889
|
-
project: projectName,
|
|
1890
|
-
hash: DefinitionHashSchema,
|
|
1891
|
-
shadows: z25.literal(true).optional(),
|
|
1892
|
-
shadowed: z25.literal(true).optional(),
|
|
1893
|
-
shadowedIn: z25.array(z25.string().max(80)).min(1).max(8).optional()
|
|
1894
|
-
}).strict();
|
|
1895
|
-
var PhoneTemplateSchema = z25.object({ id: TemplateIdSchema, name: TeamNameSchema, seats: PhoneSeatsSchema, scope, project: projectName, hash: DefinitionHashSchema }).strict();
|
|
1896
|
-
var PhoneProblemSchema = z25.object({ file: z25.string().max(80), scope, project: projectName, reason: z25.string().max(200) }).strict();
|
|
1897
|
-
var PhoneCatalogSchema = z25.object({
|
|
1898
|
-
/** The names of the projects with a local repository: the ones a « Dépôt » scope or a « Lever » can name. */
|
|
1899
|
-
projects: z25.array(z25.string().max(80)).max(50),
|
|
1900
|
-
roles: z25.array(PhoneRoleSchema).max(200),
|
|
1901
|
-
templates: z25.array(PhoneTemplateSchema).max(100),
|
|
1902
|
-
problems: z25.array(PhoneProblemSchema).max(50)
|
|
1903
|
-
}).strict();
|
|
1904
|
-
var TEAMS_OPERATION_TYPES = ["role.write", "role.delete", "template.write", "template.delete", "team.launch", "team.compose", "team.seat", "team.dissolve"];
|
|
1905
|
-
var isTeamsOperation = (m) => TEAMS_OPERATION_TYPES.includes(m.type);
|
|
1906
|
-
function canonicalJson(v) {
|
|
1907
|
-
const sort = (x) => {
|
|
1908
|
-
if (Array.isArray(x)) return x.map(sort);
|
|
1909
|
-
if (x !== null && typeof x === "object") {
|
|
1910
|
-
const o = x;
|
|
1911
|
-
return Object.fromEntries(Object.keys(o).sort().filter((k) => o[k] !== void 0).map((k) => [k, sort(o[k])]));
|
|
1912
|
-
}
|
|
1913
|
-
return x;
|
|
1914
|
-
};
|
|
1915
|
-
return JSON.stringify(sort(v));
|
|
1916
|
-
}
|
|
1917
|
-
|
|
1918
1821
|
// ../protocol/src/phone.ts
|
|
1919
1822
|
var PHONE_PROTOCOL = 1;
|
|
1920
1823
|
var PAD_TIERS = [1024, 4096, 16384, 65536, 262144, 655360];
|
|
@@ -1933,38 +1836,38 @@ var THREAD_TEXT_MAX = 8192;
|
|
|
1933
1836
|
var TOOL_TEXT_MAX = 2048;
|
|
1934
1837
|
var CHECKLIST_TASKS_MAX = 50;
|
|
1935
1838
|
var CHECKLIST_TEXT_MAX = 200;
|
|
1936
|
-
var ChecklistStatusSchema =
|
|
1937
|
-
var PhoneChecklistSchema =
|
|
1938
|
-
tasks:
|
|
1939
|
-
done:
|
|
1940
|
-
total:
|
|
1941
|
-
cut:
|
|
1942
|
-
});
|
|
1943
|
-
var PhoneChecklistSummarySchema =
|
|
1944
|
-
done:
|
|
1945
|
-
total:
|
|
1946
|
-
current:
|
|
1947
|
-
cut:
|
|
1839
|
+
var ChecklistStatusSchema = z25.enum(["pending", "in_progress", "completed"]);
|
|
1840
|
+
var PhoneChecklistSchema = z25.object({
|
|
1841
|
+
tasks: z25.array(z25.object({ text: z25.string().max(CHECKLIST_TEXT_MAX), status: ChecklistStatusSchema })).max(CHECKLIST_TASKS_MAX),
|
|
1842
|
+
done: z25.number().int().nonnegative(),
|
|
1843
|
+
total: z25.number().int().nonnegative(),
|
|
1844
|
+
cut: z25.literal(true).optional()
|
|
1845
|
+
});
|
|
1846
|
+
var PhoneChecklistSummarySchema = z25.object({
|
|
1847
|
+
done: z25.number().int().nonnegative(),
|
|
1848
|
+
total: z25.number().int().nonnegative(),
|
|
1849
|
+
current: z25.string().max(CHECKLIST_TEXT_MAX).optional(),
|
|
1850
|
+
cut: z25.literal(true).optional()
|
|
1948
1851
|
});
|
|
1949
1852
|
var PENDING_BODY_MAX = 65536;
|
|
1950
1853
|
var SNAPSHOT_BODY_MAX = 2048;
|
|
1951
|
-
var RiskSchema =
|
|
1952
|
-
var RiskReasonSchema =
|
|
1953
|
-
var OperationIdSchema =
|
|
1954
|
-
var OperationStatusSchema =
|
|
1955
|
-
var OperationReasonSchema =
|
|
1956
|
-
var CapabilitiesSchema =
|
|
1854
|
+
var RiskSchema = z25.enum(["low", "high"]);
|
|
1855
|
+
var RiskReasonSchema = z25.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"]);
|
|
1856
|
+
var OperationIdSchema = z25.string().uuid();
|
|
1857
|
+
var OperationStatusSchema = z25.enum(["received", "applied", "rejected", "failed"]);
|
|
1858
|
+
var OperationReasonSchema = z25.enum([...RefusalCodeSchema.options, "untypable", "confirm_required", "conflict", "assertion_invalid", "assertion_expired", "scheduled", ...ModelRefusalSchema.options]);
|
|
1859
|
+
var CapabilitiesSchema = z25.object({
|
|
1957
1860
|
/** A question can be answered in free text. */
|
|
1958
|
-
freeTextAnswer:
|
|
1861
|
+
freeTextAnswer: z25.boolean(),
|
|
1959
1862
|
/** The session's accept/deny can be typed; absent = true. */
|
|
1960
|
-
decide:
|
|
1863
|
+
decide: z25.boolean().optional(),
|
|
1961
1864
|
/** OMP's dialog questions can be answered from the phone; absent = false. */
|
|
1962
|
-
questions:
|
|
1865
|
+
questions: z25.boolean().optional()
|
|
1963
1866
|
});
|
|
1964
1867
|
var UNTYPABLE = /[\u0000-\u001f\u007f-\u009f\u200b\u200e\u200f\u2028-\u202e\u2066-\u2069\ufeff]/;
|
|
1965
|
-
var CapabilitiesByToolSchema =
|
|
1966
|
-
var PhonePendingSchema = PendingSchema.extend({ key:
|
|
1967
|
-
var SwitchableSessionSchema = SessionSchema.extend({ canSwitch:
|
|
1868
|
+
var CapabilitiesByToolSchema = z25.object({ claude: CapabilitiesSchema, codex: CapabilitiesSchema, cursor: CapabilitiesSchema, omp: CapabilitiesSchema });
|
|
1869
|
+
var PhonePendingSchema = PendingSchema.extend({ key: z25.string().max(64), risk: RiskSchema, riskReason: RiskReasonSchema, cut: z25.literal(true).optional() });
|
|
1870
|
+
var SwitchableSessionSchema = SessionSchema.extend({ canSwitch: z25.literal(true).optional() });
|
|
1968
1871
|
var PhoneSessionSchema = SwitchableSessionSchema.pick({
|
|
1969
1872
|
id: true,
|
|
1970
1873
|
name: true,
|
|
@@ -1985,10 +1888,6 @@ var PhoneSessionSchema = SwitchableSessionSchema.pick({
|
|
|
1985
1888
|
effort: true,
|
|
1986
1889
|
modelNext: true,
|
|
1987
1890
|
canSwitch: true,
|
|
1988
|
-
/** Its role and its live team (ledge home spec §2.4): the agents screen groups a project's sessions by table. */
|
|
1989
|
-
role: true,
|
|
1990
|
-
roleLabel: true,
|
|
1991
|
-
team: true,
|
|
1992
1891
|
/** Its context and its relief (context handover spec §3.2): the phone shows the gauge; the relief is started from the PC. */
|
|
1993
1892
|
context: true,
|
|
1994
1893
|
relieves: true,
|
|
@@ -1996,373 +1895,291 @@ var PhoneSessionSchema = SwitchableSessionSchema.pick({
|
|
|
1996
1895
|
exitedAt: true
|
|
1997
1896
|
}).extend({
|
|
1998
1897
|
pending: PhonePendingSchema.optional(),
|
|
1999
|
-
unread:
|
|
2000
|
-
handover:
|
|
1898
|
+
unread: z25.boolean(),
|
|
1899
|
+
handover: z25.object({ state: HandoverStateSchema, toName: z25.string().max(80).optional() }).strict().optional(),
|
|
2001
1900
|
/** Absent: the agent has no checklist. */
|
|
2002
1901
|
checklist: PhoneChecklistSummarySchema.optional(),
|
|
2003
1902
|
/** Started without Ledge (`hook_only`): the phone can neither close nor resume it. */
|
|
2004
|
-
readOnly:
|
|
1903
|
+
readOnly: z25.literal(true).optional()
|
|
2005
1904
|
});
|
|
2006
|
-
var B64U2 =
|
|
2007
|
-
var CredentialSchema =
|
|
1905
|
+
var B64U2 = z25.string().regex(/^[A-Za-z0-9_-]*$/);
|
|
1906
|
+
var CredentialSchema = z25.object({
|
|
2008
1907
|
id: B64U2.max(1366),
|
|
2009
1908
|
publicKey: B64U2.max(2048),
|
|
2010
|
-
alg:
|
|
1909
|
+
alg: z25.union([z25.literal(-7), z25.literal(-257)]),
|
|
2011
1910
|
clientDataJSON: B64U2.max(4096),
|
|
2012
1911
|
authenticatorData: B64U2.max(4096),
|
|
2013
|
-
transports:
|
|
1912
|
+
transports: z25.array(z25.string().max(20)).max(8).optional()
|
|
2014
1913
|
});
|
|
2015
|
-
var AssertionSchema =
|
|
1914
|
+
var AssertionSchema = z25.object({
|
|
2016
1915
|
id: B64U2.max(1366),
|
|
2017
1916
|
clientDataJSON: B64U2.max(4096),
|
|
2018
1917
|
authenticatorData: B64U2.max(4096),
|
|
2019
1918
|
signature: B64U2.max(1024)
|
|
2020
1919
|
});
|
|
2021
|
-
var
|
|
2022
|
-
var ConfirmPurposeSchema = z26.enum(["register", "decide", "launch", "close", "act", "define", "team", "pc"]);
|
|
1920
|
+
var ConfirmPurposeSchema = z25.enum(["register", "decide", "launch", "close", "act", "pc"]);
|
|
2023
1921
|
var PhoneChatStepSchema = ChatStepSchema.pick({ kind: true, id: true, name: true }).strict();
|
|
2024
|
-
var PhoneChatProposalSchema =
|
|
2025
|
-
project:
|
|
1922
|
+
var PhoneChatProposalSchema = z25.object({
|
|
1923
|
+
project: z25.string().max(80),
|
|
2026
1924
|
tool: ToolSchema,
|
|
2027
|
-
prompt:
|
|
2028
|
-
launchedId:
|
|
2029
|
-
failed:
|
|
1925
|
+
prompt: z25.string().max(TOOL_TEXT_MAX).optional(),
|
|
1926
|
+
launchedId: z25.string().optional(),
|
|
1927
|
+
failed: z25.literal(true).optional()
|
|
2030
1928
|
}).strict();
|
|
2031
|
-
var PhoneChatRelaySchema =
|
|
2032
|
-
id:
|
|
2033
|
-
name:
|
|
1929
|
+
var PhoneChatRelaySchema = z25.object({
|
|
1930
|
+
id: z25.string().min(1),
|
|
1931
|
+
name: z25.string(),
|
|
2034
1932
|
tool: ToolSchema,
|
|
2035
|
-
text:
|
|
2036
|
-
status:
|
|
2037
|
-
sentAt:
|
|
2038
|
-
failed:
|
|
1933
|
+
text: z25.string().max(TOOL_TEXT_MAX),
|
|
1934
|
+
status: z25.enum(["queued", "sent"]).optional(),
|
|
1935
|
+
sentAt: z25.string().datetime().optional(),
|
|
1936
|
+
failed: z25.literal(true).optional(),
|
|
2039
1937
|
/** With `failed`: why, as the PC's code (never its text). */
|
|
2040
|
-
code:
|
|
1938
|
+
code: z25.string().max(40).optional()
|
|
2041
1939
|
}).strict();
|
|
2042
|
-
var CloseHowSchema =
|
|
2043
|
-
var PhoneChatCloseSchema =
|
|
2044
|
-
id:
|
|
2045
|
-
name:
|
|
1940
|
+
var CloseHowSchema = z25.enum(["exit", "killed"]);
|
|
1941
|
+
var PhoneChatCloseSchema = z25.object({
|
|
1942
|
+
id: z25.string().min(1),
|
|
1943
|
+
name: z25.string(),
|
|
2046
1944
|
tool: ToolSchema,
|
|
2047
1945
|
how: CloseHowSchema.optional(),
|
|
2048
|
-
closedAt:
|
|
2049
|
-
failed:
|
|
2050
|
-
}).strict();
|
|
2051
|
-
var PhoneChatTeamSchema = z26.object({
|
|
2052
|
-
project: z26.string().max(80),
|
|
2053
|
-
name: z26.string().max(60),
|
|
2054
|
-
template: z26.string().max(64).optional(),
|
|
2055
|
-
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),
|
|
2056
|
-
teamId: z26.string().max(40).optional(),
|
|
2057
|
-
launchedAt: z26.string().datetime().optional(),
|
|
2058
|
-
failed: z26.literal(true).optional()
|
|
1946
|
+
closedAt: z25.string().datetime().optional(),
|
|
1947
|
+
failed: z25.literal(true).optional()
|
|
2059
1948
|
}).strict();
|
|
2060
|
-
var PhoneChatTaskSchema =
|
|
2061
|
-
to:
|
|
2062
|
-
toName:
|
|
2063
|
-
title:
|
|
2064
|
-
text:
|
|
2065
|
-
taskId:
|
|
2066
|
-
ownerName:
|
|
2067
|
-
state:
|
|
2068
|
-
failed:
|
|
1949
|
+
var PhoneChatTaskSchema = z25.object({
|
|
1950
|
+
to: z25.string().max(80),
|
|
1951
|
+
toName: z25.string().max(80).optional(),
|
|
1952
|
+
title: z25.string().max(200),
|
|
1953
|
+
text: z25.string().max(TOOL_TEXT_MAX).optional(),
|
|
1954
|
+
taskId: z25.string().max(40).optional(),
|
|
1955
|
+
ownerName: z25.string().max(80).optional(),
|
|
1956
|
+
state: z25.enum(["open", "taken", "done", "refused", "dropped"]).optional(),
|
|
1957
|
+
failed: z25.literal(true).optional()
|
|
2069
1958
|
}).strict();
|
|
2070
|
-
var PhoneChatActionSchema =
|
|
2071
|
-
action:
|
|
2072
|
-
summary:
|
|
1959
|
+
var PhoneChatActionSchema = z25.object({
|
|
1960
|
+
action: z25.string().min(1).max(40),
|
|
1961
|
+
summary: z25.string().max(300),
|
|
2073
1962
|
vars: ActionVarsSchema.optional(),
|
|
2074
|
-
detail:
|
|
2075
|
-
detailCut:
|
|
1963
|
+
detail: z25.string().max(TOOL_TEXT_MAX).optional(),
|
|
1964
|
+
detailCut: z25.literal(true).optional(),
|
|
2076
1965
|
risk: ActionRiskSchema,
|
|
2077
|
-
session:
|
|
2078
|
-
team: z26.string().max(40).optional(),
|
|
1966
|
+
session: z25.string().max(100).optional(),
|
|
2079
1967
|
state: ChatActionStateSchema.optional(),
|
|
2080
|
-
doneAt:
|
|
2081
|
-
code:
|
|
1968
|
+
doneAt: z25.string().datetime().optional(),
|
|
1969
|
+
code: z25.string().max(40).optional()
|
|
2082
1970
|
}).strict();
|
|
2083
|
-
var
|
|
2084
|
-
id:
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
template: z26.string().max(64).optional(),
|
|
2089
|
-
/** Absent from a daemon older than the phone: the phone then says no start time. */
|
|
2090
|
-
createdAt: z26.string().optional(),
|
|
2091
|
-
/** `tool`, `model` and `effort` are what the seat was composed with; `leaving` is a seat that finishes its turn and is then closed. */
|
|
2092
|
-
seats: z26.array(z26.object({
|
|
2093
|
-
role: z26.string().max(40),
|
|
2094
|
-
sessionId: z26.string().max(100).nullable(),
|
|
2095
|
-
tool: ToolSchema.optional(),
|
|
2096
|
-
model: ModelIdSchema.optional(),
|
|
2097
|
-
effort: EffortSchema.optional(),
|
|
2098
|
-
leaving: z26.literal(true).optional()
|
|
2099
|
-
}).strict()).max(16),
|
|
2100
|
-
done: z26.number().int().min(0),
|
|
2101
|
-
given: z26.number().int().min(0)
|
|
2102
|
-
}).strict();
|
|
2103
|
-
var PhoneTaskSchema = z26.object({
|
|
2104
|
-
id: z26.string().max(40),
|
|
2105
|
-
title: z26.string().max(200),
|
|
2106
|
-
owner: z26.string().max(100),
|
|
2107
|
-
ownerName: z26.string().max(80),
|
|
2108
|
-
ownerRole: z26.string().max(40).optional(),
|
|
1971
|
+
var PhoneTaskSchema = z25.object({
|
|
1972
|
+
id: z25.string().max(40),
|
|
1973
|
+
title: z25.string().max(200),
|
|
1974
|
+
owner: z25.string().max(100),
|
|
1975
|
+
ownerName: z25.string().max(80),
|
|
2109
1976
|
/** Who gave it: `ledge` for Ledge's own; a session for a decision it put to the user (owner `ledge`), with its detail (the options). */
|
|
2110
|
-
giver:
|
|
2111
|
-
giverName:
|
|
2112
|
-
text:
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
updatedAt: z26.string(),
|
|
2120
|
-
seen: z26.literal(true).optional()
|
|
1977
|
+
giver: z25.string().max(100).optional(),
|
|
1978
|
+
giverName: z25.string().max(80).optional(),
|
|
1979
|
+
text: z25.string().max(TOOL_TEXT_MAX).optional(),
|
|
1980
|
+
state: z25.enum(["open", "taken", "done", "refused", "dropped"]),
|
|
1981
|
+
result: z25.string().max(TOOL_TEXT_MAX).optional(),
|
|
1982
|
+
cut: z25.literal(true).optional(),
|
|
1983
|
+
at: z25.string(),
|
|
1984
|
+
updatedAt: z25.string(),
|
|
1985
|
+
seen: z25.literal(true).optional()
|
|
2121
1986
|
}).strict();
|
|
2122
|
-
var ChatErrorCodeSchema =
|
|
2123
|
-
var PhoneChatTurnSchema =
|
|
1987
|
+
var ChatErrorCodeSchema = z25.enum(["busy", "timeout", "cancelled", "failed"]);
|
|
1988
|
+
var PhoneChatTurnSchema = z25.object({
|
|
2124
1989
|
qid: OperationIdSchema,
|
|
2125
|
-
question:
|
|
2126
|
-
askedAt:
|
|
2127
|
-
steps:
|
|
2128
|
-
answer:
|
|
2129
|
-
answeredAt:
|
|
1990
|
+
question: z25.string().max(MESSAGE_MAX),
|
|
1991
|
+
askedAt: z25.string().datetime(),
|
|
1992
|
+
steps: z25.array(PhoneChatStepSchema).max(50),
|
|
1993
|
+
answer: z25.string().max(THREAD_TEXT_MAX).optional(),
|
|
1994
|
+
answeredAt: z25.string().datetime().optional(),
|
|
2130
1995
|
error: ChatErrorCodeSchema.optional(),
|
|
2131
|
-
proposals:
|
|
1996
|
+
proposals: z25.array(PhoneChatProposalSchema).max(MAX_PROPOSALS).optional(),
|
|
2132
1997
|
relay: PhoneChatRelaySchema.optional(),
|
|
2133
|
-
closes:
|
|
2134
|
-
cut:
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
attachments: z26.array(AttachmentRefSchema).max(ATTACHMENTS_MAX).optional()
|
|
1998
|
+
closes: z25.array(PhoneChatCloseSchema).min(1).max(MAX_PROPOSALS).optional(),
|
|
1999
|
+
cut: z25.literal(true).optional(),
|
|
2000
|
+
tasks: z25.array(PhoneChatTaskSchema).min(1).max(MAX_PROPOSALS).optional(),
|
|
2001
|
+
actions: z25.array(PhoneChatActionSchema).min(1).max(MAX_PROPOSALS).optional(),
|
|
2002
|
+
ignoredAt: z25.string().datetime().optional(),
|
|
2003
|
+
attachments: z25.array(AttachmentRefSchema).max(ATTACHMENTS_MAX).optional()
|
|
2140
2004
|
}).strict();
|
|
2141
2005
|
var CHAT_HISTORY_BUDGET = 393216;
|
|
2142
|
-
var sessionId =
|
|
2143
|
-
var PhoneExpectSchema = PendingSchema.pick({ kind: true, text: true }).extend({ key:
|
|
2144
|
-
var CardRowsSchema =
|
|
2145
|
-
var
|
|
2146
|
-
var PcActionSchema =
|
|
2006
|
+
var sessionId = z25.string().min(1).max(100);
|
|
2007
|
+
var PhoneExpectSchema = PendingSchema.pick({ kind: true, text: true }).extend({ key: z25.string().min(1).max(64) });
|
|
2008
|
+
var CardRowsSchema = z25.array(z25.number().int().min(0).max(MAX_PROPOSALS - 1)).min(1).max(MAX_PROPOSALS).refine((r) => new Set(r).size === r.length, "a row twice");
|
|
2009
|
+
var pcOp = { op: OperationIdSchema, assertion: AssertionSchema.optional() };
|
|
2010
|
+
var PcActionSchema = z25.enum(["update", "restart"]);
|
|
2147
2011
|
var pcSubject = (action, version) => action === "update" ? `update@${version ?? ""}` : "restart";
|
|
2148
|
-
var
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
z26.object({ type: z26.literal("session.thread"), id: sessionId }),
|
|
2012
|
+
var PhoneClientMessageSchema = z25.discriminatedUnion("type", [
|
|
2013
|
+
z25.object({ type: z25.literal("snapshot.request") }),
|
|
2014
|
+
z25.object({ type: z25.literal("session.thread"), id: sessionId }),
|
|
2152
2015
|
/** The session's request with its whole body (up to `PENDING_BODY_MAX`). */
|
|
2153
|
-
|
|
2016
|
+
z25.object({ type: z25.literal("session.pending"), id: sessionId }),
|
|
2154
2017
|
/** The session whose terminal the phone shows; null when it shows none. */
|
|
2155
|
-
|
|
2156
|
-
|
|
2018
|
+
z25.object({ type: z25.literal("session.watch"), id: sessionId.nullable() }),
|
|
2019
|
+
z25.object({ type: z25.literal("session.read"), id: sessionId, at: z25.string().datetime() }),
|
|
2157
2020
|
/**
|
|
2158
2021
|
* Asks for a challenge. One object for every purpose: the gateway refuses a `decide` without `id` and `expect`. A `close`
|
|
2159
2022
|
* or `act` names a turn of the chat (`qid`) or a session (`id`, for `session.close` and `session.resume`).
|
|
2160
2023
|
*/
|
|
2161
|
-
|
|
2162
|
-
type:
|
|
2024
|
+
z25.object({
|
|
2025
|
+
type: z25.literal("confirm.prepare"),
|
|
2163
2026
|
purpose: ConfirmPurposeSchema,
|
|
2164
2027
|
id: sessionId.optional(),
|
|
2165
2028
|
expect: PhoneExpectSchema.optional(),
|
|
2166
2029
|
qid: OperationIdSchema.optional(),
|
|
2167
|
-
/** sha256 of the `define` or `team` operation the challenge is for (`teamsDigest`). */
|
|
2168
|
-
digest: TeamsDigestSchema.optional(),
|
|
2169
2030
|
/** A `pc` challenge: what it is for, and for an update the version it covers. */
|
|
2170
2031
|
action: PcActionSchema.optional(),
|
|
2171
|
-
version:
|
|
2032
|
+
version: z25.string().regex(SEMVER).optional()
|
|
2172
2033
|
}),
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
type:
|
|
2034
|
+
z25.object({ type: z25.literal("credential.register"), op: OperationIdSchema, credential: CredentialSchema }),
|
|
2035
|
+
z25.object({
|
|
2036
|
+
type: z25.literal("session.decide"),
|
|
2176
2037
|
op: OperationIdSchema,
|
|
2177
2038
|
id: sessionId,
|
|
2178
2039
|
decision: DecisionSchema,
|
|
2179
|
-
note:
|
|
2040
|
+
note: z25.string().trim().min(1).max(NOTE_MAX).optional(),
|
|
2180
2041
|
/** The request the phone showed: refused unless it is still the pending one. */
|
|
2181
2042
|
expect: PhoneExpectSchema,
|
|
2182
2043
|
/** The device check over the challenge of `confirm.prepare`; required by the daemon for a high-risk accept. */
|
|
2183
2044
|
assertion: AssertionSchema.optional()
|
|
2184
2045
|
}),
|
|
2185
|
-
|
|
2186
|
-
type:
|
|
2046
|
+
z25.object({
|
|
2047
|
+
type: z25.literal("session.reply"),
|
|
2187
2048
|
op: OperationIdSchema,
|
|
2188
2049
|
id: sessionId,
|
|
2189
|
-
text:
|
|
2190
|
-
attachments:
|
|
2050
|
+
text: z25.string().max(MESSAGE_MAX),
|
|
2051
|
+
attachments: z25.array(AttachmentIdSchema).max(ATTACHMENTS_MAX).optional(),
|
|
2191
2052
|
/** The request the reply answers, or null when the phone showed none: refused if the session's request is no longer that one. */
|
|
2192
2053
|
expect: PhoneExpectSchema.nullable(),
|
|
2193
2054
|
assertion: AssertionSchema.optional()
|
|
2194
2055
|
}),
|
|
2195
2056
|
/** OMP's `ask`: the answers to every question of the dialog `requestId`, in order; `cancel` declines it. Bounds as the local `session.answer`. */
|
|
2196
|
-
|
|
2197
|
-
type:
|
|
2057
|
+
z25.object({
|
|
2058
|
+
type: z25.literal("session.answer"),
|
|
2198
2059
|
op: OperationIdSchema,
|
|
2199
2060
|
id: sessionId,
|
|
2200
|
-
requestId:
|
|
2201
|
-
answers:
|
|
2202
|
-
cancel:
|
|
2061
|
+
requestId: z25.string().min(1).max(200),
|
|
2062
|
+
answers: z25.array(z25.object({ id: z25.string().max(200), selected: z25.array(z25.string().max(2e3)).max(100), text: z25.string().max(2e4).optional() })).max(50),
|
|
2063
|
+
cancel: z25.literal(true).optional(),
|
|
2203
2064
|
expect: PhoneExpectSchema
|
|
2204
2065
|
}),
|
|
2205
|
-
|
|
2066
|
+
z25.object({ type: z25.literal("session.interrupt"), op: OperationIdSchema, id: sessionId }),
|
|
2206
2067
|
/** Ends a live session as `/exit` would, killed as a last resort; answered with its `how`. Passkey, purpose `close`, over the session. */
|
|
2207
|
-
|
|
2068
|
+
z25.object({ type: z25.literal("session.close"), op: OperationIdSchema, id: sessionId, assertion: AssertionSchema.optional() }),
|
|
2208
2069
|
/** Starts an ended session again on its conversation. Passkey, purpose `act`, over the session. */
|
|
2209
|
-
|
|
2070
|
+
z25.object({ type: z25.literal("session.resume"), op: OperationIdSchema, id: sessionId, assertion: AssertionSchema.optional() }),
|
|
2210
2071
|
/** Changes a live session's model and effort, `null` for the agent's own default; answered by `operation.result` and, when refused, `session.model.failed`. */
|
|
2211
|
-
|
|
2072
|
+
z25.object({ type: z25.literal("session.model"), op: OperationIdSchema, id: sessionId, model: ModelIdSchema.nullable(), effort: EffortSchema.nullable() }),
|
|
2212
2073
|
/** The models an agent offers on the PC. */
|
|
2213
|
-
|
|
2074
|
+
z25.object({ type: z25.literal("models.list"), tool: ToolSchema }),
|
|
2214
2075
|
/** The phone drops its passkey from the daemon. */
|
|
2215
|
-
|
|
2076
|
+
z25.object({ type: z25.literal("device.forget"), op: OperationIdSchema }),
|
|
2216
2077
|
/** The phone's push subscription, with the VAPID key it was made with (so a key change is seen). */
|
|
2217
|
-
|
|
2218
|
-
|
|
2078
|
+
z25.object({ type: z25.literal("push.subscribe"), op: OperationIdSchema, subscription: PushSubscriptionSchema, key: B64U2.length(87) }),
|
|
2079
|
+
z25.object({ type: z25.literal("push.unsubscribe"), op: OperationIdSchema }),
|
|
2219
2080
|
/** The phone's own chat with Ledge. */
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2081
|
+
z25.object({ type: z25.literal("chat.ask"), qid: OperationIdSchema, text: z25.string().trim().max(MESSAGE_MAX), attachments: z25.array(AttachmentIdSchema).max(ATTACHMENTS_MAX).optional() }),
|
|
2082
|
+
z25.object({ type: z25.literal("chat.cancel"), qid: OperationIdSchema }),
|
|
2083
|
+
z25.object({ type: z25.literal("chat.reset") }),
|
|
2084
|
+
z25.object({ type: z25.literal("chat.history") }),
|
|
2224
2085
|
/** An image to store, sent alone before the message that names it; no `id`, and at most `ATTACHMENT_MAX` bytes. */
|
|
2225
|
-
AttachmentPutSchema.pick({ type: true, requestId: true }).extend({ image: ImageUploadSchema.extend({ data:
|
|
2086
|
+
AttachmentPutSchema.pick({ type: true, requestId: true }).extend({ image: ImageUploadSchema.extend({ data: z25.string().min(1).max(b64Max(ATTACHMENT_MAX)) }) }),
|
|
2226
2087
|
AttachmentGetSchema.pick({ type: true, requestId: true, attachment: true, preview: true }),
|
|
2227
|
-
|
|
2088
|
+
z25.object({ type: z25.literal("chat.relay"), op: OperationIdSchema, qid: OperationIdSchema }),
|
|
2228
2089
|
/** Takes the card's queued instruction back out of the queue, as the local `session.relay.cancel`. */
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
/** The turn's team card (roles spec §3.8): launched like a session card, with the device check (purpose `launch`, the turn). */
|
|
2233
|
-
z26.object({ type: z26.literal("chat.team"), op: OperationIdSchema, qid: OperationIdSchema, assertion: AssertionSchema.optional() }),
|
|
2090
|
+
z25.object({ type: z25.literal("chat.relay.cancel"), op: OperationIdSchema, qid: OperationIdSchema }),
|
|
2091
|
+
z25.object({ type: z25.literal("chat.launch"), op: OperationIdSchema, qid: OperationIdSchema, rows: CardRowsSchema.optional(), assertion: AssertionSchema.optional() }),
|
|
2092
|
+
z25.object({ type: z25.literal("chat.close"), op: OperationIdSchema, qid: OperationIdSchema, rows: CardRowsSchema.optional(), assertion: AssertionSchema.optional() }),
|
|
2234
2093
|
/** A row of the turn's task card: given by Ledge. */
|
|
2235
|
-
|
|
2094
|
+
z25.object({ type: z25.literal("chat.task"), op: OperationIdSchema, qid: OperationIdSchema, row: z25.number().int().min(0).max(MAX_PROPOSALS - 1) }),
|
|
2236
2095
|
/** Rows of the turn's generic card (action registry spec §5): `confirmed` as the local `chat.act`; a row whose action asks
|
|
2237
2096
|
* for a device check (`phone`) needs one assertion, purpose `act`, over the turn. */
|
|
2238
|
-
|
|
2239
|
-
type:
|
|
2097
|
+
z25.object({
|
|
2098
|
+
type: z25.literal("chat.act"),
|
|
2240
2099
|
op: OperationIdSchema,
|
|
2241
2100
|
qid: OperationIdSchema,
|
|
2242
2101
|
rows: CardRowsSchema.optional(),
|
|
2243
|
-
confirmed:
|
|
2102
|
+
confirmed: z25.literal(true).optional(),
|
|
2244
2103
|
assertion: AssertionSchema.optional(),
|
|
2245
2104
|
/** « Refuser », as the local `chat.act`: no passkey, no confirmation. */
|
|
2246
|
-
deny:
|
|
2105
|
+
deny: z25.literal(true).optional()
|
|
2247
2106
|
}),
|
|
2248
2107
|
/** « Ignorer » the turn's cards, or `undo` (« Revoir »), as the local `chat.ignore`. */
|
|
2249
|
-
|
|
2250
|
-
/** « Reprendre » a resting team. */
|
|
2251
|
-
z26.object({ type: z26.literal("team.resume"), op: OperationIdSchema, team: z26.string().min(1).max(40) }),
|
|
2108
|
+
z25.object({ type: z25.literal("chat.ignore"), op: OperationIdSchema, qid: OperationIdSchema, undo: z25.literal(true).optional() }),
|
|
2252
2109
|
/** Puts a closed task Ledge gave away from « À traiter ». */
|
|
2253
|
-
|
|
2110
|
+
z25.object({ type: z25.literal("task.seen"), op: OperationIdSchema, task: z25.string().min(1).max(40) }),
|
|
2254
2111
|
/** Whether the phone's app is in front: a device that is visible gets no push. */
|
|
2255
|
-
|
|
2256
|
-
/** The roles, templates and problems of every scope the phone may name; then one role whole, when the catalog cut its prompt. */
|
|
2257
|
-
z26.object({ type: z26.literal("teams.catalog") }),
|
|
2258
|
-
z26.object({ type: z26.literal("teams.role"), ...teamsScope, id: RoleIdSchema }).strict(),
|
|
2259
|
-
/** `base` is the hash the phone was shown, null to create. */
|
|
2260
|
-
z26.object({ type: z26.literal("role.write"), ...teamsOp, ...teamsScope, role: PhoneRoleDraftSchema, base: DefinitionHashSchema.nullable() }).strict(),
|
|
2261
|
-
z26.object({ type: z26.literal("role.delete"), ...teamsOp, ...teamsScope, id: RoleIdSchema, base: DefinitionHashSchema }).strict(),
|
|
2262
|
-
/** No `id`: create, the id comes from the name. */
|
|
2263
|
-
z26.object({ type: z26.literal("template.write"), ...teamsOp, ...teamsScope, id: TemplateIdSchema.optional(), name: TeamNameSchema, seats: PhoneSeatsSchema, base: DefinitionHashSchema.nullable() }).strict(),
|
|
2264
|
-
z26.object({ type: z26.literal("template.delete"), ...teamsOp, ...teamsScope, id: TemplateIdSchema, base: DefinitionHashSchema }).strict(),
|
|
2265
|
-
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(),
|
|
2266
|
-
z26.object({ type: z26.literal("team.compose"), ...teamsOp, team: TeamIdSchema, seats: PhoneSeatsSchema }).strict(),
|
|
2267
|
-
z26.object({ type: z26.literal("team.seat"), ...teamsOp, team: TeamIdSchema, role: RoleIdSchema, action: z26.enum(["start", "restart"]) }).strict(),
|
|
2268
|
-
z26.object({ type: z26.literal("team.dissolve"), ...teamsOp, team: TeamIdSchema }).strict(),
|
|
2112
|
+
z25.object({ type: z25.literal("presence"), visible: z25.boolean() }),
|
|
2269
2113
|
/** Installs `version` on the PC, then restarts its daemon; the phone asks for its own build's version. Passkey, purpose `pc`. */
|
|
2270
|
-
|
|
2114
|
+
z25.object({ type: z25.literal("daemon.update"), ...pcOp, version: z25.string().regex(SEMVER) }).strict(),
|
|
2271
2115
|
/** Restarts the PC's daemon without installing anything. Passkey, purpose `pc`. */
|
|
2272
|
-
|
|
2273
|
-
])
|
|
2274
|
-
|
|
2275
|
-
if (issue) ctx.addIssue({ code: z26.ZodIssueCode.custom, message: issue, path: ["project"] });
|
|
2276
|
-
});
|
|
2277
|
-
var PhoneModelChoiceSchema = z26.object({
|
|
2116
|
+
z25.object({ type: z25.literal("daemon.restart"), ...pcOp }).strict()
|
|
2117
|
+
]);
|
|
2118
|
+
var PhoneModelChoiceSchema = z25.object({
|
|
2278
2119
|
id: ModelChoiceSchema.shape.id.max(120),
|
|
2279
|
-
label:
|
|
2280
|
-
description:
|
|
2281
|
-
efforts:
|
|
2120
|
+
label: z25.string().max(80),
|
|
2121
|
+
description: z25.string().max(200).optional(),
|
|
2122
|
+
efforts: z25.array(EffortSchema).max(8).optional(),
|
|
2282
2123
|
defaultEffort: EffortSchema.optional(),
|
|
2283
|
-
isDefault:
|
|
2124
|
+
isDefault: z25.boolean().optional()
|
|
2284
2125
|
}).strict();
|
|
2285
|
-
var
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
boot: z26.string().uuid().optional(),
|
|
2291
|
-
teams: z26.literal(true).optional(),
|
|
2126
|
+
var PhoneServerMessageSchema = z25.discriminatedUnion("type", [
|
|
2127
|
+
z25.object({ type: z25.literal("snapshot"), protocol: z25.literal(PHONE_PROTOCOL), sessions: z25.array(PhoneSessionSchema), capabilities: CapabilitiesByToolSchema, daemon: z25.object({
|
|
2128
|
+
version: z25.string(),
|
|
2129
|
+
name: z25.string().max(40),
|
|
2130
|
+
boot: z25.string().uuid().optional(),
|
|
2292
2131
|
/** The daemon takes `session.model`. */
|
|
2293
|
-
models:
|
|
2132
|
+
models: z25.literal(true).optional(),
|
|
2294
2133
|
/** The daemon sends `session.checklist` and a session's `checklist` summary. */
|
|
2295
|
-
checklist:
|
|
2134
|
+
checklist: z25.literal(true).optional(),
|
|
2296
2135
|
/** `update`: the daemon can install a version and restart (npm, systemd); `restart`: it can restart (systemd). */
|
|
2297
|
-
update:
|
|
2298
|
-
restart:
|
|
2136
|
+
update: z25.literal(true).optional(),
|
|
2137
|
+
restart: z25.literal(true).optional(),
|
|
2299
2138
|
/** The daemon takes `session.close` and `session.resume`. */
|
|
2300
|
-
sessionClose:
|
|
2301
|
-
}), device:
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
challenge: B64U2.max(64),
|
|
2306
|
-
rpId: z26.string().max(253),
|
|
2307
|
-
credentialId: B64U2.max(1366).optional(),
|
|
2308
|
-
expiresInMs: z26.number().int().positive(),
|
|
2309
|
-
/** 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. */
|
|
2310
|
-
digest: TeamsDigestSchema.optional()
|
|
2311
|
-
}),
|
|
2312
|
-
z26.object({ type: z26.literal("session.updated"), session: PhoneSessionSchema }),
|
|
2313
|
-
z26.object({ type: z26.literal("session.removed"), id: z26.string() }),
|
|
2139
|
+
sessionClose: z25.literal(true).optional()
|
|
2140
|
+
}), device: z25.object({ confirm: z25.boolean(), push: z25.enum(["on", "off", "stale", "unavailable"]).optional(), chat: z25.literal(true).optional(), contextNear: ContextPrefsSchema.shape.near.optional() }).optional() }),
|
|
2141
|
+
z25.object({ type: z25.literal("confirm.challenge"), purpose: ConfirmPurposeSchema, challenge: B64U2.max(64), rpId: z25.string().max(253), credentialId: B64U2.max(1366).optional(), expiresInMs: z25.number().int().positive() }),
|
|
2142
|
+
z25.object({ type: z25.literal("session.updated"), session: PhoneSessionSchema }),
|
|
2143
|
+
z25.object({ type: z25.literal("session.removed"), id: z25.string() }),
|
|
2314
2144
|
/** A session's checklist, sent to the phone that watches it; `null`: it has none (any more). */
|
|
2315
|
-
|
|
2145
|
+
z25.object({ type: z25.literal("session.checklist"), id: z25.string(), checklist: PhoneChecklistSchema.nullable() }),
|
|
2316
2146
|
/** `pending.cut` is set when even this body was shortened. */
|
|
2317
|
-
|
|
2318
|
-
|
|
2147
|
+
z25.object({ type: z25.literal("session.pending"), id: z25.string(), pending: PhonePendingSchema }),
|
|
2148
|
+
z25.object({ type: z25.literal("session.preview"), id: z25.string(), lines: z25.array(z25.string()) }),
|
|
2319
2149
|
/** `cut`: the ids of the items shortened; `more`: older items were left out. */
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
type:
|
|
2150
|
+
z25.object({ type: z25.literal("session.thread"), id: z25.string(), items: z25.array(ThreadItemSchema), cut: z25.array(z25.string()), more: z25.boolean() }),
|
|
2151
|
+
z25.object({ type: z25.literal("session.thread.item"), id: z25.string(), item: ThreadItemSchema, cut: z25.literal(true).optional() }),
|
|
2152
|
+
z25.object({
|
|
2153
|
+
type: z25.literal("operation.result"),
|
|
2324
2154
|
op: OperationIdSchema,
|
|
2325
2155
|
status: OperationStatusSchema,
|
|
2326
2156
|
reason: OperationReasonSchema.optional(),
|
|
2327
|
-
models: z26.array(PhoneSeatModelSchema).max(16).optional(),
|
|
2328
2157
|
/** How an applied `session.close` ended the agent: `killed` when it had to be forced. */
|
|
2329
2158
|
how: CloseHowSchema.optional()
|
|
2330
2159
|
}),
|
|
2331
2160
|
/** The models an agent offers; `error`: it could not be asked, `models` is then what Ledge knows without it. */
|
|
2332
|
-
|
|
2161
|
+
z25.object({ type: z25.literal("models.listing"), tool: ToolSchema, models: z25.array(PhoneModelChoiceSchema).max(40), error: z25.literal(true).optional() }),
|
|
2333
2162
|
/** A model change that was accepted and then failed (the agent could not restart). */
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2163
|
+
z25.object({ type: z25.literal("session.model.failed"), id: z25.string(), reason: ModelRefusalSchema }),
|
|
2164
|
+
z25.object({ type: z25.literal("chat.history"), turns: z25.array(PhoneChatTurnSchema).max(50) }),
|
|
2165
|
+
z25.object({ type: z25.literal("chat.step"), qid: OperationIdSchema, step: PhoneChatStepSchema }),
|
|
2337
2166
|
/** The whole text so far, not an increment. */
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
z26.object({ type: z26.literal("teams.catalog"), catalog: PhoneCatalogSchema }),
|
|
2167
|
+
z25.object({ type: z25.literal("chat.delta"), qid: OperationIdSchema, text: z25.string().max(THREAD_TEXT_MAX) }),
|
|
2168
|
+
z25.object({ type: z25.literal("chat.done"), qid: OperationIdSchema, turn: PhoneChatTurnSchema }),
|
|
2169
|
+
z25.object({ type: z25.literal("chat.error"), qid: OperationIdSchema, code: ChatErrorCodeSchema }),
|
|
2342
2170
|
/** The daemon updating or restarting itself, whoever asked: npm runs, then the service restarts (the link drops right after). */
|
|
2343
|
-
|
|
2171
|
+
z25.object({ type: z25.literal("daemon.progress"), version: z25.string().max(40), step: z25.enum(["installing", "restarting"]) }),
|
|
2344
2172
|
/** Nothing was changed. Never npm's output nor a command: both hold the PC's paths. */
|
|
2345
|
-
|
|
2346
|
-
z26.object({ type: z26.literal("teams.role"), role: PhoneRoleSchema }),
|
|
2347
|
-
/** The live teams, after each snapshot and on every change. */
|
|
2348
|
-
z26.object({ type: z26.literal("teams"), teams: z26.array(PhoneTeamSchema).max(50) }),
|
|
2173
|
+
z25.object({ type: z25.literal("daemon.failed"), version: z25.string().max(40), reason: UpdateFailureSchema }),
|
|
2349
2174
|
/** The tasks Ledge gave, open or closed lately, after each snapshot; then each change. */
|
|
2350
|
-
|
|
2351
|
-
|
|
2175
|
+
z25.object({ type: z25.literal("tasks"), tasks: z25.array(PhoneTaskSchema).max(200) }),
|
|
2176
|
+
z25.object({ type: z25.literal("task.updated"), task: PhoneTaskSchema }),
|
|
2352
2177
|
AttachmentStoredSchema,
|
|
2353
2178
|
AttachmentDataSchema,
|
|
2354
2179
|
AttachmentErrorSchema,
|
|
2355
2180
|
/** Never carries free text. */
|
|
2356
|
-
|
|
2181
|
+
z25.object({ type: z25.literal("error"), code: z25.enum(["invalid", "unknown_session", "too_large"]), request: z25.string().max(40).optional() })
|
|
2357
2182
|
]);
|
|
2358
|
-
var teamsPurpose = (type) => type.startsWith("team.") ? "team" : "define";
|
|
2359
|
-
var DIGEST_OP = "00000000-0000-4000-8000-000000000000";
|
|
2360
|
-
async function teamsDigest(m) {
|
|
2361
|
-
const { op: _op, assertion: _assertion, ...raw } = m;
|
|
2362
|
-
const { op: _parsedOp, assertion: _parsedAssertion, ...rest } = PhoneClientMessageSchema.parse({ ...raw, op: DIGEST_OP });
|
|
2363
|
-
const bytes = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(canonicalJson(rest))));
|
|
2364
|
-
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
2365
|
-
}
|
|
2366
2183
|
|
|
2367
2184
|
// ../protocol/src/todos.ts
|
|
2368
2185
|
var TODO_TOOLS = /* @__PURE__ */ new Set(["TodoWrite", "update_plan", "todo"]);
|
|
@@ -2555,8 +2372,6 @@ export {
|
|
|
2555
2372
|
contextNear,
|
|
2556
2373
|
BRIEF_MAX,
|
|
2557
2374
|
ToolSchema,
|
|
2558
|
-
autonomyArgs,
|
|
2559
|
-
ompApprovalFor,
|
|
2560
2375
|
SessionSchema,
|
|
2561
2376
|
backendOf,
|
|
2562
2377
|
isArchived,
|
|
@@ -2566,25 +2381,8 @@ export {
|
|
|
2566
2381
|
extractProposal,
|
|
2567
2382
|
parseRelayBlock,
|
|
2568
2383
|
parseCloseBlock,
|
|
2569
|
-
parseTeamBlock,
|
|
2570
2384
|
parseTaskBlock,
|
|
2571
2385
|
parseProjectBlock,
|
|
2572
|
-
SshAliasSchema,
|
|
2573
|
-
MachinesSchema,
|
|
2574
|
-
PROJECT_COLORS,
|
|
2575
|
-
ProjectsSchema,
|
|
2576
|
-
DEFAULT_PROJECTS,
|
|
2577
|
-
projectOf,
|
|
2578
|
-
RoleIdSchema,
|
|
2579
|
-
ROLE_LABEL_MAX,
|
|
2580
|
-
ROLE_PROMPT_MAX,
|
|
2581
|
-
RoleSchema,
|
|
2582
|
-
TEAM_SEATS_MAX,
|
|
2583
|
-
SeatsSchema,
|
|
2584
|
-
TeamNameSchema,
|
|
2585
|
-
TemplateIdSchema,
|
|
2586
|
-
TeamSchema,
|
|
2587
|
-
isTeamLive,
|
|
2588
2386
|
NOTE_MAX,
|
|
2589
2387
|
NOTE_NOT_TYPED,
|
|
2590
2388
|
offers,
|
|
@@ -2608,7 +2406,20 @@ export {
|
|
|
2608
2406
|
ChatTurnSchema,
|
|
2609
2407
|
proposalRows,
|
|
2610
2408
|
DOCUMENT_MAX_BYTES,
|
|
2409
|
+
SshAliasSchema,
|
|
2410
|
+
MachinesSchema,
|
|
2611
2411
|
IslandPrefsSchema,
|
|
2412
|
+
PROJECT_COLORS,
|
|
2413
|
+
ProjectsSchema,
|
|
2414
|
+
DEFAULT_PROJECTS,
|
|
2415
|
+
projectOf,
|
|
2416
|
+
RigSeatNameSchema,
|
|
2417
|
+
KERNEL_RIG,
|
|
2418
|
+
rigCommands,
|
|
2419
|
+
showRigCommand,
|
|
2420
|
+
RIG_POLICIES,
|
|
2421
|
+
seatsByRole,
|
|
2422
|
+
seatPlan,
|
|
2612
2423
|
RouteResultSchema,
|
|
2613
2424
|
DEFAULT_RELAY_URL,
|
|
2614
2425
|
MobileConfigSchema,
|
|
@@ -2622,6 +2433,7 @@ export {
|
|
|
2622
2433
|
parseServerMessage,
|
|
2623
2434
|
NAMES,
|
|
2624
2435
|
pickName,
|
|
2436
|
+
namesInUse,
|
|
2625
2437
|
TOPIC_MAX,
|
|
2626
2438
|
cleanTopic,
|
|
2627
2439
|
sessionTitle,
|
|
@@ -2634,11 +2446,6 @@ export {
|
|
|
2634
2446
|
pushEndpointAllowed,
|
|
2635
2447
|
PushSendResultSchema,
|
|
2636
2448
|
PushPayloadSchema,
|
|
2637
|
-
PhoneRoleSchema,
|
|
2638
|
-
PhoneTemplateSchema,
|
|
2639
|
-
TEAMS_OPERATION_TYPES,
|
|
2640
|
-
isTeamsOperation,
|
|
2641
|
-
canonicalJson,
|
|
2642
2449
|
PHONE_PROTOCOL,
|
|
2643
2450
|
padPlain,
|
|
2644
2451
|
THREAD_ITEMS_MAX,
|
|
@@ -2655,8 +2462,6 @@ export {
|
|
|
2655
2462
|
pcSubject,
|
|
2656
2463
|
PhoneClientMessageSchema,
|
|
2657
2464
|
PhoneModelChoiceSchema,
|
|
2658
|
-
teamsPurpose,
|
|
2659
|
-
teamsDigest,
|
|
2660
2465
|
TODO_TOOLS,
|
|
2661
2466
|
latestTodos,
|
|
2662
2467
|
doneCount,
|