@paradow/ledge 0.22.0 → 0.23.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.
@@ -0,0 +1,6 @@
1
+ // src/version.ts
2
+ var LEDGE_VERSION = true ? "0.23.0" : "0.0.0-dev";
3
+
4
+ export {
5
+ LEDGE_VERSION
6
+ };
@@ -47,7 +47,7 @@ import {
47
47
  } from "./chunk-ARB4BKZJ.js";
48
48
  import {
49
49
  LEDGE_VERSION
50
- } from "./chunk-4DEVJE4H.js";
50
+ } from "./chunk-XSYWXHOK.js";
51
51
  import {
52
52
  SERVICE,
53
53
  inDaemonService,
package/dist/cli/index.js CHANGED
@@ -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-7IGQIDWB.js");
40
+ const { startDaemon } = await import("./daemon-WTMGEJOI.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-EHETEZAK.js");
48
+ const { LEDGE_VERSION } = await import("./version-6FTNFHX2.js");
49
49
  console.log(LEDGE_VERSION);
50
50
  return 0;
51
51
  }
@@ -118,7 +118,7 @@ async function main(argv) {
118
118
  return r.code;
119
119
  }
120
120
  case "tui": {
121
- const { runTui } = await import("./tui-ZJDNIBIB.js");
121
+ const { runTui } = await import("./tui-YK6TXFYX.js");
122
122
  return runTui(rest);
123
123
  }
124
124
  case "bridge": {
@@ -1511,7 +1511,7 @@ function getImage(client, attachment, route = {}, preview = false, timeoutMs = T
1511
1511
 
1512
1512
  // src/tui/App.tsx
1513
1513
  import { useCallback, useEffect as useEffect12, useMemo as useMemo8, useRef as useRef13, useState as useState14 } from "react";
1514
- import { useApp, useInput as useInput7, useStdout, useWindowSize as useWindowSize9 } from "ink";
1514
+ import { useApp, useInput as useInput7, useStdout, useWindowSize as useWindowSize2 } from "ink";
1515
1515
 
1516
1516
  // src/tui/actions.ts
1517
1517
  import { useEffect as useEffect3, useMemo, useRef as useRef2 } from "react";
@@ -1871,6 +1871,7 @@ async function openImage(file, env = process.env, spawnImpl = spawn2, platform =
1871
1871
 
1872
1872
  // src/tui/context.tsx
1873
1873
  import { createContext, useContext, useEffect as useEffect4, useRef as useRef3 } from "react";
1874
+ import { useWindowSize } from "ink";
1874
1875
  var SCREENS = ["overview", "session", "ask", "launch", "settings", "teams"];
1875
1876
  var TuiContext = createContext(null);
1876
1877
  var useTui = () => {
@@ -1878,6 +1879,10 @@ var useTui = () => {
1878
1879
  if (!tui) throw new Error("useTui outside the TUI");
1879
1880
  return tui;
1880
1881
  };
1882
+ function screenSize({ columns, rows }, env) {
1883
+ return { columns: env.WT_SESSION ? Math.max(1, columns - 1) : columns, rows };
1884
+ }
1885
+ var useScreenSize = () => screenSize(useWindowSize(), useTui().env);
1881
1886
  function useScreenKeys(handler) {
1882
1887
  const { keys } = useTui();
1883
1888
  const latest = useRef3(handler);
@@ -2448,7 +2453,7 @@ var fr3 = {
2448
2453
  loading: "chargement\u2026",
2449
2454
  drawn: "(tir\xE9 au sort \xB7 ctrl+r pour un autre)",
2450
2455
  folderHint: "chemin sur la machine (~ accept\xE9)",
2451
- joins: (name, table) => `${name} rejoindra ${table}`,
2456
+ joins: (name, table2) => `${name} rejoindra ${table2}`,
2452
2457
  launch: "Lancer",
2453
2458
  cancel: "Annuler",
2454
2459
  thenAttach: "puis a pour s\u2019attacher \xE0 son terminal",
@@ -2840,7 +2845,7 @@ var en3 = {
2840
2845
  loading: "loading\u2026",
2841
2846
  drawn: "(drawn at random \xB7 ctrl+r for another)",
2842
2847
  folderHint: "path on the machine (~ allowed)",
2843
- joins: (name, table) => `${name} will join ${table}`,
2848
+ joins: (name, table2) => `${name} will join ${table2}`,
2844
2849
  launch: "Launch",
2845
2850
  cancel: "Cancel",
2846
2851
  thenAttach: "then a to attach to its terminal",
@@ -3122,7 +3127,7 @@ var title = (text5) => `\x1B]0;${text5.replace(/[\u0000-\u001f\u007f]/g, " ")}\x
3122
3127
 
3123
3128
  // src/tui/screens/Overview.tsx
3124
3129
  import { useMemo as useMemo2 } from "react";
3125
- import { Box as Box6, Text as Text6, useWindowSize as useWindowSize2 } from "ink";
3130
+ import { Box as Box6, Text as Text6 } from "ink";
3126
3131
  import { randomUUID } from "crypto";
3127
3132
  import { useState as useState3 } from "react";
3128
3133
 
@@ -3249,7 +3254,7 @@ function setTone(next2) {
3249
3254
  var projectColor = (color2) => color2 ? PROJECT_COLORS[color2] : C.dim;
3250
3255
 
3251
3256
  // src/tui/ui/Frame.tsx
3252
- import { Box as Box2, Text as Text2, useWindowSize } from "ink";
3257
+ import { Box as Box2, Text as Text2 } from "ink";
3253
3258
 
3254
3259
  // src/tui/model/cells.ts
3255
3260
  import stringWidth from "string-width";
@@ -3357,7 +3362,7 @@ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
3357
3362
  var MIN = { columns: 60, rows: 16 };
3358
3363
  function Frame({ crumb, crumbShort, keys, kept, children }) {
3359
3364
  const { d, machines, t, g, lastToast, editing } = useTui();
3360
- const { rows, columns } = useWindowSize();
3365
+ const { rows, columns } = useScreenSize();
3361
3366
  const live = listed(d.sessions);
3362
3367
  const pending = live.filter(isPending);
3363
3368
  const waiting = pending.length;
@@ -3570,7 +3575,7 @@ function windowed(rows, selectedKey, height) {
3570
3575
  function Overview() {
3571
3576
  const tui = useTui();
3572
3577
  const { d, projects, t, g, selected, select, actions, go, attach } = tui;
3573
- const { columns, rows: height } = useWindowSize2();
3578
+ const { columns, rows: height } = useScreenSize();
3574
3579
  const wide = columns >= WIDE;
3575
3580
  const left2 = wide ? Math.min(64, Math.max(44, Math.floor(columns * 0.42))) : columns;
3576
3581
  const teams = useTeams(tui.client);
@@ -3854,7 +3859,7 @@ function SessionRow({ s, on, nameW, topicW, stateW, indent: indent2 = 0 }) {
3854
3859
 
3855
3860
  // src/tui/screens/Session.tsx
3856
3861
  import { useEffect as useEffect7, useMemo as useMemo3, useState as useState7 } from "react";
3857
- import { Box as Box10, Text as Text10, useInput as useInput3, useWindowSize as useWindowSize4 } from "ink";
3862
+ import { Box as Box10, Text as Text10, useInput as useInput3 } from "ink";
3858
3863
 
3859
3864
  // src/tui/images.tsx
3860
3865
  import { mkdir, writeFile } from "fs/promises";
@@ -3975,6 +3980,7 @@ function useOpenImage() {
3975
3980
  }
3976
3981
 
3977
3982
  // ../ui/src/thread/turns.ts
3983
+ var OPEN_TURNS = 3;
3978
3984
  var byTime = (a, b2) => a.at < b2.at ? -1 : a.at > b2.at ? 1 : 0;
3979
3985
  function withoutEcho(items, reply) {
3980
3986
  if (!reply) return items;
@@ -4695,7 +4701,7 @@ function peekDelete() {
4695
4701
  function defaultStringLength(value) {
4696
4702
  return value.length;
4697
4703
  }
4698
- function markdownTable(table, options) {
4704
+ function markdownTable(table2, options) {
4699
4705
  const settings = options || {};
4700
4706
  const align = (settings.align || []).concat();
4701
4707
  const stringLength = settings.stringLength || defaultStringLength;
@@ -4705,15 +4711,15 @@ function markdownTable(table, options) {
4705
4711
  const longestCellByColumn = [];
4706
4712
  let mostCellsPerRow = 0;
4707
4713
  let rowIndex = -1;
4708
- while (++rowIndex < table.length) {
4714
+ while (++rowIndex < table2.length) {
4709
4715
  const row3 = [];
4710
4716
  const sizes2 = [];
4711
4717
  let columnIndex2 = -1;
4712
- if (table[rowIndex].length > mostCellsPerRow) {
4713
- mostCellsPerRow = table[rowIndex].length;
4718
+ if (table2[rowIndex].length > mostCellsPerRow) {
4719
+ mostCellsPerRow = table2[rowIndex].length;
4714
4720
  }
4715
- while (++columnIndex2 < table[rowIndex].length) {
4716
- const cell = serialize(table[rowIndex][columnIndex2]);
4721
+ while (++columnIndex2 < table2[rowIndex].length) {
4722
+ const cell = serialize(table2[rowIndex][columnIndex2]);
4717
4723
  if (settings.alignDelimiters !== false) {
4718
4724
  const size = stringLength(cell);
4719
4725
  sizes2[columnIndex2] = size;
@@ -12491,15 +12497,15 @@ function flushCell(map3, context, range, rowKind, rowEnd, previousCell) {
12491
12497
  }
12492
12498
  return previousCell;
12493
12499
  }
12494
- function flushTableEnd(map3, context, index2, table, tableBody) {
12500
+ function flushTableEnd(map3, context, index2, table2, tableBody) {
12495
12501
  const exits = [];
12496
12502
  const related = getPoint(context.events, index2);
12497
12503
  if (tableBody) {
12498
12504
  tableBody.end = Object.assign({}, related);
12499
12505
  exits.push(["exit", tableBody, context]);
12500
12506
  }
12501
- table.end = Object.assign({}, related);
12502
- exits.push(["exit", table, context]);
12507
+ table2.end = Object.assign({}, related);
12508
+ exits.push(["exit", table2, context]);
12503
12509
  map3.add(index2 + 1, 0, exits);
12504
12510
  }
12505
12511
  function getPoint(events, index2) {
@@ -15858,13 +15864,35 @@ function block(n, width, ctx) {
15858
15864
  const start = list3.start ?? 1;
15859
15865
  return listItems(list3, width, ctx, start, String(start + n.children.length - 1).length);
15860
15866
  }
15861
- // Out of the subset: a table stays as it was written, cut, not wrapped; HTML and footnotes as they were written.
15862
15867
  case "table":
15863
- return source(n, ctx).split("\n").map((l) => cut([{ ...ctx.base, text: l, italic: false }], width));
15868
+ return table(n, width, ctx);
15869
+ // Out of the subset: HTML and footnotes as they were written.
15864
15870
  default:
15865
15871
  return wrapSegs([{ ...ctx.base, text: source(n, ctx) }], width);
15866
15872
  }
15867
15873
  }
15874
+ function table(n, width, ctx) {
15875
+ const { g } = ctx;
15876
+ const align = n.align ?? [];
15877
+ const rows = n.children.map((r, i) => r.children.map((c) => inline(c.children, i ? ctx.base : { ...ctx.base, bold: true }, ctx)));
15878
+ const cols = Math.max(1, ...rows.map((r) => r.length));
15879
+ const room = width - 3 * (cols - 1);
15880
+ if (room < 4 * cols) return source(n, ctx).split("\n").map((l) => cut([{ ...ctx.base, text: l, italic: false }], width));
15881
+ const w = Array.from({ length: cols }, (_, j) => Math.max(1, ...rows.map((r) => lineCells(r[j] ?? []))));
15882
+ for (let over = w.reduce((a, b2) => a + b2, 0) - room; over > 0; over--) w[w.indexOf(Math.max(...w))]--;
15883
+ const sep = { text: ` ${g.bar} `, color: C.faint };
15884
+ const rule = [{ text: w.map((x) => g.rule.repeat(x)).join(`${g.rule}${g.cross}${g.rule}`), color: C.faint }];
15885
+ const drawn = rows.map((r) => {
15886
+ const cells2 = w.map((x, j) => wrapSegs(r[j] ?? [], x));
15887
+ return Array.from({ length: Math.max(...cells2.map((c) => c.length)) }, (_, k) => cells2.flatMap((c, j) => {
15888
+ const l = c[k] ?? [], free = Math.max(0, w[j] - lineCells(l)), last = j === cols - 1;
15889
+ const left2 = align[j] === "right" ? free : align[j] === "center" ? Math.floor(free / 2) : 0;
15890
+ return [...j ? [sep] : [], ...left2 ? [pad(left2)] : [], ...l, ...last ? [] : [pad(free - left2)]];
15891
+ }));
15892
+ });
15893
+ const wrapped = drawn.slice(1).some((r) => r.length > 1);
15894
+ return drawn.flatMap((r, i) => i === 0 ? [...r, rule] : i > 1 && wrapped ? [rule, ...r] : r);
15895
+ }
15868
15896
  function listItems(list3, width, ctx, start, wide) {
15869
15897
  const { g } = ctx, out = [];
15870
15898
  list3.children.forEach((item, i) => {
@@ -16001,10 +16029,10 @@ function threadView(items, o) {
16001
16029
  }
16002
16030
  };
16003
16031
  all2.forEach((turn, i) => {
16004
- const last = i === all2.length - 1;
16032
+ const recent = i >= all2.length - OPEN_TURNS;
16005
16033
  const first = turn.prompt?.id ?? turn.items[0]?.id ?? String(i);
16006
16034
  for (const it of turn.items) turnOf.set(it.id, first);
16007
- if (!last && !o.unfolded) {
16035
+ if (!recent && !o.unfolded) {
16008
16036
  push2(first, [cut(foldedLine(turn, o), o.width)]);
16009
16037
  return;
16010
16038
  }
@@ -16021,7 +16049,7 @@ function anchorLine(v, anchor) {
16021
16049
  }
16022
16050
  function threadImages(items, unfolded) {
16023
16051
  const all2 = turns(items);
16024
- return (unfolded ? all2 : all2.slice(-1)).flatMap((turn) => turn.items.flatMap((it) => it.kind === "prompt" ? it.images ?? [] : []));
16052
+ return (unfolded ? all2 : all2.slice(-OPEN_TURNS)).flatMap((turn) => turn.items.flatMap((it) => it.kind === "prompt" ? it.images ?? [] : []));
16025
16053
  }
16026
16054
 
16027
16055
  // src/tui/ui/ModelPicker.tsx
@@ -16133,7 +16161,7 @@ function Lines({ lines, up = 0, onHeight }) {
16133
16161
 
16134
16162
  // src/tui/ui/Field.tsx
16135
16163
  import { useReducer, useRef as useRef8 } from "react";
16136
- import { Box as Box9, usePaste as usePaste2, useInput as useInput2, useWindowSize as useWindowSize3 } from "ink";
16164
+ import { Box as Box9, usePaste as usePaste2, useInput as useInput2 } from "ink";
16137
16165
 
16138
16166
  // src/tui/model/field.ts
16139
16167
  var graphemes2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
@@ -16252,7 +16280,7 @@ var fieldRows = (columns, rows) => rows < 24 ? 3 : columns >= 120 && rows >= 32
16252
16280
  var inHistory = (b2) => b2 !== null && b2.i < b2.items.length - 1;
16253
16281
  function Field({ value, onChange, onSubmit, onEscape, onBrowse, history = [], active, placeholder, title: title2, color: color2 = C.coral, titleColor }) {
16254
16282
  const { t, g } = useTui();
16255
- const { columns, rows: height } = useWindowSize3();
16283
+ const { columns, rows: height } = useScreenSize();
16256
16284
  const st = useRef8({ f: { text: value, cursor: value.length }, browse: null, pasted: 0 });
16257
16285
  const told = useRef8(value);
16258
16286
  if (value !== told.current) {
@@ -16395,7 +16423,7 @@ function SessionScreen() {
16395
16423
  }
16396
16424
  function SessionView({ s }) {
16397
16425
  const { client, d, t, g, actions, attach, toast, machines, kept, lastToast, tone: tone2 } = useTui();
16398
- const { columns, rows } = useWindowSize4();
16426
+ const { columns, rows } = useScreenSize();
16399
16427
  const [mode, setMode] = useState7("read");
16400
16428
  const [draft, setDraftState] = useState7(() => kept.drafts.get(s.id) ?? "");
16401
16429
  const setDraft = (x) => {
@@ -16646,7 +16674,7 @@ function PendingBox({ s, a }) {
16646
16674
  // src/tui/screens/Ask.tsx
16647
16675
  import { randomUUID as randomUUID2 } from "crypto";
16648
16676
  import { useEffect as useEffect9, useMemo as useMemo4, useRef as useRef10, useState as useState9 } from "react";
16649
- import { Box as Box12, Text as Text12, useInput as useInput4, useWindowSize as useWindowSize6 } from "ink";
16677
+ import { Box as Box12, Text as Text12, useInput as useInput4 } from "ink";
16650
16678
 
16651
16679
  // ../ui/src/chat/actionRow.ts
16652
16680
  var CODES = new Set(ACTION_ERROR_CODES);
@@ -16823,13 +16851,13 @@ function useThrottled(value, ms) {
16823
16851
  }
16824
16852
 
16825
16853
  // src/tui/ui/ActionBox.tsx
16826
- import { Box as Box11, Text as Text11, useWindowSize as useWindowSize5 } from "ink";
16854
+ import { Box as Box11, Text as Text11 } from "ink";
16827
16855
  import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
16828
16856
  var deniable = (r, s) => r.action === "session.decide" && r.decision === "accept" && (s === "proposed" || s === "held" || s === "cut");
16829
16857
  var appliable = (s) => s === "proposed" || s === "held" || s === "failed";
16830
16858
  function ActionBox({ turn, focused, busy, sel, confirming, plan }) {
16831
16859
  const { t, g } = useTui();
16832
- const { columns } = useWindowSize5();
16860
+ const { columns } = useScreenSize();
16833
16861
  const a = t.ask.action, c = a.copy;
16834
16862
  const p = plan ?? cardPlan(turn.actions ?? []);
16835
16863
  const many = p.rows.length > 1;
@@ -16972,7 +17000,7 @@ var CARD_MS = 2e4;
16972
17000
  var CONVO = -2;
16973
17001
  function Ask() {
16974
17002
  const { client, d, machines, t, g, toast, go, kept, small, tone: tone2, select } = useTui();
16975
- const { columns, rows: height } = useWindowSize6();
17003
+ const { columns, rows: height } = useScreenSize();
16976
17004
  const [draft, setDraftState] = useState9(() => kept.drafts.get("ask") ?? "");
16977
17005
  const setDraft = (x) => {
16978
17006
  setDraftState(x);
@@ -18116,7 +18144,6 @@ function Settings() {
18116
18144
 
18117
18145
  // src/tui/screens/Help.tsx
18118
18146
  import { useState as useState12 } from "react";
18119
- import { useWindowSize as useWindowSize7 } from "ink";
18120
18147
  import { jsx as jsx19 } from "react/jsx-runtime";
18121
18148
  var COLUMN = 36;
18122
18149
  var KEY = 15;
@@ -18149,7 +18176,7 @@ function helpLines(groups, width) {
18149
18176
  }
18150
18177
  function Help() {
18151
18178
  const { t } = useTui();
18152
- const { columns } = useWindowSize7();
18179
+ const { columns } = useScreenSize();
18153
18180
  const k = t.keys;
18154
18181
  const groups = [
18155
18182
  [t.help.global, [["1\u20266", t.help.screens], ["/", k.ask], ["+", k.launch], [",", k.settings], ["?", k.help], ["esc", k.back], ["q", k.quit]]],
@@ -18192,7 +18219,7 @@ function Help() {
18192
18219
 
18193
18220
  // src/tui/screens/Teams.tsx
18194
18221
  import { useEffect as useEffect11, useMemo as useMemo7, useState as useState13 } from "react";
18195
- import { Box as Box16, Text as Text17, useWindowSize as useWindowSize8 } from "ink";
18222
+ import { Box as Box16, Text as Text17 } from "ink";
18196
18223
  import { randomUUID as randomUUID4 } from "crypto";
18197
18224
 
18198
18225
  // src/tui/model/catalog.ts
@@ -18257,7 +18284,7 @@ var ROLES_MS = 4e3;
18257
18284
  function Teams() {
18258
18285
  const tui = useTui();
18259
18286
  const { client, d, projects, machines, t, g, selected, catalog, go } = tui;
18260
- const { columns, rows: height } = useWindowSize8();
18287
+ const { columns, rows: height } = useScreenSize();
18261
18288
  const wide = columns >= WIDE;
18262
18289
  const left2 = wide ? Math.min(64, Math.max(44, Math.floor(columns * 0.42))) : columns;
18263
18290
  const teams = useTeams(client) ?? [];
@@ -18620,7 +18647,7 @@ function Shell({ client, lang, setLang: setLangState, saveLang, theme, setThemeS
18620
18647
  if (code3 !== 0) toast({ text: t.toast.exited(argv[0], code3), tone: "error" });
18621
18648
  });
18622
18649
  }, [suspendTerminal, run2, t, toast]);
18623
- const size = useWindowSize9();
18650
+ const size = screenSize(useWindowSize2(), env);
18624
18651
  const small = size.columns < MIN.columns || size.rows < MIN.rows;
18625
18652
  const tui = {
18626
18653
  client,
@@ -18770,6 +18797,8 @@ var UNICODE = {
18770
18797
  codeEnd: "\u2570",
18771
18798
  link: "\u2197",
18772
18799
  caret: "\u258D",
18800
+ /** Where a table's rule crosses its columns' bars. */
18801
+ cross: "\u253C",
18773
18802
  /** An action card's row (#94): proposed is `idle`, applied `ok`, failed or refused `fail`. */
18774
18803
  running: "\u25D0",
18775
18804
  held: "\xB7",
@@ -18820,6 +18849,7 @@ var ASCII = {
18820
18849
  codeEnd: "+",
18821
18850
  link: "",
18822
18851
  caret: "_",
18852
+ cross: "+",
18823
18853
  running: "~",
18824
18854
  held: ".",
18825
18855
  stale: "!",
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  LEDGE_VERSION
3
- } from "./chunk-4DEVJE4H.js";
3
+ } from "./chunk-XSYWXHOK.js";
4
4
  import "./chunk-U67V476Y.js";
5
5
  export {
6
6
  LEDGE_VERSION
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paradow/ledge",
3
- "version": "0.22.0",
3
+ "version": "0.23.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.22.0" : "0.0.0-dev";
3
-
4
- export {
5
- LEDGE_VERSION
6
- };