@paradow/ledge 0.18.0 → 0.19.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/README.md +7 -1
- package/assets/ledge.ico +0 -0
- package/dist/cli/{attach-I6TTCGNV.js → attach-3BKQSEWC.js} +2 -2
- package/dist/cli/{chunk-QQZALYNI.js → chunk-LOOOHYZR.js} +1 -1
- package/dist/cli/chunk-TVIAHOOD.js +6 -0
- package/dist/cli/{chunk-7IQ6FV2F.js → chunk-WP77O5LC.js} +1 -1
- package/dist/cli/{daemon-SKC7VKYQ.js → daemon-YHRAZSRS.js} +2 -2
- package/dist/cli/index.js +6 -6
- package/dist/cli/{launch-T5FJ42XS.js → launch-YQYCDZ7N.js} +2 -2
- package/dist/cli/{tui-MQLMUUJB.js → tui-5XPPX4GR.js} +124 -15
- package/dist/cli/{version-AEN2CRT2.js → version-HB3S4IVG.js} +1 -1
- package/package.json +2 -2
- package/dist/cli/chunk-G6K2NSQS.js +0 -6
package/README.md
CHANGED
|
@@ -42,11 +42,17 @@ ledge claude # start Claude Code in a tracked tmux session (tab renam
|
|
|
42
42
|
ledge claude --name max # pick the session's Ledge name
|
|
43
43
|
ledge status # list bots and what they wait for
|
|
44
44
|
ledge attach <id> # put this terminal on a running session (what the overlay opens a tab with)
|
|
45
|
-
ledge tui # follow and answer every session
|
|
45
|
+
ledge tui # follow and answer every session (--notify bell|osc9|off); see below for Windows Terminal
|
|
46
46
|
ledge daemon # run the daemon in the foreground (normally run by the systemd service)
|
|
47
47
|
ledge uninstall # undo ledge setup: hooks, service and ~/.local/bin/ledge (--purge: ~/.ledge too)
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
From a WSL tab of Windows Terminal, `ledge tui` opens in a tab of its own with the Ledge mascot as its icon. A tab's
|
|
51
|
+
icon comes only from its profile, so Ledge installs a `Ledge` profile as a fragment under
|
|
52
|
+
`%LOCALAPPDATA%\Microsoft\Windows Terminal\Fragments\Ledge` (no admin right needed). That profile runs
|
|
53
|
+
`~/.ledge/tui.sh`, which each `ledge tui` rewrites with its node and CLI. `ledge tui --here`, tmux, SSH and any other
|
|
54
|
+
terminal keep the TUI where it was started.
|
|
55
|
+
|
|
50
56
|
When a Claude it launched exits, Ledge appends a `custom-title` « name - topic » to its transcript, so `claude --resume` lists the conversation that way, unless the user named it (`claude -n`, `/rename`).
|
|
51
57
|
|
|
52
58
|
`ledge setup` installs `ledge-daemon.service` as a systemd user unit, starts it and enables linger, so the daemon runs from WSL boot and restarts after a crash. Rerun it after a node upgrade or a repository move: the unit is rewritten and the service restarted. Useful commands:
|
package/assets/ledge.ico
ADDED
|
Binary file
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
startServer,
|
|
8
8
|
tasksJournal,
|
|
9
9
|
teamsJournal
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-WP77O5LC.js";
|
|
11
11
|
import "./chunk-3EIRKAX7.js";
|
|
12
12
|
import "./chunk-OLLQBK6N.js";
|
|
13
13
|
import {
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
} from "./chunk-HP3G2TYJ.js";
|
|
46
46
|
import {
|
|
47
47
|
LEDGE_VERSION
|
|
48
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-TVIAHOOD.js";
|
|
49
49
|
import {
|
|
50
50
|
SERVICE,
|
|
51
51
|
inDaemonService,
|
package/dist/cli/index.js
CHANGED
|
@@ -14,7 +14,7 @@ ledge read <id> print a long messag
|
|
|
14
14
|
ledge task <give|list|show|take|done|refuse|pass> \u2026 give another session work, take it, close it (ledge task: details)
|
|
15
15
|
ledge handover "<bilan>" | show the relief brief, when Ledge asks for it; show: read your predecessor's
|
|
16
16
|
ledge team <up|list> \u2026 start a team from a template, list templates, roles and live teams
|
|
17
|
-
ledge tui [--notify bell|osc9|off]
|
|
17
|
+
ledge tui [--notify bell|osc9|off] [--here] follow and answer the sessions (in a Ledge tab of Windows Terminal unless --here)
|
|
18
18
|
ledge bridge exchange Ledge messages over SSH stdio
|
|
19
19
|
ledge --version print the installed version`;
|
|
20
20
|
async function hookMain(args) {
|
|
@@ -35,7 +35,7 @@ async function main(argv) {
|
|
|
35
35
|
const [cmd, ...rest] = argv;
|
|
36
36
|
switch (cmd) {
|
|
37
37
|
case "daemon": {
|
|
38
|
-
const { startDaemon } = await import("./daemon-
|
|
38
|
+
const { startDaemon } = await import("./daemon-YHRAZSRS.js");
|
|
39
39
|
await startDaemon();
|
|
40
40
|
await new Promise(() => {
|
|
41
41
|
});
|
|
@@ -43,7 +43,7 @@ async function main(argv) {
|
|
|
43
43
|
}
|
|
44
44
|
case "--version":
|
|
45
45
|
case "version": {
|
|
46
|
-
const { LEDGE_VERSION } = await import("./version-
|
|
46
|
+
const { LEDGE_VERSION } = await import("./version-HB3S4IVG.js");
|
|
47
47
|
console.log(LEDGE_VERSION);
|
|
48
48
|
return 0;
|
|
49
49
|
}
|
|
@@ -104,7 +104,7 @@ async function main(argv) {
|
|
|
104
104
|
return r.code;
|
|
105
105
|
}
|
|
106
106
|
case "tui": {
|
|
107
|
-
const { runTui } = await import("./tui-
|
|
107
|
+
const { runTui } = await import("./tui-5XPPX4GR.js");
|
|
108
108
|
return runTui(rest);
|
|
109
109
|
}
|
|
110
110
|
case "bridge": {
|
|
@@ -115,11 +115,11 @@ async function main(argv) {
|
|
|
115
115
|
case "claude":
|
|
116
116
|
case "codex":
|
|
117
117
|
case "cursor": {
|
|
118
|
-
const { launch } = await import("./launch-
|
|
118
|
+
const { launch } = await import("./launch-YQYCDZ7N.js");
|
|
119
119
|
return launch(cmd, rest);
|
|
120
120
|
}
|
|
121
121
|
case "attach": {
|
|
122
|
-
const { attach } = await import("./attach-
|
|
122
|
+
const { attach } = await import("./attach-3BKQSEWC.js");
|
|
123
123
|
return attach(rest.find((a) => !a.startsWith("--")) ?? "", { readOnly: rest.includes("--read-only") });
|
|
124
124
|
}
|
|
125
125
|
default:
|
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
launch,
|
|
7
7
|
parseLaunchArgs,
|
|
8
8
|
roleArgs
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-LOOOHYZR.js";
|
|
10
|
+
import "./chunk-WP77O5LC.js";
|
|
11
11
|
import "./chunk-3EIRKAX7.js";
|
|
12
12
|
import "./chunk-OLLQBK6N.js";
|
|
13
13
|
import "./chunk-KKNE7BFZ.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
attachEnv
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-LOOOHYZR.js";
|
|
4
|
+
import "./chunk-WP77O5LC.js";
|
|
5
5
|
import "./chunk-3EIRKAX7.js";
|
|
6
6
|
import "./chunk-OLLQBK6N.js";
|
|
7
7
|
import "./chunk-KKNE7BFZ.js";
|
|
@@ -1797,7 +1797,7 @@ var fr = {
|
|
|
1797
1797
|
question: (n, text) => `${n} a une question : ${text}`,
|
|
1798
1798
|
title: (n) => n > 0 ? `ledge \xB7 ${n} t\u2019${plural(n, "attend", "attendent")}` : "ledge"
|
|
1799
1799
|
},
|
|
1800
|
-
cli: { notTty: "ledge tui: needs a terminal (stdin and stdout must be a TTY)" }
|
|
1800
|
+
cli: { notTty: "ledge tui: needs a terminal (stdin and stdout must be a TTY)", movedToTab: "ledge tui s\u2019ouvre dans l\u2019onglet Ledge.", loadingProfile: "Windows Terminal charge le profil Ledge\u2026" }
|
|
1801
1801
|
};
|
|
1802
1802
|
|
|
1803
1803
|
// src/tui/i18n/en.ts
|
|
@@ -2032,7 +2032,7 @@ var en = {
|
|
|
2032
2032
|
question: (n, text) => `${n} has a question: ${text}`,
|
|
2033
2033
|
title: (n) => n > 0 ? `ledge \xB7 ${n} waiting` : "ledge"
|
|
2034
2034
|
},
|
|
2035
|
-
cli: { notTty: "ledge tui: needs a terminal (stdin and stdout must be a TTY)" }
|
|
2035
|
+
cli: { notTty: "ledge tui: needs a terminal (stdin and stdout must be a TTY)", movedToTab: "ledge tui opens in the Ledge tab.", loadingProfile: "Windows Terminal is loading the Ledge profile\u2026" }
|
|
2036
2036
|
};
|
|
2037
2037
|
|
|
2038
2038
|
// src/tui/i18n/lang.tsx
|
|
@@ -3140,12 +3140,12 @@ function SessionView({ s }) {
|
|
|
3140
3140
|
offers(s.tool, p.kind, "note") ? /* @__PURE__ */ jsx11(Button, { label: t.overview.denyWithNote, k: "r" }) : null
|
|
3141
3141
|
] }) })
|
|
3142
3142
|
] }) : null,
|
|
3143
|
-
/* @__PURE__ */ jsx11(TitledBox, { title: mode === "note" ? t.overview.denyWithNote : t.keys.write, color: mode === "read" ? C.line : C.coral, children: /* @__PURE__ */ jsxs8(
|
|
3143
|
+
/* @__PURE__ */ jsx11(TitledBox, { title: mode === "note" ? t.overview.denyWithNote : t.keys.write, color: mode === "read" ? C.line : C.coral, children: /* @__PURE__ */ jsxs8(Box9, { children: [
|
|
3144
3144
|
/* @__PURE__ */ jsxs8(Text10, { color: C.coral, children: [
|
|
3145
3145
|
g.cursor,
|
|
3146
3146
|
" "
|
|
3147
3147
|
] }),
|
|
3148
|
-
/* @__PURE__ */ jsx11(
|
|
3148
|
+
/* @__PURE__ */ jsx11(Box9, { flexGrow: 1, overflow: "hidden", children: /* @__PURE__ */ jsx11(
|
|
3149
3149
|
TextInput,
|
|
3150
3150
|
{
|
|
3151
3151
|
value: draft,
|
|
@@ -3155,7 +3155,7 @@ function SessionView({ s }) {
|
|
|
3155
3155
|
active: mode === "reply" || mode === "note",
|
|
3156
3156
|
placeholder: mode === "note" ? t.session.noteFor(s.name) : t.session.replyTo(s.name)
|
|
3157
3157
|
}
|
|
3158
|
-
)
|
|
3158
|
+
) })
|
|
3159
3159
|
] }) })
|
|
3160
3160
|
] });
|
|
3161
3161
|
}
|
|
@@ -3310,14 +3310,14 @@ function Ask() {
|
|
|
3310
3310
|
return /* @__PURE__ */ jsxs9(Frame, { crumb: `${t.tabs.ask}`, keys: [["\u21B5", t.keys.send], ["tab", t.keys.nextCard], ["s", t.keys.save], ["ctrl+n", t.keys.newChat], ["ctrl+c", t.keys.stopAnswer], ["esc", t.keys.back]], children: [
|
|
3311
3311
|
/* @__PURE__ */ jsx12(TitledBox, { title: t.ask.operator(sessions, Math.max(1, machines.length)), flexGrow: 1, children: lines.length === 0 ? /* @__PURE__ */ jsx12(Text11, { color: C.faint, children: t.ask.empty }) : /* @__PURE__ */ jsx12(Lines, { lines }) }),
|
|
3312
3312
|
cards.slice(0, 2).map((c, i) => /* @__PURE__ */ jsx12(CardBox, { card: c, turn: d.chat.find((x) => x.qid === c.qid), focused: i === focus, busy: busy?.qid === c.qid }, `${c.kind}:${c.qid}`)),
|
|
3313
|
-
/* @__PURE__ */ jsx12(TitledBox, { title: t.ask.question, flexShrink: 0, color: focus === -1 ? C.coral : C.line, children: /* @__PURE__ */ jsxs9(
|
|
3313
|
+
/* @__PURE__ */ jsx12(TitledBox, { title: t.ask.question, flexShrink: 0, color: focus === -1 ? C.coral : C.line, children: /* @__PURE__ */ jsxs9(Box10, { children: [
|
|
3314
3314
|
/* @__PURE__ */ jsxs9(Text11, { color: C.coral, children: [
|
|
3315
3315
|
g.cursor,
|
|
3316
3316
|
" "
|
|
3317
3317
|
] }),
|
|
3318
|
-
/* @__PURE__ */ jsx12(TextInput, { value: draft, onChange: setDraft, onSubmit: ask, onEscape: () => {
|
|
3318
|
+
/* @__PURE__ */ jsx12(Box10, { flexGrow: 1, overflow: "hidden", children: /* @__PURE__ */ jsx12(TextInput, { value: draft, onChange: setDraft, onSubmit: ask, onEscape: () => {
|
|
3319
3319
|
if (!draft) go("overview");
|
|
3320
|
-
}, active: focus === -1 })
|
|
3320
|
+
}, active: focus === -1 }) })
|
|
3321
3321
|
] }) })
|
|
3322
3322
|
] });
|
|
3323
3323
|
}
|
|
@@ -4007,7 +4007,7 @@ function App(props) {
|
|
|
4007
4007
|
const [lang, setLangState] = useState9(props.lang);
|
|
4008
4008
|
return /* @__PURE__ */ jsx16(I18nProvider, { lang, children: /* @__PURE__ */ jsx16(Shell, { ...props, lang, setLang: setLangState }) });
|
|
4009
4009
|
}
|
|
4010
|
-
function Shell({ client, lang, setLang: setLangState, saveLang, notify, glyphs, env, run }) {
|
|
4010
|
+
function Shell({ client, lang, setLang: setLangState, saveLang, notify, glyphs, env, run: run2 }) {
|
|
4011
4011
|
const { exit, suspendTerminal } = useApp();
|
|
4012
4012
|
const { stdout } = useStdout();
|
|
4013
4013
|
const write = useCallback((seq) => {
|
|
@@ -4074,10 +4074,10 @@ function Shell({ client, lang, setLang: setLangState, saveLang, notify, glyphs,
|
|
|
4074
4074
|
return;
|
|
4075
4075
|
}
|
|
4076
4076
|
void suspendTerminal(async () => {
|
|
4077
|
-
const code = await (
|
|
4077
|
+
const code = await (run2 ?? runAttached)(cmd.argv);
|
|
4078
4078
|
if (code !== 0) toast({ text: t.toast.attachFailed(code), tone: "error" });
|
|
4079
4079
|
});
|
|
4080
|
-
}, [fleet, suspendTerminal,
|
|
4080
|
+
}, [fleet, suspendTerminal, run2, t, toast]);
|
|
4081
4081
|
const tui = {
|
|
4082
4082
|
client,
|
|
4083
4083
|
fleet,
|
|
@@ -4260,18 +4260,123 @@ function saveSettings(settings) {
|
|
|
4260
4260
|
renameSync(tmp, path);
|
|
4261
4261
|
}
|
|
4262
4262
|
|
|
4263
|
+
// src/tui/terminalProfile.ts
|
|
4264
|
+
import { execFile, spawn as spawn2 } from "child_process";
|
|
4265
|
+
import { mkdir, readFile, realpath, writeFile } from "fs/promises";
|
|
4266
|
+
import { dirname, join as join2 } from "path";
|
|
4267
|
+
import { fileURLToPath } from "url";
|
|
4268
|
+
import { promisify } from "util";
|
|
4269
|
+
var PROFILE = "Ledge";
|
|
4270
|
+
var ICON = fileURLToPath(new URL("../../assets/ledge.ico", import.meta.url));
|
|
4271
|
+
var SETTINGS = [
|
|
4272
|
+
"Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/LocalState/settings.json",
|
|
4273
|
+
"Packages/Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe/LocalState/settings.json",
|
|
4274
|
+
"Microsoft/Windows Terminal/settings.json"
|
|
4275
|
+
];
|
|
4276
|
+
var fragmentDir = (localAppData) => join2(localAppData, "Microsoft", "Windows Terminal", "Fragments", PROFILE);
|
|
4277
|
+
var PROFILE_ID = "{d10fee13-0978-595f-a851-b60ec80f11c9}";
|
|
4278
|
+
function movesToLedgeTab(env, here, script) {
|
|
4279
|
+
return !here && !!env.WT_SESSION && !!env.WSL_DISTRO_NAME && !env.TMUX && env.WT_PROFILE_ID !== PROFILE_ID && !script.endsWith(".ts");
|
|
4280
|
+
}
|
|
4281
|
+
function winArg(s) {
|
|
4282
|
+
if (!s || /["\u0000-\u001f]/.test(s) || s.endsWith("\\")) return null;
|
|
4283
|
+
return /\s/.test(s) ? `"${s}"` : s;
|
|
4284
|
+
}
|
|
4285
|
+
function profileCommandline(distro, launcher) {
|
|
4286
|
+
const args = ["wsl.exe", "-d", distro, "--cd", "~", "--exec", "/bin/sh", launcher].map(winArg);
|
|
4287
|
+
return args.every((a) => a !== null) ? args.join(" ") : null;
|
|
4288
|
+
}
|
|
4289
|
+
var shQuote = (s) => `'${s.replace(/'/g, `'\\''`)}'`;
|
|
4290
|
+
function launcherScript(node, script, ledgeHome) {
|
|
4291
|
+
const home = ledgeHome ? `export LEDGE_HOME=${shQuote(ledgeHome)}
|
|
4292
|
+
` : "";
|
|
4293
|
+
return `#!/bin/sh
|
|
4294
|
+
# Written by \`ledge tui\`: the Ledge profile of Windows Terminal runs it.
|
|
4295
|
+
${home}exec ${shQuote(node)} ${shQuote(script)} tui --here
|
|
4296
|
+
`;
|
|
4297
|
+
}
|
|
4298
|
+
function fragment(commandline, iconWin) {
|
|
4299
|
+
return `${JSON.stringify({ profiles: [{ name: PROFILE, commandline, icon: iconWin }] }, null, 2)}
|
|
4300
|
+
`;
|
|
4301
|
+
}
|
|
4302
|
+
async function profileLoaded(localAppData) {
|
|
4303
|
+
for (const rel of SETTINGS) {
|
|
4304
|
+
const text = await readFile(join2(localAppData, rel), "utf8").catch(() => "");
|
|
4305
|
+
if (new RegExp(`"source"\\s*:\\s*"${PROFILE}"`).test(text)) return true;
|
|
4306
|
+
}
|
|
4307
|
+
return false;
|
|
4308
|
+
}
|
|
4309
|
+
async function writeIfChanged(path, content) {
|
|
4310
|
+
const current = await readFile(path).catch(() => null);
|
|
4311
|
+
if (current && current.equals(Buffer.from(content))) return false;
|
|
4312
|
+
await writeFile(path, content);
|
|
4313
|
+
return true;
|
|
4314
|
+
}
|
|
4315
|
+
async function openInLedgeTab(o) {
|
|
4316
|
+
const commandline = profileCommandline(o.distro, o.launcher);
|
|
4317
|
+
if (!commandline) return false;
|
|
4318
|
+
await mkdir(dirname(o.launcher), { recursive: true });
|
|
4319
|
+
await writeIfChanged(o.launcher, launcherScript(o.node, o.script, o.ledgeHome));
|
|
4320
|
+
const dir = fragmentDir(o.localAppData.linux);
|
|
4321
|
+
await mkdir(dir, { recursive: true });
|
|
4322
|
+
await writeIfChanged(join2(dir, "ledge.ico"), await readFile(o.icon ?? ICON));
|
|
4323
|
+
const iconWin = `${o.localAppData.win}\\Microsoft\\Windows Terminal\\Fragments\\${PROFILE}\\ledge.ico`;
|
|
4324
|
+
await writeIfChanged(join2(dir, "ledge.json"), fragment(commandline, iconWin));
|
|
4325
|
+
const deadline = Date.now() + (o.waitMs ?? 15e3);
|
|
4326
|
+
for (let first = true; !await profileLoaded(o.localAppData.linux); first = false) {
|
|
4327
|
+
if (Date.now() > deadline) return false;
|
|
4328
|
+
if (first) o.onWait?.();
|
|
4329
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
4330
|
+
}
|
|
4331
|
+
await o.wt(["-w", "0", "new-tab", "-p", PROFILE]);
|
|
4332
|
+
return true;
|
|
4333
|
+
}
|
|
4334
|
+
var run = promisify(execFile);
|
|
4335
|
+
async function openTuiInLedgeTab(env, onWait) {
|
|
4336
|
+
try {
|
|
4337
|
+
const cmd = "/mnt/c/Windows/System32/cmd.exe";
|
|
4338
|
+
const win = (await run(cmd, ["/d", "/c", "echo %LOCALAPPDATA%"], { cwd: "/mnt/c", timeout: 5e3 })).stdout.trim();
|
|
4339
|
+
if (!/^[A-Za-z]:\\/.test(win)) return false;
|
|
4340
|
+
const linux = (await run("wslpath", ["-u", win], { timeout: 5e3 })).stdout.trim();
|
|
4341
|
+
return await openInLedgeTab({
|
|
4342
|
+
localAppData: { win, linux },
|
|
4343
|
+
distro: env.WSL_DISTRO_NAME,
|
|
4344
|
+
node: await realpath(process.execPath),
|
|
4345
|
+
script: await realpath(process.argv[1]),
|
|
4346
|
+
launcher: join2(ledgeDir(), "tui.sh"),
|
|
4347
|
+
ledgeHome: env.LEDGE_HOME,
|
|
4348
|
+
onWait,
|
|
4349
|
+
wt: (args) => new Promise((resolve, reject) => {
|
|
4350
|
+
const child = spawn2(join2(linux, "Microsoft", "WindowsApps", "wt.exe"), args, { cwd: "/mnt/c", stdio: "ignore", detached: true });
|
|
4351
|
+
child.once("error", reject);
|
|
4352
|
+
child.once("spawn", () => {
|
|
4353
|
+
child.unref();
|
|
4354
|
+
resolve();
|
|
4355
|
+
});
|
|
4356
|
+
})
|
|
4357
|
+
});
|
|
4358
|
+
} catch {
|
|
4359
|
+
return false;
|
|
4360
|
+
}
|
|
4361
|
+
}
|
|
4362
|
+
|
|
4263
4363
|
// src/tui/index.tsx
|
|
4264
4364
|
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
4265
|
-
var TUI_USAGE = "ledge tui [--notify bell|osc9|off]";
|
|
4365
|
+
var TUI_USAGE = "ledge tui [--notify bell|osc9|off] [--here]";
|
|
4266
4366
|
function tuiArgs(args) {
|
|
4267
4367
|
let notify = "bell";
|
|
4368
|
+
let here = false;
|
|
4268
4369
|
for (let i = 0; i < args.length; i++) {
|
|
4269
4370
|
const a = args[i];
|
|
4371
|
+
if (a === "--here") {
|
|
4372
|
+
here = true;
|
|
4373
|
+
continue;
|
|
4374
|
+
}
|
|
4270
4375
|
const value = a.startsWith("--notify=") ? a.slice("--notify=".length) : a === "--notify" ? args[++i] : void 0;
|
|
4271
4376
|
if (value === void 0 || !NOTIFY_MODES.includes(value)) return null;
|
|
4272
4377
|
notify = value;
|
|
4273
4378
|
}
|
|
4274
|
-
return { notify };
|
|
4379
|
+
return { notify, here };
|
|
4275
4380
|
}
|
|
4276
4381
|
async function runTui(args) {
|
|
4277
4382
|
const parsed = tuiArgs(args);
|
|
@@ -4285,6 +4390,10 @@ async function runTui(args) {
|
|
|
4285
4390
|
console.error(MESSAGES[lang].cli.notTty);
|
|
4286
4391
|
return 2;
|
|
4287
4392
|
}
|
|
4393
|
+
if (movesToLedgeTab(process.env, parsed.here, process.argv[1] ?? "") && await openTuiInLedgeTab(process.env, () => console.log(MESSAGES[lang].cli.loadingProfile))) {
|
|
4394
|
+
console.log(MESSAGES[lang].cli.movedToTab);
|
|
4395
|
+
return 0;
|
|
4396
|
+
}
|
|
4288
4397
|
const client = createTuiFleet();
|
|
4289
4398
|
const detach = attachClient(client);
|
|
4290
4399
|
client.connect();
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paradow/ledge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.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" },
|
|
7
|
-
"files": ["dist"],
|
|
7
|
+
"files": ["dist", "assets/ledge.ico"],
|
|
8
8
|
"engines": { "node": ">=22" },
|
|
9
9
|
"repository": { "type": "git", "url": "git+https://github.com/Lyssaen/ledge.git", "directory": "packages/ledge" },
|
|
10
10
|
"homepage": "https://github.com/Lyssaen/ledge#readme",
|