@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
@@ -1,12 +1,12 @@
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
  BRIEF_MAX
9
- } from "./chunk-WXE2NOE5.js";
9
+ } from "./chunk-IWY7DSSO.js";
10
10
 
11
11
  // src/cli/handover.ts
12
12
  import { randomUUID } from "crypto";
@@ -0,0 +1,6 @@
1
+ // src/version.ts
2
+ var LEDGE_VERSION = true ? "0.34.0" : "0.0.0-dev";
3
+
4
+ export {
5
+ LEDGE_VERSION
6
+ };
@@ -1,27 +1,25 @@
1
1
  import {
2
2
  connect
3
- } from "./chunk-ASYAWVFW.js";
3
+ } from "./chunk-7NHQGP6J.js";
4
4
  import {
5
5
  isArchived
6
- } from "./chunk-WXE2NOE5.js";
6
+ } from "./chunk-IWY7DSSO.js";
7
7
 
8
8
  // src/cli/who.ts
9
9
  import { basename } from "path";
10
10
  function formatWho(sessions, self) {
11
11
  const live = sessions.filter((s) => s.state !== "exited" && !isArchived(s));
12
12
  if (live.length === 0) return "aucune autre session";
13
- const roles = live.some((s) => s.role);
14
13
  const rows = live.map((s) => [
15
14
  s.id === self ? "*" : " ",
16
15
  s.name,
17
- ...roles ? [s.role ? `@${s.role}` : "-"] : [],
18
16
  s.tool,
19
17
  s.state,
20
18
  `${s.repo ?? s.project}${s.worktree ? ` (${basename(s.cwd)})` : ""}`,
21
19
  s.branch ?? "-",
22
20
  `${s.topic ?? "-"}${s.source === "hook_only" ? " \xB7 lecture seule" : ""}`
23
21
  ]);
24
- const head = [" ", "NOM", ...roles ? ["R\xD4LE"] : [], "OUTIL", "\xC9TAT", "PROJET", "BRANCHE", "SUJET"];
22
+ const head = [" ", "NOM", "OUTIL", "\xC9TAT", "PROJET", "BRANCHE", "SUJET"];
25
23
  const widths = head.map((h, i) => Math.max(h.length, ...rows.map((r) => r[i].length)));
26
24
  return [head, ...rows].map((r) => r.map((c, i) => i === r.length - 1 ? c : c.padEnd(widths[i])).join(" ")).join("\n");
27
25
  }
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  log
3
- } from "./chunk-6IYPRUQG.js";
3
+ } from "./chunk-54KF5RBY.js";
4
4
  import {
5
5
  paths
6
- } from "./chunk-HOOHS3MX.js";
6
+ } from "./chunk-53ISXX2R.js";
7
7
 
8
8
  // src/tmux.ts
9
9
  import { execFile } from "child_process";
@@ -27,7 +27,7 @@ function newSessionCommand(tmuxArgs, scoped, unit) {
27
27
  }
28
28
  function realTmux(socket = "ledge", opts = {}) {
29
29
  const scope = opts.scope ?? (async () => systemdAvailable());
30
- const base = () => ["-L", socket, "-f", paths().tmuxConf];
30
+ const base = () => socket === null ? [] : ["-L", socket, "-f", paths().tmuxConf];
31
31
  const t = (args, env) => run([...base(), ...args], env);
32
32
  return {
33
33
  async newSession({ name, cwd, env, unset = [], command }) {
@@ -68,6 +68,11 @@ function realTmux(socket = "ledge", opts = {}) {
68
68
  async hasSession(name) {
69
69
  return (await t(["has-session", "-t", `=${name}`])).code === 0;
70
70
  },
71
+ async paneCwd(name) {
72
+ const r = await t(["display-message", "-p", "-t", `=${name}:`, "#{pane_current_path}"]);
73
+ const p = r.stdout.trim();
74
+ return r.code === 0 && p.startsWith("/") ? p : null;
75
+ },
71
76
  async listSessions() {
72
77
  const r = await t(["list-sessions", "-F", "#{session_name}"]);
73
78
  if (r.code === 0) return r.stdout.split("\n").map((s) => s.trim()).filter(Boolean);
@@ -86,9 +91,38 @@ function realTmux(socket = "ledge", opts = {}) {
86
91
  }
87
92
  };
88
93
  }
94
+ var isSeatSession = (name) => name.includes("@");
95
+ function routedTmux(own, seats) {
96
+ const of = (name) => isSeatSession(name) ? seats : own;
97
+ return {
98
+ newSession: (o) => own.newSession(o),
99
+ sendText: (n, text) => of(n).sendText(n, text),
100
+ sendKeys: (n, keys) => of(n).sendKeys(n, keys),
101
+ capture: (n, lines) => of(n).capture(n, lines),
102
+ width: async (n) => {
103
+ const t = of(n);
104
+ return t.width ? t.width(n) : null;
105
+ },
106
+ paneCwd: async (n) => {
107
+ const t = of(n);
108
+ return t.paneCwd ? t.paneCwd(n) : null;
109
+ },
110
+ hasSession: (n) => of(n).hasSession(n),
111
+ async listSessions() {
112
+ const mine = await own.listSessions();
113
+ const theirs = await seats.listSessions().catch(() => []);
114
+ return [...mine, ...theirs.filter(isSeatSession)];
115
+ },
116
+ killSession: (n) => of(n).killSession(n),
117
+ setOption: (n, option, value) => of(n).setOption(n, option, value),
118
+ attachArgs: (n, opts) => of(n).attachArgs(n, opts)
119
+ };
120
+ }
89
121
 
90
122
  export {
91
123
  runFile,
92
124
  run,
93
- realTmux
125
+ realTmux,
126
+ isSeatSession,
127
+ routedTmux
94
128
  };
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  run
3
- } from "./chunk-NLL2EQJ2.js";
3
+ } from "./chunk-T547FLQN.js";
4
4
  import {
5
5
  ensureLedgeDir,
6
6
  paths
7
- } from "./chunk-HOOHS3MX.js";
7
+ } from "./chunk-53ISXX2R.js";
8
8
 
9
9
  // src/cli/setup.ts
10
10
  import { readFile as readFile2, writeFile, mkdir, rename, realpath, rm, stat, lstat, readlink } from "fs/promises";
@@ -1,13 +1,13 @@
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
  SESSION_KEY_VAR,
9
9
  actionById
10
- } from "./chunk-WXE2NOE5.js";
10
+ } from "./chunk-IWY7DSSO.js";
11
11
 
12
12
  // src/cli/action.ts
13
13
  import { randomUUID } from "crypto";
@@ -37,7 +37,7 @@ var plain = (s) => s.replace(/\*\*/g, "");
37
37
  function resultLine(r, json = false) {
38
38
  const ok = r.reason === void 0;
39
39
  if (json) return { line: JSON.stringify({ ok, ...r }), code: ok ? 0 : 1 };
40
- if (ok) return { line: [`fait : ${plain(r.row?.summary ?? r.action)}`, ...r.path ? [`mod\xE8le \xE9crit : ${r.path}`] : []].join("\n"), code: 0 };
40
+ if (ok) return { line: `fait : ${plain(r.row?.summary ?? r.action)}`, code: 0 };
41
41
  if (r.code === "confirm_required") return { line: `${plain(r.row?.summary ?? r.action)} : irr\xE9versible ; relance avec --yes pour confirmer`, code: 1 };
42
42
  return { line: `${r.code === "failed" ? "\xE9chec" : "refus\xE9"} : ${r.reason}`, code: 1 };
43
43
  }
@@ -1,31 +1,24 @@
1
- import {
2
- EFFORT_ARGS,
3
- MODEL_ARGS
4
- } from "./chunk-PZ3F4QH3.js";
5
- import {
6
- findRole
7
- } from "./chunk-4VNKZOC2.js";
8
1
  import {
9
2
  exitFile,
10
3
  spawnSession
11
- } from "./chunk-JEGPTNWV.js";
4
+ } from "./chunk-4TCSADFR.js";
12
5
  import {
13
6
  DaemonRefusedError,
14
7
  connect
15
- } from "./chunk-ASYAWVFW.js";
8
+ } from "./chunk-7NHQGP6J.js";
16
9
  import {
17
10
  PROTOCOL_PORT,
18
- autonomyArgs
19
- } from "./chunk-WXE2NOE5.js";
11
+ namesInUse
12
+ } from "./chunk-IWY7DSSO.js";
20
13
  import {
21
14
  realTmux
22
- } from "./chunk-NLL2EQJ2.js";
15
+ } from "./chunk-T547FLQN.js";
23
16
  import {
24
17
  log
25
- } from "./chunk-6IYPRUQG.js";
18
+ } from "./chunk-54KF5RBY.js";
26
19
  import {
27
20
  ensureLedgeDir
28
- } from "./chunk-HOOHS3MX.js";
21
+ } from "./chunk-53ISXX2R.js";
29
22
 
30
23
  // src/cli/launch.ts
31
24
  import { spawn } from "child_process";
@@ -36,30 +29,19 @@ var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
36
29
  function parseLaunchArgs(argv) {
37
30
  const args = [];
38
31
  let name;
39
- let role;
40
32
  for (let i = 0; i < argv.length; i++) {
41
33
  const a = argv[i];
42
34
  if (a === "--name") {
43
35
  name = argv[++i];
44
36
  continue;
45
37
  }
46
- if (a === "--role") {
47
- role = argv[++i];
48
- continue;
49
- }
50
38
  if (a === "--") {
51
39
  args.push(...argv.slice(i + 1));
52
40
  break;
53
41
  }
54
42
  args.push(a);
55
43
  }
56
- return { name, ...role ? { role } : {}, args };
57
- }
58
- function roleArgs(tool, role, args) {
59
- const own = role.tool === void 0 || role.tool === tool;
60
- const hasModel = args.some((a) => a === "--model" || a === "-m" || a.startsWith("--model="));
61
- const hasEffort = args.some((a) => a === "--effort" || a.startsWith("--effort=") || a.includes("model_reasoning_effort"));
62
- return [...own && role.model && !hasModel ? MODEL_ARGS[tool](role.model) : [], ...own && role.effort && !hasEffort ? EFFORT_ARGS[tool]?.(role.effort) ?? [] : [], ...autonomyArgs(tool, role.autonomy)];
44
+ return { name, args };
63
45
  }
64
46
  function portOpen(port) {
65
47
  return new Promise((res) => {
@@ -132,13 +114,10 @@ async function createSession(opts) {
132
114
  } catch (e) {
133
115
  throw new DaemonError(`daemon did not answer: ${e.message}`);
134
116
  }
135
- for (const s of snap.sessions) {
136
- names.push(s.name);
137
- ids.push(s.id);
138
- }
117
+ names.push(...namesInUse(snap.sessions));
118
+ for (const s of snap.sessions) ids.push(s.id);
139
119
  }
140
- const { role, ...rest } = opts;
141
- const session = await spawnSession({ ...rest, ...role ? { args: [...roleArgs(opts.tool, role, opts.args), ...opts.args], role: { id: role.id, label: role.label }, ...role.autonomy ? { autonomy: role.autonomy } : {} } : {}, taken: { names, ids } });
120
+ const session = await spawnSession({ ...opts, taken: { names, ids } });
142
121
  try {
143
122
  opts.client?.send({ type: "session.register", session });
144
123
  } catch (e) {
@@ -176,20 +155,15 @@ var UNTRACKED = {
176
155
  };
177
156
  async function launch(tool, argv, opts = {}) {
178
157
  await ensureLedgeDir();
179
- const { name, role: roleId, args } = parseLaunchArgs(argv);
158
+ const { name, args } = parseLaunchArgs(argv);
180
159
  const port = opts.port ?? PROTOCOL_PORT;
181
160
  const socket = opts.tmuxSocket ?? TMUX_SOCKET;
182
161
  const tmux = realTmux(socket);
183
162
  const cwd = opts.cwd ?? process.cwd();
184
- const role = roleId ? findRole(roleId, cwd) : void 0;
185
- if (roleId && !role) {
186
- console.error(`ledge: r\xF4le inconnu : ${roleId} (aucun fichier .ledge/roles/${roleId}.md ni ~/.ledge/roles/${roleId}.md)`);
187
- return 1;
188
- }
189
163
  const daemon = await ensureDaemon({ port, spawnDaemon: opts.spawnDaemon, retryDelayMs: opts.retryDelayMs });
190
164
  let client = daemon.client;
191
165
  if (!daemon.client) console.error(UNTRACKED[daemon.reason](port));
192
- const create = (c) => createSession({ tool, args, command: opts.command, recordExit: true, name, ...role ? { role } : {}, cwd, tmux, client: c });
166
+ const create = (c) => createSession({ tool, args, command: opts.command, recordExit: true, name, cwd, tmux, client: c });
193
167
  let session;
194
168
  try {
195
169
  session = await create(client);
@@ -223,7 +197,6 @@ async function launch(tool, argv, opts = {}) {
223
197
 
224
198
  export {
225
199
  parseLaunchArgs,
226
- roleArgs,
227
200
  ensureDaemon,
228
201
  DaemonError,
229
202
  createSession,