@paradow/ledge 0.22.0 → 0.22.1
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.
- package/dist/cli/chunk-ONFWK2WW.js +6 -0
- package/dist/cli/{daemon-7IGQIDWB.js → daemon-DLJCIC7L.js} +1 -1
- package/dist/cli/index.js +3 -3
- package/dist/cli/{tui-ZJDNIBIB.js → tui-GL6Q3KOX.js} +60 -31
- package/dist/cli/{version-EHETEZAK.js → version-ZPC6END5.js} +1 -1
- package/package.json +1 -1
- package/dist/cli/chunk-4DEVJE4H.js +0 -6
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-
|
|
40
|
+
const { startDaemon } = await import("./daemon-DLJCIC7L.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-
|
|
48
|
+
const { LEDGE_VERSION } = await import("./version-ZPC6END5.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-
|
|
121
|
+
const { runTui } = await import("./tui-GL6Q3KOX.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
|
|
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,
|
|
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,
|
|
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
|
|
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
|
|
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 } =
|
|
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 } =
|
|
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
|
|
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";
|
|
@@ -4695,7 +4700,7 @@ function peekDelete() {
|
|
|
4695
4700
|
function defaultStringLength(value) {
|
|
4696
4701
|
return value.length;
|
|
4697
4702
|
}
|
|
4698
|
-
function markdownTable(
|
|
4703
|
+
function markdownTable(table2, options) {
|
|
4699
4704
|
const settings = options || {};
|
|
4700
4705
|
const align = (settings.align || []).concat();
|
|
4701
4706
|
const stringLength = settings.stringLength || defaultStringLength;
|
|
@@ -4705,15 +4710,15 @@ function markdownTable(table, options) {
|
|
|
4705
4710
|
const longestCellByColumn = [];
|
|
4706
4711
|
let mostCellsPerRow = 0;
|
|
4707
4712
|
let rowIndex = -1;
|
|
4708
|
-
while (++rowIndex <
|
|
4713
|
+
while (++rowIndex < table2.length) {
|
|
4709
4714
|
const row3 = [];
|
|
4710
4715
|
const sizes2 = [];
|
|
4711
4716
|
let columnIndex2 = -1;
|
|
4712
|
-
if (
|
|
4713
|
-
mostCellsPerRow =
|
|
4717
|
+
if (table2[rowIndex].length > mostCellsPerRow) {
|
|
4718
|
+
mostCellsPerRow = table2[rowIndex].length;
|
|
4714
4719
|
}
|
|
4715
|
-
while (++columnIndex2 <
|
|
4716
|
-
const cell = serialize(
|
|
4720
|
+
while (++columnIndex2 < table2[rowIndex].length) {
|
|
4721
|
+
const cell = serialize(table2[rowIndex][columnIndex2]);
|
|
4717
4722
|
if (settings.alignDelimiters !== false) {
|
|
4718
4723
|
const size = stringLength(cell);
|
|
4719
4724
|
sizes2[columnIndex2] = size;
|
|
@@ -12491,15 +12496,15 @@ function flushCell(map3, context, range, rowKind, rowEnd, previousCell) {
|
|
|
12491
12496
|
}
|
|
12492
12497
|
return previousCell;
|
|
12493
12498
|
}
|
|
12494
|
-
function flushTableEnd(map3, context, index2,
|
|
12499
|
+
function flushTableEnd(map3, context, index2, table2, tableBody) {
|
|
12495
12500
|
const exits = [];
|
|
12496
12501
|
const related = getPoint(context.events, index2);
|
|
12497
12502
|
if (tableBody) {
|
|
12498
12503
|
tableBody.end = Object.assign({}, related);
|
|
12499
12504
|
exits.push(["exit", tableBody, context]);
|
|
12500
12505
|
}
|
|
12501
|
-
|
|
12502
|
-
exits.push(["exit",
|
|
12506
|
+
table2.end = Object.assign({}, related);
|
|
12507
|
+
exits.push(["exit", table2, context]);
|
|
12503
12508
|
map3.add(index2 + 1, 0, exits);
|
|
12504
12509
|
}
|
|
12505
12510
|
function getPoint(events, index2) {
|
|
@@ -15858,13 +15863,35 @@ function block(n, width, ctx) {
|
|
|
15858
15863
|
const start = list3.start ?? 1;
|
|
15859
15864
|
return listItems(list3, width, ctx, start, String(start + n.children.length - 1).length);
|
|
15860
15865
|
}
|
|
15861
|
-
// Out of the subset: a table stays as it was written, cut, not wrapped; HTML and footnotes as they were written.
|
|
15862
15866
|
case "table":
|
|
15863
|
-
return
|
|
15867
|
+
return table(n, width, ctx);
|
|
15868
|
+
// Out of the subset: HTML and footnotes as they were written.
|
|
15864
15869
|
default:
|
|
15865
15870
|
return wrapSegs([{ ...ctx.base, text: source(n, ctx) }], width);
|
|
15866
15871
|
}
|
|
15867
15872
|
}
|
|
15873
|
+
function table(n, width, ctx) {
|
|
15874
|
+
const { g } = ctx;
|
|
15875
|
+
const align = n.align ?? [];
|
|
15876
|
+
const rows = n.children.map((r, i) => r.children.map((c) => inline(c.children, i ? ctx.base : { ...ctx.base, bold: true }, ctx)));
|
|
15877
|
+
const cols = Math.max(1, ...rows.map((r) => r.length));
|
|
15878
|
+
const room = width - 3 * (cols - 1);
|
|
15879
|
+
if (room < 4 * cols) return source(n, ctx).split("\n").map((l) => cut([{ ...ctx.base, text: l, italic: false }], width));
|
|
15880
|
+
const w = Array.from({ length: cols }, (_, j) => Math.max(1, ...rows.map((r) => lineCells(r[j] ?? []))));
|
|
15881
|
+
for (let over = w.reduce((a, b2) => a + b2, 0) - room; over > 0; over--) w[w.indexOf(Math.max(...w))]--;
|
|
15882
|
+
const sep = { text: ` ${g.bar} `, color: C.faint };
|
|
15883
|
+
const rule = [{ text: w.map((x) => g.rule.repeat(x)).join(`${g.rule}${g.cross}${g.rule}`), color: C.faint }];
|
|
15884
|
+
const drawn = rows.map((r) => {
|
|
15885
|
+
const cells2 = w.map((x, j) => wrapSegs(r[j] ?? [], x));
|
|
15886
|
+
return Array.from({ length: Math.max(...cells2.map((c) => c.length)) }, (_, k) => cells2.flatMap((c, j) => {
|
|
15887
|
+
const l = c[k] ?? [], free = Math.max(0, w[j] - lineCells(l)), last = j === cols - 1;
|
|
15888
|
+
const left2 = align[j] === "right" ? free : align[j] === "center" ? Math.floor(free / 2) : 0;
|
|
15889
|
+
return [...j ? [sep] : [], ...left2 ? [pad(left2)] : [], ...l, ...last ? [] : [pad(free - left2)]];
|
|
15890
|
+
}));
|
|
15891
|
+
});
|
|
15892
|
+
const wrapped = drawn.slice(1).some((r) => r.length > 1);
|
|
15893
|
+
return drawn.flatMap((r, i) => i === 0 ? [...r, rule] : i > 1 && wrapped ? [rule, ...r] : r);
|
|
15894
|
+
}
|
|
15868
15895
|
function listItems(list3, width, ctx, start, wide) {
|
|
15869
15896
|
const { g } = ctx, out = [];
|
|
15870
15897
|
list3.children.forEach((item, i) => {
|
|
@@ -16133,7 +16160,7 @@ function Lines({ lines, up = 0, onHeight }) {
|
|
|
16133
16160
|
|
|
16134
16161
|
// src/tui/ui/Field.tsx
|
|
16135
16162
|
import { useReducer, useRef as useRef8 } from "react";
|
|
16136
|
-
import { Box as Box9, usePaste as usePaste2, useInput as useInput2
|
|
16163
|
+
import { Box as Box9, usePaste as usePaste2, useInput as useInput2 } from "ink";
|
|
16137
16164
|
|
|
16138
16165
|
// src/tui/model/field.ts
|
|
16139
16166
|
var graphemes2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
@@ -16252,7 +16279,7 @@ var fieldRows = (columns, rows) => rows < 24 ? 3 : columns >= 120 && rows >= 32
|
|
|
16252
16279
|
var inHistory = (b2) => b2 !== null && b2.i < b2.items.length - 1;
|
|
16253
16280
|
function Field({ value, onChange, onSubmit, onEscape, onBrowse, history = [], active, placeholder, title: title2, color: color2 = C.coral, titleColor }) {
|
|
16254
16281
|
const { t, g } = useTui();
|
|
16255
|
-
const { columns, rows: height } =
|
|
16282
|
+
const { columns, rows: height } = useScreenSize();
|
|
16256
16283
|
const st = useRef8({ f: { text: value, cursor: value.length }, browse: null, pasted: 0 });
|
|
16257
16284
|
const told = useRef8(value);
|
|
16258
16285
|
if (value !== told.current) {
|
|
@@ -16395,7 +16422,7 @@ function SessionScreen() {
|
|
|
16395
16422
|
}
|
|
16396
16423
|
function SessionView({ s }) {
|
|
16397
16424
|
const { client, d, t, g, actions, attach, toast, machines, kept, lastToast, tone: tone2 } = useTui();
|
|
16398
|
-
const { columns, rows } =
|
|
16425
|
+
const { columns, rows } = useScreenSize();
|
|
16399
16426
|
const [mode, setMode] = useState7("read");
|
|
16400
16427
|
const [draft, setDraftState] = useState7(() => kept.drafts.get(s.id) ?? "");
|
|
16401
16428
|
const setDraft = (x) => {
|
|
@@ -16646,7 +16673,7 @@ function PendingBox({ s, a }) {
|
|
|
16646
16673
|
// src/tui/screens/Ask.tsx
|
|
16647
16674
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
16648
16675
|
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
|
|
16676
|
+
import { Box as Box12, Text as Text12, useInput as useInput4 } from "ink";
|
|
16650
16677
|
|
|
16651
16678
|
// ../ui/src/chat/actionRow.ts
|
|
16652
16679
|
var CODES = new Set(ACTION_ERROR_CODES);
|
|
@@ -16823,13 +16850,13 @@ function useThrottled(value, ms) {
|
|
|
16823
16850
|
}
|
|
16824
16851
|
|
|
16825
16852
|
// src/tui/ui/ActionBox.tsx
|
|
16826
|
-
import { Box as Box11, Text as Text11
|
|
16853
|
+
import { Box as Box11, Text as Text11 } from "ink";
|
|
16827
16854
|
import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
16828
16855
|
var deniable = (r, s) => r.action === "session.decide" && r.decision === "accept" && (s === "proposed" || s === "held" || s === "cut");
|
|
16829
16856
|
var appliable = (s) => s === "proposed" || s === "held" || s === "failed";
|
|
16830
16857
|
function ActionBox({ turn, focused, busy, sel, confirming, plan }) {
|
|
16831
16858
|
const { t, g } = useTui();
|
|
16832
|
-
const { columns } =
|
|
16859
|
+
const { columns } = useScreenSize();
|
|
16833
16860
|
const a = t.ask.action, c = a.copy;
|
|
16834
16861
|
const p = plan ?? cardPlan(turn.actions ?? []);
|
|
16835
16862
|
const many = p.rows.length > 1;
|
|
@@ -16972,7 +16999,7 @@ var CARD_MS = 2e4;
|
|
|
16972
16999
|
var CONVO = -2;
|
|
16973
17000
|
function Ask() {
|
|
16974
17001
|
const { client, d, machines, t, g, toast, go, kept, small, tone: tone2, select } = useTui();
|
|
16975
|
-
const { columns, rows: height } =
|
|
17002
|
+
const { columns, rows: height } = useScreenSize();
|
|
16976
17003
|
const [draft, setDraftState] = useState9(() => kept.drafts.get("ask") ?? "");
|
|
16977
17004
|
const setDraft = (x) => {
|
|
16978
17005
|
setDraftState(x);
|
|
@@ -18116,7 +18143,6 @@ function Settings() {
|
|
|
18116
18143
|
|
|
18117
18144
|
// src/tui/screens/Help.tsx
|
|
18118
18145
|
import { useState as useState12 } from "react";
|
|
18119
|
-
import { useWindowSize as useWindowSize7 } from "ink";
|
|
18120
18146
|
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
18121
18147
|
var COLUMN = 36;
|
|
18122
18148
|
var KEY = 15;
|
|
@@ -18149,7 +18175,7 @@ function helpLines(groups, width) {
|
|
|
18149
18175
|
}
|
|
18150
18176
|
function Help() {
|
|
18151
18177
|
const { t } = useTui();
|
|
18152
|
-
const { columns } =
|
|
18178
|
+
const { columns } = useScreenSize();
|
|
18153
18179
|
const k = t.keys;
|
|
18154
18180
|
const groups = [
|
|
18155
18181
|
[t.help.global, [["1\u20266", t.help.screens], ["/", k.ask], ["+", k.launch], [",", k.settings], ["?", k.help], ["esc", k.back], ["q", k.quit]]],
|
|
@@ -18192,7 +18218,7 @@ function Help() {
|
|
|
18192
18218
|
|
|
18193
18219
|
// src/tui/screens/Teams.tsx
|
|
18194
18220
|
import { useEffect as useEffect11, useMemo as useMemo7, useState as useState13 } from "react";
|
|
18195
|
-
import { Box as Box16, Text as Text17
|
|
18221
|
+
import { Box as Box16, Text as Text17 } from "ink";
|
|
18196
18222
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
18197
18223
|
|
|
18198
18224
|
// src/tui/model/catalog.ts
|
|
@@ -18257,7 +18283,7 @@ var ROLES_MS = 4e3;
|
|
|
18257
18283
|
function Teams() {
|
|
18258
18284
|
const tui = useTui();
|
|
18259
18285
|
const { client, d, projects, machines, t, g, selected, catalog, go } = tui;
|
|
18260
|
-
const { columns, rows: height } =
|
|
18286
|
+
const { columns, rows: height } = useScreenSize();
|
|
18261
18287
|
const wide = columns >= WIDE;
|
|
18262
18288
|
const left2 = wide ? Math.min(64, Math.max(44, Math.floor(columns * 0.42))) : columns;
|
|
18263
18289
|
const teams = useTeams(client) ?? [];
|
|
@@ -18620,7 +18646,7 @@ function Shell({ client, lang, setLang: setLangState, saveLang, theme, setThemeS
|
|
|
18620
18646
|
if (code3 !== 0) toast({ text: t.toast.exited(argv[0], code3), tone: "error" });
|
|
18621
18647
|
});
|
|
18622
18648
|
}, [suspendTerminal, run2, t, toast]);
|
|
18623
|
-
const size =
|
|
18649
|
+
const size = screenSize(useWindowSize2(), env);
|
|
18624
18650
|
const small = size.columns < MIN.columns || size.rows < MIN.rows;
|
|
18625
18651
|
const tui = {
|
|
18626
18652
|
client,
|
|
@@ -18770,6 +18796,8 @@ var UNICODE = {
|
|
|
18770
18796
|
codeEnd: "\u2570",
|
|
18771
18797
|
link: "\u2197",
|
|
18772
18798
|
caret: "\u258D",
|
|
18799
|
+
/** Where a table's rule crosses its columns' bars. */
|
|
18800
|
+
cross: "\u253C",
|
|
18773
18801
|
/** An action card's row (#94): proposed is `idle`, applied `ok`, failed or refused `fail`. */
|
|
18774
18802
|
running: "\u25D0",
|
|
18775
18803
|
held: "\xB7",
|
|
@@ -18820,6 +18848,7 @@ var ASCII = {
|
|
|
18820
18848
|
codeEnd: "+",
|
|
18821
18849
|
link: "",
|
|
18822
18850
|
caret: "_",
|
|
18851
|
+
cross: "+",
|
|
18823
18852
|
running: "~",
|
|
18824
18853
|
held: ".",
|
|
18825
18854
|
stale: "!",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paradow/ledge",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.1",
|
|
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" },
|