@paradow/ledge 0.29.0 → 0.30.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 (32) hide show
  1. package/dist/cli/{action-MAPPYLUM.js → action-IL5A2O4K.js} +4 -4
  2. package/dist/cli/{attach-OC64CLB2.js → attach-XFRWCGMD.js} +8 -8
  3. package/dist/cli/{bridge-TWX4V37E.js → bridge-KEDZGBEK.js} +1 -1
  4. package/dist/cli/{chunk-XZYQMKKO.js → chunk-2GSAJOLJ.js} +3 -3
  5. package/dist/cli/{chunk-WIUJNSAZ.js → chunk-4JQHF3HM.js} +5 -5
  6. package/dist/cli/{chunk-ETGOWBUL.js → chunk-D2EYVNJ6.js} +3 -3
  7. package/dist/cli/{chunk-73YNZ3BN.js → chunk-GOBUJGB6.js} +1 -1
  8. package/dist/cli/{chunk-TNYBWWRO.js → chunk-H563AKHN.js} +2 -2
  9. package/dist/cli/{chunk-WCBXS3EU.js → chunk-HH6LFLPR.js} +107 -15
  10. package/dist/cli/{chunk-RFFTWAAF.js → chunk-JBYVS2F4.js} +1 -1
  11. package/dist/cli/{chunk-353WRRGG.js → chunk-KESZUXUI.js} +3 -3
  12. package/dist/cli/{chunk-UWDE365N.js → chunk-LHWJBSLO.js} +47 -3
  13. package/dist/cli/{chunk-TREGH6WM.js → chunk-OOPOJK6Y.js} +206 -175
  14. package/dist/cli/chunk-P2X2M3TR.js +6 -0
  15. package/dist/cli/{chunk-MZVMW356.js → chunk-RGYQFRG5.js} +2 -2
  16. package/dist/cli/{chunk-7S7ZLGIY.js → chunk-U44NT4XJ.js} +35 -7
  17. package/dist/cli/{chunk-K3SDHHZF.js → chunk-XHC6EPZE.js} +1 -1
  18. package/dist/cli/{daemon-ZTZ7VMYA.js → daemon-A54MACKQ.js} +7 -7
  19. package/dist/cli/{decide-4BIYS3Y2.js → decide-2HKZF4VI.js} +8 -6
  20. package/dist/cli/{handover-IS7BJYGZ.js → handover-3PV3MDK3.js} +4 -4
  21. package/dist/cli/{hook-3VKVD4IP.js → hook-S5226MJF.js} +34 -13
  22. package/dist/cli/index.js +16 -16
  23. package/dist/cli/{launch-XAPN2M3Q.js → launch-NGWPGU6E.js} +8 -8
  24. package/dist/cli/{send-ZLF2ZXMJ.js → send-NYKZRELC.js} +4 -4
  25. package/dist/cli/{status-NONO6E2S.js → status-6USM7SJE.js} +2 -2
  26. package/dist/cli/{task-47MVWDCY.js → task-E5J6UT7S.js} +4 -4
  27. package/dist/cli/{team-EJ4YIXJH.js → team-AP7A5VMP.js} +6 -6
  28. package/dist/cli/{tui-CAP4O4YQ.js → tui-EK7VC7YP.js} +1273 -1176
  29. package/dist/cli/{version-EHBPJO7K.js → version-KORN5SQT.js} +1 -1
  30. package/dist/cli/{who-FHAXYCM2.js → who-RA4QBVUA.js} +3 -3
  31. package/package.json +1 -1
  32. package/dist/cli/chunk-JZEWCO6X.js +0 -6
@@ -0,0 +1,6 @@
1
+ // src/version.ts
2
+ var LEDGE_VERSION = true ? "0.30.0" : "0.0.0-dev";
3
+
4
+ export {
5
+ LEDGE_VERSION
6
+ };
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  CODEX_HOOK_VAR
3
- } from "./chunk-K3SDHHZF.js";
3
+ } from "./chunk-XHC6EPZE.js";
4
4
  import {
5
5
  connect,
6
6
  sendMessageAndAwaitAck
7
- } from "./chunk-RFFTWAAF.js";
7
+ } from "./chunk-JBYVS2F4.js";
8
8
 
9
9
  // src/cli/send.ts
10
10
  import { randomUUID } from "crypto";
@@ -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; `leaving` marks a seat removed
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;
@@ -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,
@@ -3,7 +3,7 @@ import {
3
3
  SESSION_KEY_VAR,
4
4
  pickName,
5
5
  sessionKey
6
- } from "./chunk-7S7ZLGIY.js";
6
+ } from "./chunk-U44NT4XJ.js";
7
7
  import {
8
8
  paths
9
9
  } from "./chunk-HOOHS3MX.js";
@@ -9,9 +9,9 @@ import {
9
9
  startServer,
10
10
  tasksJournal,
11
11
  teamsJournal
12
- } from "./chunk-TREGH6WM.js";
12
+ } from "./chunk-OOPOJK6Y.js";
13
13
  import "./chunk-OLLQBK6N.js";
14
- import "./chunk-WCBXS3EU.js";
14
+ import "./chunk-HH6LFLPR.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-UWDE365N.js";
30
- import "./chunk-73YNZ3BN.js";
29
+ } from "./chunk-LHWJBSLO.js";
30
+ import "./chunk-GOBUJGB6.js";
31
31
  import {
32
32
  agentMessages
33
- } from "./chunk-K3SDHHZF.js";
33
+ } from "./chunk-XHC6EPZE.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-7S7ZLGIY.js";
47
+ } from "./chunk-U44NT4XJ.js";
48
48
  import {
49
49
  LEDGE_VERSION
50
- } from "./chunk-JZEWCO6X.js";
50
+ } from "./chunk-P2X2M3TR.js";
51
51
  import {
52
52
  SERVICE,
53
53
  inDaemonService,
@@ -1,13 +1,16 @@
1
+ import {
2
+ runOnClient
3
+ } from "./chunk-KESZUXUI.js";
1
4
  import {
2
5
  CODEX_HOOK_VAR
3
- } from "./chunk-K3SDHHZF.js";
6
+ } from "./chunk-XHC6EPZE.js";
4
7
  import {
5
8
  connect
6
- } from "./chunk-RFFTWAAF.js";
9
+ } from "./chunk-JBYVS2F4.js";
7
10
  import {
8
11
  LEDGE_GIVER,
9
12
  TASK_TEXT_MAX
10
- } from "./chunk-7S7ZLGIY.js";
13
+ } from "./chunk-U44NT4XJ.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
- client.send({ type: "task.cmd", rid: randomUUID(), by: LEDGE_GIVER, op: "done", task: op.task, text: op.text });
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.task.giverName}`, code: 0 };
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-XZYQMKKO.js";
7
- import "./chunk-K3SDHHZF.js";
8
- import "./chunk-RFFTWAAF.js";
9
- import "./chunk-7S7ZLGIY.js";
6
+ } from "./chunk-2GSAJOLJ.js";
7
+ import "./chunk-XHC6EPZE.js";
8
+ import "./chunk-JBYVS2F4.js";
9
+ import "./chunk-U44NT4XJ.js";
10
10
  import "./chunk-HOOHS3MX.js";
11
11
  import "./chunk-U67V476Y.js";
12
12
  export {
@@ -6,38 +6,42 @@ import {
6
6
  resolveRoleAddress,
7
7
  resolveTarget,
8
8
  seatContext,
9
+ seatKey,
10
+ seatView,
9
11
  takeImages,
12
+ teamChangeLine,
10
13
  teammates
11
- } from "./chunk-UWDE365N.js";
14
+ } from "./chunk-LHWJBSLO.js";
12
15
  import {
13
16
  findRole
14
- } from "./chunk-73YNZ3BN.js";
17
+ } from "./chunk-GOBUJGB6.js";
15
18
  import {
16
19
  parseLedgeCommand,
17
20
  readOnClient,
18
21
  sendOnClient
19
- } from "./chunk-MZVMW356.js";
22
+ } from "./chunk-RGYQFRG5.js";
20
23
  import {
21
24
  taskOnClient
22
- } from "./chunk-ETGOWBUL.js";
25
+ } from "./chunk-D2EYVNJ6.js";
23
26
  import {
24
27
  handoverOnClient
25
- } from "./chunk-XZYQMKKO.js";
28
+ } from "./chunk-2GSAJOLJ.js";
26
29
  import {
27
30
  CODEX_ENV_VAR,
28
31
  CODEX_HOOK_VAR,
29
32
  codexPlan
30
- } from "./chunk-K3SDHHZF.js";
33
+ } from "./chunk-XHC6EPZE.js";
31
34
  import {
32
35
  formatWho
33
- } from "./chunk-TNYBWWRO.js";
36
+ } from "./chunk-H563AKHN.js";
34
37
  import {
35
38
  connect,
36
39
  sendMessageAndAwaitAck
37
- } from "./chunk-RFFTWAAF.js";
40
+ } from "./chunk-JBYVS2F4.js";
38
41
  import {
42
+ MESSAGE_MAX,
39
43
  taskClosed
40
- } from "./chunk-7S7ZLGIY.js";
44
+ } from "./chunk-U44NT4XJ.js";
41
45
  import {
42
46
  log
43
47
  } from "./chunk-6IYPRUQG.js";
@@ -51,15 +55,14 @@ import { randomUUID } from "crypto";
51
55
  import { readFileSync, openSync, fstatSync, readSync, closeSync } from "fs";
52
56
  import { basename, join } from "path";
53
57
  var str = (v) => typeof v === "string" ? v : void 0;
54
- var PROMPT_MAX = 500;
55
- var fromAgent = (t) => t.startsWith('<agent-message from="') || t.startsWith("<cross-session-message ") || t.startsWith("[Cross-session ");
58
+ var PROMPT_MAX = MESSAGE_MAX;
56
59
  var promptText = (p) => {
57
60
  const raw = str(p.prompt)?.trim();
58
61
  if (!raw) return {};
59
62
  const taken = takeImages(raw, paths().attachments);
60
63
  const ids = taken.ids;
61
64
  const t = ids.length ? taken.text : raw;
62
- return { ...t ? { text: t.slice(0, fromAgent(t) ? INPUT_MAX : PROMPT_MAX) } : {}, ...ids.length ? { attachments: ids } : {} };
65
+ return { ...t ? { text: t.slice(0, PROMPT_MAX) } : {}, ...ids.length ? { attachments: ids } : {} };
63
66
  };
64
67
  function describeTool(tool, input) {
65
68
  const i = input && typeof input === "object" ? input : {};
@@ -391,6 +394,19 @@ function seatOf(known, dir, live) {
391
394
  const seat = seatContext({ ...role ? { role } : {}, roleId, roleLabel: known?.roleLabel, ...team ? { team: { name: team.name, members: teammates(team, live.sessions).filter((m) => m.name !== known?.name) } } : {} });
392
395
  return seat ? { seat } : {};
393
396
  }
397
+ var SEAT_REFRESH_MS = 500;
398
+ async function seatChange(client, id, deadline) {
399
+ const left = () => Math.max(0, deadline - Date.now());
400
+ const snapshot = await client.next("snapshot", left()).catch(() => void 0);
401
+ const me = snapshot?.sessions.find((s) => s.id === id);
402
+ if (!snapshot || !me || !me.team && !me.teamSeen) return void 0;
403
+ const teams = me.team ? (await client.next("teams", left()).catch(() => void 0))?.teams : [];
404
+ if (!teams) return void 0;
405
+ const key = seatKey(seatView(id, snapshot.sessions, teams));
406
+ if (key === me.teamSeen) return void 0;
407
+ client.send({ type: "seat.seen", id, key });
408
+ return teamChangeLine(me.teamSeen, key);
409
+ }
394
410
  var SEND_MESSAGE_MS = 1500;
395
411
  var deny = (reason) => JSON.stringify({ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: reason } });
396
412
  async function relayMessage(client, from, toolUseId, input, deadline) {
@@ -446,6 +462,7 @@ async function runHook(eventName, stdin, opts = {}) {
446
462
  let live = { sessions: [], teams: [] };
447
463
  let deadline = Date.now() + (opts.timeoutMs ?? 100);
448
464
  let relayed;
465
+ let seatLine;
449
466
  let held = [];
450
467
  try {
451
468
  const payload = JSON.parse(stdin || "{}");
@@ -456,10 +473,11 @@ async function runHook(eventName, stdin, opts = {}) {
456
473
  }
457
474
  const launchedId = agent === "codex" ? codexLedgeId() : agent === "claude" ? process.env.LEDGE_SESSION : void 0;
458
475
  identify = eventName === "SessionStart" && !!launchedId && mapped.id === launchedId;
476
+ const refresh = eventName === "UserPromptSubmit" && agent !== "cursor" && !!launchedId && mapped.id === launchedId;
459
477
  const input = payload.tool_input ?? {};
460
478
  const intercept = agent === "claude" && eventName === "PreToolUse" && str(payload.tool_name) === "SendMessage" && typeof input.to === "string" && typeof input.message === "string" && !!input.message;
461
479
  const command = agent === "codex" && eventName === "PreToolUse" && str(payload.tool_name) === "Bash" && typeof input.command === "string" ? parseLedgeCommand(input.command) : void 0;
462
- const timeoutMs = opts.timeoutMs ?? (identify ? 1e3 : intercept || command ? SEND_MESSAGE_MS : 100);
480
+ const timeoutMs = opts.timeoutMs ?? (identify ? 1e3 : intercept || command ? SEND_MESSAGE_MS : refresh ? SEAT_REFRESH_MS : 100);
463
481
  deadline = Date.now() + timeoutMs;
464
482
  const client = await connect({ port: opts.port, timeoutMs });
465
483
  client.send({ type: "session.event", id: mapped.id, event: mapped.event, agent: mapped.agent, ...mapped.cwd ? { cwd: mapped.cwd } : {} });
@@ -468,10 +486,12 @@ async function runHook(eventName, stdin, opts = {}) {
468
486
  known = snapshot?.sessions.find((s) => s.id === mapped.id);
469
487
  const teamList = known?.team ? (await client.next("teams", Math.max(0, deadline - Date.now())).catch(() => void 0))?.teams : void 0;
470
488
  live = { sessions: snapshot?.sessions ?? [], teams: teamList ?? [] };
489
+ if (snapshot && known && (!known.team || teamList)) client.send({ type: "seat.seen", id: known.id, key: seatKey(seatView(known.id, live.sessions, live.teams)) });
471
490
  client.send({ type: "task.cmd", rid: randomUUID(), by: mapped.id, op: "list" });
472
491
  const listed = await client.next("task.result", Math.max(0, deadline - Date.now())).catch(() => void 0);
473
492
  held = (listed?.tasks ?? []).filter((t) => t.owner === mapped.id && !taskClosed(t));
474
493
  }
494
+ if (refresh) seatLine = await seatChange(client, mapped.id, deadline);
475
495
  if (intercept) relayed = await relayMessage(client, mapped.id, str(payload.tool_use_id), input, deadline);
476
496
  if (command) relayed = await runLedgeCommand(client, command, mapped.id, deadline);
477
497
  await Promise.race([client.close(), new Promise((r) => setTimeout(r, Math.max(0, deadline - Date.now())))]);
@@ -479,6 +499,7 @@ async function runHook(eventName, stdin, opts = {}) {
479
499
  log(`hook ${label} dropped: ${e.message}`);
480
500
  }
481
501
  if (relayed) return relayed;
502
+ if (seatLine) return JSON.stringify({ hookSpecificOutput: { hookEventName: "UserPromptSubmit", additionalContext: seatLine } });
482
503
  if (!identify || !mapped) return void 0;
483
504
  const found = await identity(agent, mapped.cwd, known, deadline, live);
484
505
  const who = found ? { ...found, ...held.length ? { tasks: held } : {}, ...known?.relieves ? { relieves: known.relieves } : {} } : void 0;
package/dist/cli/index.js CHANGED
@@ -25,7 +25,7 @@ async function hookMain(args) {
25
25
  try {
26
26
  const chunks = [];
27
27
  for await (const c of process.stdin) chunks.push(c);
28
- const { runHook } = await import("./hook-3VKVD4IP.js");
28
+ const { runHook } = await import("./hook-S5226MJF.js");
29
29
  const out = await runHook(event, Buffer.concat(chunks).toString("utf8"), { tool });
30
30
  if (out) process.stdout.write(`${out}
31
31
  `);
@@ -37,7 +37,7 @@ async function main(argv) {
37
37
  const [cmd, ...rest] = argv;
38
38
  switch (cmd) {
39
39
  case "daemon": {
40
- const { startDaemon } = await import("./daemon-ZTZ7VMYA.js");
40
+ const { startDaemon } = await import("./daemon-A54MACKQ.js");
41
41
  await startDaemon();
42
42
  await new Promise(() => {
43
43
  });
@@ -45,7 +45,7 @@ async function main(argv) {
45
45
  }
46
46
  case "--version":
47
47
  case "version": {
48
- const { LEDGE_VERSION } = await import("./version-EHBPJO7K.js");
48
+ const { LEDGE_VERSION } = await import("./version-KORN5SQT.js");
49
49
  console.log(LEDGE_VERSION);
50
50
  return 0;
51
51
  }
@@ -66,74 +66,74 @@ async function main(argv) {
66
66
  return r.ok ? 0 : 1;
67
67
  }
68
68
  case "status": {
69
- const { printStatus } = await import("./status-NONO6E2S.js");
69
+ const { printStatus } = await import("./status-6USM7SJE.js");
70
70
  console.log(await printStatus());
71
71
  return 0;
72
72
  }
73
73
  case "who": {
74
- const { printWho } = await import("./who-FHAXYCM2.js");
74
+ const { printWho } = await import("./who-RA4QBVUA.js");
75
75
  console.log(await printWho());
76
76
  return 0;
77
77
  }
78
78
  case "send": {
79
- const { sendMessage } = await import("./send-ZLF2ZXMJ.js");
79
+ const { sendMessage } = await import("./send-NYKZRELC.js");
80
80
  const r = await sendMessage(rest);
81
81
  console.log(r.line);
82
82
  return r.code;
83
83
  }
84
84
  case "read": {
85
- const { readMessage } = await import("./send-ZLF2ZXMJ.js");
85
+ const { readMessage } = await import("./send-NYKZRELC.js");
86
86
  const r = await readMessage(rest);
87
87
  console.log(r.line);
88
88
  return r.code;
89
89
  }
90
90
  case "task": {
91
- const { runTask } = await import("./task-47MVWDCY.js");
91
+ const { runTask } = await import("./task-E5J6UT7S.js");
92
92
  const r = await runTask(rest);
93
93
  console.log(r.line);
94
94
  return r.code;
95
95
  }
96
96
  case "decide": {
97
- const { runDecide } = await import("./decide-4BIYS3Y2.js");
97
+ const { runDecide } = await import("./decide-2HKZF4VI.js");
98
98
  const r = await runDecide(rest);
99
99
  console.log(r.line);
100
100
  return r.code;
101
101
  }
102
102
  case "handover": {
103
- const { runHandover } = await import("./handover-IS7BJYGZ.js");
103
+ const { runHandover } = await import("./handover-3PV3MDK3.js");
104
104
  const r = await runHandover(rest);
105
105
  console.log(r.line);
106
106
  return r.code;
107
107
  }
108
108
  case "close": {
109
- const { runClose } = await import("./action-MAPPYLUM.js");
109
+ const { runClose } = await import("./action-IL5A2O4K.js");
110
110
  const r = await runClose(rest);
111
111
  console.log(r.line);
112
112
  return r.code;
113
113
  }
114
114
  case "team": {
115
- const { runTeam } = await import("./team-EJ4YIXJH.js");
115
+ const { runTeam } = await import("./team-AP7A5VMP.js");
116
116
  const r = await runTeam(rest);
117
117
  console.log(r.line);
118
118
  return r.code;
119
119
  }
120
120
  case "tui": {
121
- const { runTui } = await import("./tui-CAP4O4YQ.js");
121
+ const { runTui } = await import("./tui-EK7VC7YP.js");
122
122
  return runTui(rest);
123
123
  }
124
124
  case "bridge": {
125
- const { bridge } = await import("./bridge-TWX4V37E.js");
125
+ const { bridge } = await import("./bridge-KEDZGBEK.js");
126
126
  await bridge();
127
127
  return 0;
128
128
  }
129
129
  case "claude":
130
130
  case "codex":
131
131
  case "cursor": {
132
- const { launch } = await import("./launch-XAPN2M3Q.js");
132
+ const { launch } = await import("./launch-NGWPGU6E.js");
133
133
  return launch(cmd, rest);
134
134
  }
135
135
  case "attach": {
136
- const { attach } = await import("./attach-OC64CLB2.js");
136
+ const { attach } = await import("./attach-XFRWCGMD.js");
137
137
  return attach(rest.find((a) => !a.startsWith("--")) ?? "", { readOnly: rest.includes("--read-only") });
138
138
  }
139
139
  default:
@@ -6,18 +6,18 @@ import {
6
6
  launch,
7
7
  parseLaunchArgs,
8
8
  roleArgs
9
- } from "./chunk-WIUJNSAZ.js";
10
- import "./chunk-TREGH6WM.js";
9
+ } from "./chunk-4JQHF3HM.js";
10
+ import "./chunk-OOPOJK6Y.js";
11
11
  import "./chunk-OLLQBK6N.js";
12
- import "./chunk-WCBXS3EU.js";
13
- import "./chunk-UWDE365N.js";
14
- import "./chunk-73YNZ3BN.js";
12
+ import "./chunk-HH6LFLPR.js";
13
+ import "./chunk-LHWJBSLO.js";
14
+ import "./chunk-GOBUJGB6.js";
15
15
  import {
16
16
  agentEnv,
17
17
  exitFile
18
- } from "./chunk-K3SDHHZF.js";
19
- import "./chunk-RFFTWAAF.js";
20
- import "./chunk-7S7ZLGIY.js";
18
+ } from "./chunk-XHC6EPZE.js";
19
+ import "./chunk-JBYVS2F4.js";
20
+ import "./chunk-U44NT4XJ.js";
21
21
  import "./chunk-NLL2EQJ2.js";
22
22
  import "./chunk-6IYPRUQG.js";
23
23
  import "./chunk-HOOHS3MX.js";
@@ -4,10 +4,10 @@ import {
4
4
  readOnClient,
5
5
  sendMessage,
6
6
  sendOnClient
7
- } from "./chunk-MZVMW356.js";
8
- import "./chunk-K3SDHHZF.js";
9
- import "./chunk-RFFTWAAF.js";
10
- import "./chunk-7S7ZLGIY.js";
7
+ } from "./chunk-RGYQFRG5.js";
8
+ import "./chunk-XHC6EPZE.js";
9
+ import "./chunk-JBYVS2F4.js";
10
+ import "./chunk-U44NT4XJ.js";
11
11
  import "./chunk-HOOHS3MX.js";
12
12
  import "./chunk-U67V476Y.js";
13
13
  export {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  connect
3
- } from "./chunk-RFFTWAAF.js";
4
- import "./chunk-7S7ZLGIY.js";
3
+ } from "./chunk-JBYVS2F4.js";
4
+ import "./chunk-U44NT4XJ.js";
5
5
  import "./chunk-HOOHS3MX.js";
6
6
  import "./chunk-U67V476Y.js";
7
7
 
@@ -4,10 +4,10 @@ import {
4
4
  runTask,
5
5
  taskArgs,
6
6
  taskOnClient
7
- } from "./chunk-ETGOWBUL.js";
8
- import "./chunk-K3SDHHZF.js";
9
- import "./chunk-RFFTWAAF.js";
10
- import "./chunk-7S7ZLGIY.js";
7
+ } from "./chunk-D2EYVNJ6.js";
8
+ import "./chunk-XHC6EPZE.js";
9
+ import "./chunk-JBYVS2F4.js";
10
+ import "./chunk-U44NT4XJ.js";
11
11
  import "./chunk-HOOHS3MX.js";
12
12
  import "./chunk-U67V476Y.js";
13
13
  export {
@@ -4,20 +4,20 @@ import {
4
4
  callerOf,
5
5
  resultLine,
6
6
  runOnClient
7
- } from "./chunk-353WRRGG.js";
7
+ } from "./chunk-KESZUXUI.js";
8
8
  import {
9
9
  listDefinitions
10
- } from "./chunk-WCBXS3EU.js";
11
- import "./chunk-73YNZ3BN.js";
12
- import "./chunk-K3SDHHZF.js";
10
+ } from "./chunk-HH6LFLPR.js";
11
+ import "./chunk-GOBUJGB6.js";
12
+ import "./chunk-XHC6EPZE.js";
13
13
  import {
14
14
  connect
15
- } from "./chunk-RFFTWAAF.js";
15
+ } from "./chunk-JBYVS2F4.js";
16
16
  import {
17
17
  RoleIdSchema,
18
18
  SeatsSchema,
19
19
  ToolSchema
20
- } from "./chunk-7S7ZLGIY.js";
20
+ } from "./chunk-U44NT4XJ.js";
21
21
  import "./chunk-6IYPRUQG.js";
22
22
  import "./chunk-HOOHS3MX.js";
23
23
  import "./chunk-U67V476Y.js";