@paradow/ledge 0.15.1 → 0.16.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.
@@ -1,27 +1,29 @@
1
1
  import {
2
2
  parseLedgeCommand,
3
3
  sendOnClient
4
- } from "./chunk-IMSPQUFC.js";
4
+ } from "./chunk-QJVODYJ5.js";
5
5
  import {
6
6
  formatWho
7
- } from "./chunk-NKYJF3VT.js";
7
+ } from "./chunk-TB47EHML.js";
8
8
  import {
9
9
  connect,
10
10
  sendMessageAndAwaitAck
11
- } from "./chunk-PXO4FFJR.js";
11
+ } from "./chunk-DEXDXDO4.js";
12
12
  import {
13
13
  QUESTION_TOOLS,
14
- bareName,
15
- gitInfo
16
- } from "./chunk-QCEVJMXI.js";
14
+ gitInfo,
15
+ messageNote,
16
+ readPeers,
17
+ resolveTarget
18
+ } from "./chunk-DBSCO3HI.js";
17
19
  import {
18
20
  CODEX_ENV_VAR,
19
21
  CODEX_HOOK_VAR,
20
22
  codexPlan
21
- } from "./chunk-KGEF6OIU.js";
23
+ } from "./chunk-H36JD4E3.js";
22
24
  import {
23
25
  MESSAGE_MAX
24
- } from "./chunk-2LQITRTR.js";
26
+ } from "./chunk-Q5WWH7FG.js";
25
27
  import {
26
28
  log
27
29
  } from "./chunk-BNKPXSUY.js";
@@ -318,7 +320,7 @@ function identityContext(s) {
318
320
  return [
319
321
  `Tu es ${s.name}, ${where} : une session lanc\xE9e par Ledge (${s.tool}). Les autres sessions Ledge te connaissent sous le nom ${s.name}.`,
320
322
  "Pour voir les autres sessions (nom, outil, \xE9tat, projet, branche, sujet), lance `ledge who`.",
321
- s.tool === "claude" ? "Pour \xE9crire \xE0 une autre session Ledge, Claude ou Codex, utilise son nom Ledge comme adresse SendMessage." : "Pour \xE9crire \xE0 une autre session Ledge, lance `ledge send <nom> \"<message>\"` (seul, sans && ni |). Ledge ex\xE9cute lui-m\xEAme `ledge send` et `ledge who` : leur r\xE9sultat t'arrive comme \xAB Command blocked by PreToolUse hook: \u2026 \xBB, c'est la r\xE9ponse, pas une erreur."
323
+ s.tool === "claude" ? "Pour \xE9crire \xE0 une autre session Ledge, Claude ou Codex, utilise son nom Ledge (donn\xE9 par `ledge who`) comme adresse SendMessage : Ledge le transmet. `ListAgents` montre les noms internes de Claude, pas les noms Ledge." : "Pour \xE9crire \xE0 une autre session Ledge, lance `ledge send <nom> \"<message>\"` (seul, sans && ni |). Ledge ex\xE9cute lui-m\xEAme `ledge send` et `ledge who` : leur r\xE9sultat t'arrive comme \xAB Command blocked by PreToolUse hook: \u2026 \xBB, c'est la r\xE9ponse, pas une erreur."
322
324
  ].join("\n");
323
325
  }
324
326
  async function identity(agent, cwd, known, deadline) {
@@ -337,18 +339,30 @@ async function identity(agent, cwd, known, deadline) {
337
339
  };
338
340
  }
339
341
  var SEND_MESSAGE_MS = 1500;
342
+ var deny = (reason) => JSON.stringify({ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: reason } });
340
343
  async function relayMessage(client, from, toolUseId, input, deadline) {
341
344
  if (!toolUseId) return void 0;
342
345
  const left = () => Math.max(0, deadline - Date.now());
343
346
  const to = input.to;
344
347
  const snapshot = await client.next("snapshot", left());
345
- const tool = snapshot.sessions.find((s) => s.name === bareName(to))?.tool;
348
+ const sender = snapshot.sessions.find((s) => s.id === from);
349
+ if (sender?.source !== "launcher") return void 0;
350
+ const r = resolveTarget(to, snapshot.sessions, readPeers());
351
+ if (r.outcome === "unknown") return void 0;
352
+ if (r.outcome === "refused") return deny(`Ledge n'a pas pu transmettre le message \xE0 ${to} : ${r.reason}`);
353
+ if (r.outcome === "native") {
354
+ const note = messageNote(sender.name, "claude");
355
+ const named = (text) => text.startsWith(note) ? text : `${note} ${text}`;
356
+ const updatedInput = { ...input, to: r.address, message: named(input.message), ...typeof input.content === "string" ? { content: named(input.content) } : {} };
357
+ return JSON.stringify({ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "allow", updatedInput } });
358
+ }
359
+ const tool = r.target.tool;
346
360
  if (tool !== "codex" && input.message.length > MESSAGE_MAX) return void 0;
347
361
  const summary = str(input.summary);
348
362
  const ack = await sendMessageAndAwaitAck(client, { type: "session.message", rid: toolUseId, from, to, text: input.message, ...summary ? { summary } : {}, intercept: true }, left());
349
- const target = tool ? `${to} (${tool})` : to;
363
+ const target = `${to} (${tool})`;
350
364
  const reason = ack.outcome === "accepted" ? `Message transmis par Ledge \xE0 ${target} : il le re\xE7oit maintenant.` : ack.outcome === "queued" ? `Message transmis par Ledge \xE0 ${target} : il le recevra d\xE8s qu'il sera libre.` : ack.outcome === "refused" ? `Ledge n'a pas pu transmettre le message \xE0 ${to} : ${ack.reason ?? "raison inconnue"}` : void 0;
351
- return reason ? JSON.stringify({ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: reason } }) : void 0;
365
+ return reason ? deny(reason) : void 0;
352
366
  }
353
367
  async function runLedgeCommand(client, cmd, from, deadline) {
354
368
  const left = () => Math.max(0, deadline - Date.now());
@@ -357,7 +371,7 @@ async function runLedgeCommand(client, cmd, from, deadline) {
357
371
  else {
358
372
  line = (await sendOnClient(client, cmd.args, from, left())).line;
359
373
  }
360
- return JSON.stringify({ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: line } });
374
+ return deny(line);
361
375
  }
362
376
  async function runHook(eventName, stdin, opts = {}) {
363
377
  const agent = opts.tool ?? "claude";
package/dist/cli/index.js CHANGED
@@ -18,7 +18,7 @@ async function hookMain(args) {
18
18
  try {
19
19
  const chunks = [];
20
20
  for await (const c of process.stdin) chunks.push(c);
21
- const { runHook } = await import("./hook-PRPEB3T7.js");
21
+ const { runHook } = await import("./hook-LY2YTK5U.js");
22
22
  const out = await runHook(event, Buffer.concat(chunks).toString("utf8"), { tool });
23
23
  if (out) process.stdout.write(`${out}
24
24
  `);
@@ -30,7 +30,7 @@ async function main(argv) {
30
30
  const [cmd, ...rest] = argv;
31
31
  switch (cmd) {
32
32
  case "daemon": {
33
- const { startDaemon } = await import("./daemon-TBYCUHC3.js");
33
+ const { startDaemon } = await import("./daemon-HWAHX4RR.js");
34
34
  await startDaemon();
35
35
  await new Promise(() => {
36
36
  });
@@ -38,50 +38,55 @@ async function main(argv) {
38
38
  }
39
39
  case "--version":
40
40
  case "version": {
41
- const { LEDGE_VERSION } = await import("./version-5BLH6OA6.js");
41
+ const { LEDGE_VERSION } = await import("./version-5DA7G7HN.js");
42
42
  console.log(LEDGE_VERSION);
43
43
  return 0;
44
44
  }
45
45
  case "setup": {
46
- const { runSetup } = await import("./setup-LWYZEVNE.js");
46
+ const { runSetup } = await import("./setup-3N2EOJXS.js");
47
47
  for (const l of await runSetup()) console.log(l);
48
48
  return 0;
49
49
  }
50
50
  case "uninstall": {
51
- const { runUninstall } = await import("./uninstall-TFC4LALT.js");
52
- const r = await runUninstall({ purge: rest.includes("--purge") });
51
+ const { runUninstall, uninstallArgs } = await import("./uninstall-W2OMKU3B.js");
52
+ const args = uninstallArgs(rest);
53
+ if (!args) {
54
+ console.log(USAGE);
55
+ return rest.every((a) => a === "--help" || a === "-h") ? 0 : 1;
56
+ }
57
+ const r = await runUninstall(args);
53
58
  for (const l of r.lines) console.log(l);
54
59
  return r.ok ? 0 : 1;
55
60
  }
56
61
  case "status": {
57
- const { printStatus } = await import("./status-Q6TQXVLF.js");
62
+ const { printStatus } = await import("./status-ZQSYXILE.js");
58
63
  console.log(await printStatus());
59
64
  return 0;
60
65
  }
61
66
  case "who": {
62
- const { printWho } = await import("./who-KAAEASAA.js");
67
+ const { printWho } = await import("./who-VGIMGQNS.js");
63
68
  console.log(await printWho());
64
69
  return 0;
65
70
  }
66
71
  case "send": {
67
- const { sendMessage } = await import("./send-JX6O7AQR.js");
72
+ const { sendMessage } = await import("./send-EY63XQXI.js");
68
73
  const r = await sendMessage(rest);
69
74
  console.log(r.line);
70
75
  return r.code;
71
76
  }
72
77
  case "bridge": {
73
- const { bridge } = await import("./bridge-6K523KUX.js");
78
+ const { bridge } = await import("./bridge-LXMOQN6Q.js");
74
79
  await bridge();
75
80
  return 0;
76
81
  }
77
82
  case "claude":
78
83
  case "codex":
79
84
  case "cursor": {
80
- const { launch } = await import("./launch-JS74JGW6.js");
85
+ const { launch } = await import("./launch-UQEFFPBN.js");
81
86
  return launch(cmd, rest);
82
87
  }
83
88
  case "attach": {
84
- const { attach } = await import("./attach-Y4OMZXAH.js");
89
+ const { attach } = await import("./attach-5H727FCW.js");
85
90
  return attach(rest.find((a) => !a.startsWith("--")) ?? "", { readOnly: rest.includes("--read-only") });
86
91
  }
87
92
  default:
@@ -5,13 +5,13 @@ import {
5
5
  ensureDaemon,
6
6
  launch,
7
7
  parseLaunchArgs
8
- } from "./chunk-4IBQ4PG6.js";
9
- import "./chunk-PXO4FFJR.js";
8
+ } from "./chunk-MQICEVKR.js";
9
+ import "./chunk-DEXDXDO4.js";
10
10
  import {
11
11
  agentEnv,
12
12
  exitFile
13
- } from "./chunk-KGEF6OIU.js";
14
- import "./chunk-2LQITRTR.js";
13
+ } from "./chunk-H36JD4E3.js";
14
+ import "./chunk-Q5WWH7FG.js";
15
15
  import "./chunk-2H5FJH4Q.js";
16
16
  import "./chunk-BNKPXSUY.js";
17
17
  import "./chunk-R5462SQM.js";
@@ -2,10 +2,10 @@ import {
2
2
  parseLedgeCommand,
3
3
  sendMessage,
4
4
  sendOnClient
5
- } from "./chunk-IMSPQUFC.js";
6
- import "./chunk-PXO4FFJR.js";
7
- import "./chunk-KGEF6OIU.js";
8
- import "./chunk-2LQITRTR.js";
5
+ } from "./chunk-QJVODYJ5.js";
6
+ import "./chunk-DEXDXDO4.js";
7
+ import "./chunk-H36JD4E3.js";
8
+ import "./chunk-Q5WWH7FG.js";
9
9
  import "./chunk-R5462SQM.js";
10
10
  export {
11
11
  parseLedgeCommand,
@@ -14,7 +14,7 @@ import {
14
14
  stopDetachedDaemon,
15
15
  systemdUnit,
16
16
  writeBin
17
- } from "./chunk-ZANOMSLW.js";
17
+ } from "./chunk-S4ANPQGA.js";
18
18
  import "./chunk-2H5FJH4Q.js";
19
19
  import "./chunk-BNKPXSUY.js";
20
20
  import "./chunk-R5462SQM.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  connect
3
- } from "./chunk-PXO4FFJR.js";
4
- import "./chunk-2LQITRTR.js";
3
+ } from "./chunk-DEXDXDO4.js";
4
+ import "./chunk-Q5WWH7FG.js";
5
5
  import "./chunk-R5462SQM.js";
6
6
 
7
7
  // src/cli/status.ts
@@ -3,7 +3,7 @@ import {
3
3
  SERVICE,
4
4
  execRunner,
5
5
  stopDetachedDaemon
6
- } from "./chunk-ZANOMSLW.js";
6
+ } from "./chunk-S4ANPQGA.js";
7
7
  import "./chunk-2H5FJH4Q.js";
8
8
  import "./chunk-BNKPXSUY.js";
9
9
  import {
@@ -105,6 +105,9 @@ async function removeLink(link, script) {
105
105
  await rm(link, { force: true });
106
106
  return true;
107
107
  }
108
+ function uninstallArgs(args) {
109
+ return args.every((a) => a === "--purge") && args.length <= 1 ? { purge: args.length === 1 } : null;
110
+ }
108
111
  async function runUninstall(opts = {}) {
109
112
  const lines = [];
110
113
  let ok = true;
@@ -153,5 +156,6 @@ export {
153
156
  removeClaudeHooks,
154
157
  removeCursorHooks,
155
158
  removeService,
156
- runUninstall
159
+ runUninstall,
160
+ uninstallArgs
157
161
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  LEDGE_VERSION
3
- } from "./chunk-LKQ5DDQ4.js";
3
+ } from "./chunk-CBKKOJIG.js";
4
4
  export {
5
5
  LEDGE_VERSION
6
6
  };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  formatWho,
3
3
  printWho
4
- } from "./chunk-NKYJF3VT.js";
5
- import "./chunk-PXO4FFJR.js";
6
- import "./chunk-2LQITRTR.js";
4
+ } from "./chunk-TB47EHML.js";
5
+ import "./chunk-DEXDXDO4.js";
6
+ import "./chunk-Q5WWH7FG.js";
7
7
  import "./chunk-R5462SQM.js";
8
8
  export {
9
9
  formatWho,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paradow/ledge",
3
- "version": "0.15.1",
3
+ "version": "0.16.0",
4
4
  "description": "Follow and answer your WSL agent sessions (Claude Code, Codex, Cursor Agent) from the Ledge island on Windows.",
5
5
  "type": "module",
6
6
  "bin": { "ledge": "dist/cli/index.js" },
@@ -1,6 +0,0 @@
1
- // src/version.ts
2
- var LEDGE_VERSION = true ? "0.15.1" : "0.0.0-dev";
3
-
4
- export {
5
- LEDGE_VERSION
6
- };