sisyphi 1.1.38 → 1.1.40
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 +10 -0
- package/dist/cli.js +847 -468
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +251 -173
- package/dist/daemon.js.map +1 -1
- package/dist/tui.js +307 -160
- package/dist/tui.js.map +1 -1
- package/package.json +1 -1
package/dist/tui.js
CHANGED
|
@@ -302,6 +302,53 @@ var init_paths = __esm({
|
|
|
302
302
|
}
|
|
303
303
|
});
|
|
304
304
|
|
|
305
|
+
// src/shared/platform.ts
|
|
306
|
+
import { execSync } from "child_process";
|
|
307
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
308
|
+
function detectPlatform() {
|
|
309
|
+
if (cachedPlatform) return cachedPlatform;
|
|
310
|
+
if (process.platform === "darwin") {
|
|
311
|
+
cachedPlatform = "darwin";
|
|
312
|
+
} else if (process.platform === "win32") {
|
|
313
|
+
cachedPlatform = "win32";
|
|
314
|
+
} else if (process.platform === "linux") {
|
|
315
|
+
cachedPlatform = isWsl() ? "wsl" : "linux";
|
|
316
|
+
} else {
|
|
317
|
+
cachedPlatform = "unknown";
|
|
318
|
+
}
|
|
319
|
+
return cachedPlatform;
|
|
320
|
+
}
|
|
321
|
+
function isWsl() {
|
|
322
|
+
if (process.env["WSL_DISTRO_NAME"] || process.env["WSL_INTEROP"]) return true;
|
|
323
|
+
try {
|
|
324
|
+
if (existsSync2("/proc/version")) {
|
|
325
|
+
const v = readFileSync2("/proc/version", "utf-8").toLowerCase();
|
|
326
|
+
if (v.includes("microsoft") || v.includes("wsl")) return true;
|
|
327
|
+
}
|
|
328
|
+
} catch {
|
|
329
|
+
}
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
function hasCommand(cmd) {
|
|
333
|
+
const cached2 = cmdCache.get(cmd);
|
|
334
|
+
if (cached2 !== void 0) return cached2;
|
|
335
|
+
try {
|
|
336
|
+
execSync(`command -v ${cmd}`, { stdio: "pipe", shell: "/bin/sh" });
|
|
337
|
+
cmdCache.set(cmd, true);
|
|
338
|
+
return true;
|
|
339
|
+
} catch {
|
|
340
|
+
cmdCache.set(cmd, false);
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
var cachedPlatform, cmdCache;
|
|
345
|
+
var init_platform = __esm({
|
|
346
|
+
"src/shared/platform.ts"() {
|
|
347
|
+
"use strict";
|
|
348
|
+
cmdCache = /* @__PURE__ */ new Map();
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
|
|
305
352
|
// src/tui/render.ts
|
|
306
353
|
import stringWidth2 from "string-width";
|
|
307
354
|
function colorToSGR(color) {
|
|
@@ -630,10 +677,10 @@ var init_render = __esm({
|
|
|
630
677
|
});
|
|
631
678
|
|
|
632
679
|
// src/shared/config.ts
|
|
633
|
-
import { readFileSync as
|
|
680
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
634
681
|
function readJsonFile(filePath) {
|
|
635
682
|
try {
|
|
636
|
-
const content =
|
|
683
|
+
const content = readFileSync5(filePath, "utf-8");
|
|
637
684
|
return JSON.parse(content);
|
|
638
685
|
} catch {
|
|
639
686
|
return {};
|
|
@@ -684,14 +731,14 @@ var init_config = __esm({
|
|
|
684
731
|
},
|
|
685
732
|
companionPopup: true,
|
|
686
733
|
requiredPlugins: [
|
|
687
|
-
{ name: "devcore", marketplace: "crouton-kit" }
|
|
734
|
+
{ name: "devcore", marketplace: "crouton-kit", owner: "crouton-labs" }
|
|
688
735
|
]
|
|
689
736
|
};
|
|
690
737
|
}
|
|
691
738
|
});
|
|
692
739
|
|
|
693
740
|
// src/daemon/history.ts
|
|
694
|
-
import { appendFileSync, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4, renameSync as renameSync3, readdirSync as readdirSync2, readFileSync as
|
|
741
|
+
import { appendFileSync, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4, renameSync as renameSync3, readdirSync as readdirSync2, readFileSync as readFileSync6, rmSync as rmSync2, statSync } from "fs";
|
|
695
742
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
696
743
|
import { dirname as dirname3, join as join6 } from "path";
|
|
697
744
|
var init_history = __esm({
|
|
@@ -737,7 +784,7 @@ var init_atomic = __esm({
|
|
|
737
784
|
});
|
|
738
785
|
|
|
739
786
|
// src/shared/gitignore.ts
|
|
740
|
-
import { existsSync as
|
|
787
|
+
import { existsSync as existsSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
741
788
|
import { join as join8 } from "path";
|
|
742
789
|
var init_gitignore = __esm({
|
|
743
790
|
"src/shared/gitignore.ts"() {
|
|
@@ -753,7 +800,7 @@ var init_types = __esm({
|
|
|
753
800
|
});
|
|
754
801
|
|
|
755
802
|
// src/daemon/state.ts
|
|
756
|
-
import { copyFileSync, cpSync, existsSync as
|
|
803
|
+
import { copyFileSync, cpSync, existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync8, readdirSync as readdirSync3, rmSync as rmSync3, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
|
|
757
804
|
import { join as join9 } from "path";
|
|
758
805
|
var init_state = __esm({
|
|
759
806
|
"src/daemon/state.ts"() {
|
|
@@ -777,7 +824,7 @@ var init_shell = __esm({
|
|
|
777
824
|
|
|
778
825
|
// src/daemon/notify.ts
|
|
779
826
|
import { spawn, execFile as execFile2 } from "child_process";
|
|
780
|
-
import { writeFileSync as writeFileSync8, mkdirSync as mkdirSync6, existsSync as
|
|
827
|
+
import { writeFileSync as writeFileSync8, mkdirSync as mkdirSync6, existsSync as existsSync7 } from "fs";
|
|
781
828
|
import { join as join10 } from "path";
|
|
782
829
|
import { homedir as homedir3 } from "os";
|
|
783
830
|
var TMUX_SOCKET, SWITCH_SCRIPT;
|
|
@@ -785,55 +832,57 @@ var init_notify = __esm({
|
|
|
785
832
|
"src/daemon/notify.ts"() {
|
|
786
833
|
"use strict";
|
|
787
834
|
init_shell();
|
|
835
|
+
init_platform();
|
|
788
836
|
TMUX_SOCKET = `/tmp/tmux-${process.getuid?.() ?? 0}/default`;
|
|
789
837
|
SWITCH_SCRIPT = [
|
|
790
838
|
"#!/bin/bash",
|
|
791
839
|
'SESSION="$1"',
|
|
792
840
|
`TMUX_SOCKET="${TMUX_SOCKET}"`,
|
|
793
|
-
"TMUX=/opt/homebrew/bin/tmux",
|
|
794
841
|
"",
|
|
795
842
|
"# Find any attached client (user is likely on a different session)",
|
|
796
|
-
`CLIENT_TTY=$(
|
|
843
|
+
`CLIENT_TTY=$(tmux -S "$TMUX_SOCKET" list-clients -F '#{client_tty}' 2>/dev/null | head -1)`,
|
|
797
844
|
'[ -z "$CLIENT_TTY" ] && exit 0',
|
|
798
845
|
"",
|
|
799
846
|
"# Switch that client to the target session",
|
|
800
|
-
'
|
|
801
|
-
'
|
|
847
|
+
'tmux -S "$TMUX_SOCKET" switch-client -c "$CLIENT_TTY" -t "$SESSION" 2>/dev/null',
|
|
848
|
+
'tmux -S "$TMUX_SOCKET" select-window -t "$SESSION" 2>/dev/null',
|
|
802
849
|
"",
|
|
803
|
-
"#
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
'
|
|
807
|
-
|
|
808
|
-
"
|
|
809
|
-
"
|
|
810
|
-
"
|
|
811
|
-
"
|
|
812
|
-
"
|
|
813
|
-
"
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
"
|
|
817
|
-
"
|
|
818
|
-
"
|
|
819
|
-
"
|
|
820
|
-
"
|
|
821
|
-
"
|
|
822
|
-
"
|
|
823
|
-
"
|
|
824
|
-
"
|
|
825
|
-
|
|
850
|
+
"# macOS-only: bring iTerm2 to front and select the tab with this client",
|
|
851
|
+
'if [ "$(uname -s)" = "Darwin" ] && command -v osascript >/dev/null 2>&1; then',
|
|
852
|
+
` TTY_SHORT=$(echo "$CLIENT_TTY" | sed 's|/dev/||')`,
|
|
853
|
+
' osascript -e "',
|
|
854
|
+
' tell application \\"iTerm2\\"',
|
|
855
|
+
" activate",
|
|
856
|
+
" repeat with w in windows",
|
|
857
|
+
" tell w",
|
|
858
|
+
" repeat with t in tabs",
|
|
859
|
+
" tell t",
|
|
860
|
+
" repeat with s in sessions",
|
|
861
|
+
" tell s",
|
|
862
|
+
' if tty contains \\"$TTY_SHORT\\" then',
|
|
863
|
+
" select t",
|
|
864
|
+
" return",
|
|
865
|
+
" end if",
|
|
866
|
+
" end tell",
|
|
867
|
+
" end repeat",
|
|
868
|
+
" end tell",
|
|
869
|
+
" end repeat",
|
|
870
|
+
" end tell",
|
|
871
|
+
" end repeat",
|
|
872
|
+
" end tell",
|
|
873
|
+
` " 2>/dev/null || osascript -e 'tell application "iTerm2" to activate' 2>/dev/null`,
|
|
874
|
+
"fi",
|
|
826
875
|
""
|
|
827
876
|
].join("\n");
|
|
828
877
|
}
|
|
829
878
|
});
|
|
830
879
|
|
|
831
880
|
// src/daemon/ask-store.ts
|
|
832
|
-
import { existsSync as
|
|
881
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync9, readdirSync as readdirSync4 } from "fs";
|
|
833
882
|
function readDecisions(cwd2, sessionId2, askId2) {
|
|
834
883
|
const p = askDecisionsPath(cwd2, sessionId2, askId2);
|
|
835
884
|
try {
|
|
836
|
-
return JSON.parse(
|
|
885
|
+
return JSON.parse(readFileSync9(p, { encoding: "utf-8" }));
|
|
837
886
|
} catch (_e) {
|
|
838
887
|
return null;
|
|
839
888
|
}
|
|
@@ -841,7 +890,7 @@ function readDecisions(cwd2, sessionId2, askId2) {
|
|
|
841
890
|
function readProgress(cwd2, sessionId2, askId2) {
|
|
842
891
|
const p = askProgressPath(cwd2, sessionId2, askId2);
|
|
843
892
|
try {
|
|
844
|
-
const data = JSON.parse(
|
|
893
|
+
const data = JSON.parse(readFileSync9(p, { encoding: "utf-8" }));
|
|
845
894
|
if (!Array.isArray(data["responses"])) return null;
|
|
846
895
|
return { responses: data["responses"], savedAt: data["savedAt"] };
|
|
847
896
|
} catch (_e) {
|
|
@@ -856,10 +905,10 @@ function writeOutput(cwd2, sessionId2, askId2, responses, completedAt) {
|
|
|
856
905
|
}
|
|
857
906
|
function readMeta(cwd2, sessionId2, askId2) {
|
|
858
907
|
const p = askMetaPath(cwd2, sessionId2, askId2);
|
|
859
|
-
if (!
|
|
908
|
+
if (!existsSync8(p)) {
|
|
860
909
|
return null;
|
|
861
910
|
}
|
|
862
|
-
return JSON.parse(
|
|
911
|
+
return JSON.parse(readFileSync9(p, "utf-8"));
|
|
863
912
|
}
|
|
864
913
|
async function updateMeta(cwd2, sessionId2, askId2, patch) {
|
|
865
914
|
return withLock(askId2, () => {
|
|
@@ -890,7 +939,7 @@ var single_ask_exports = {};
|
|
|
890
939
|
__export(single_ask_exports, {
|
|
891
940
|
runSingleAsk: () => runSingleAsk
|
|
892
941
|
});
|
|
893
|
-
import { existsSync as
|
|
942
|
+
import { existsSync as existsSync12, watchFile, unwatchFile } from "fs";
|
|
894
943
|
import { mountPanel as mountPanel2 } from "@crouton-kit/humanloop";
|
|
895
944
|
async function runSingleAsk(opts) {
|
|
896
945
|
const { cwd: cwd2, sessionId: sessionId2, askId: askId2 } = opts;
|
|
@@ -936,7 +985,7 @@ async function runSingleAsk(opts) {
|
|
|
936
985
|
};
|
|
937
986
|
const onExternalChange = () => {
|
|
938
987
|
if (exiting) return;
|
|
939
|
-
if (!
|
|
988
|
+
if (!existsSync12(outputPath)) return;
|
|
940
989
|
exit(0);
|
|
941
990
|
};
|
|
942
991
|
let lastResponses = [];
|
|
@@ -990,7 +1039,7 @@ async function runSingleAsk(opts) {
|
|
|
990
1039
|
flushHost(panel.render());
|
|
991
1040
|
});
|
|
992
1041
|
watchFile(outputPath, { interval: 250 }, onExternalChange);
|
|
993
|
-
if (
|
|
1042
|
+
if (existsSync12(outputPath)) {
|
|
994
1043
|
exit(0);
|
|
995
1044
|
return;
|
|
996
1045
|
}
|
|
@@ -1216,12 +1265,11 @@ function autoExpandCycle(state2) {
|
|
|
1216
1265
|
}
|
|
1217
1266
|
|
|
1218
1267
|
// src/tui/app.ts
|
|
1219
|
-
import { readFileSync as
|
|
1268
|
+
import { readFileSync as readFileSync16, existsSync as existsSync11, readdirSync as readdirSync7, statSync as statSync4 } from "fs";
|
|
1220
1269
|
import { join as join15 } from "path";
|
|
1221
1270
|
|
|
1222
1271
|
// src/tui/input.ts
|
|
1223
|
-
import {
|
|
1224
|
-
import { readFileSync as readFileSync10, readdirSync as readdirSync5, statSync as statSync3 } from "fs";
|
|
1272
|
+
import { readFileSync as readFileSync11, readdirSync as readdirSync5, statSync as statSync3 } from "fs";
|
|
1225
1273
|
import { join as join11 } from "path";
|
|
1226
1274
|
|
|
1227
1275
|
// src/shared/session-export.ts
|
|
@@ -1346,6 +1394,96 @@ async function exportSessionToZip(sessionId2, cwd2, options) {
|
|
|
1346
1394
|
return outputPath;
|
|
1347
1395
|
}
|
|
1348
1396
|
|
|
1397
|
+
// src/shared/clipboard.ts
|
|
1398
|
+
init_platform();
|
|
1399
|
+
import { execFileSync, spawnSync } from "child_process";
|
|
1400
|
+
function detectClipboard() {
|
|
1401
|
+
const platform = detectPlatform();
|
|
1402
|
+
if (platform === "darwin") {
|
|
1403
|
+
return {
|
|
1404
|
+
copy: { cmd: "pbcopy", args: [] },
|
|
1405
|
+
paste: { cmd: "pbpaste", args: [] },
|
|
1406
|
+
hint: null
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
if (platform === "wsl") {
|
|
1410
|
+
const copy = hasCommand("clip.exe") ? { cmd: "clip.exe", args: [] } : null;
|
|
1411
|
+
const paste = hasCommand("powershell.exe") ? { cmd: "powershell.exe", args: ["-NoProfile", "-Command", "Get-Clipboard"] } : null;
|
|
1412
|
+
return {
|
|
1413
|
+
copy,
|
|
1414
|
+
paste,
|
|
1415
|
+
hint: copy && paste ? null : "WSL clipboard needs Windows interop. Ensure /mnt/c/Windows/System32 is on PATH (it is by default)."
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1418
|
+
if (platform === "linux") {
|
|
1419
|
+
if (process.env["WAYLAND_DISPLAY"] && hasCommand("wl-copy") && hasCommand("wl-paste")) {
|
|
1420
|
+
return {
|
|
1421
|
+
copy: { cmd: "wl-copy", args: [] },
|
|
1422
|
+
paste: { cmd: "wl-paste", args: ["--no-newline"] },
|
|
1423
|
+
hint: null
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
if (hasCommand("xclip")) {
|
|
1427
|
+
return {
|
|
1428
|
+
copy: { cmd: "xclip", args: ["-selection", "clipboard"] },
|
|
1429
|
+
paste: { cmd: "xclip", args: ["-selection", "clipboard", "-o"] },
|
|
1430
|
+
hint: null
|
|
1431
|
+
};
|
|
1432
|
+
}
|
|
1433
|
+
if (hasCommand("xsel")) {
|
|
1434
|
+
return {
|
|
1435
|
+
copy: { cmd: "xsel", args: ["--clipboard", "--input"] },
|
|
1436
|
+
paste: { cmd: "xsel", args: ["--clipboard", "--output"] },
|
|
1437
|
+
hint: null
|
|
1438
|
+
};
|
|
1439
|
+
}
|
|
1440
|
+
return {
|
|
1441
|
+
copy: null,
|
|
1442
|
+
paste: null,
|
|
1443
|
+
hint: "Install a clipboard tool: `sudo apt install xclip` (or wl-clipboard for Wayland)."
|
|
1444
|
+
};
|
|
1445
|
+
}
|
|
1446
|
+
return {
|
|
1447
|
+
copy: null,
|
|
1448
|
+
paste: null,
|
|
1449
|
+
hint: "Clipboard not supported on this platform."
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1452
|
+
var cached;
|
|
1453
|
+
function cap() {
|
|
1454
|
+
if (!cached) cached = detectClipboard();
|
|
1455
|
+
return cached;
|
|
1456
|
+
}
|
|
1457
|
+
function copyToClipboard(text) {
|
|
1458
|
+
const c = cap();
|
|
1459
|
+
if (!c.copy) {
|
|
1460
|
+
return { reason: c.hint === null ? "No clipboard backend available" : c.hint };
|
|
1461
|
+
}
|
|
1462
|
+
try {
|
|
1463
|
+
execFileSync(c.copy.cmd, c.copy.args, { input: text, stdio: ["pipe", "ignore", "pipe"] });
|
|
1464
|
+
return null;
|
|
1465
|
+
} catch (err) {
|
|
1466
|
+
const msg = err instanceof Error ? err.message.split("\n")[0] : String(err);
|
|
1467
|
+
return { reason: `${c.copy.cmd} failed: ${msg}` };
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
function pasteFromClipboard() {
|
|
1471
|
+
const c = cap();
|
|
1472
|
+
if (!c.paste) {
|
|
1473
|
+
return { reason: c.hint === null ? "No clipboard backend available" : c.hint };
|
|
1474
|
+
}
|
|
1475
|
+
const result = spawnSync(c.paste.cmd, c.paste.args, { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
|
|
1476
|
+
if (result.status !== 0) {
|
|
1477
|
+
const stderr = typeof result.stderr === "string" ? result.stderr.trim() : "";
|
|
1478
|
+
if (stderr.length > 0) {
|
|
1479
|
+
return { reason: `${c.paste.cmd}: ${stderr.split("\n")[0]}` };
|
|
1480
|
+
}
|
|
1481
|
+
return { reason: `${c.paste.cmd} exited ${result.status}` };
|
|
1482
|
+
}
|
|
1483
|
+
const stdout = typeof result.stdout === "string" ? result.stdout : "";
|
|
1484
|
+
return { text: stdout.replace(/\s+$/, "") };
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1349
1487
|
// src/tui/input.ts
|
|
1350
1488
|
init_paths();
|
|
1351
1489
|
|
|
@@ -1392,6 +1530,19 @@ function statusColor(status) {
|
|
|
1392
1530
|
return "white";
|
|
1393
1531
|
}
|
|
1394
1532
|
}
|
|
1533
|
+
var COLOR_ENABLED = process.env["FORCE_COLOR"] === "1" || process.stdout.isTTY === true && process.env["NO_COLOR"] === void 0 && process.env["TERM"] !== "dumb";
|
|
1534
|
+
function wrap(open, close = "\x1B[0m") {
|
|
1535
|
+
return (s) => COLOR_ENABLED ? `${open}${s}${close}` : s;
|
|
1536
|
+
}
|
|
1537
|
+
var bold = wrap("\x1B[1m");
|
|
1538
|
+
var dim = wrap("\x1B[2m");
|
|
1539
|
+
var red = wrap("\x1B[31m");
|
|
1540
|
+
var green = wrap("\x1B[32m");
|
|
1541
|
+
var yellow = wrap("\x1B[33m");
|
|
1542
|
+
var cyan = wrap("\x1B[36m");
|
|
1543
|
+
var gray = wrap("\x1B[90m");
|
|
1544
|
+
var magenta = wrap("\x1B[35m");
|
|
1545
|
+
var white = wrap("\x1B[37m");
|
|
1395
1546
|
|
|
1396
1547
|
// src/tui/lib/format.ts
|
|
1397
1548
|
function formatTimeAgo(iso) {
|
|
@@ -1547,10 +1698,10 @@ function ansiBold(text) {
|
|
|
1547
1698
|
function ansiDim(text) {
|
|
1548
1699
|
return `\x1B[2m${text}\x1B[0m`;
|
|
1549
1700
|
}
|
|
1550
|
-
function ansiColor(text, color,
|
|
1701
|
+
function ansiColor(text, color, bold2 = false) {
|
|
1551
1702
|
const COLOR_MAP = { black: 30, red: 31, green: 32, yellow: 33, blue: 34, magenta: 35, cyan: 36, white: 37, gray: 90 };
|
|
1552
1703
|
const codes = [];
|
|
1553
|
-
if (
|
|
1704
|
+
if (bold2) codes.push(1);
|
|
1554
1705
|
const sgr = COLOR_MAP[color];
|
|
1555
1706
|
if (sgr !== void 0) codes.push(sgr);
|
|
1556
1707
|
if (codes.length === 0) return text;
|
|
@@ -2147,7 +2298,7 @@ function applyColor(result, fields, facePart, mood, opts) {
|
|
|
2147
2298
|
|
|
2148
2299
|
// src/daemon/companion.ts
|
|
2149
2300
|
init_paths();
|
|
2150
|
-
import { existsSync as
|
|
2301
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
2151
2302
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
2152
2303
|
import { dirname as dirname2, join as join5 } from "path";
|
|
2153
2304
|
|
|
@@ -2273,7 +2424,7 @@ var ACHIEVEMENTS = [
|
|
|
2273
2424
|
|
|
2274
2425
|
// src/daemon/companion-memory.ts
|
|
2275
2426
|
init_paths();
|
|
2276
|
-
import { existsSync as
|
|
2427
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, renameSync, writeFileSync as writeFileSync2 } from "fs";
|
|
2277
2428
|
import { dirname, join as join4 } from "path";
|
|
2278
2429
|
import { randomUUID } from "crypto";
|
|
2279
2430
|
import { z } from "zod";
|
|
@@ -3096,7 +3247,7 @@ function stripAnsiForWidth(s) {
|
|
|
3096
3247
|
return s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
3097
3248
|
}
|
|
3098
3249
|
function renderBadgeCard(def, unlock, opts) {
|
|
3099
|
-
const
|
|
3250
|
+
const dim2 = opts?.dim === true || unlock === null;
|
|
3100
3251
|
const art = BADGE_ART[def.id] ?? [];
|
|
3101
3252
|
const lines = [];
|
|
3102
3253
|
const category = def.category.toUpperCase();
|
|
@@ -3110,7 +3261,7 @@ function renderBadgeCard(def, unlock, opts) {
|
|
|
3110
3261
|
const artSlice = art.slice(0, artMaxLines);
|
|
3111
3262
|
for (const artLine of artSlice) {
|
|
3112
3263
|
const centered = centerLine(artLine, CARD_INNER);
|
|
3113
|
-
lines.push(`\u2502${
|
|
3264
|
+
lines.push(`\u2502${dim2 ? dimText(centered) : centered}\u2502`);
|
|
3114
3265
|
}
|
|
3115
3266
|
for (let i = artSlice.length; i < artMaxLines; i++) {
|
|
3116
3267
|
lines.push(`\u2502${" ".repeat(CARD_INNER)}\u2502`);
|
|
@@ -3121,7 +3272,7 @@ function renderBadgeCard(def, unlock, opts) {
|
|
|
3121
3272
|
const descLines = wrapText2(def.description, CARD_INNER - 4);
|
|
3122
3273
|
for (const dl of descLines.slice(0, 2)) {
|
|
3123
3274
|
const centered = centerLine(dl, CARD_INNER);
|
|
3124
|
-
lines.push(`\u2502${
|
|
3275
|
+
lines.push(`\u2502${dim2 ? dimText(centered) : centered}\u2502`);
|
|
3125
3276
|
}
|
|
3126
3277
|
const usedContent = 1 + 1 + artMaxLines + 1 + 1 + Math.min(descLines.length, 2);
|
|
3127
3278
|
const remaining = CARD_HEIGHT - 2 - usedContent;
|
|
@@ -3592,7 +3743,7 @@ function renderCompanionDebugOverlay(buf, rows, cols, companion) {
|
|
|
3592
3743
|
// src/tui/panels/mounted-humanloop.ts
|
|
3593
3744
|
init_ask_store();
|
|
3594
3745
|
init_paths();
|
|
3595
|
-
import { readFileSync as
|
|
3746
|
+
import { readFileSync as readFileSync10 } from "fs";
|
|
3596
3747
|
import { mountPanel } from "@crouton-kit/humanloop";
|
|
3597
3748
|
|
|
3598
3749
|
// src/shared/client.ts
|
|
@@ -3691,7 +3842,7 @@ function mountResolutionPanel(opts, state2) {
|
|
|
3691
3842
|
}, 6e4);
|
|
3692
3843
|
if (res.ok) {
|
|
3693
3844
|
const ansiPath = res.data.ansiPath;
|
|
3694
|
-
const ansi =
|
|
3845
|
+
const ansi = readFileSync10(ansiPath, "utf-8");
|
|
3695
3846
|
state2.visuals.set(qid, { status: "ready", content: ansi, visible: true });
|
|
3696
3847
|
} else {
|
|
3697
3848
|
state2.visuals.set(qid, { status: "error", content: "", visible: true, error: res.error });
|
|
@@ -4277,8 +4428,9 @@ function handleLeaderAction(action, state2, actions) {
|
|
|
4277
4428
|
break;
|
|
4278
4429
|
}
|
|
4279
4430
|
try {
|
|
4280
|
-
const text = actions.promptInPopup("Delete session? (yes
|
|
4281
|
-
|
|
4431
|
+
const text = actions.promptInPopup("Delete session? (y/yes to confirm):");
|
|
4432
|
+
const answer = text?.trim().toLowerCase();
|
|
4433
|
+
if (answer === "y" || answer === "yes") {
|
|
4282
4434
|
actions.sendAndNotify({ type: "delete", sessionId: selectedSessionId, cwd: state2.cwd }, "Session deleted");
|
|
4283
4435
|
} else {
|
|
4284
4436
|
notify(state2, "Delete cancelled");
|
|
@@ -4477,7 +4629,7 @@ function handleLeaderAction(action, state2, actions) {
|
|
|
4477
4629
|
break;
|
|
4478
4630
|
}
|
|
4479
4631
|
try {
|
|
4480
|
-
const content =
|
|
4632
|
+
const content = readFileSync11(latest, "utf-8");
|
|
4481
4633
|
actions.copyToClipboard(content);
|
|
4482
4634
|
notify(state2, `Copied latest report (${content.length} chars)`);
|
|
4483
4635
|
} catch {
|
|
@@ -4638,13 +4790,12 @@ function handleLeaderAction(action, state2, actions) {
|
|
|
4638
4790
|
notify(state2, "No session selected");
|
|
4639
4791
|
break;
|
|
4640
4792
|
}
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
} catch {
|
|
4645
|
-
notify(state2, "pbpaste not available \u2014 macOS only");
|
|
4793
|
+
const pasted = pasteFromClipboard();
|
|
4794
|
+
if ("reason" in pasted) {
|
|
4795
|
+
notify(state2, pasted.reason);
|
|
4646
4796
|
break;
|
|
4647
4797
|
}
|
|
4798
|
+
const exploreInstruction = pasted.text.trim();
|
|
4648
4799
|
if (exploreInstruction.length < 20) {
|
|
4649
4800
|
notify(state2, `Clipboard too short (${exploreInstruction.length} chars; need 20+)`);
|
|
4650
4801
|
break;
|
|
@@ -4660,13 +4811,12 @@ function handleLeaderAction(action, state2, actions) {
|
|
|
4660
4811
|
notify(state2, "No session selected");
|
|
4661
4812
|
break;
|
|
4662
4813
|
}
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
} catch {
|
|
4667
|
-
notify(state2, "pbpaste not available \u2014 macOS only");
|
|
4814
|
+
const pasted = pasteFromClipboard();
|
|
4815
|
+
if ("reason" in pasted) {
|
|
4816
|
+
notify(state2, pasted.reason);
|
|
4668
4817
|
break;
|
|
4669
4818
|
}
|
|
4819
|
+
const debugInstruction = pasted.text.trim();
|
|
4670
4820
|
if (debugInstruction.length < 20) {
|
|
4671
4821
|
notify(state2, `Clipboard too short (${debugInstruction.length} chars; need 20+)`);
|
|
4672
4822
|
break;
|
|
@@ -5446,10 +5596,10 @@ function precomputePrefixes(nodes) {
|
|
|
5446
5596
|
}
|
|
5447
5597
|
|
|
5448
5598
|
// src/tui/lib/reports.ts
|
|
5449
|
-
import { readFileSync as
|
|
5599
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
5450
5600
|
function loadReportContent(report) {
|
|
5451
5601
|
try {
|
|
5452
|
-
return
|
|
5602
|
+
return readFileSync12(report.filePath, "utf-8");
|
|
5453
5603
|
} catch {
|
|
5454
5604
|
return report.summary;
|
|
5455
5605
|
}
|
|
@@ -5477,7 +5627,7 @@ async function inboxList() {
|
|
|
5477
5627
|
init_paths();
|
|
5478
5628
|
import { execSync as execSync3 } from "child_process";
|
|
5479
5629
|
import { join as join12 } from "path";
|
|
5480
|
-
import { readFileSync as
|
|
5630
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, mkdtempSync, rmSync as rmSync4, cpSync as cpSync2, existsSync as existsSync9, mkdirSync as mkdirSync8 } from "fs";
|
|
5481
5631
|
import { tmpdir } from "os";
|
|
5482
5632
|
init_shell();
|
|
5483
5633
|
|
|
@@ -5545,7 +5695,7 @@ function registerDashboardWindow(cwd2) {
|
|
|
5545
5695
|
function setupCompanionPlugin() {
|
|
5546
5696
|
const srcDir = join12(import.meta.dirname, "templates", "companion-plugin");
|
|
5547
5697
|
const destDir = join12(globalDir(), "companion-plugin");
|
|
5548
|
-
if (!
|
|
5698
|
+
if (!existsSync9(destDir)) mkdirSync8(destDir, { recursive: true });
|
|
5549
5699
|
cpSync2(srcDir, destDir, { recursive: true });
|
|
5550
5700
|
return destDir;
|
|
5551
5701
|
}
|
|
@@ -5575,7 +5725,7 @@ function openCompanionPane(cwd2) {
|
|
|
5575
5725
|
const templatePath = join12(import.meta.dirname, "templates", "dashboard-claude.md");
|
|
5576
5726
|
let template;
|
|
5577
5727
|
try {
|
|
5578
|
-
template =
|
|
5728
|
+
template = readFileSync13(templatePath, "utf-8");
|
|
5579
5729
|
} catch {
|
|
5580
5730
|
template = `You are a Sisyphus dashboard companion. Help the user manage multi-agent sessions.
|
|
5581
5731
|
Project: ${cwd2}
|
|
@@ -5604,7 +5754,7 @@ function editInPopup(cwd2, editor, opts) {
|
|
|
5604
5754
|
try {
|
|
5605
5755
|
writeFileSync9(filePath, opts?.content ? opts.content : "", "utf-8");
|
|
5606
5756
|
openEditorPopup(cwd2, editor, filePath, opts?.size);
|
|
5607
|
-
const result =
|
|
5757
|
+
const result = readFileSync13(filePath, "utf-8").trim();
|
|
5608
5758
|
return result || null;
|
|
5609
5759
|
} finally {
|
|
5610
5760
|
rmSync4(tmpDir, { recursive: true, force: true });
|
|
@@ -5620,8 +5770,8 @@ function promptInPopup(prompt, opts) {
|
|
|
5620
5770
|
`tmux display-popup -E -w ${w} -h ${h} ${shellQuote(`bash -c ${shellQuote(script)}`)}`,
|
|
5621
5771
|
{ stdio: "inherit", env: EXEC_ENV }
|
|
5622
5772
|
);
|
|
5623
|
-
if (!
|
|
5624
|
-
const result =
|
|
5773
|
+
if (!existsSync9(outFile)) return null;
|
|
5774
|
+
const result = readFileSync13(outFile, "utf-8").trim();
|
|
5625
5775
|
return result || null;
|
|
5626
5776
|
} finally {
|
|
5627
5777
|
rmSync4(tmpDir, { recursive: true, force: true });
|
|
@@ -5716,18 +5866,12 @@ function openEditorPopup(cwd2, editor, filePath, size) {
|
|
|
5716
5866
|
}
|
|
5717
5867
|
}
|
|
5718
5868
|
|
|
5719
|
-
// src/tui/lib/clipboard.ts
|
|
5720
|
-
import { execSync as execSync4 } from "child_process";
|
|
5721
|
-
function copyToClipboard(text) {
|
|
5722
|
-
execSync4("pbcopy", { input: text });
|
|
5723
|
-
}
|
|
5724
|
-
|
|
5725
5869
|
// src/tui/lib/context.ts
|
|
5726
5870
|
init_paths();
|
|
5727
|
-
import { readFileSync as
|
|
5871
|
+
import { readFileSync as readFileSync14, readdirSync as readdirSync6 } from "fs";
|
|
5728
5872
|
function readFileSafe(filePath) {
|
|
5729
5873
|
try {
|
|
5730
|
-
return
|
|
5874
|
+
return readFileSync14(filePath, "utf-8");
|
|
5731
5875
|
} catch {
|
|
5732
5876
|
return null;
|
|
5733
5877
|
}
|
|
@@ -5830,7 +5974,7 @@ function renderNodeContent(node, maxWidth) {
|
|
|
5830
5974
|
case "session": {
|
|
5831
5975
|
const icon = statusIndicator(node.status);
|
|
5832
5976
|
const color = statusColor(node.status);
|
|
5833
|
-
const
|
|
5977
|
+
const dim2 = node.status === "completed" || node.orphaned === true;
|
|
5834
5978
|
const cyclePart = node.cycleCount > 0 ? `C${node.cycleCount}` : "";
|
|
5835
5979
|
const dur = formatDuration(node.activeMs);
|
|
5836
5980
|
const agopart = node.status === "completed" && node.completedAt ? formatTimeAgo(node.completedAt) : "";
|
|
@@ -5842,7 +5986,7 @@ function renderNodeContent(node, maxWidth) {
|
|
|
5842
5986
|
const displayText = node.name ?? node.task;
|
|
5843
5987
|
const suffixWidth = suffix ? suffix.length + 1 : 0;
|
|
5844
5988
|
const maxLabel = Math.max(8, maxWidth - meta.length - 4 - suffixWidth);
|
|
5845
|
-
return { icon, label: truncate(displayText, maxLabel), meta, color, dim, metaColor, suffix, suffixColor };
|
|
5989
|
+
return { icon, label: truncate(displayText, maxLabel), meta, color, dim: dim2, metaColor, suffix, suffixColor };
|
|
5846
5990
|
}
|
|
5847
5991
|
case "cycle": {
|
|
5848
5992
|
const isRunning = !node.completedAt;
|
|
@@ -5863,7 +6007,7 @@ function renderNodeContent(node, maxWidth) {
|
|
|
5863
6007
|
const color = statusColor(node.status);
|
|
5864
6008
|
const dur = formatDuration(node.activeMs);
|
|
5865
6009
|
const durClr = durationColor(node.activeMs) || void 0;
|
|
5866
|
-
const
|
|
6010
|
+
const dim2 = node.status === "completed" || node.orphaned === true;
|
|
5867
6011
|
const displayName = agentDisplayName({
|
|
5868
6012
|
name: node.name,
|
|
5869
6013
|
id: node.agentId,
|
|
@@ -5878,7 +6022,7 @@ function renderNodeContent(node, maxWidth) {
|
|
|
5878
6022
|
label: truncate(displayName, maxLabel),
|
|
5879
6023
|
meta: dur,
|
|
5880
6024
|
color,
|
|
5881
|
-
dim,
|
|
6025
|
+
dim: dim2,
|
|
5882
6026
|
metaColor: durClr,
|
|
5883
6027
|
suffix,
|
|
5884
6028
|
suffixColor
|
|
@@ -6001,16 +6145,16 @@ function renderTreePanel(buf, rect, nodes, cursorIndex, focused, companion) {
|
|
|
6001
6145
|
const isSelected = realIdx === cursorIndex;
|
|
6002
6146
|
const prefix = node.prefix ?? renderTreePrefix(node, nodes, realIdx);
|
|
6003
6147
|
const contentWidth = innerW;
|
|
6004
|
-
const { icon, label, meta, color, dim, metaColor, suffix, suffixColor } = renderNodeContent(
|
|
6148
|
+
const { icon, label, meta, color, dim: dim2, metaColor, suffix, suffixColor } = renderNodeContent(
|
|
6005
6149
|
node,
|
|
6006
6150
|
contentWidth - prefix.length
|
|
6007
6151
|
);
|
|
6008
6152
|
let content = "";
|
|
6009
6153
|
if (icon) {
|
|
6010
|
-
if (
|
|
6154
|
+
if (dim2) content += `\x1B[2;${colorToSGR(color)}m${icon}\x1B[0m `;
|
|
6011
6155
|
else content += `\x1B[${colorToSGR(color)}m${icon}\x1B[0m `;
|
|
6012
6156
|
}
|
|
6013
|
-
if (
|
|
6157
|
+
if (dim2) content += `\x1B[2m${label}\x1B[0m`;
|
|
6014
6158
|
else content += label;
|
|
6015
6159
|
if (meta) {
|
|
6016
6160
|
if (metaColor) content += ` \x1B[${colorToSGR(metaColor)}m${meta}\x1B[0m`;
|
|
@@ -6021,9 +6165,9 @@ function renderTreePanel(buf, rect, nodes, cursorIndex, focused, companion) {
|
|
|
6021
6165
|
}
|
|
6022
6166
|
let line = prefix;
|
|
6023
6167
|
if (isSelected) {
|
|
6024
|
-
const
|
|
6168
|
+
const bold2 = "\x1B[1m";
|
|
6025
6169
|
const inverse = focused ? "\x1B[7m" : "";
|
|
6026
|
-
line += `${inverse}${
|
|
6170
|
+
line += `${inverse}${bold2}${content}\x1B[0m`;
|
|
6027
6171
|
} else {
|
|
6028
6172
|
line += content;
|
|
6029
6173
|
}
|
|
@@ -6106,7 +6250,7 @@ function buildOrchestratorNode(cycle, agents, width, bright, showConnectorBottom
|
|
|
6106
6250
|
const lines = [];
|
|
6107
6251
|
const inner = width - 2;
|
|
6108
6252
|
const bg2 = BG_TINTS.yellow;
|
|
6109
|
-
const
|
|
6253
|
+
const dim2 = !bright;
|
|
6110
6254
|
const isRunning = !cycle.completedAt;
|
|
6111
6255
|
const icon = isRunning ? "\u25CF" : "\u25CB";
|
|
6112
6256
|
const cycleLabel = `C${cycle.cycle}`;
|
|
@@ -6124,63 +6268,63 @@ function buildOrchestratorNode(cycle, agents, width, bright, showConnectorBottom
|
|
|
6124
6268
|
const leftW = stringWidth5(leftContent);
|
|
6125
6269
|
const rightW = stringWidth5(rightText);
|
|
6126
6270
|
const gap = Math.max(1, inner - 2 - leftW - rightW);
|
|
6127
|
-
lines.push([seg("\u256D" + "\u2500".repeat(inner) + "\u256E", { color: "yellow", dim })]);
|
|
6271
|
+
lines.push([seg("\u256D" + "\u2500".repeat(inner) + "\u256E", { color: "yellow", dim: dim2 })]);
|
|
6128
6272
|
const contentSegs = [
|
|
6129
|
-
seg("\u2502", { color: "yellow", dim }),
|
|
6130
|
-
seg(" " + icon + " ", { bg: bg2, color: isRunning ? "green" : void 0, dim: !isRunning &&
|
|
6131
|
-
seg(cycleLabel, { bg: bg2, dim, bold: bright }),
|
|
6273
|
+
seg("\u2502", { color: "yellow", dim: dim2 }),
|
|
6274
|
+
seg(" " + icon + " ", { bg: bg2, color: isRunning ? "green" : void 0, dim: !isRunning && dim2, bold: bright }),
|
|
6275
|
+
seg(cycleLabel, { bg: bg2, dim: dim2, bold: bright }),
|
|
6132
6276
|
seg(" ", { bg: bg2 }),
|
|
6133
|
-
seg(modeLabel, { bg: bg2, color: mColor, dim }),
|
|
6277
|
+
seg(modeLabel, { bg: bg2, color: mColor, dim: dim2 }),
|
|
6134
6278
|
seg(" ".repeat(gap), { bg: bg2 })
|
|
6135
6279
|
];
|
|
6136
6280
|
if (isRunning && bright) {
|
|
6137
6281
|
contentSegs.push(seg(rightText, { bg: bg2, color: "green", bold: true }));
|
|
6138
6282
|
} else {
|
|
6139
|
-
contentSegs.push(seg(rightText, { bg: bg2, dim }));
|
|
6283
|
+
contentSegs.push(seg(rightText, { bg: bg2, dim: dim2 }));
|
|
6140
6284
|
}
|
|
6141
6285
|
contentSegs.push(seg(" ", { bg: bg2 }));
|
|
6142
6286
|
const usedWidth = 1 + 1 + 1 + 1 + stringWidth5(cycleLabel) + 2 + stringWidth5(modeLabel) + gap + stringWidth5(rightText) + 1;
|
|
6143
6287
|
if (usedWidth < inner) {
|
|
6144
6288
|
contentSegs.push(seg(" ".repeat(inner - usedWidth), { bg: bg2 }));
|
|
6145
6289
|
}
|
|
6146
|
-
contentSegs.push(seg("\u2502", { color: "yellow", dim }));
|
|
6290
|
+
contentSegs.push(seg("\u2502", { color: "yellow", dim: dim2 }));
|
|
6147
6291
|
lines.push(contentSegs);
|
|
6148
6292
|
if (agents.length > 0) {
|
|
6149
6293
|
const running = agents.filter((a) => a.status === "running").length;
|
|
6150
6294
|
const done = agents.filter((a) => a.status === "completed").length;
|
|
6151
6295
|
const failed = agents.filter((a) => a.status === "killed" || a.status === "crashed").length;
|
|
6152
6296
|
const parts = [
|
|
6153
|
-
seg("\u2502", { color: "yellow", dim }),
|
|
6297
|
+
seg("\u2502", { color: "yellow", dim: dim2 }),
|
|
6154
6298
|
seg(` ${agents.length} agent${agents.length !== 1 ? "s" : ""}: `, { bg: bg2, dim: true })
|
|
6155
6299
|
];
|
|
6156
|
-
if (running > 0) parts.push(seg(`${running}\u25B6 `, { bg: bg2, color: "green", dim }));
|
|
6157
|
-
if (done > 0) parts.push(seg(`${done}\u2713 `, { bg: bg2, color: "cyan", dim }));
|
|
6158
|
-
if (failed > 0) parts.push(seg(`${failed}\u2715 `, { bg: bg2, color: "red", dim }));
|
|
6300
|
+
if (running > 0) parts.push(seg(`${running}\u25B6 `, { bg: bg2, color: "green", dim: dim2 }));
|
|
6301
|
+
if (done > 0) parts.push(seg(`${done}\u2713 `, { bg: bg2, color: "cyan", dim: dim2 }));
|
|
6302
|
+
if (failed > 0) parts.push(seg(`${failed}\u2715 `, { bg: bg2, color: "red", dim: dim2 }));
|
|
6159
6303
|
const labelLen = ` ${agents.length} agent${agents.length !== 1 ? "s" : ""}: `.length;
|
|
6160
6304
|
const countLen = (running > 0 ? `${running}\u25B6 `.length : 0) + (done > 0 ? `${done}\u2713 `.length : 0) + (failed > 0 ? `${failed}\u2715 `.length : 0);
|
|
6161
6305
|
const remaining = Math.max(0, inner - labelLen - countLen);
|
|
6162
6306
|
parts.push(seg(" ".repeat(remaining), { bg: bg2 }));
|
|
6163
|
-
parts.push(seg("\u2502", { color: "yellow", dim }));
|
|
6307
|
+
parts.push(seg("\u2502", { color: "yellow", dim: dim2 }));
|
|
6164
6308
|
lines.push(parts);
|
|
6165
6309
|
}
|
|
6166
6310
|
if (showConnectorBottom) {
|
|
6167
6311
|
const mid = Math.floor(inner / 2);
|
|
6168
6312
|
const left = mid;
|
|
6169
6313
|
const right = inner - mid - 1;
|
|
6170
|
-
lines.push([seg("\u2570" + "\u2500".repeat(left) + "\u252C" + "\u2500".repeat(right) + "\u256F", { color: "yellow", dim })]);
|
|
6314
|
+
lines.push([seg("\u2570" + "\u2500".repeat(left) + "\u252C" + "\u2500".repeat(right) + "\u256F", { color: "yellow", dim: dim2 })]);
|
|
6171
6315
|
} else {
|
|
6172
|
-
lines.push([seg("\u2570" + "\u2500".repeat(inner) + "\u256F", { color: "yellow", dim })]);
|
|
6316
|
+
lines.push([seg("\u2570" + "\u2500".repeat(inner) + "\u256F", { color: "yellow", dim: dim2 })]);
|
|
6173
6317
|
}
|
|
6174
6318
|
return lines;
|
|
6175
6319
|
}
|
|
6176
6320
|
function stemCol(width) {
|
|
6177
6321
|
return Math.floor(width / 2);
|
|
6178
6322
|
}
|
|
6179
|
-
function buildVerticalConnector(width,
|
|
6323
|
+
function buildVerticalConnector(width, dim2) {
|
|
6180
6324
|
const col = stemCol(width);
|
|
6181
6325
|
return [
|
|
6182
6326
|
seg(" ".repeat(col)),
|
|
6183
|
-
seg("\u2502", { dim })
|
|
6327
|
+
seg("\u2502", { dim: dim2 })
|
|
6184
6328
|
];
|
|
6185
6329
|
}
|
|
6186
6330
|
function buildBranchConnector(boxWidth, count, totalWidth, direction) {
|
|
@@ -6286,9 +6430,9 @@ function buildAgentBoxRows(agents, boxWidth, totalWidth, bright, maxPerRow) {
|
|
|
6286
6430
|
const a = rowAgents[i];
|
|
6287
6431
|
const isError = a.status === "killed" || a.status === "crashed";
|
|
6288
6432
|
const borderColor = isError ? "red" : resolveColor(a.color);
|
|
6289
|
-
const
|
|
6433
|
+
const dim2 = !bright;
|
|
6290
6434
|
const mid = Math.floor(innerW / 2);
|
|
6291
|
-
topSegs.push(seg("\u256D" + "\u2500".repeat(mid) + "\u2534" + "\u2500".repeat(innerW - mid - 1) + "\u256E", { color: borderColor, dim }));
|
|
6435
|
+
topSegs.push(seg("\u256D" + "\u2500".repeat(mid) + "\u2534" + "\u2500".repeat(innerW - mid - 1) + "\u256E", { color: borderColor, dim: dim2 }));
|
|
6292
6436
|
}
|
|
6293
6437
|
lines.push(topSegs);
|
|
6294
6438
|
const line1Segs = [];
|
|
@@ -6297,14 +6441,14 @@ function buildAgentBoxRows(agents, boxWidth, totalWidth, bright, maxPerRow) {
|
|
|
6297
6441
|
const isError = a.status === "killed" || a.status === "crashed";
|
|
6298
6442
|
const borderColor = isError ? "red" : resolveColor(a.color);
|
|
6299
6443
|
const agentBg = BG_TINTS[isError ? "red" : resolveColor(a.color)] ?? BG_TINTS.gray;
|
|
6300
|
-
const
|
|
6444
|
+
const dim2 = !bright;
|
|
6301
6445
|
const icon = agentStatusIcon(a.status);
|
|
6302
6446
|
const iconColor = statusColor(a.status);
|
|
6303
6447
|
const idPadded = padTo(` ${a.id}`, innerW - stringWidth5(icon));
|
|
6304
|
-
line1Segs.push(seg("\u2502", { color: borderColor, dim }));
|
|
6448
|
+
line1Segs.push(seg("\u2502", { color: borderColor, dim: dim2 }));
|
|
6305
6449
|
line1Segs.push(seg(icon, { bg: agentBg, color: iconColor, bold: bright }));
|
|
6306
|
-
line1Segs.push(seg(idPadded, { bg: agentBg, dim, bold: bright && a.status === "running" }));
|
|
6307
|
-
line1Segs.push(seg("\u2502", { color: borderColor, dim }));
|
|
6450
|
+
line1Segs.push(seg(idPadded, { bg: agentBg, dim: dim2, bold: bright && a.status === "running" }));
|
|
6451
|
+
line1Segs.push(seg("\u2502", { color: borderColor, dim: dim2 }));
|
|
6308
6452
|
}
|
|
6309
6453
|
lines.push(line1Segs);
|
|
6310
6454
|
const line2Segs = [];
|
|
@@ -6313,11 +6457,11 @@ function buildAgentBoxRows(agents, boxWidth, totalWidth, bright, maxPerRow) {
|
|
|
6313
6457
|
const isError = a.status === "killed" || a.status === "crashed";
|
|
6314
6458
|
const borderColor = isError ? "red" : resolveColor(a.color);
|
|
6315
6459
|
const agentBg = BG_TINTS[isError ? "red" : resolveColor(a.color)] ?? BG_TINTS.gray;
|
|
6316
|
-
const
|
|
6460
|
+
const dim2 = !bright;
|
|
6317
6461
|
const name = padTo(agentDisplayName(a), innerW);
|
|
6318
|
-
line2Segs.push(seg("\u2502", { color: borderColor, dim }));
|
|
6319
|
-
line2Segs.push(seg(name, { bg: agentBg, dim }));
|
|
6320
|
-
line2Segs.push(seg("\u2502", { color: borderColor, dim }));
|
|
6462
|
+
line2Segs.push(seg("\u2502", { color: borderColor, dim: dim2 }));
|
|
6463
|
+
line2Segs.push(seg(name, { bg: agentBg, dim: dim2 }));
|
|
6464
|
+
line2Segs.push(seg("\u2502", { color: borderColor, dim: dim2 }));
|
|
6321
6465
|
}
|
|
6322
6466
|
lines.push(line2Segs);
|
|
6323
6467
|
const line3Segs = [];
|
|
@@ -6326,7 +6470,7 @@ function buildAgentBoxRows(agents, boxWidth, totalWidth, bright, maxPerRow) {
|
|
|
6326
6470
|
const isError = a.status === "killed" || a.status === "crashed";
|
|
6327
6471
|
const borderColor = isError ? "red" : resolveColor(a.color);
|
|
6328
6472
|
const agentBg = BG_TINTS[isError ? "red" : resolveColor(a.color)] ?? BG_TINTS.gray;
|
|
6329
|
-
const
|
|
6473
|
+
const dim2 = !bright;
|
|
6330
6474
|
const dur = formatDuration(a.activeMs);
|
|
6331
6475
|
const durClr = isError ? "red" : durationColor(a.activeMs) || void 0;
|
|
6332
6476
|
let durText;
|
|
@@ -6338,9 +6482,9 @@ function buildAgentBoxRows(agents, boxWidth, totalWidth, bright, maxPerRow) {
|
|
|
6338
6482
|
} else {
|
|
6339
6483
|
durText = padTo(dur, innerW);
|
|
6340
6484
|
}
|
|
6341
|
-
line3Segs.push(seg("\u2502", { color: borderColor, dim }));
|
|
6342
|
-
line3Segs.push(seg(durText, { bg: agentBg, dim, color: durClr }));
|
|
6343
|
-
line3Segs.push(seg("\u2502", { color: borderColor, dim }));
|
|
6485
|
+
line3Segs.push(seg("\u2502", { color: borderColor, dim: dim2 }));
|
|
6486
|
+
line3Segs.push(seg(durText, { bg: agentBg, dim: dim2, color: durClr }));
|
|
6487
|
+
line3Segs.push(seg("\u2502", { color: borderColor, dim: dim2 }));
|
|
6344
6488
|
}
|
|
6345
6489
|
lines.push(line3Segs);
|
|
6346
6490
|
const line4Segs = [];
|
|
@@ -6349,11 +6493,11 @@ function buildAgentBoxRows(agents, boxWidth, totalWidth, bright, maxPerRow) {
|
|
|
6349
6493
|
const isError = a.status === "killed" || a.status === "crashed";
|
|
6350
6494
|
const borderColor = isError ? "red" : resolveColor(a.color);
|
|
6351
6495
|
const agentBg = BG_TINTS[isError ? "red" : resolveColor(a.color)] ?? BG_TINTS.gray;
|
|
6352
|
-
const
|
|
6496
|
+
const dim2 = !bright;
|
|
6353
6497
|
const summary = padTo(agentSummary(a, innerW), innerW);
|
|
6354
|
-
line4Segs.push(seg("\u2502", { color: borderColor, dim }));
|
|
6498
|
+
line4Segs.push(seg("\u2502", { color: borderColor, dim: dim2 }));
|
|
6355
6499
|
line4Segs.push(seg(summary, { bg: agentBg, dim: true }));
|
|
6356
|
-
line4Segs.push(seg("\u2502", { color: borderColor, dim }));
|
|
6500
|
+
line4Segs.push(seg("\u2502", { color: borderColor, dim: dim2 }));
|
|
6357
6501
|
}
|
|
6358
6502
|
lines.push(line4Segs);
|
|
6359
6503
|
const botSegs = [];
|
|
@@ -6361,11 +6505,11 @@ function buildAgentBoxRows(agents, boxWidth, totalWidth, bright, maxPerRow) {
|
|
|
6361
6505
|
for (const a of rowAgents) {
|
|
6362
6506
|
const isError = a.status === "killed" || a.status === "crashed";
|
|
6363
6507
|
const borderColor = isError ? "red" : resolveColor(a.color);
|
|
6364
|
-
const
|
|
6508
|
+
const dim2 = !bright;
|
|
6365
6509
|
const mid = Math.floor(innerW / 2);
|
|
6366
6510
|
const left = mid;
|
|
6367
6511
|
const right = innerW - mid - 1;
|
|
6368
|
-
botSegs.push(seg("\u2570" + "\u2500".repeat(left) + "\u252C" + "\u2500".repeat(right) + "\u256F", { color: borderColor, dim }));
|
|
6512
|
+
botSegs.push(seg("\u2570" + "\u2500".repeat(left) + "\u252C" + "\u2500".repeat(right) + "\u256F", { color: borderColor, dim: dim2 }));
|
|
6369
6513
|
}
|
|
6370
6514
|
lines.push(botSegs);
|
|
6371
6515
|
}
|
|
@@ -6406,19 +6550,19 @@ function buildYieldNode(prompt, width, bright, known) {
|
|
|
6406
6550
|
const lines = [];
|
|
6407
6551
|
const inner = width - 2;
|
|
6408
6552
|
const bg2 = BG_TINTS.gray;
|
|
6409
|
-
const
|
|
6553
|
+
const dim2 = !bright;
|
|
6410
6554
|
if (known && prompt) {
|
|
6411
|
-
lines.push([seg("\u256D" + "\u2500".repeat(inner) + "\u256E", { color: "yellow", dim })]);
|
|
6555
|
+
lines.push([seg("\u256D" + "\u2500".repeat(inner) + "\u256E", { color: "yellow", dim: dim2 })]);
|
|
6412
6556
|
const wrapped = wrapText(prompt, inner - 2);
|
|
6413
6557
|
for (const wl of wrapped) {
|
|
6414
6558
|
const padded = padTo(" " + wl, inner);
|
|
6415
6559
|
lines.push([
|
|
6416
|
-
seg("\u2502", { color: "yellow", dim }),
|
|
6560
|
+
seg("\u2502", { color: "yellow", dim: dim2 }),
|
|
6417
6561
|
seg(padded, { bg: bg2, dim: true }),
|
|
6418
|
-
seg("\u2502", { color: "yellow", dim })
|
|
6562
|
+
seg("\u2502", { color: "yellow", dim: dim2 })
|
|
6419
6563
|
]);
|
|
6420
6564
|
}
|
|
6421
|
-
lines.push([seg("\u2570" + "\u2500".repeat(inner) + "\u256F", { color: "yellow", dim })]);
|
|
6565
|
+
lines.push([seg("\u2570" + "\u2500".repeat(inner) + "\u256F", { color: "yellow", dim: dim2 })]);
|
|
6422
6566
|
} else {
|
|
6423
6567
|
lines.push([seg("\u256D" + "\u2500".repeat(inner) + "\u256E", { dim: true })]);
|
|
6424
6568
|
const placeholder = padTo(" awaiting agents\u2026", inner);
|
|
@@ -8264,13 +8408,13 @@ init_paths();
|
|
|
8264
8408
|
|
|
8265
8409
|
// src/tui/lib/popup-compose.ts
|
|
8266
8410
|
init_shell();
|
|
8267
|
-
import { execSync as
|
|
8268
|
-
import { mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync10, readFileSync as
|
|
8411
|
+
import { execSync as execSync4 } from "child_process";
|
|
8412
|
+
import { mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync10, readFileSync as readFileSync15, rmSync as rmSync5 } from "fs";
|
|
8269
8413
|
import { join as join14 } from "path";
|
|
8270
8414
|
import { tmpdir as tmpdir2 } from "os";
|
|
8271
8415
|
|
|
8272
8416
|
// src/shared/sisyphus-init-lua.ts
|
|
8273
|
-
import { mkdirSync as mkdirSync9, existsSync as
|
|
8417
|
+
import { mkdirSync as mkdirSync9, existsSync as existsSync10, cpSync as cpSync3 } from "fs";
|
|
8274
8418
|
import { join as join13 } from "path";
|
|
8275
8419
|
import { homedir as homedir4 } from "os";
|
|
8276
8420
|
var initLuaEnsured = false;
|
|
@@ -8280,7 +8424,7 @@ function ensureSisyphusInitLua() {
|
|
|
8280
8424
|
try {
|
|
8281
8425
|
const destDir = join13(homedir4(), ".config", "sisyphus");
|
|
8282
8426
|
const destPath = join13(destDir, "init.lua");
|
|
8283
|
-
if (
|
|
8427
|
+
if (existsSync10(destPath)) return;
|
|
8284
8428
|
mkdirSync9(destDir, { recursive: true });
|
|
8285
8429
|
const srcPath = join13(import.meta.dirname, "templates", "sisyphus-init.lua");
|
|
8286
8430
|
cpSync3(srcPath, destPath);
|
|
@@ -8295,13 +8439,13 @@ function composeViaPopup(action, state2, actions) {
|
|
|
8295
8439
|
try {
|
|
8296
8440
|
writeFileSync10(tempFile, "", "utf-8");
|
|
8297
8441
|
const cmd = `NVIM_APPNAME=sisyphus nvim ${shellQuote(tempFile)}`;
|
|
8298
|
-
|
|
8442
|
+
execSync4(
|
|
8299
8443
|
`tmux display-popup -E -w 90% -h 90% -d ${shellQuote(state2.cwd)} ${shellQuote(cmd)}`,
|
|
8300
8444
|
{ stdio: "inherit", env: EXEC_ENV }
|
|
8301
8445
|
);
|
|
8302
8446
|
let rawContent = "";
|
|
8303
8447
|
try {
|
|
8304
|
-
rawContent =
|
|
8448
|
+
rawContent = readFileSync15(tempFile, "utf-8");
|
|
8305
8449
|
} catch {
|
|
8306
8450
|
}
|
|
8307
8451
|
const required = !OPTIONAL_COMPOSE.has(action.kind);
|
|
@@ -8326,7 +8470,7 @@ function getCompanion() {
|
|
|
8326
8470
|
const { mtimeMs } = statSync4(companionPath());
|
|
8327
8471
|
if (_cachedCompanion && mtimeMs === _companionMtime) return _cachedCompanion;
|
|
8328
8472
|
_companionMtime = mtimeMs;
|
|
8329
|
-
_cachedCompanion = normalizeCompanion(JSON.parse(
|
|
8473
|
+
_cachedCompanion = normalizeCompanion(JSON.parse(readFileSync16(companionPath(), "utf-8")));
|
|
8330
8474
|
return _cachedCompanion;
|
|
8331
8475
|
} catch {
|
|
8332
8476
|
return _cachedCompanion;
|
|
@@ -8448,40 +8592,40 @@ function startApp(state2, cleanup2) {
|
|
|
8448
8592
|
selectedSession = statusRes.data?.session ?? null;
|
|
8449
8593
|
}
|
|
8450
8594
|
if (selectedSession?.tmuxWindowId) {
|
|
8451
|
-
const
|
|
8452
|
-
paneAlive =
|
|
8595
|
+
const cached2 = sessions.find((s) => s.id === state2.selectedSessionId);
|
|
8596
|
+
paneAlive = cached2?.windowAlive ?? false;
|
|
8453
8597
|
}
|
|
8454
8598
|
try {
|
|
8455
8599
|
const pp = roadmapPath(state2.cwd, state2.selectedSessionId);
|
|
8456
|
-
if (
|
|
8457
|
-
planContent =
|
|
8600
|
+
if (existsSync11(pp)) {
|
|
8601
|
+
planContent = readFileSync16(pp, "utf-8");
|
|
8458
8602
|
}
|
|
8459
8603
|
} catch {
|
|
8460
8604
|
}
|
|
8461
8605
|
try {
|
|
8462
8606
|
const gp = goalPath(state2.cwd, state2.selectedSessionId);
|
|
8463
|
-
if (
|
|
8464
|
-
goalContent =
|
|
8607
|
+
if (existsSync11(gp)) {
|
|
8608
|
+
goalContent = readFileSync16(gp, "utf-8");
|
|
8465
8609
|
}
|
|
8466
8610
|
} catch {
|
|
8467
8611
|
}
|
|
8468
8612
|
try {
|
|
8469
8613
|
const sp = strategyPath(state2.cwd, state2.selectedSessionId);
|
|
8470
|
-
if (
|
|
8471
|
-
strategyContent =
|
|
8614
|
+
if (existsSync11(sp)) {
|
|
8615
|
+
strategyContent = readFileSync16(sp, "utf-8");
|
|
8472
8616
|
}
|
|
8473
8617
|
} catch {
|
|
8474
8618
|
}
|
|
8475
8619
|
try {
|
|
8476
8620
|
const cp = join15(contextDir(state2.cwd, state2.selectedSessionId), "completion-summary.md");
|
|
8477
|
-
if (
|
|
8478
|
-
completionSummaryContent =
|
|
8621
|
+
if (existsSync11(cp)) {
|
|
8622
|
+
completionSummaryContent = readFileSync16(cp, "utf-8");
|
|
8479
8623
|
}
|
|
8480
8624
|
} catch {
|
|
8481
8625
|
}
|
|
8482
8626
|
try {
|
|
8483
8627
|
const ld = logsDir(state2.cwd, state2.selectedSessionId);
|
|
8484
|
-
if (
|
|
8628
|
+
if (existsSync11(ld)) {
|
|
8485
8629
|
if (state2.selectedSessionId !== cachedLogSessionId) {
|
|
8486
8630
|
cachedLogFiles = /* @__PURE__ */ new Map();
|
|
8487
8631
|
cachedLogSessionId = state2.selectedSessionId;
|
|
@@ -8494,11 +8638,11 @@ function startApp(state2, cleanup2) {
|
|
|
8494
8638
|
for (const f of files) {
|
|
8495
8639
|
const filePath = join15(ld, f);
|
|
8496
8640
|
const mtime = statSync4(filePath).mtimeMs;
|
|
8497
|
-
const
|
|
8498
|
-
if (!
|
|
8641
|
+
const cached2 = cachedLogFiles.get(f);
|
|
8642
|
+
if (!cached2 || cached2.mtime !== mtime) {
|
|
8499
8643
|
const match = f.match(/cycle-(\d+)\.md$/);
|
|
8500
8644
|
const cycle = match ? parseInt(match[1], 10) : 0;
|
|
8501
|
-
const content =
|
|
8645
|
+
const content = readFileSync16(filePath, "utf-8");
|
|
8502
8646
|
cachedLogFiles.set(f, { mtime, cycle, content });
|
|
8503
8647
|
}
|
|
8504
8648
|
}
|
|
@@ -8512,7 +8656,7 @@ function startApp(state2, cleanup2) {
|
|
|
8512
8656
|
}
|
|
8513
8657
|
try {
|
|
8514
8658
|
const cd = contextDir(state2.cwd, state2.selectedSessionId);
|
|
8515
|
-
if (
|
|
8659
|
+
if (existsSync11(cd)) {
|
|
8516
8660
|
const entries = readdirSync7(cd, { withFileTypes: true }).filter((e) => !e.name.startsWith("."));
|
|
8517
8661
|
const flat = [];
|
|
8518
8662
|
for (const e of entries) {
|
|
@@ -8532,8 +8676,8 @@ function startApp(state2, cleanup2) {
|
|
|
8532
8676
|
}
|
|
8533
8677
|
try {
|
|
8534
8678
|
const dp = digestPath(state2.cwd, state2.selectedSessionId);
|
|
8535
|
-
if (
|
|
8536
|
-
const raw = JSON.parse(
|
|
8679
|
+
if (existsSync11(dp)) {
|
|
8680
|
+
const raw = JSON.parse(readFileSync16(dp, "utf-8"));
|
|
8537
8681
|
if (raw && typeof raw.recentWork === "string" && typeof raw.currentActivity === "string" && typeof raw.whatsNext === "string" && Array.isArray(raw.unusualEvents)) {
|
|
8538
8682
|
digestData = raw;
|
|
8539
8683
|
}
|
|
@@ -8676,8 +8820,8 @@ function startApp(state2, cleanup2) {
|
|
|
8676
8820
|
if (cursorNode.filePath !== cachedContextFilePath) {
|
|
8677
8821
|
cachedContextFilePath = cursorNode.filePath;
|
|
8678
8822
|
try {
|
|
8679
|
-
if (
|
|
8680
|
-
cachedContextFileContent =
|
|
8823
|
+
if (existsSync11(cursorNode.filePath)) {
|
|
8824
|
+
cachedContextFileContent = readFileSync16(cursorNode.filePath, "utf-8");
|
|
8681
8825
|
} else {
|
|
8682
8826
|
cachedContextFileContent = null;
|
|
8683
8827
|
}
|
|
@@ -8821,7 +8965,10 @@ function startApp(state2, cleanup2) {
|
|
|
8821
8965
|
openLogPopup,
|
|
8822
8966
|
openShellPopup,
|
|
8823
8967
|
openInFileManager,
|
|
8824
|
-
copyToClipboard
|
|
8968
|
+
copyToClipboard: (text) => {
|
|
8969
|
+
const err = copyToClipboard(text);
|
|
8970
|
+
if (err !== null) notify(state2, err.reason);
|
|
8971
|
+
},
|
|
8825
8972
|
buildSessionContext,
|
|
8826
8973
|
resolveEditor: () => {
|
|
8827
8974
|
if (config.editor) return config.editor;
|