@paradow/ledge 0.29.0 → 0.31.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-MAPPYLUM.js → action-CFYJM2A2.js} +4 -4
- package/dist/cli/{attach-OC64CLB2.js → attach-23PTEIAA.js} +9 -8
- package/dist/cli/{bridge-TWX4V37E.js → bridge-UJKWEKA5.js} +1 -1
- package/dist/cli/{chunk-RFFTWAAF.js → chunk-6YBIZZQG.js} +1 -1
- package/dist/cli/{chunk-TREGH6WM.js → chunk-GMG3ROBU.js} +504 -302
- package/dist/cli/{chunk-MZVMW356.js → chunk-HEYHVOD6.js} +2 -2
- package/dist/cli/{chunk-XZYQMKKO.js → chunk-HNC5Q5PV.js} +3 -3
- package/dist/cli/{chunk-WCBXS3EU.js → chunk-HUY4CFMX.js} +107 -15
- package/dist/cli/{chunk-73YNZ3BN.js → chunk-MIPE2FWL.js} +2 -1
- package/dist/cli/{chunk-7S7ZLGIY.js → chunk-MYIBYAZC.js} +36 -8
- package/dist/cli/{chunk-WIUJNSAZ.js → chunk-NXNIRIGI.js} +5 -5
- package/dist/cli/{chunk-353WRRGG.js → chunk-QXH2L4UH.js} +3 -3
- package/dist/cli/{chunk-UWDE365N.js → chunk-TCJG3EHB.js} +47 -3
- package/dist/cli/{chunk-K3SDHHZF.js → chunk-TLFKLMBN.js} +1 -1
- package/dist/cli/{chunk-TNYBWWRO.js → chunk-WF27BASF.js} +2 -2
- package/dist/cli/chunk-WY5WSK2D.js +6 -0
- package/dist/cli/{chunk-ETGOWBUL.js → chunk-YI4V7YVW.js} +3 -3
- package/dist/cli/{daemon-ZTZ7VMYA.js → daemon-WW2P7RDV.js} +7 -7
- package/dist/cli/{decide-4BIYS3Y2.js → decide-HLRD37PW.js} +8 -6
- package/dist/cli/{handover-IS7BJYGZ.js → handover-56M4LIOP.js} +4 -4
- package/dist/cli/{hook-3VKVD4IP.js → hook-UJVKYSQ5.js} +34 -13
- package/dist/cli/index.js +16 -16
- package/dist/cli/{launch-XAPN2M3Q.js → launch-GIPQDPAC.js} +9 -8
- package/dist/cli/{send-ZLF2ZXMJ.js → send-HWZHE65N.js} +4 -4
- package/dist/cli/{status-NONO6E2S.js → status-V6ITP7VT.js} +2 -2
- package/dist/cli/{task-47MVWDCY.js → task-N53TM34B.js} +4 -4
- package/dist/cli/{team-EJ4YIXJH.js → team-CZFZ24P6.js} +6 -6
- package/dist/cli/{tui-CAP4O4YQ.js → tui-K32C34XI.js} +1274 -1176
- package/dist/cli/{version-EHBPJO7K.js → version-QIFJVKAQ.js} +1 -1
- package/dist/cli/{who-FHAXYCM2.js → who-NIOLHHB3.js} +3 -3
- package/dist/ledge-guide.md +268 -0
- package/package.json +1 -1
- package/dist/cli/chunk-JZEWCO6X.js +0 -6
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CODEX_HOOK_VAR
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TLFKLMBN.js";
|
|
4
4
|
import {
|
|
5
5
|
connect,
|
|
6
6
|
sendMessageAndAwaitAck
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-6YBIZZQG.js";
|
|
8
8
|
|
|
9
9
|
// src/cli/send.ts
|
|
10
10
|
import { randomUUID } from "crypto";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CODEX_HOOK_VAR
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TLFKLMBN.js";
|
|
4
4
|
import {
|
|
5
5
|
connect
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-6YBIZZQG.js";
|
|
7
7
|
import {
|
|
8
8
|
BRIEF_MAX
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MYIBYAZC.js";
|
|
10
10
|
|
|
11
11
|
// src/cli/handover.ts
|
|
12
12
|
import { randomUUID } from "crypto";
|
|
@@ -3,14 +3,17 @@ import {
|
|
|
3
3
|
definitionFiles,
|
|
4
4
|
definitionHash,
|
|
5
5
|
listRoles,
|
|
6
|
+
loadRole,
|
|
6
7
|
quoteScalar,
|
|
7
8
|
readSmall,
|
|
9
|
+
repoRoot,
|
|
8
10
|
scalarValue
|
|
9
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-MIPE2FWL.js";
|
|
10
12
|
import {
|
|
11
13
|
SeatsSchema,
|
|
12
|
-
TeamNameSchema
|
|
13
|
-
|
|
14
|
+
TeamNameSchema,
|
|
15
|
+
TemplateIdSchema
|
|
16
|
+
} from "./chunk-MYIBYAZC.js";
|
|
14
17
|
import {
|
|
15
18
|
log
|
|
16
19
|
} from "./chunk-6IYPRUQG.js";
|
|
@@ -19,8 +22,87 @@ import {
|
|
|
19
22
|
} from "./chunk-HOOHS3MX.js";
|
|
20
23
|
|
|
21
24
|
// src/daemon/teams.ts
|
|
22
|
-
import {
|
|
23
|
-
import { join } from "path";
|
|
25
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
26
|
+
import { join as join2 } from "path";
|
|
27
|
+
|
|
28
|
+
// src/daemon/definitions.ts
|
|
29
|
+
import { linkSync, mkdirSync, readFileSync, renameSync, rmSync, unlinkSync, writeFileSync } from "fs";
|
|
30
|
+
import { basename, dirname, join } from "path";
|
|
31
|
+
function roleText(r) {
|
|
32
|
+
const lines = [];
|
|
33
|
+
for (const [key, value] of [["label", r.label], ["tool", r.tool], ["model", r.model], ["effort", r.effort], ["autonomy", r.autonomy]]) {
|
|
34
|
+
if (value === void 0) continue;
|
|
35
|
+
const q = quoteScalar(value);
|
|
36
|
+
if (q === null) return null;
|
|
37
|
+
lines.push(`${key}: ${q}`);
|
|
38
|
+
}
|
|
39
|
+
return `---
|
|
40
|
+
${lines.join("\n")}
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
${r.prompt}
|
|
44
|
+
`;
|
|
45
|
+
}
|
|
46
|
+
function current(path) {
|
|
47
|
+
try {
|
|
48
|
+
return readFileSync(path, "utf8");
|
|
49
|
+
} catch (e) {
|
|
50
|
+
if (e.code === "ENOENT") return void 0;
|
|
51
|
+
throw e;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function writeDefinition(path, text, base) {
|
|
55
|
+
const now = current(path);
|
|
56
|
+
if (base === null) {
|
|
57
|
+
if (now !== void 0) return { code: "exists" };
|
|
58
|
+
} else if (now === void 0 || definitionHash(now) !== base) return { code: "changed" };
|
|
59
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
60
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
61
|
+
try {
|
|
62
|
+
writeFileSync(tmp, text);
|
|
63
|
+
if (base === null) linkSync(tmp, path);
|
|
64
|
+
else renameSync(tmp, path);
|
|
65
|
+
} catch (e) {
|
|
66
|
+
rmSync(tmp, { force: true });
|
|
67
|
+
if (base === null && e.code === "EEXIST") return { code: "exists" };
|
|
68
|
+
throw e;
|
|
69
|
+
}
|
|
70
|
+
rmSync(tmp, { force: true });
|
|
71
|
+
return { hash: definitionHash(readFileSync(path, "utf8")) };
|
|
72
|
+
}
|
|
73
|
+
function deleteDefinition(path, base) {
|
|
74
|
+
const now = current(path);
|
|
75
|
+
if (now === void 0) return { code: "missing" };
|
|
76
|
+
if (definitionHash(now) !== base) return { code: "changed" };
|
|
77
|
+
unlinkSync(path);
|
|
78
|
+
return { ok: true };
|
|
79
|
+
}
|
|
80
|
+
function scopeDir(kind, scope, repoFolder) {
|
|
81
|
+
if (scope === "home") return join(ledgeDir(), kind);
|
|
82
|
+
if (!repoFolder) throw new Error("the repository scope needs a folder");
|
|
83
|
+
return join(repoRoot(repoFolder), ".ledge", kind);
|
|
84
|
+
}
|
|
85
|
+
function scopeDefinitions(dir, scope) {
|
|
86
|
+
const problems = [];
|
|
87
|
+
const roles = [];
|
|
88
|
+
const templates = /* @__PURE__ */ new Map();
|
|
89
|
+
for (const path of definitionFiles(dir.roles, [".md"])) {
|
|
90
|
+
const r = loadRole(basename(path, ".md"), path, scope, problems);
|
|
91
|
+
if (r) roles.push(r);
|
|
92
|
+
}
|
|
93
|
+
for (const path of definitionFiles(dir.teams, [".yaml", ".yml"])) {
|
|
94
|
+
const id = basename(path).replace(/\.ya?ml$/, "");
|
|
95
|
+
if (templates.has(id)) continue;
|
|
96
|
+
const t = loadTemplate(id, path, scope, problems);
|
|
97
|
+
if (t) templates.set(id, t);
|
|
98
|
+
}
|
|
99
|
+
return { roles: roles.sort((a, b) => a.id.localeCompare(b.id)), templates: [...templates.values()].sort((a, b) => a.id.localeCompare(b.id)), problems };
|
|
100
|
+
}
|
|
101
|
+
function promptRecipients(roleId, path, sessions, resolve) {
|
|
102
|
+
return sessions.filter((s) => s.role === roleId && s.source === "launcher" && s.state !== "exited" && s.archivedAt === void 0 && resolve(roleId, s.cwd)?.path === path);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// src/daemon/teams.ts
|
|
24
106
|
var scalar = scalarValue;
|
|
25
107
|
function flowMap(raw) {
|
|
26
108
|
const inner = raw.trim().replace(/^\{/, "").replace(/\}$/, "");
|
|
@@ -89,6 +171,7 @@ function parseTemplateText(text) {
|
|
|
89
171
|
return out;
|
|
90
172
|
}
|
|
91
173
|
function parseTemplate(id, text, source, path) {
|
|
174
|
+
if (!TemplateIdSchema.safeParse(id).success) return "nom de fichier invalide : lettres, chiffres, - et _ seulement (64 au plus, sans point), puis .yaml";
|
|
92
175
|
let raw;
|
|
93
176
|
try {
|
|
94
177
|
raw = parseTemplateText(text);
|
|
@@ -174,25 +257,34 @@ function templateText(name, seats) {
|
|
|
174
257
|
return `${lines.join("\n")}
|
|
175
258
|
`;
|
|
176
259
|
}
|
|
177
|
-
var templatePath = (name, dir) =>
|
|
178
|
-
|
|
179
|
-
|
|
260
|
+
var templatePath = (name, dir) => join2(dir, `${templateId(name)}.yaml`);
|
|
261
|
+
function templateHash(name, dir = join2(ledgeDir(), "teams")) {
|
|
262
|
+
try {
|
|
263
|
+
return definitionHash(readFileSync2(templatePath(name, dir), "utf8"));
|
|
264
|
+
} catch (e) {
|
|
265
|
+
if (e.code === "ENOENT") return void 0;
|
|
266
|
+
throw e;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
function saveTemplate(name, seats, base, dir = join2(ledgeDir(), "teams")) {
|
|
180
270
|
const path = templatePath(name, dir);
|
|
181
271
|
const text = templateText(name, seats);
|
|
182
272
|
if (text === null) throw new Error("a team name or seat value cannot be written as YAML");
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
writeFileSync(tmp, text);
|
|
186
|
-
renameSync(tmp, path);
|
|
187
|
-
return path;
|
|
273
|
+
const r = writeDefinition(path, text, base ?? null);
|
|
274
|
+
return "code" in r ? { path, code: r.code } : { path };
|
|
188
275
|
}
|
|
189
276
|
|
|
190
277
|
export {
|
|
191
|
-
|
|
278
|
+
roleText,
|
|
279
|
+
writeDefinition,
|
|
280
|
+
deleteDefinition,
|
|
281
|
+
scopeDir,
|
|
282
|
+
scopeDefinitions,
|
|
283
|
+
promptRecipients,
|
|
192
284
|
resolveSeats,
|
|
193
285
|
listDefinitions,
|
|
194
286
|
templateId,
|
|
195
287
|
templateText,
|
|
196
|
-
|
|
288
|
+
templateHash,
|
|
197
289
|
saveTemplate
|
|
198
290
|
};
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
ROLE_LABEL_MAX,
|
|
3
3
|
ROLE_PROMPT_MAX,
|
|
4
4
|
RoleSchema
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-MYIBYAZC.js";
|
|
6
6
|
import {
|
|
7
7
|
log
|
|
8
8
|
} from "./chunk-6IYPRUQG.js";
|
|
@@ -150,6 +150,7 @@ export {
|
|
|
150
150
|
definitionDirs,
|
|
151
151
|
definitionFiles,
|
|
152
152
|
readSmall,
|
|
153
|
+
frontMatter,
|
|
153
154
|
scalarValue,
|
|
154
155
|
quoteScalar,
|
|
155
156
|
definitionHash,
|
|
@@ -143,6 +143,10 @@ var SessionSchema = z2.object({
|
|
|
143
143
|
roleLabel: z2.string().optional(),
|
|
144
144
|
/** The live team it sits in (`team-…`); left out, the project's common table. */
|
|
145
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(),
|
|
146
150
|
/** Its role's autonomy, as launched (kept by a resume); left out, `ask`. */
|
|
147
151
|
autonomy: AutonomySchema.optional(),
|
|
148
152
|
/** Its context as its agent last reported it, after a turn (context handover spec §3.1); left out, not measured. */
|
|
@@ -340,14 +344,15 @@ var TeamSchema = z7.object({
|
|
|
340
344
|
machine: z7.string(),
|
|
341
345
|
cwd: z7.string(),
|
|
342
346
|
state: TeamStateSchema,
|
|
343
|
-
/** A live seat: `tool`, `model` and `effort` are what it was composed with over the role's defaults
|
|
344
|
-
* from the composition that finishes its turn and then is closed. */
|
|
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. */
|
|
345
349
|
seats: z7.array(z7.object({
|
|
346
350
|
role: RoleIdSchema,
|
|
347
351
|
sessionId: z7.string().nullable(),
|
|
348
352
|
tool: ToolSchema.optional(),
|
|
349
353
|
model: ModelIdSchema.optional(),
|
|
350
354
|
effort: EffortSchema.optional(),
|
|
355
|
+
name: SeatSchema.shape.name,
|
|
351
356
|
leaving: z7.literal(true).optional()
|
|
352
357
|
})).max(TEAM_SEATS_MAX * 2),
|
|
353
358
|
createdAt: z7.string(),
|
|
@@ -381,7 +386,7 @@ var TeamJoinSchema = z7.object({ type: z7.literal("team.join"), team: TeamIdSche
|
|
|
381
386
|
var TeamLeaveSchema = z7.object({ type: z7.literal("team.leave"), team: TeamIdSchema, session: z7.string().min(1) });
|
|
382
387
|
var TeamResumeSchema = z7.object({ type: z7.literal("team.resume"), team: TeamIdSchema });
|
|
383
388
|
var TeamDissolveSchema = z7.object({ type: z7.literal("team.dissolve"), team: TeamIdSchema });
|
|
384
|
-
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() });
|
|
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() });
|
|
385
390
|
var DefinitionScopeSchema = z7.enum(["home", "repo"]);
|
|
386
391
|
var RoleDraftSchema = RoleSchema.pick({ id: true, label: true, prompt: true, tool: true, model: true, effort: true, autonomy: true });
|
|
387
392
|
var DefinitionCodeSchema = z7.enum(["changed", "exists", "missing", "unknown_project", "invalid"]);
|
|
@@ -420,7 +425,7 @@ var TeamsMessageSchema = z7.object({ type: z7.literal("teams"), teams: z7.array(
|
|
|
420
425
|
var TeamUpdatedSchema = z7.object({ type: z7.literal("team.updated"), team: TeamSchema });
|
|
421
426
|
var TeamLaunchedSchema = z7.object({ type: z7.literal("team.launched"), rid: z7.string(), team: TeamSchema });
|
|
422
427
|
var TeamFailedSchema = z7.object({ type: z7.literal("team.failed"), rid: z7.string(), reason: z7.string(), team: TeamSchema.optional() });
|
|
423
|
-
var TeamSavedSchema = z7.object({ type: z7.literal("team.saved"), rid: z7.string(), path: z7.string().optional(), reason: z7.string().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() });
|
|
424
429
|
var isTeamLive = (t) => t.state !== "dissolved";
|
|
425
430
|
|
|
426
431
|
// ../protocol/src/tasks.ts
|
|
@@ -465,6 +470,7 @@ function transmissions(t) {
|
|
|
465
470
|
}
|
|
466
471
|
var givenByLedge = (t) => t.giver === LEDGE_GIVER;
|
|
467
472
|
var taskClosed = (t) => t.state === "done" || t.state === "refused" || t.state === "dropped";
|
|
473
|
+
var openDecision = (t) => t.owner === LEDGE_GIVER && !taskClosed(t);
|
|
468
474
|
var TaskCmdSchema = z8.object({
|
|
469
475
|
type: z8.literal("task.cmd"),
|
|
470
476
|
rid: z8.string().min(1),
|
|
@@ -617,7 +623,8 @@ var ACTION_IDS = [
|
|
|
617
623
|
"team.dissolve",
|
|
618
624
|
"team.save",
|
|
619
625
|
"task.cancel",
|
|
620
|
-
"task.pass"
|
|
626
|
+
"task.pass",
|
|
627
|
+
"task.answer"
|
|
621
628
|
];
|
|
622
629
|
var ActionIdSchema = z11.enum(ACTION_IDS);
|
|
623
630
|
var def = (d) => d;
|
|
@@ -800,7 +807,7 @@ var ACTIONS = [
|
|
|
800
807
|
card: "generic",
|
|
801
808
|
phone: "act",
|
|
802
809
|
risk: "destructive",
|
|
803
|
-
max:
|
|
810
|
+
max: 8,
|
|
804
811
|
cli: "ledge team dissolve <\xE9quipe>",
|
|
805
812
|
summary: "dissoudre une \xE9quipe : elle dispara\xEEt, ses sessions restent ; irr\xE9versible",
|
|
806
813
|
when: "seulement quand l'utilisateur demande explicitement de dissoudre une \xE9quipe pr\xE9cise",
|
|
@@ -838,6 +845,17 @@ var ACTIONS = [
|
|
|
838
845
|
summary: "passer une t\xE2che de tasks.md \xE0 une autre session (elle redevient ouverte)",
|
|
839
846
|
when: "quand l'utilisateur demande de r\xE9assigner ou de passer une t\xE2che \xE0 une autre session",
|
|
840
847
|
example: { task: "t91b0d4", to: "Bix" }
|
|
848
|
+
}),
|
|
849
|
+
def({
|
|
850
|
+
id: "task.answer",
|
|
851
|
+
args: z11.object({ task: TaskRef, answer: z11.string().trim().min(1).max(TASK_TEXT_MAX) }),
|
|
852
|
+
card: "generic",
|
|
853
|
+
phone: "act",
|
|
854
|
+
risk: "destructive",
|
|
855
|
+
max: 1,
|
|
856
|
+
summary: "r\xE9pondre, au nom de l'utilisateur, \xE0 une d\xE9cision qu'une session lui a pos\xE9e (tasks.md : owner Ledge) ; la session reprend avec cette r\xE9ponse ; irr\xE9versible",
|
|
857
|
+
when: "seulement quand l'utilisateur donne lui-m\xEAme sa r\xE9ponse \xE0 une d\xE9cision ouverte : answer reprend ses mots, ou l'option qu'il a choisie parmi celles de la session, sans rien inventer ni choisir \xE0 sa place ; si sa r\xE9ponse manque, cite les options et demande-la",
|
|
858
|
+
example: { task: "t91b0d4", answer: "Oui, fusionne feat/roles" }
|
|
841
859
|
})
|
|
842
860
|
];
|
|
843
861
|
var byId = new Map(ACTIONS.map((a) => [a.id, a]));
|
|
@@ -986,7 +1004,8 @@ var ChatTeamProposalSchema = z13.object({
|
|
|
986
1004
|
teamId: z13.string().optional(),
|
|
987
1005
|
launchedAt: z13.string().datetime().optional(),
|
|
988
1006
|
error: z13.string().optional(),
|
|
989
|
-
savedPath: z13.string().optional()
|
|
1007
|
+
savedPath: z13.string().optional(),
|
|
1008
|
+
saveError: z13.string().optional()
|
|
990
1009
|
});
|
|
991
1010
|
var ChatTaskProposalSchema = z13.object({
|
|
992
1011
|
to: z13.string().min(1),
|
|
@@ -1026,6 +1045,7 @@ var ACTION_ERROR_CODES = [
|
|
|
1026
1045
|
"holder",
|
|
1027
1046
|
"changed",
|
|
1028
1047
|
"cut",
|
|
1048
|
+
"not_decision",
|
|
1029
1049
|
"failed"
|
|
1030
1050
|
];
|
|
1031
1051
|
var ChatActionStateSchema = z13.enum(["running", "done", "denied", "failed", "refused"]);
|
|
@@ -1574,6 +1594,8 @@ var ClientMessageSchema = z21.discriminatedUnion("type", [
|
|
|
1574
1594
|
z21.object({ type: z21.literal("session.delete"), id: z21.string() }),
|
|
1575
1595
|
/** 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. */
|
|
1576
1596
|
z21.object({ type: z21.literal("session.rename"), id: z21.string(), topic: z21.string().max(500) }),
|
|
1597
|
+
/** A seat's hook told it its team as `key` names it (`seatKey`): at its start, or at a turn after the team changed. */
|
|
1598
|
+
z21.object({ type: z21.literal("seat.seen"), id: z21.string(), key: z21.string().max(4e3) }),
|
|
1577
1599
|
z21.object({ type: z21.literal("session.thread"), id: z21.string() }),
|
|
1578
1600
|
z21.object({ type: z21.literal("session.register"), session: SessionSchema }),
|
|
1579
1601
|
/** `agent` and `cwd` describe the session when the daemon does not know it yet (a hook from an agent started without ledge). */
|
|
@@ -1838,7 +1860,7 @@ var PushSubscriptionSchema = z24.object({
|
|
|
1838
1860
|
});
|
|
1839
1861
|
var PushPayloadSchema = z24.object({
|
|
1840
1862
|
v: z24.literal(1),
|
|
1841
|
-
kind: z24.enum(["request", "question", "finished", "chat"]),
|
|
1863
|
+
kind: z24.enum(["request", "question", "finished", "chat", "decision"]),
|
|
1842
1864
|
title: z24.string().max(80),
|
|
1843
1865
|
body: z24.string().max(120),
|
|
1844
1866
|
url: z24.string().regex(/^\/#\/[A-Za-z0-9/%._~-]*$/).max(300),
|
|
@@ -2080,6 +2102,10 @@ var PhoneTaskSchema = z26.object({
|
|
|
2080
2102
|
owner: z26.string().max(100),
|
|
2081
2103
|
ownerName: z26.string().max(80),
|
|
2082
2104
|
ownerRole: z26.string().max(40).optional(),
|
|
2105
|
+
/** 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). */
|
|
2106
|
+
giver: z26.string().max(100).optional(),
|
|
2107
|
+
giverName: z26.string().max(80).optional(),
|
|
2108
|
+
text: z26.string().max(TOOL_TEXT_MAX).optional(),
|
|
2083
2109
|
team: z26.string().max(40).optional(),
|
|
2084
2110
|
teamName: z26.string().max(60).optional(),
|
|
2085
2111
|
state: z26.enum(["open", "taken", "done", "refused", "dropped"]),
|
|
@@ -2547,6 +2573,7 @@ export {
|
|
|
2547
2573
|
ROLE_LABEL_MAX,
|
|
2548
2574
|
ROLE_PROMPT_MAX,
|
|
2549
2575
|
RoleSchema,
|
|
2576
|
+
TEAM_SEATS_MAX,
|
|
2550
2577
|
SeatsSchema,
|
|
2551
2578
|
TeamNameSchema,
|
|
2552
2579
|
TemplateIdSchema,
|
|
@@ -2562,6 +2589,7 @@ export {
|
|
|
2562
2589
|
transmissions,
|
|
2563
2590
|
givenByLedge,
|
|
2564
2591
|
taskClosed,
|
|
2592
|
+
openDecision,
|
|
2565
2593
|
ACTIONS,
|
|
2566
2594
|
actionById,
|
|
2567
2595
|
riskOf,
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
2
|
EFFORT_ARGS,
|
|
3
3
|
MODEL_ARGS
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-GMG3ROBU.js";
|
|
5
5
|
import {
|
|
6
6
|
findRole
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-MIPE2FWL.js";
|
|
8
8
|
import {
|
|
9
9
|
exitFile,
|
|
10
10
|
spawnSession
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-TLFKLMBN.js";
|
|
12
12
|
import {
|
|
13
13
|
DaemonRefusedError,
|
|
14
14
|
connect
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-6YBIZZQG.js";
|
|
16
16
|
import {
|
|
17
17
|
PROTOCOL_PORT,
|
|
18
18
|
autonomyArgs
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-MYIBYAZC.js";
|
|
20
20
|
import {
|
|
21
21
|
realTmux
|
|
22
22
|
} from "./chunk-NLL2EQJ2.js";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CODEX_HOOK_VAR
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TLFKLMBN.js";
|
|
4
4
|
import {
|
|
5
5
|
connect
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-6YBIZZQG.js";
|
|
7
7
|
import {
|
|
8
8
|
SESSION_KEY_VAR,
|
|
9
9
|
actionById
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-MYIBYAZC.js";
|
|
11
11
|
|
|
12
12
|
// src/cli/action.ts
|
|
13
13
|
import { randomUUID } from "crypto";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ledgeTitleRest
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TLFKLMBN.js";
|
|
4
4
|
import {
|
|
5
5
|
cleanTopic,
|
|
6
6
|
isArchived,
|
|
7
7
|
sessionTitle
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-MYIBYAZC.js";
|
|
9
9
|
|
|
10
10
|
// src/daemon/seat.ts
|
|
11
11
|
function teammates(team, sessions) {
|
|
@@ -30,11 +30,51 @@ function seatContext(o) {
|
|
|
30
30
|
}
|
|
31
31
|
return lines.join("\n");
|
|
32
32
|
}
|
|
33
|
+
function noTeamReason(to, sender) {
|
|
34
|
+
return sender?.teamLeft ? `tu n'es plus dans l'\xE9quipe ${sender.teamLeft} : ${to} ne te sert plus (ledge team list)` : `${to} n'existe que dans une \xE9quipe`;
|
|
35
|
+
}
|
|
36
|
+
function seatView(id, sessions, teams) {
|
|
37
|
+
const s = sessions.find((x) => x.id === id);
|
|
38
|
+
const team = s?.team ? teams.find((t) => t.id === s.team && t.state !== "dissolved") : void 0;
|
|
39
|
+
if (!s || !team) return null;
|
|
40
|
+
return { id: team.id, name: team.name, members: teammates(team, sessions).filter((m) => m.name !== s.name) };
|
|
41
|
+
}
|
|
42
|
+
var seatKey = (v) => v ? JSON.stringify({ t: v.id, n: v.name, m: v.members.map((m) => `${m.name}@${m.role}`) }) : "";
|
|
43
|
+
var parseKey = (k) => {
|
|
44
|
+
try {
|
|
45
|
+
return k ? JSON.parse(k) : null;
|
|
46
|
+
} catch {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
var member = (m) => {
|
|
51
|
+
const at = m.lastIndexOf("@");
|
|
52
|
+
return { name: m.slice(0, at), role: m.slice(at + 1) };
|
|
53
|
+
};
|
|
54
|
+
var listOf = (k) => k.m.map(member).map((m) => `${m.name} (${m.role})`).join(", ") || "personne d'autre pour l'instant";
|
|
55
|
+
function teamChangeLine(seen, now) {
|
|
56
|
+
if (seen === void 0 || seen === now) return void 0;
|
|
57
|
+
const before = parseKey(seen);
|
|
58
|
+
const after = parseKey(now);
|
|
59
|
+
if (!after) return before ? `Ledge : tu n'es plus dans l'\xE9quipe ${before.n} ; les adresses @r\xF4le ne te servent plus (ledge team list).` : void 0;
|
|
60
|
+
const reach = '\xC9cris-leur par leur r\xF4le : ledge send @r\xF4le "\u2026".';
|
|
61
|
+
if (!before || before.t !== after.t) return `Ledge : tu es maintenant dans l'\xE9quipe ${after.n}. Ton \xE9quipe : ${listOf(after)}. ${reach}`;
|
|
62
|
+
const was = before.m.map(member);
|
|
63
|
+
const is = after.m.map(member);
|
|
64
|
+
const changes = [];
|
|
65
|
+
for (const m of is) {
|
|
66
|
+
if (was.some((w) => w.name === m.name && w.role === m.role)) continue;
|
|
67
|
+
const prior = was.find((w) => w.role === m.role && !is.some((x) => x.name === w.name && x.role === w.role));
|
|
68
|
+
changes.push(prior ? `${m.name} remplace ${prior.name} (${m.role})` : `${m.name} (${m.role}) arrive`);
|
|
69
|
+
}
|
|
70
|
+
for (const w of was) if (!is.some((m) => m.name === w.name && m.role === w.role) && !is.some((m) => m.role === w.role)) changes.push(`${w.name} (${w.role}) part`);
|
|
71
|
+
return `Ledge : ton \xE9quipe ${after.n} a chang\xE9${changes.length ? ` (${changes.join(", ")})` : ""}. Ton \xE9quipe : ${listOf(after)}. ${reach}`;
|
|
72
|
+
}
|
|
33
73
|
function resolveRoleAddress(to, from, sessions, teams) {
|
|
34
74
|
if (!to.startsWith("@")) return { to };
|
|
35
75
|
const role = to.slice(1);
|
|
36
76
|
const team = teams.find((t) => t.state !== "dissolved" && t.seats.some((s) => s.sessionId === from));
|
|
37
|
-
if (!team) return { reason:
|
|
77
|
+
if (!team) return { reason: noTeamReason(to, sessions.find((s) => s.id === from)) };
|
|
38
78
|
const byId = new Map(sessions.map((s) => [s.id, s]));
|
|
39
79
|
const held = team.seats.filter((s) => s.role === role && s.sessionId).map((s) => byId.get(s.sessionId)).filter((s) => !!s && s.state !== "exited" && !isArchived(s));
|
|
40
80
|
if (held.length === 1) return { to: held[0].name };
|
|
@@ -637,6 +677,10 @@ function takeImages(text, dir) {
|
|
|
637
677
|
export {
|
|
638
678
|
teammates,
|
|
639
679
|
seatContext,
|
|
680
|
+
noTeamReason,
|
|
681
|
+
seatView,
|
|
682
|
+
seatKey,
|
|
683
|
+
teamChangeLine,
|
|
640
684
|
resolveRoleAddress,
|
|
641
685
|
crossSession,
|
|
642
686
|
messageNote,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CODEX_HOOK_VAR
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TLFKLMBN.js";
|
|
4
4
|
import {
|
|
5
5
|
connect
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-6YBIZZQG.js";
|
|
7
7
|
import {
|
|
8
8
|
LEDGE_GIVER,
|
|
9
9
|
TASK_TEXT_MAX,
|
|
10
10
|
TASK_TITLE_MAX
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-MYIBYAZC.js";
|
|
12
12
|
|
|
13
13
|
// src/cli/task.ts
|
|
14
14
|
import { randomUUID } from "crypto";
|
|
@@ -9,9 +9,9 @@ import {
|
|
|
9
9
|
startServer,
|
|
10
10
|
tasksJournal,
|
|
11
11
|
teamsJournal
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-GMG3ROBU.js";
|
|
13
13
|
import "./chunk-OLLQBK6N.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-HUY4CFMX.js";
|
|
15
15
|
import {
|
|
16
16
|
QUESTION_TOOLS,
|
|
17
17
|
crossSession,
|
|
@@ -26,11 +26,11 @@ import {
|
|
|
26
26
|
readPeers,
|
|
27
27
|
reduce,
|
|
28
28
|
stripNote
|
|
29
|
-
} from "./chunk-
|
|
30
|
-
import "./chunk-
|
|
29
|
+
} from "./chunk-TCJG3EHB.js";
|
|
30
|
+
import "./chunk-MIPE2FWL.js";
|
|
31
31
|
import {
|
|
32
32
|
agentMessages
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-TLFKLMBN.js";
|
|
34
34
|
import {
|
|
35
35
|
DEFAULT_RELAY_URL,
|
|
36
36
|
DevicePollResponseSchema,
|
|
@@ -44,10 +44,10 @@ import {
|
|
|
44
44
|
SealedFrameSchema,
|
|
45
45
|
SessionSchema,
|
|
46
46
|
backendOf
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-MYIBYAZC.js";
|
|
48
48
|
import {
|
|
49
49
|
LEDGE_VERSION
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-WY5WSK2D.js";
|
|
51
51
|
import {
|
|
52
52
|
SERVICE,
|
|
53
53
|
inDaemonService,
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runOnClient
|
|
3
|
+
} from "./chunk-QXH2L4UH.js";
|
|
1
4
|
import {
|
|
2
5
|
CODEX_HOOK_VAR
|
|
3
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-TLFKLMBN.js";
|
|
4
7
|
import {
|
|
5
8
|
connect
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6YBIZZQG.js";
|
|
7
10
|
import {
|
|
8
11
|
LEDGE_GIVER,
|
|
9
12
|
TASK_TEXT_MAX
|
|
10
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-MYIBYAZC.js";
|
|
11
14
|
import "./chunk-HOOHS3MX.js";
|
|
12
15
|
import "./chunk-U67V476Y.js";
|
|
13
16
|
|
|
@@ -40,10 +43,9 @@ async function runDecide(args, opts = {}) {
|
|
|
40
43
|
if (!asked.length) return { line: "aucune d\xE9cision en attente", code: 0 };
|
|
41
44
|
return { line: asked.map((t) => [`${t.id} de ${t.giverName} ${t.title}`, ...t.text ? t.text.split("\n").map((l) => ` ${l}`) : []].join("\n")).join("\n\n"), code: 0 };
|
|
42
45
|
}
|
|
43
|
-
|
|
44
|
-
const r = await client.next("task.result", DECIDE_MS);
|
|
46
|
+
const r = await runOnClient(client, "task.answer", { task: op.task, answer: op.text }, { confirmed: true, ms: DECIDE_MS });
|
|
45
47
|
if (r.reason !== void 0) return { line: `refus\xE9 : ${r.reason}`, code: 1 };
|
|
46
|
-
return { line: `r\xE9ponse envoy\xE9e \xE0 ${r.
|
|
48
|
+
return { line: `r\xE9ponse envoy\xE9e \xE0 ${r.row?.vars?.session ?? "la session"}`, code: 0 };
|
|
47
49
|
} catch (e) {
|
|
48
50
|
return { line: `pas de r\xE9ponse de Ledge : ${e.message}`, code: 1 };
|
|
49
51
|
} finally {
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
handoverArgs,
|
|
4
4
|
handoverOnClient,
|
|
5
5
|
runHandover
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-HNC5Q5PV.js";
|
|
7
|
+
import "./chunk-TLFKLMBN.js";
|
|
8
|
+
import "./chunk-6YBIZZQG.js";
|
|
9
|
+
import "./chunk-MYIBYAZC.js";
|
|
10
10
|
import "./chunk-HOOHS3MX.js";
|
|
11
11
|
import "./chunk-U67V476Y.js";
|
|
12
12
|
export {
|