@paradow/ledge 0.33.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.
Files changed (42) hide show
  1. package/dist/cli/{action-QW2ZQQBN.js → action-K42H5BDA.js} +5 -5
  2. package/dist/cli/{attach-ULTYWCJ7.js → attach-KEE4A5YP.js} +28 -15
  3. package/dist/cli/{bridge-CSLF7EW6.js → bridge-X327AZY4.js} +2 -2
  4. package/dist/cli/{chunk-3DB3VOMM.js → chunk-25RVT5MR.js} +3 -103
  5. package/dist/cli/{chunk-GXL3X7M7.js → chunk-3OJCWJAA.js} +2 -2
  6. package/dist/cli/chunk-4OYVM4MT.js +49 -0
  7. package/dist/cli/{chunk-JEGPTNWV.js → chunk-4TCSADFR.js} +5 -23
  8. package/dist/cli/{chunk-HOOHS3MX.js → chunk-53ISXX2R.js} +1 -1
  9. package/dist/cli/{chunk-6IYPRUQG.js → chunk-54KF5RBY.js} +1 -1
  10. package/dist/cli/{chunk-ASYAWVFW.js → chunk-7NHQGP6J.js} +1 -1
  11. package/dist/cli/{chunk-4HXJQEUN.js → chunk-G7XPEVCG.js} +5 -5
  12. package/dist/cli/{chunk-WXE2NOE5.js → chunk-IWY7DSSO.js} +835 -1033
  13. package/dist/cli/{chunk-CSLVBADC.js → chunk-KPDTYX7F.js} +3 -3
  14. package/dist/cli/chunk-RPH773TY.js +6 -0
  15. package/dist/cli/{chunk-CCSUP5ZI.js → chunk-RX5CJ7YH.js} +3 -5
  16. package/dist/cli/{chunk-NLL2EQJ2.js → chunk-T547FLQN.js} +38 -4
  17. package/dist/cli/{chunk-K7UEKSB2.js → chunk-UJ2WBGLW.js} +2 -2
  18. package/dist/cli/{chunk-XOZD4BP5.js → chunk-ULOMKEB6.js} +4 -4
  19. package/dist/cli/{chunk-CPERVAPQ.js → chunk-V4XKKL6K.js} +13 -40
  20. package/dist/cli/{chunk-PZ3F4QH3.js → daemon-RO43S3S5.js} +4655 -2964
  21. package/dist/cli/{decide-PFHHOCFZ.js → decide-KZFYL3HY.js} +5 -5
  22. package/dist/cli/{handover-EMO6JT7O.js → handover-BWNMI2RA.js} +5 -5
  23. package/dist/cli/{hook-W2BU74H5.js → hook-ZLWXI5EQ.js} +21 -71
  24. package/dist/cli/index.js +18 -25
  25. package/dist/cli/launch-GCX7TXOH.js +28 -0
  26. package/dist/cli/{send-NEI4X33R.js → send-SXZAPVRH.js} +5 -5
  27. package/dist/cli/{setup-K42IVMHS.js → setup-TJ32FMVJ.js} +4 -4
  28. package/dist/cli/{status-U2HGGKHF.js → status-YDVRES4E.js} +3 -3
  29. package/dist/cli/{task-PDDCE23D.js → task-TUSOVJK7.js} +5 -5
  30. package/dist/cli/{tui-UPMRMCPC.js → tui-TCVIRZCQ.js} +1401 -1269
  31. package/dist/cli/{uninstall-4IMMR55T.js → uninstall-QO7YMSLA.js} +4 -4
  32. package/dist/cli/{version-LUMK3Z3T.js → version-BAYSYWFP.js} +1 -1
  33. package/dist/cli/who-6AZYSP7T.js +12 -0
  34. package/dist/ledge-guide.md +26 -49
  35. package/package.json +2 -1
  36. package/dist/cli/chunk-4VNKZOC2.js +0 -160
  37. package/dist/cli/chunk-E3LXONBI.js +0 -6
  38. package/dist/cli/chunk-NWIICISV.js +0 -290
  39. package/dist/cli/daemon-5GT545BB.js +0 -2322
  40. package/dist/cli/launch-LP7YJR5N.js +0 -36
  41. package/dist/cli/team-S3ASP22H.js +0 -205
  42. package/dist/cli/who-NM3GPAPJ.js +0 -12
@@ -8,11 +8,11 @@ import {
8
8
  resultLine,
9
9
  runClose,
10
10
  runOnClient
11
- } from "./chunk-XOZD4BP5.js";
12
- import "./chunk-JEGPTNWV.js";
13
- import "./chunk-ASYAWVFW.js";
14
- import "./chunk-WXE2NOE5.js";
15
- import "./chunk-HOOHS3MX.js";
11
+ } from "./chunk-ULOMKEB6.js";
12
+ import "./chunk-4TCSADFR.js";
13
+ import "./chunk-7NHQGP6J.js";
14
+ import "./chunk-IWY7DSSO.js";
15
+ import "./chunk-53ISXX2R.js";
16
16
  import "./chunk-U67V476Y.js";
17
17
  export {
18
18
  CLOSE_USAGE,
@@ -1,25 +1,20 @@
1
1
  import {
2
2
  attachEnv
3
- } from "./chunk-CPERVAPQ.js";
4
- import "./chunk-PZ3F4QH3.js";
5
- import "./chunk-OLLQBK6N.js";
6
- import "./chunk-NWIICISV.js";
7
- import "./chunk-3DB3VOMM.js";
8
- import "./chunk-4VNKZOC2.js";
9
- import "./chunk-JEGPTNWV.js";
3
+ } from "./chunk-V4XKKL6K.js";
4
+ import "./chunk-4TCSADFR.js";
10
5
  import {
11
6
  connect
12
- } from "./chunk-ASYAWVFW.js";
7
+ } from "./chunk-7NHQGP6J.js";
13
8
  import {
14
9
  PROTOCOL_PORT,
15
10
  backendOf
16
- } from "./chunk-WXE2NOE5.js";
17
- import "./chunk-E3LXONBI.js";
11
+ } from "./chunk-IWY7DSSO.js";
18
12
  import {
13
+ isSeatSession,
19
14
  realTmux
20
- } from "./chunk-NLL2EQJ2.js";
21
- import "./chunk-6IYPRUQG.js";
22
- import "./chunk-HOOHS3MX.js";
15
+ } from "./chunk-T547FLQN.js";
16
+ import "./chunk-54KF5RBY.js";
17
+ import "./chunk-53ISXX2R.js";
23
18
  import "./chunk-U67V476Y.js";
24
19
 
25
20
  // src/cli/attach.ts
@@ -32,6 +27,17 @@ function attachInherit(args, env) {
32
27
  child.on("exit", (c) => resolve(c ?? 1));
33
28
  });
34
29
  }
30
+ async function seatSession(id, port) {
31
+ try {
32
+ const c = await connect({ port, timeoutMs: 800 });
33
+ const snap = await c.next("snapshot");
34
+ await Promise.race([c.close(), new Promise((r) => setTimeout(r, 500))]);
35
+ const s = snap.sessions.find((x) => x.id === id);
36
+ return s?.source === "rig" && s.tmuxSession && isSeatSession(s.tmuxSession) ? s.tmuxSession : null;
37
+ } catch {
38
+ return null;
39
+ }
40
+ }
35
41
  async function nativeSession(id, port) {
36
42
  try {
37
43
  const c = await connect({ port, timeoutMs: 800 });
@@ -48,8 +54,15 @@ async function attach(id, opts = {}) {
48
54
  console.error("ledge attach: missing session id");
49
55
  return 2;
50
56
  }
51
- const tmux = realTmux(opts.tmuxSocket ?? TMUX_SOCKET);
52
- const tmuxName = `ledge-${id}`;
57
+ let tmux = realTmux(opts.tmuxSocket ?? TMUX_SOCKET);
58
+ let tmuxName = `ledge-${id}`;
59
+ if (!await tmux.hasSession(tmuxName)) {
60
+ const seat = await seatSession(id, opts.port ?? PROTOCOL_PORT);
61
+ if (seat) {
62
+ tmux = realTmux(opts.seatSocket === void 0 ? null : opts.seatSocket);
63
+ tmuxName = seat;
64
+ }
65
+ }
53
66
  if (!await tmux.hasSession(tmuxName)) {
54
67
  const native = await nativeSession(id, opts.port ?? PROTOCOL_PORT);
55
68
  console.error(native ? `ledge attach: ${native} is driven by Ledge over OMP's own protocol: there is no terminal to attach to (open a shell from the app)` : `ledge attach: no session ${id}`);
@@ -7,8 +7,8 @@ import {
7
7
  parseClientMessage,
8
8
  parseServerMessage,
9
9
  readDaemonToken
10
- } from "./chunk-WXE2NOE5.js";
11
- import "./chunk-HOOHS3MX.js";
10
+ } from "./chunk-IWY7DSSO.js";
11
+ import "./chunk-53ISXX2R.js";
12
12
  import "./chunk-U67V476Y.js";
13
13
 
14
14
  // src/cli/bridge.ts
@@ -1,87 +1,10 @@
1
1
  import {
2
2
  ledgeTitleRest
3
- } from "./chunk-JEGPTNWV.js";
3
+ } from "./chunk-4TCSADFR.js";
4
4
  import {
5
5
  cleanTopic,
6
- isArchived,
7
6
  sessionTitle
8
- } from "./chunk-WXE2NOE5.js";
9
-
10
- // src/daemon/seat.ts
11
- function teammates(team, sessions) {
12
- const byId = new Map(sessions.map((s) => [s.id, s]));
13
- return team.seats.flatMap((seat) => {
14
- const s = seat.sessionId ? byId.get(seat.sessionId) : void 0;
15
- return s && s.state !== "exited" && !isArchived(s) ? [{ name: s.name, role: seat.role }] : [];
16
- });
17
- }
18
- function seatContext(o) {
19
- const id = o.role?.id ?? o.roleId;
20
- const label = o.role?.label ?? o.roleLabel ?? id;
21
- const lines = [];
22
- if (id) lines.push(`Ton r\xF4le : ${label} (${id})${o.team ? `, dans l'\xE9quipe ${o.team.name}` : ""}.`);
23
- if (o.role?.prompt.trim()) lines.push(o.role.prompt.trim());
24
- if (o.team) {
25
- const members = o.team.members.map((m) => `${m.name} (${m.role})`).join(", ") || "personne d'autre pour l'instant";
26
- lines.push(
27
- `Ton \xE9quipe : ${members}. \xC9cris-leur par leur r\xF4le : ledge send @build "\u2026", ledge task give @qa "\u2026".`,
28
- `L'op\xE9rateur est Ledge : il t'a confi\xE9 ou te confiera ton travail par une <ledge-task>. Travaille en autonomie avec ton \xE9quipe ; ne t'arr\xEAte pour l'utilisateur que pour une d\xE9cision qui lui revient. Termine toujours une t\xE2che re\xE7ue (ledge task done <id> "<r\xE9sultat>", ou refuse) : c'est ainsi que Ledge et l'utilisateur savent o\xF9 en est l'\xE9quipe.`
29
- );
30
- }
31
- return lines.join("\n");
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
- }
73
- function resolveRoleAddress(to, from, sessions, teams) {
74
- if (!to.startsWith("@")) return { to };
75
- const role = to.slice(1);
76
- const team = teams.find((t) => t.state !== "dissolved" && t.seats.some((s) => s.sessionId === from));
77
- if (!team) return { reason: noTeamReason(to, sessions.find((s) => s.id === from)) };
78
- const byId = new Map(sessions.map((s) => [s.id, s]));
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));
80
- if (held.length === 1) return { to: held[0].name };
81
- if (held.length > 1) return { reason: `plusieurs sessions tiennent ${to} dans ${team.name} : ${held.map((s) => s.name).join(", ")}` };
82
- const roles = teammates(team, sessions).map((m) => `@${m.role}`);
83
- return { reason: `personne ne tient ${to} dans l'\xE9quipe ${team.name}${roles.length ? ` (r\xF4les tenus : ${roles.join(", ")})` : ""}` };
84
- }
7
+ } from "./chunk-IWY7DSSO.js";
85
8
 
86
9
  // src/daemon/crossSession.ts
87
10
  import { createHash } from "crypto";
@@ -153,19 +76,6 @@ function formatLedgeNotice(n) {
153
76
  const quote = ledgeBody(flat.length > NOTICE_QUOTE ? `${flat.slice(0, NOTICE_QUOTE)}\u2026` : flat);
154
77
  return `<ledge-notice to="${to}">Ledge n'a pas pu remettre ton message \xE0 ${to} (\xAB ${quote}${NOTICE_REASON}${ledgeBody(n.reason)}</ledge-notice>`;
155
78
  }
156
- function formatTeamNotice(n) {
157
- return `<ledge-notice team="${attr(n.team)}">${ledgeBody(n.text)}</ledge-notice>`;
158
- }
159
- function formatRoleNotice(n) {
160
- return `<ledge-notice role="${attr(n.role)}">${ledgeBody(n.text)}</ledge-notice>`;
161
- }
162
- var TEAM_NOTICE = /^<ledge-notice\b([^>]*\bteam="[^"]*"[^>]*)>([\s\S]*?)(?:<\/ledge-notice>|$)/;
163
- function ledgeTeamNotice(text) {
164
- const m = TEAM_NOTICE.exec(text.trimStart());
165
- if (!m) return void 0;
166
- const team = new Map([...m[1].matchAll(ATTR)].map((a) => [a[1], a[2]])).get("team");
167
- return team ? { team, text: m[2].trim() } : void 0;
168
- }
169
79
  var TASK_BLOCK = /^<ledge-task\b([^>]*)>([\s\S]*?)(?:<\/ledge-task>|$)/;
170
80
  function formatLedgeTask(t) {
171
81
  return `<ledge-task id="${attr(t.id)}" from="${attr(t.from)}">${ledgeBody(t.text)}</ledge-task>`;
@@ -531,7 +441,7 @@ function reduceEvent(s, ev) {
531
441
  case "PreToolUse":
532
442
  case "PermissionRequest":
533
443
  case "Notification": {
534
- const notice2 = ev.name === "UserPromptSubmit" && !!ev.text && (!!crossSessionNotices(ev.text) || !!ledgeNotice(ev.text) || !!ledgeTask(ev.text) || !!ledgeTeamNotice(ev.text));
444
+ const notice2 = ev.name === "UserPromptSubmit" && !!ev.text && (!!crossSessionNotices(ev.text) || !!ledgeNotice(ev.text) || !!ledgeTask(ev.text));
535
445
  if (ev.name === "UserPromptSubmit" && ev.text && !s.topic && !notice2 && !crossSession(ev.text)) s = withTopic(s, ev.text, "prompt");
536
446
  if (s.pending?.source === "rpc" && ev.name === "PreToolUse") return { ...s, lastHookAt: at, lastActivityAt: at };
537
447
  const incoming = pendingFor(ev);
@@ -675,13 +585,6 @@ function takeImages(text, dir) {
675
585
  }
676
586
 
677
587
  export {
678
- teammates,
679
- seatContext,
680
- noTeamReason,
681
- seatView,
682
- seatKey,
683
- teamChangeLine,
684
- resolveRoleAddress,
685
588
  crossSession,
686
589
  messageNote,
687
590
  stripNote,
@@ -691,9 +594,6 @@ export {
691
594
  formatLedgeMessage,
692
595
  ledgeMessages,
693
596
  formatLedgeNotice,
694
- formatTeamNotice,
695
- formatRoleNotice,
696
- ledgeTeamNotice,
697
597
  formatLedgeTask,
698
598
  ledgeTask,
699
599
  ledgeNotice,
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  CODEX_HOOK_VAR
3
- } from "./chunk-JEGPTNWV.js";
3
+ } from "./chunk-4TCSADFR.js";
4
4
  import {
5
5
  connect,
6
6
  sendMessageAndAwaitAck
7
- } from "./chunk-ASYAWVFW.js";
7
+ } from "./chunk-7NHQGP6J.js";
8
8
 
9
9
  // src/cli/send.ts
10
10
  import { randomUUID } from "crypto";
@@ -0,0 +1,49 @@
1
+ // src/imageInfo.ts
2
+ var ok = (mime, width, height) => width > 0 && height > 0 ? { mime, width, height } : null;
3
+ function jpeg(b) {
4
+ let i = 2;
5
+ while (i + 4 <= b.length) {
6
+ if (b[i] !== 255) {
7
+ i++;
8
+ continue;
9
+ }
10
+ const m = b[i + 1];
11
+ if (m === 255) {
12
+ i++;
13
+ continue;
14
+ }
15
+ if (m === 216 || m === 1 || m >= 208 && m <= 215) {
16
+ i += 2;
17
+ continue;
18
+ }
19
+ const len = b.readUInt16BE(i + 2);
20
+ if (m >= 192 && m <= 207 && m !== 196 && m !== 200 && m !== 204) return i + 9 <= b.length ? ok("image/jpeg", b.readUInt16BE(i + 7), b.readUInt16BE(i + 5)) : null;
21
+ i += 2 + len;
22
+ }
23
+ return null;
24
+ }
25
+ function webp(b) {
26
+ const kind = b.toString("latin1", 12, 16);
27
+ if (kind === "VP8X") return b.length >= 30 ? ok("image/webp", b.readUIntLE(24, 3) + 1, b.readUIntLE(27, 3) + 1) : null;
28
+ if (kind === "VP8L") {
29
+ if (b.length < 25 || b[20] !== 47) return null;
30
+ const bits = b.readUInt32LE(21);
31
+ return ok("image/webp", (bits & 16383) + 1, (bits >>> 14 & 16383) + 1);
32
+ }
33
+ if (kind === "VP8 ") return b.length >= 30 && b[23] === 157 && b[24] === 1 && b[25] === 42 ? ok("image/webp", b.readUInt16LE(26) & 16383, b.readUInt16LE(28) & 16383) : null;
34
+ return null;
35
+ }
36
+ function imageInfo(b) {
37
+ try {
38
+ if (b.length >= 24 && b.readUInt32BE(0) === 2303741511 && b.readUInt32BE(4) === 218765834 && b.toString("latin1", 12, 16) === "IHDR") return ok("image/png", b.readUInt32BE(16), b.readUInt32BE(20));
39
+ if (b.length >= 10 && (b.toString("latin1", 0, 6) === "GIF87a" || b.toString("latin1", 0, 6) === "GIF89a")) return ok("image/gif", b.readUInt16LE(6), b.readUInt16LE(8));
40
+ if (b.length >= 4 && b[0] === 255 && b[1] === 216) return jpeg(b);
41
+ if (b.length >= 16 && b.toString("latin1", 0, 4) === "RIFF" && b.toString("latin1", 8, 12) === "WEBP") return webp(b);
42
+ } catch {
43
+ }
44
+ return null;
45
+ }
46
+
47
+ export {
48
+ imageInfo
49
+ };
@@ -3,10 +3,10 @@ import {
3
3
  SESSION_KEY_VAR,
4
4
  pickName,
5
5
  sessionKey
6
- } from "./chunk-WXE2NOE5.js";
6
+ } from "./chunk-IWY7DSSO.js";
7
7
  import {
8
8
  paths
9
- } from "./chunk-HOOHS3MX.js";
9
+ } from "./chunk-53ISXX2R.js";
10
10
 
11
11
  // src/daemon/transcript.ts
12
12
  import { appendFileSync, closeSync, fstatSync, openSync, readFileSync, readSync, statSync } from "fs";
@@ -210,7 +210,7 @@ var PARENT_AGENT_VARS = [
210
210
  var PARENT_AGENT = new Set(PARENT_AGENT_VARS);
211
211
  function agentEnv(base, extra) {
212
212
  const env = {};
213
- for (const [k, v] of Object.entries(base)) if (v !== void 0 && k !== "TMUX" && !k.startsWith("TMUX_") && !PARENT_AGENT.has(k) && k !== "LEDGE_ROLE" && k !== "LEDGE_TEAM") env[k] = v;
213
+ for (const [k, v] of Object.entries(base)) if (v !== void 0 && k !== "TMUX" && !k.startsWith("TMUX_") && !PARENT_AGENT.has(k)) env[k] = v;
214
214
  return { ...env, ...extra };
215
215
  }
216
216
  async function spawnSession(opts) {
@@ -229,27 +229,9 @@ async function spawnSession(opts) {
229
229
  const transcriptPath = agentSessionId ? claudeTranscriptPath(opts.cwd, agentSessionId, env) : void 0;
230
230
  const command = opts.recordExit ? ["sh", "-c", '"$@"; echo $? > "$0"', exitFile(id), ...agent] : agent;
231
231
  const key = sessionKey(id);
232
- await opts.tmux.newSession({ name: tmuxSession, cwd: opts.cwd, env: agentEnv(env, { LEDGE_SESSION: id, ...key ? { [SESSION_KEY_VAR]: key } : {}, LEDGE_NAME: name, ...opts.role ? { LEDGE_ROLE: opts.role.id } : {}, ...opts.team ? { LEDGE_TEAM: opts.team } : {}, ...opts.tool === "codex" ? { [CODEX_ENV_VAR]: id } : {} }), unset: PARENT_AGENT_VARS, command });
232
+ await opts.tmux.newSession({ name: tmuxSession, cwd: opts.cwd, env: agentEnv(env, { LEDGE_SESSION: id, ...key ? { [SESSION_KEY_VAR]: key } : {}, LEDGE_NAME: name, ...opts.tool === "codex" ? { [CODEX_ENV_VAR]: id } : {} }), unset: PARENT_AGENT_VARS, command });
233
233
  const at = now();
234
- return {
235
- id,
236
- name,
237
- tool: opts.tool,
238
- cwd: opts.cwd,
239
- project,
240
- title: `${name} \xB7 ${project}`,
241
- tmuxSession,
242
- state: "starting",
243
- helpers: [],
244
- startedAt: at,
245
- lastActivityAt: at,
246
- source: "launcher",
247
- ...agentSessionId ? { agentSessionId } : {},
248
- ...transcriptPath ? { transcriptPath } : {},
249
- ...opts.role ? { role: opts.role.id, roleLabel: opts.role.label } : {},
250
- ...opts.team ? { team: opts.team } : {},
251
- ...opts.autonomy && opts.autonomy !== "ask" ? { autonomy: opts.autonomy } : {}
252
- };
234
+ return { id, name, tool: opts.tool, cwd: opts.cwd, project, title: `${name} \xB7 ${project}`, tmuxSession, state: "starting", helpers: [], startedAt: at, lastActivityAt: at, source: "launcher", ...agentSessionId ? { agentSessionId } : {}, ...transcriptPath ? { transcriptPath } : {} };
253
235
  }
254
236
 
255
237
  export {
@@ -17,7 +17,7 @@ function ledgeDir() {
17
17
  }
18
18
  function paths() {
19
19
  const dir = ledgeDir();
20
- return { dir, tmuxConf: join(dir, "tmux.conf"), journal: join(dir, "sessions.json"), log: join(dir, "daemon.log"), pid: join(dir, "daemon.pid"), history: join(dir, "history"), mail: join(dir, "mail.json"), tasks: join(dir, "tasks.json"), teams: join(dir, "teams-live.json"), machines: join(dir, "machines.json"), projects: join(dir, "projects.json"), island: join(dir, "island.json"), token: join(dir, "token"), mobile: join(dir, "mobile.json"), mobileSession: join(dir, "mobile-session.json"), mobileKey: join(dir, "mobile-key"), devices: join(dir, "devices.json"), revocations: join(dir, "revocations.json"), attachments: join(dir, "attachments") };
20
+ return { dir, tmuxConf: join(dir, "tmux.conf"), journal: join(dir, "sessions.json"), log: join(dir, "daemon.log"), pid: join(dir, "daemon.pid"), history: join(dir, "history"), mail: join(dir, "mail.json"), tasks: join(dir, "tasks.json"), machines: join(dir, "machines.json"), projects: join(dir, "projects.json"), island: join(dir, "island.json"), token: join(dir, "token"), mobile: join(dir, "mobile.json"), mobileSession: join(dir, "mobile-session.json"), mobileKey: join(dir, "mobile-key"), devices: join(dir, "devices.json"), revocations: join(dir, "revocations.json"), attachments: join(dir, "attachments") };
21
21
  }
22
22
  async function ensureLedgeDir() {
23
23
  const p = paths();
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  paths
3
- } from "./chunk-HOOHS3MX.js";
3
+ } from "./chunk-53ISXX2R.js";
4
4
 
5
5
  // src/log.ts
6
6
  import { appendFileSync } from "fs";
@@ -4,7 +4,7 @@ import {
4
4
  SUMMARY_MAX,
5
5
  parseServerMessage,
6
6
  readDaemonToken
7
- } from "./chunk-WXE2NOE5.js";
7
+ } from "./chunk-IWY7DSSO.js";
8
8
 
9
9
  // src/client.ts
10
10
  import WebSocket from "ws";
@@ -1,25 +1,25 @@
1
1
  import {
2
2
  CODEX_HOOK_VAR
3
- } from "./chunk-JEGPTNWV.js";
3
+ } from "./chunk-4TCSADFR.js";
4
4
  import {
5
5
  connect
6
- } from "./chunk-ASYAWVFW.js";
6
+ } from "./chunk-7NHQGP6J.js";
7
7
  import {
8
8
  LEDGE_GIVER,
9
9
  TASK_TEXT_MAX,
10
10
  TASK_TITLE_MAX
11
- } from "./chunk-WXE2NOE5.js";
11
+ } from "./chunk-IWY7DSSO.js";
12
12
 
13
13
  // src/cli/task.ts
14
14
  import { randomUUID } from "crypto";
15
- var TASK_USAGE = `ledge task give <nom|@r\xF4le> "<titre>" ["<d\xE9tail>"] confier un travail \xE0 une session (@r\xF4le : dans ton \xE9quipe)
15
+ var TASK_USAGE = `ledge task give <nom> "<titre>" ["<d\xE9tail>"] confier un travail \xE0 une session
16
16
  ledge task give ledge "<question>" "<options, recommandation>" une d\xE9cision pour l'utilisateur ; sa r\xE9ponse te r\xE9veille
17
17
  ledge task list [--all] tes t\xE2ches (tenues ou confi\xE9es), ouvertes ; --all : closes aussi
18
18
  ledge task show <id> une t\xE2che, son d\xE9tail et son historique
19
19
  ledge task take <id> la prendre
20
20
  ledge task done <id> "<r\xE9sultat>" la terminer, avec ce qui en est sorti (la session qui l'a confi\xE9e est pr\xE9venue)
21
21
  ledge task refuse <id> "<raison>" la refuser, ou l'annuler si tu l'as confi\xE9e
22
- ledge task pass <id> <nom|@r\xF4le> ["<note>"] la passer \xE0 une autre session`;
22
+ ledge task pass <id> <nom> ["<note>"] la passer \xE0 une autre session`;
23
23
  var TASK_MS = 4e3;
24
24
  var ID = /^t[0-9a-f]{6}$/;
25
25
  function taskArgs(args) {