sisyphi 1.1.38 → 1.1.39
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.js +620 -311
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +236 -172
- package/dist/daemon.js.map +1 -1
- package/dist/tui.js +235 -102
- 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 {};
|
|
@@ -691,7 +738,7 @@ var init_config = __esm({
|
|
|
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
|
|
|
@@ -2147,7 +2285,7 @@ function applyColor(result, fields, facePart, mood, opts) {
|
|
|
2147
2285
|
|
|
2148
2286
|
// src/daemon/companion.ts
|
|
2149
2287
|
init_paths();
|
|
2150
|
-
import { existsSync as
|
|
2288
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
2151
2289
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
2152
2290
|
import { dirname as dirname2, join as join5 } from "path";
|
|
2153
2291
|
|
|
@@ -2273,7 +2411,7 @@ var ACHIEVEMENTS = [
|
|
|
2273
2411
|
|
|
2274
2412
|
// src/daemon/companion-memory.ts
|
|
2275
2413
|
init_paths();
|
|
2276
|
-
import { existsSync as
|
|
2414
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, renameSync, writeFileSync as writeFileSync2 } from "fs";
|
|
2277
2415
|
import { dirname, join as join4 } from "path";
|
|
2278
2416
|
import { randomUUID } from "crypto";
|
|
2279
2417
|
import { z } from "zod";
|
|
@@ -3592,7 +3730,7 @@ function renderCompanionDebugOverlay(buf, rows, cols, companion) {
|
|
|
3592
3730
|
// src/tui/panels/mounted-humanloop.ts
|
|
3593
3731
|
init_ask_store();
|
|
3594
3732
|
init_paths();
|
|
3595
|
-
import { readFileSync as
|
|
3733
|
+
import { readFileSync as readFileSync10 } from "fs";
|
|
3596
3734
|
import { mountPanel } from "@crouton-kit/humanloop";
|
|
3597
3735
|
|
|
3598
3736
|
// src/shared/client.ts
|
|
@@ -3691,7 +3829,7 @@ function mountResolutionPanel(opts, state2) {
|
|
|
3691
3829
|
}, 6e4);
|
|
3692
3830
|
if (res.ok) {
|
|
3693
3831
|
const ansiPath = res.data.ansiPath;
|
|
3694
|
-
const ansi =
|
|
3832
|
+
const ansi = readFileSync10(ansiPath, "utf-8");
|
|
3695
3833
|
state2.visuals.set(qid, { status: "ready", content: ansi, visible: true });
|
|
3696
3834
|
} else {
|
|
3697
3835
|
state2.visuals.set(qid, { status: "error", content: "", visible: true, error: res.error });
|
|
@@ -4477,7 +4615,7 @@ function handleLeaderAction(action, state2, actions) {
|
|
|
4477
4615
|
break;
|
|
4478
4616
|
}
|
|
4479
4617
|
try {
|
|
4480
|
-
const content =
|
|
4618
|
+
const content = readFileSync11(latest, "utf-8");
|
|
4481
4619
|
actions.copyToClipboard(content);
|
|
4482
4620
|
notify(state2, `Copied latest report (${content.length} chars)`);
|
|
4483
4621
|
} catch {
|
|
@@ -4638,13 +4776,12 @@ function handleLeaderAction(action, state2, actions) {
|
|
|
4638
4776
|
notify(state2, "No session selected");
|
|
4639
4777
|
break;
|
|
4640
4778
|
}
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
} catch {
|
|
4645
|
-
notify(state2, "pbpaste not available \u2014 macOS only");
|
|
4779
|
+
const pasted = pasteFromClipboard();
|
|
4780
|
+
if ("reason" in pasted) {
|
|
4781
|
+
notify(state2, pasted.reason);
|
|
4646
4782
|
break;
|
|
4647
4783
|
}
|
|
4784
|
+
const exploreInstruction = pasted.text.trim();
|
|
4648
4785
|
if (exploreInstruction.length < 20) {
|
|
4649
4786
|
notify(state2, `Clipboard too short (${exploreInstruction.length} chars; need 20+)`);
|
|
4650
4787
|
break;
|
|
@@ -4660,13 +4797,12 @@ function handleLeaderAction(action, state2, actions) {
|
|
|
4660
4797
|
notify(state2, "No session selected");
|
|
4661
4798
|
break;
|
|
4662
4799
|
}
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
} catch {
|
|
4667
|
-
notify(state2, "pbpaste not available \u2014 macOS only");
|
|
4800
|
+
const pasted = pasteFromClipboard();
|
|
4801
|
+
if ("reason" in pasted) {
|
|
4802
|
+
notify(state2, pasted.reason);
|
|
4668
4803
|
break;
|
|
4669
4804
|
}
|
|
4805
|
+
const debugInstruction = pasted.text.trim();
|
|
4670
4806
|
if (debugInstruction.length < 20) {
|
|
4671
4807
|
notify(state2, `Clipboard too short (${debugInstruction.length} chars; need 20+)`);
|
|
4672
4808
|
break;
|
|
@@ -5446,10 +5582,10 @@ function precomputePrefixes(nodes) {
|
|
|
5446
5582
|
}
|
|
5447
5583
|
|
|
5448
5584
|
// src/tui/lib/reports.ts
|
|
5449
|
-
import { readFileSync as
|
|
5585
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
5450
5586
|
function loadReportContent(report) {
|
|
5451
5587
|
try {
|
|
5452
|
-
return
|
|
5588
|
+
return readFileSync12(report.filePath, "utf-8");
|
|
5453
5589
|
} catch {
|
|
5454
5590
|
return report.summary;
|
|
5455
5591
|
}
|
|
@@ -5477,7 +5613,7 @@ async function inboxList() {
|
|
|
5477
5613
|
init_paths();
|
|
5478
5614
|
import { execSync as execSync3 } from "child_process";
|
|
5479
5615
|
import { join as join12 } from "path";
|
|
5480
|
-
import { readFileSync as
|
|
5616
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, mkdtempSync, rmSync as rmSync4, cpSync as cpSync2, existsSync as existsSync9, mkdirSync as mkdirSync8 } from "fs";
|
|
5481
5617
|
import { tmpdir } from "os";
|
|
5482
5618
|
init_shell();
|
|
5483
5619
|
|
|
@@ -5545,7 +5681,7 @@ function registerDashboardWindow(cwd2) {
|
|
|
5545
5681
|
function setupCompanionPlugin() {
|
|
5546
5682
|
const srcDir = join12(import.meta.dirname, "templates", "companion-plugin");
|
|
5547
5683
|
const destDir = join12(globalDir(), "companion-plugin");
|
|
5548
|
-
if (!
|
|
5684
|
+
if (!existsSync9(destDir)) mkdirSync8(destDir, { recursive: true });
|
|
5549
5685
|
cpSync2(srcDir, destDir, { recursive: true });
|
|
5550
5686
|
return destDir;
|
|
5551
5687
|
}
|
|
@@ -5575,7 +5711,7 @@ function openCompanionPane(cwd2) {
|
|
|
5575
5711
|
const templatePath = join12(import.meta.dirname, "templates", "dashboard-claude.md");
|
|
5576
5712
|
let template;
|
|
5577
5713
|
try {
|
|
5578
|
-
template =
|
|
5714
|
+
template = readFileSync13(templatePath, "utf-8");
|
|
5579
5715
|
} catch {
|
|
5580
5716
|
template = `You are a Sisyphus dashboard companion. Help the user manage multi-agent sessions.
|
|
5581
5717
|
Project: ${cwd2}
|
|
@@ -5604,7 +5740,7 @@ function editInPopup(cwd2, editor, opts) {
|
|
|
5604
5740
|
try {
|
|
5605
5741
|
writeFileSync9(filePath, opts?.content ? opts.content : "", "utf-8");
|
|
5606
5742
|
openEditorPopup(cwd2, editor, filePath, opts?.size);
|
|
5607
|
-
const result =
|
|
5743
|
+
const result = readFileSync13(filePath, "utf-8").trim();
|
|
5608
5744
|
return result || null;
|
|
5609
5745
|
} finally {
|
|
5610
5746
|
rmSync4(tmpDir, { recursive: true, force: true });
|
|
@@ -5620,8 +5756,8 @@ function promptInPopup(prompt, opts) {
|
|
|
5620
5756
|
`tmux display-popup -E -w ${w} -h ${h} ${shellQuote(`bash -c ${shellQuote(script)}`)}`,
|
|
5621
5757
|
{ stdio: "inherit", env: EXEC_ENV }
|
|
5622
5758
|
);
|
|
5623
|
-
if (!
|
|
5624
|
-
const result =
|
|
5759
|
+
if (!existsSync9(outFile)) return null;
|
|
5760
|
+
const result = readFileSync13(outFile, "utf-8").trim();
|
|
5625
5761
|
return result || null;
|
|
5626
5762
|
} finally {
|
|
5627
5763
|
rmSync4(tmpDir, { recursive: true, force: true });
|
|
@@ -5716,18 +5852,12 @@ function openEditorPopup(cwd2, editor, filePath, size) {
|
|
|
5716
5852
|
}
|
|
5717
5853
|
}
|
|
5718
5854
|
|
|
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
5855
|
// src/tui/lib/context.ts
|
|
5726
5856
|
init_paths();
|
|
5727
|
-
import { readFileSync as
|
|
5857
|
+
import { readFileSync as readFileSync14, readdirSync as readdirSync6 } from "fs";
|
|
5728
5858
|
function readFileSafe(filePath) {
|
|
5729
5859
|
try {
|
|
5730
|
-
return
|
|
5860
|
+
return readFileSync14(filePath, "utf-8");
|
|
5731
5861
|
} catch {
|
|
5732
5862
|
return null;
|
|
5733
5863
|
}
|
|
@@ -8264,13 +8394,13 @@ init_paths();
|
|
|
8264
8394
|
|
|
8265
8395
|
// src/tui/lib/popup-compose.ts
|
|
8266
8396
|
init_shell();
|
|
8267
|
-
import { execSync as
|
|
8268
|
-
import { mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync10, readFileSync as
|
|
8397
|
+
import { execSync as execSync4 } from "child_process";
|
|
8398
|
+
import { mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync10, readFileSync as readFileSync15, rmSync as rmSync5 } from "fs";
|
|
8269
8399
|
import { join as join14 } from "path";
|
|
8270
8400
|
import { tmpdir as tmpdir2 } from "os";
|
|
8271
8401
|
|
|
8272
8402
|
// src/shared/sisyphus-init-lua.ts
|
|
8273
|
-
import { mkdirSync as mkdirSync9, existsSync as
|
|
8403
|
+
import { mkdirSync as mkdirSync9, existsSync as existsSync10, cpSync as cpSync3 } from "fs";
|
|
8274
8404
|
import { join as join13 } from "path";
|
|
8275
8405
|
import { homedir as homedir4 } from "os";
|
|
8276
8406
|
var initLuaEnsured = false;
|
|
@@ -8280,7 +8410,7 @@ function ensureSisyphusInitLua() {
|
|
|
8280
8410
|
try {
|
|
8281
8411
|
const destDir = join13(homedir4(), ".config", "sisyphus");
|
|
8282
8412
|
const destPath = join13(destDir, "init.lua");
|
|
8283
|
-
if (
|
|
8413
|
+
if (existsSync10(destPath)) return;
|
|
8284
8414
|
mkdirSync9(destDir, { recursive: true });
|
|
8285
8415
|
const srcPath = join13(import.meta.dirname, "templates", "sisyphus-init.lua");
|
|
8286
8416
|
cpSync3(srcPath, destPath);
|
|
@@ -8295,13 +8425,13 @@ function composeViaPopup(action, state2, actions) {
|
|
|
8295
8425
|
try {
|
|
8296
8426
|
writeFileSync10(tempFile, "", "utf-8");
|
|
8297
8427
|
const cmd = `NVIM_APPNAME=sisyphus nvim ${shellQuote(tempFile)}`;
|
|
8298
|
-
|
|
8428
|
+
execSync4(
|
|
8299
8429
|
`tmux display-popup -E -w 90% -h 90% -d ${shellQuote(state2.cwd)} ${shellQuote(cmd)}`,
|
|
8300
8430
|
{ stdio: "inherit", env: EXEC_ENV }
|
|
8301
8431
|
);
|
|
8302
8432
|
let rawContent = "";
|
|
8303
8433
|
try {
|
|
8304
|
-
rawContent =
|
|
8434
|
+
rawContent = readFileSync15(tempFile, "utf-8");
|
|
8305
8435
|
} catch {
|
|
8306
8436
|
}
|
|
8307
8437
|
const required = !OPTIONAL_COMPOSE.has(action.kind);
|
|
@@ -8326,7 +8456,7 @@ function getCompanion() {
|
|
|
8326
8456
|
const { mtimeMs } = statSync4(companionPath());
|
|
8327
8457
|
if (_cachedCompanion && mtimeMs === _companionMtime) return _cachedCompanion;
|
|
8328
8458
|
_companionMtime = mtimeMs;
|
|
8329
|
-
_cachedCompanion = normalizeCompanion(JSON.parse(
|
|
8459
|
+
_cachedCompanion = normalizeCompanion(JSON.parse(readFileSync16(companionPath(), "utf-8")));
|
|
8330
8460
|
return _cachedCompanion;
|
|
8331
8461
|
} catch {
|
|
8332
8462
|
return _cachedCompanion;
|
|
@@ -8448,40 +8578,40 @@ function startApp(state2, cleanup2) {
|
|
|
8448
8578
|
selectedSession = statusRes.data?.session ?? null;
|
|
8449
8579
|
}
|
|
8450
8580
|
if (selectedSession?.tmuxWindowId) {
|
|
8451
|
-
const
|
|
8452
|
-
paneAlive =
|
|
8581
|
+
const cached2 = sessions.find((s) => s.id === state2.selectedSessionId);
|
|
8582
|
+
paneAlive = cached2?.windowAlive ?? false;
|
|
8453
8583
|
}
|
|
8454
8584
|
try {
|
|
8455
8585
|
const pp = roadmapPath(state2.cwd, state2.selectedSessionId);
|
|
8456
|
-
if (
|
|
8457
|
-
planContent =
|
|
8586
|
+
if (existsSync11(pp)) {
|
|
8587
|
+
planContent = readFileSync16(pp, "utf-8");
|
|
8458
8588
|
}
|
|
8459
8589
|
} catch {
|
|
8460
8590
|
}
|
|
8461
8591
|
try {
|
|
8462
8592
|
const gp = goalPath(state2.cwd, state2.selectedSessionId);
|
|
8463
|
-
if (
|
|
8464
|
-
goalContent =
|
|
8593
|
+
if (existsSync11(gp)) {
|
|
8594
|
+
goalContent = readFileSync16(gp, "utf-8");
|
|
8465
8595
|
}
|
|
8466
8596
|
} catch {
|
|
8467
8597
|
}
|
|
8468
8598
|
try {
|
|
8469
8599
|
const sp = strategyPath(state2.cwd, state2.selectedSessionId);
|
|
8470
|
-
if (
|
|
8471
|
-
strategyContent =
|
|
8600
|
+
if (existsSync11(sp)) {
|
|
8601
|
+
strategyContent = readFileSync16(sp, "utf-8");
|
|
8472
8602
|
}
|
|
8473
8603
|
} catch {
|
|
8474
8604
|
}
|
|
8475
8605
|
try {
|
|
8476
8606
|
const cp = join15(contextDir(state2.cwd, state2.selectedSessionId), "completion-summary.md");
|
|
8477
|
-
if (
|
|
8478
|
-
completionSummaryContent =
|
|
8607
|
+
if (existsSync11(cp)) {
|
|
8608
|
+
completionSummaryContent = readFileSync16(cp, "utf-8");
|
|
8479
8609
|
}
|
|
8480
8610
|
} catch {
|
|
8481
8611
|
}
|
|
8482
8612
|
try {
|
|
8483
8613
|
const ld = logsDir(state2.cwd, state2.selectedSessionId);
|
|
8484
|
-
if (
|
|
8614
|
+
if (existsSync11(ld)) {
|
|
8485
8615
|
if (state2.selectedSessionId !== cachedLogSessionId) {
|
|
8486
8616
|
cachedLogFiles = /* @__PURE__ */ new Map();
|
|
8487
8617
|
cachedLogSessionId = state2.selectedSessionId;
|
|
@@ -8494,11 +8624,11 @@ function startApp(state2, cleanup2) {
|
|
|
8494
8624
|
for (const f of files) {
|
|
8495
8625
|
const filePath = join15(ld, f);
|
|
8496
8626
|
const mtime = statSync4(filePath).mtimeMs;
|
|
8497
|
-
const
|
|
8498
|
-
if (!
|
|
8627
|
+
const cached2 = cachedLogFiles.get(f);
|
|
8628
|
+
if (!cached2 || cached2.mtime !== mtime) {
|
|
8499
8629
|
const match = f.match(/cycle-(\d+)\.md$/);
|
|
8500
8630
|
const cycle = match ? parseInt(match[1], 10) : 0;
|
|
8501
|
-
const content =
|
|
8631
|
+
const content = readFileSync16(filePath, "utf-8");
|
|
8502
8632
|
cachedLogFiles.set(f, { mtime, cycle, content });
|
|
8503
8633
|
}
|
|
8504
8634
|
}
|
|
@@ -8512,7 +8642,7 @@ function startApp(state2, cleanup2) {
|
|
|
8512
8642
|
}
|
|
8513
8643
|
try {
|
|
8514
8644
|
const cd = contextDir(state2.cwd, state2.selectedSessionId);
|
|
8515
|
-
if (
|
|
8645
|
+
if (existsSync11(cd)) {
|
|
8516
8646
|
const entries = readdirSync7(cd, { withFileTypes: true }).filter((e) => !e.name.startsWith("."));
|
|
8517
8647
|
const flat = [];
|
|
8518
8648
|
for (const e of entries) {
|
|
@@ -8532,8 +8662,8 @@ function startApp(state2, cleanup2) {
|
|
|
8532
8662
|
}
|
|
8533
8663
|
try {
|
|
8534
8664
|
const dp = digestPath(state2.cwd, state2.selectedSessionId);
|
|
8535
|
-
if (
|
|
8536
|
-
const raw = JSON.parse(
|
|
8665
|
+
if (existsSync11(dp)) {
|
|
8666
|
+
const raw = JSON.parse(readFileSync16(dp, "utf-8"));
|
|
8537
8667
|
if (raw && typeof raw.recentWork === "string" && typeof raw.currentActivity === "string" && typeof raw.whatsNext === "string" && Array.isArray(raw.unusualEvents)) {
|
|
8538
8668
|
digestData = raw;
|
|
8539
8669
|
}
|
|
@@ -8676,8 +8806,8 @@ function startApp(state2, cleanup2) {
|
|
|
8676
8806
|
if (cursorNode.filePath !== cachedContextFilePath) {
|
|
8677
8807
|
cachedContextFilePath = cursorNode.filePath;
|
|
8678
8808
|
try {
|
|
8679
|
-
if (
|
|
8680
|
-
cachedContextFileContent =
|
|
8809
|
+
if (existsSync11(cursorNode.filePath)) {
|
|
8810
|
+
cachedContextFileContent = readFileSync16(cursorNode.filePath, "utf-8");
|
|
8681
8811
|
} else {
|
|
8682
8812
|
cachedContextFileContent = null;
|
|
8683
8813
|
}
|
|
@@ -8821,7 +8951,10 @@ function startApp(state2, cleanup2) {
|
|
|
8821
8951
|
openLogPopup,
|
|
8822
8952
|
openShellPopup,
|
|
8823
8953
|
openInFileManager,
|
|
8824
|
-
copyToClipboard
|
|
8954
|
+
copyToClipboard: (text) => {
|
|
8955
|
+
const err = copyToClipboard(text);
|
|
8956
|
+
if (err !== null) notify(state2, err.reason);
|
|
8957
|
+
},
|
|
8825
8958
|
buildSessionContext,
|
|
8826
8959
|
resolveEditor: () => {
|
|
8827
8960
|
if (config.editor) return config.editor;
|