cli-remote-agent 1.0.6 → 1.0.7
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 +139 -92
- package/dist/cli.js.map +1 -1
- package/dist/index.js +123 -84
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -427,6 +427,51 @@ var init_local_control = __esm({
|
|
|
427
427
|
}
|
|
428
428
|
});
|
|
429
429
|
|
|
430
|
+
// src/pty-helper-fix.ts
|
|
431
|
+
function ensurePtyHelperExecutable() {
|
|
432
|
+
if (process.platform === "win32") return;
|
|
433
|
+
try {
|
|
434
|
+
const nodeRequire = (0, import_node_module.createRequire)(__filename);
|
|
435
|
+
const ptyMain = nodeRequire.resolve("node-pty");
|
|
436
|
+
const ptyDir = import_path3.default.dirname(import_path3.default.dirname(ptyMain));
|
|
437
|
+
const candidates = [import_path3.default.join(ptyDir, "build", "Release", "spawn-helper")];
|
|
438
|
+
const prebuilds = import_path3.default.join(ptyDir, "prebuilds");
|
|
439
|
+
try {
|
|
440
|
+
for (const d of import_fs4.default.readdirSync(prebuilds)) {
|
|
441
|
+
candidates.push(import_path3.default.join(prebuilds, d, "spawn-helper"));
|
|
442
|
+
}
|
|
443
|
+
} catch {
|
|
444
|
+
}
|
|
445
|
+
for (const file of candidates) {
|
|
446
|
+
try {
|
|
447
|
+
const mode = import_fs4.default.statSync(file).mode;
|
|
448
|
+
if (!(mode & 73)) {
|
|
449
|
+
import_fs4.default.chmodSync(file, mode | 493);
|
|
450
|
+
logger.info({ file }, "Restored execute bit on node-pty spawn-helper");
|
|
451
|
+
}
|
|
452
|
+
} catch {
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
if (process.platform === "darwin") {
|
|
456
|
+
(0, import_node_child_process.execFile)("xattr", ["-dr", "com.apple.quarantine", ptyDir], () => {
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
} catch (err) {
|
|
460
|
+
logger.warn({ error: err?.message }, "Could not verify node-pty spawn-helper permissions");
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
var import_node_module, import_node_child_process, import_fs4, import_path3;
|
|
464
|
+
var init_pty_helper_fix = __esm({
|
|
465
|
+
"src/pty-helper-fix.ts"() {
|
|
466
|
+
"use strict";
|
|
467
|
+
import_node_module = require("module");
|
|
468
|
+
import_node_child_process = require("child_process");
|
|
469
|
+
import_fs4 = __toESM(require("fs"));
|
|
470
|
+
import_path3 = __toESM(require("path"));
|
|
471
|
+
init_logger();
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
|
|
430
475
|
// src/claude-live.ts
|
|
431
476
|
function isAlive(pid) {
|
|
432
477
|
try {
|
|
@@ -439,14 +484,14 @@ function isAlive(pid) {
|
|
|
439
484
|
function getLiveClaudeSessions() {
|
|
440
485
|
let files;
|
|
441
486
|
try {
|
|
442
|
-
files =
|
|
487
|
+
files = import_fs5.default.readdirSync(LIVE_SESSIONS_DIR).filter((f) => f.endsWith(".json"));
|
|
443
488
|
} catch {
|
|
444
489
|
return [];
|
|
445
490
|
}
|
|
446
491
|
const out = [];
|
|
447
492
|
for (const f of files) {
|
|
448
493
|
try {
|
|
449
|
-
const obj = JSON.parse(
|
|
494
|
+
const obj = JSON.parse(import_fs5.default.readFileSync(import_path4.default.join(LIVE_SESSIONS_DIR, f), "utf-8"));
|
|
450
495
|
if (typeof obj?.pid !== "number" || !isAlive(obj.pid)) continue;
|
|
451
496
|
out.push({
|
|
452
497
|
pid: obj.pid,
|
|
@@ -481,31 +526,31 @@ function isDescendantOf(pid, ancestor, parents) {
|
|
|
481
526
|
}
|
|
482
527
|
return false;
|
|
483
528
|
}
|
|
484
|
-
var
|
|
529
|
+
var import_fs5, import_path4, import_os2, import_child_process, import_util, execFileAsync, LIVE_SESSIONS_DIR;
|
|
485
530
|
var init_claude_live = __esm({
|
|
486
531
|
"src/claude-live.ts"() {
|
|
487
532
|
"use strict";
|
|
488
|
-
|
|
489
|
-
|
|
533
|
+
import_fs5 = __toESM(require("fs"));
|
|
534
|
+
import_path4 = __toESM(require("path"));
|
|
490
535
|
import_os2 = __toESM(require("os"));
|
|
491
536
|
import_child_process = require("child_process");
|
|
492
537
|
import_util = require("util");
|
|
493
538
|
execFileAsync = (0, import_util.promisify)(import_child_process.execFile);
|
|
494
|
-
LIVE_SESSIONS_DIR =
|
|
539
|
+
LIVE_SESSIONS_DIR = import_path4.default.join(import_os2.default.homedir(), ".claude", "sessions");
|
|
495
540
|
}
|
|
496
541
|
});
|
|
497
542
|
|
|
498
543
|
// src/tmux.ts
|
|
499
544
|
function resolveTmuxPath() {
|
|
500
545
|
if (cachedTmuxPath !== void 0) return cachedTmuxPath;
|
|
501
|
-
const dirs = (process.env.PATH || "").split(
|
|
546
|
+
const dirs = (process.env.PATH || "").split(import_path5.default.delimiter).filter(Boolean);
|
|
502
547
|
for (const extra of ["/opt/homebrew/bin", "/usr/local/bin", "/usr/bin", "/bin", "/opt/local/bin"]) {
|
|
503
548
|
if (!dirs.includes(extra)) dirs.push(extra);
|
|
504
549
|
}
|
|
505
550
|
for (const dir of dirs) {
|
|
506
|
-
const candidate =
|
|
551
|
+
const candidate = import_path5.default.join(dir, "tmux");
|
|
507
552
|
try {
|
|
508
|
-
|
|
553
|
+
import_fs6.default.accessSync(candidate, import_fs6.default.constants.X_OK);
|
|
509
554
|
cachedTmuxPath = candidate;
|
|
510
555
|
return candidate;
|
|
511
556
|
} catch {
|
|
@@ -555,8 +600,8 @@ async function enrichWithPanesAndClaude(sessions2) {
|
|
|
555
600
|
const { file, args } = tmuxCmd(["list-panes", "-a", "-F", paneFmt]);
|
|
556
601
|
const { stdout } = await execFileAsync2(file, args, { timeout: 6e3 });
|
|
557
602
|
const panes = stdout.split("\n").map((line) => line.replace(/\r$/, "").trim()).filter(Boolean).map((line) => {
|
|
558
|
-
const [session, pid,
|
|
559
|
-
return { session, pid: parseInt(pid, 10) || 0, path:
|
|
603
|
+
const [session, pid, path10, activeFlags] = line.split(" ");
|
|
604
|
+
return { session, pid: parseInt(pid, 10) || 0, path: path10 || "", active: activeFlags === "11" };
|
|
560
605
|
});
|
|
561
606
|
const byName = new Map(sessions2.map((s) => [s.name, s]));
|
|
562
607
|
for (const pane of panes) {
|
|
@@ -595,14 +640,14 @@ function buildTmuxLaunch(name, launch) {
|
|
|
595
640
|
if (trimmed) args.push(trimmed);
|
|
596
641
|
return { file: tmuxBin, args };
|
|
597
642
|
}
|
|
598
|
-
var import_child_process2, import_util2,
|
|
643
|
+
var import_child_process2, import_util2, import_fs6, import_path5, execFileAsync2, IS_WIN, cachedTmuxPath;
|
|
599
644
|
var init_tmux = __esm({
|
|
600
645
|
"src/tmux.ts"() {
|
|
601
646
|
"use strict";
|
|
602
647
|
import_child_process2 = require("child_process");
|
|
603
648
|
import_util2 = require("util");
|
|
604
|
-
|
|
605
|
-
|
|
649
|
+
import_fs6 = __toESM(require("fs"));
|
|
650
|
+
import_path5 = __toESM(require("path"));
|
|
606
651
|
init_claude_live();
|
|
607
652
|
execFileAsync2 = (0, import_util2.promisify)(import_child_process2.execFile);
|
|
608
653
|
IS_WIN = process.platform === "win32";
|
|
@@ -632,15 +677,15 @@ var init_shell = __esm({
|
|
|
632
677
|
|
|
633
678
|
// src/pty-session.ts
|
|
634
679
|
function ensureInitFiles() {
|
|
635
|
-
const versionFile = (0,
|
|
636
|
-
if ((0,
|
|
680
|
+
const versionFile = (0, import_path6.join)(INIT_DIR, ".version");
|
|
681
|
+
if ((0, import_fs7.existsSync)(versionFile)) {
|
|
637
682
|
try {
|
|
638
|
-
if ((0,
|
|
683
|
+
if ((0, import_fs7.readFileSync)(versionFile, "utf-8").trim() === INIT_VERSION) return;
|
|
639
684
|
} catch {
|
|
640
685
|
}
|
|
641
686
|
}
|
|
642
|
-
(0,
|
|
643
|
-
(0,
|
|
687
|
+
(0, import_fs7.mkdirSync)(ZSH_DIR, { recursive: true });
|
|
688
|
+
(0, import_fs7.writeFileSync)(BASH_INIT, [
|
|
644
689
|
"[ -f ~/.bash_profile ] && source ~/.bash_profile",
|
|
645
690
|
"[ -f ~/.bashrc ] && source ~/.bashrc",
|
|
646
691
|
"__crc_s=$SECONDS",
|
|
@@ -651,11 +696,11 @@ function ensureInitFiles() {
|
|
|
651
696
|
`PROMPT_COMMAND='[ "$__crc_armed" = 1 ] && [ \${__crc_elapsed:-0} -ge ${THRESHOLD} ] && printf "\\a"; __crc_armed=1; eval "$__crc_orig_pc"'`,
|
|
652
697
|
""
|
|
653
698
|
].join("\n"), "utf-8");
|
|
654
|
-
(0,
|
|
699
|
+
(0, import_fs7.writeFileSync)(ZSH_ENV, [
|
|
655
700
|
'[ -f "${ZDOTDIR_ORIG:-$HOME}/.zshenv" ] && source "${ZDOTDIR_ORIG:-$HOME}/.zshenv"',
|
|
656
701
|
""
|
|
657
702
|
].join("\n"), "utf-8");
|
|
658
|
-
(0,
|
|
703
|
+
(0, import_fs7.writeFileSync)(ZSH_RC, [
|
|
659
704
|
'[ -f "${ZDOTDIR_ORIG:-$HOME}/.zshrc" ] && source "${ZDOTDIR_ORIG:-$HOME}/.zshrc"',
|
|
660
705
|
"__crc_s=$SECONDS",
|
|
661
706
|
"__crc_armed=0",
|
|
@@ -668,36 +713,36 @@ function ensureInitFiles() {
|
|
|
668
713
|
"fi",
|
|
669
714
|
""
|
|
670
715
|
].join("\n"), "utf-8");
|
|
671
|
-
(0,
|
|
716
|
+
(0, import_fs7.writeFileSync)(versionFile, INIT_VERSION, "utf-8");
|
|
672
717
|
}
|
|
673
718
|
function resolveCwd(cwd) {
|
|
674
719
|
const candidates = process.platform === "win32" ? [cwd, (0, import_os3.homedir)(), process.env.USERPROFILE, process.env.HOME] : [cwd, (0, import_os3.homedir)(), process.env.HOME, process.env.USERPROFILE];
|
|
675
720
|
for (const c of candidates) {
|
|
676
721
|
if (c) {
|
|
677
722
|
try {
|
|
678
|
-
if ((0,
|
|
723
|
+
if ((0, import_fs7.existsSync)(c)) return c;
|
|
679
724
|
} catch {
|
|
680
725
|
}
|
|
681
726
|
}
|
|
682
727
|
}
|
|
683
728
|
return (0, import_os3.homedir)();
|
|
684
729
|
}
|
|
685
|
-
var pty,
|
|
730
|
+
var pty, import_fs7, import_path6, import_os3, THRESHOLD, INIT_DIR, BASH_INIT, ZSH_DIR, ZSH_RC, ZSH_ENV, INIT_VERSION, PtySession;
|
|
686
731
|
var init_pty_session = __esm({
|
|
687
732
|
"src/pty-session.ts"() {
|
|
688
733
|
"use strict";
|
|
689
734
|
pty = __toESM(require("node-pty"));
|
|
690
|
-
|
|
691
|
-
|
|
735
|
+
import_fs7 = require("fs");
|
|
736
|
+
import_path6 = require("path");
|
|
692
737
|
import_os3 = require("os");
|
|
693
738
|
init_src();
|
|
694
739
|
init_shell();
|
|
695
740
|
THRESHOLD = 3;
|
|
696
|
-
INIT_DIR = (0,
|
|
697
|
-
BASH_INIT = (0,
|
|
698
|
-
ZSH_DIR = (0,
|
|
699
|
-
ZSH_RC = (0,
|
|
700
|
-
ZSH_ENV = (0,
|
|
741
|
+
INIT_DIR = (0, import_path6.join)((0, import_os3.tmpdir)(), "crc-shell-init");
|
|
742
|
+
BASH_INIT = (0, import_path6.join)(INIT_DIR, "bashrc");
|
|
743
|
+
ZSH_DIR = (0, import_path6.join)(INIT_DIR, "zsh");
|
|
744
|
+
ZSH_RC = (0, import_path6.join)(ZSH_DIR, ".zshrc");
|
|
745
|
+
ZSH_ENV = (0, import_path6.join)(ZSH_DIR, ".zshenv");
|
|
701
746
|
INIT_VERSION = "2";
|
|
702
747
|
PtySession = class {
|
|
703
748
|
id;
|
|
@@ -927,18 +972,18 @@ function buildHeartbeat(homeDir) {
|
|
|
927
972
|
memoryUsage: Math.round((totalMem - freeMem) / totalMem * 100),
|
|
928
973
|
uptime: Math.round(import_os4.default.uptime()),
|
|
929
974
|
activeSessions: getActiveSessionCount(),
|
|
930
|
-
pathSeparator:
|
|
975
|
+
pathSeparator: import_path7.default.sep,
|
|
931
976
|
homeDirectory: homeDir || import_os4.default.homedir(),
|
|
932
977
|
rootPaths: getRootPaths(),
|
|
933
978
|
capabilities: { terminal: true, fileTransfer: false }
|
|
934
979
|
};
|
|
935
980
|
}
|
|
936
|
-
var import_os4,
|
|
981
|
+
var import_os4, import_path7, import_child_process4, prevCpu;
|
|
937
982
|
var init_heartbeat = __esm({
|
|
938
983
|
"src/heartbeat.ts"() {
|
|
939
984
|
"use strict";
|
|
940
985
|
import_os4 = __toESM(require("os"));
|
|
941
|
-
|
|
986
|
+
import_path7 = __toESM(require("path"));
|
|
942
987
|
import_child_process4 = require("child_process");
|
|
943
988
|
init_terminal_manager();
|
|
944
989
|
prevCpu = null;
|
|
@@ -947,28 +992,28 @@ var init_heartbeat = __esm({
|
|
|
947
992
|
|
|
948
993
|
// src/file-explorer.ts
|
|
949
994
|
function isInSecretDir(resolved) {
|
|
950
|
-
const rel =
|
|
951
|
-
return rel === "" || !rel.startsWith(".." +
|
|
995
|
+
const rel = import_path8.default.relative(SECRET_DIR, resolved);
|
|
996
|
+
return rel === "" || !rel.startsWith(".." + import_path8.default.sep) && rel !== ".." && !import_path8.default.isAbsolute(rel);
|
|
952
997
|
}
|
|
953
998
|
function listDirectory(dirPath) {
|
|
954
999
|
try {
|
|
955
|
-
const resolved =
|
|
1000
|
+
const resolved = import_path8.default.resolve(dirPath);
|
|
956
1001
|
if (isInSecretDir(resolved)) {
|
|
957
1002
|
return { entries: [], error: "Access denied" };
|
|
958
1003
|
}
|
|
959
|
-
if (!
|
|
1004
|
+
if (!import_fs8.default.existsSync(resolved)) {
|
|
960
1005
|
return { entries: [], error: "Path does not exist" };
|
|
961
1006
|
}
|
|
962
|
-
const stat =
|
|
1007
|
+
const stat = import_fs8.default.statSync(resolved);
|
|
963
1008
|
if (!stat.isDirectory()) {
|
|
964
1009
|
return { entries: [], error: "Not a directory" };
|
|
965
1010
|
}
|
|
966
|
-
const dirents =
|
|
1011
|
+
const dirents = import_fs8.default.readdirSync(resolved, { withFileTypes: true });
|
|
967
1012
|
const entries = [];
|
|
968
1013
|
for (const dirent of dirents) {
|
|
969
1014
|
try {
|
|
970
|
-
const fullPath =
|
|
971
|
-
const s =
|
|
1015
|
+
const fullPath = import_path8.default.join(resolved, dirent.name);
|
|
1016
|
+
const s = import_fs8.default.statSync(fullPath);
|
|
972
1017
|
entries.push({
|
|
973
1018
|
name: dirent.name,
|
|
974
1019
|
isDirectory: dirent.isDirectory(),
|
|
@@ -990,22 +1035,22 @@ function listDirectory(dirPath) {
|
|
|
990
1035
|
}
|
|
991
1036
|
async function downloadFile(filePath, serverUrl, secret, agentId) {
|
|
992
1037
|
try {
|
|
993
|
-
const resolved =
|
|
1038
|
+
const resolved = import_path8.default.resolve(filePath);
|
|
994
1039
|
if (isInSecretDir(resolved)) {
|
|
995
1040
|
return { error: "Access denied" };
|
|
996
1041
|
}
|
|
997
|
-
if (!
|
|
1042
|
+
if (!import_fs8.default.existsSync(resolved)) {
|
|
998
1043
|
return { error: "File does not exist" };
|
|
999
1044
|
}
|
|
1000
|
-
const stat =
|
|
1045
|
+
const stat = import_fs8.default.statSync(resolved);
|
|
1001
1046
|
if (stat.isDirectory()) {
|
|
1002
1047
|
return { error: "Cannot download a directory" };
|
|
1003
1048
|
}
|
|
1004
1049
|
if (stat.size > FILE_MAX_SIZE) {
|
|
1005
1050
|
return { error: `File too large (max ${FILE_MAX_SIZE} bytes)` };
|
|
1006
1051
|
}
|
|
1007
|
-
const fileName =
|
|
1008
|
-
const fileStream =
|
|
1052
|
+
const fileName = import_path8.default.basename(resolved);
|
|
1053
|
+
const fileStream = import_fs8.default.createReadStream(resolved);
|
|
1009
1054
|
const baseUrl = serverUrl.replace("wss://", "https://").replace("ws://", "http://");
|
|
1010
1055
|
const url = `${baseUrl}/api/files/receive`;
|
|
1011
1056
|
const res = await fetch(url, {
|
|
@@ -1034,16 +1079,16 @@ async function downloadFile(filePath, serverUrl, secret, agentId) {
|
|
|
1034
1079
|
return { error: err.message };
|
|
1035
1080
|
}
|
|
1036
1081
|
}
|
|
1037
|
-
var
|
|
1082
|
+
var import_fs8, import_path8, import_os5, SECRET_DIR;
|
|
1038
1083
|
var init_file_explorer = __esm({
|
|
1039
1084
|
"src/file-explorer.ts"() {
|
|
1040
1085
|
"use strict";
|
|
1041
|
-
|
|
1042
|
-
|
|
1086
|
+
import_fs8 = __toESM(require("fs"));
|
|
1087
|
+
import_path8 = __toESM(require("path"));
|
|
1043
1088
|
import_os5 = __toESM(require("os"));
|
|
1044
1089
|
init_logger();
|
|
1045
1090
|
init_src();
|
|
1046
|
-
SECRET_DIR =
|
|
1091
|
+
SECRET_DIR = import_path8.default.join(import_os5.default.homedir(), ".crc-agent");
|
|
1047
1092
|
}
|
|
1048
1093
|
});
|
|
1049
1094
|
|
|
@@ -1066,8 +1111,8 @@ async function runCmd(cmd2, shell) {
|
|
|
1066
1111
|
}
|
|
1067
1112
|
function getConfigPath(profile) {
|
|
1068
1113
|
const file = profile.configFile || `${profile.id}.conf`;
|
|
1069
|
-
if (
|
|
1070
|
-
return
|
|
1114
|
+
if (import_path9.default.isAbsolute(file)) return file;
|
|
1115
|
+
return import_path9.default.join(VPN_DIR, file);
|
|
1071
1116
|
}
|
|
1072
1117
|
async function getScutilStatus(serviceName) {
|
|
1073
1118
|
const { stdout } = await runCmd(`scutil --nc status '${shq(serviceName)}'`);
|
|
@@ -1183,7 +1228,7 @@ async function connectWireGuard(profile) {
|
|
|
1183
1228
|
const tunnelName = profile.tunnelName || profile.id;
|
|
1184
1229
|
if (isWindows) {
|
|
1185
1230
|
const confPath2 = getConfigPath(profile);
|
|
1186
|
-
if (!
|
|
1231
|
+
if (!import_fs9.default.existsSync(confPath2)) {
|
|
1187
1232
|
return `Config file not found: ${confPath2}`;
|
|
1188
1233
|
}
|
|
1189
1234
|
const script = `
|
|
@@ -1209,7 +1254,7 @@ async function connectWireGuard(profile) {
|
|
|
1209
1254
|
async function connectOpenVpn(profile) {
|
|
1210
1255
|
if (isWindows) {
|
|
1211
1256
|
const confPath2 = getConfigPath(profile);
|
|
1212
|
-
if (!
|
|
1257
|
+
if (!import_fs9.default.existsSync(confPath2)) {
|
|
1213
1258
|
return `Config file not found: ${confPath2}`;
|
|
1214
1259
|
}
|
|
1215
1260
|
const connector = "C:\\Program Files\\OpenVPN Connect\\ovpnconnector.exe";
|
|
@@ -1236,7 +1281,7 @@ async function connectOpenVpn(profile) {
|
|
|
1236
1281
|
return scutilStart(profile.serviceName);
|
|
1237
1282
|
}
|
|
1238
1283
|
const confPath = getConfigPath(profile);
|
|
1239
|
-
if (!
|
|
1284
|
+
if (!import_fs9.default.existsSync(confPath)) {
|
|
1240
1285
|
return `Config file not found: ${confPath}`;
|
|
1241
1286
|
}
|
|
1242
1287
|
const { stderr } = await runCmd(`sudo openvpn --config '${shq(confPath)}' --daemon`);
|
|
@@ -1245,7 +1290,7 @@ async function connectOpenVpn(profile) {
|
|
|
1245
1290
|
async function connectAzure(profile) {
|
|
1246
1291
|
if (isWindows) {
|
|
1247
1292
|
const confPath = getConfigPath(profile);
|
|
1248
|
-
if (!
|
|
1293
|
+
if (!import_fs9.default.existsSync(confPath)) {
|
|
1249
1294
|
return `Config file not found: ${confPath}`;
|
|
1250
1295
|
}
|
|
1251
1296
|
await runCmd(`& 'AzureVpn.exe' -i '${psq(confPath)}' 2>&1`);
|
|
@@ -1365,19 +1410,19 @@ async function disconnectVpn(configs, profileId) {
|
|
|
1365
1410
|
}
|
|
1366
1411
|
return profiles;
|
|
1367
1412
|
}
|
|
1368
|
-
var import_child_process5, import_util3,
|
|
1413
|
+
var import_child_process5, import_util3, import_fs9, import_path9, import_os6, execAsync, isWindows, VPN_DIR;
|
|
1369
1414
|
var init_vpn_manager = __esm({
|
|
1370
1415
|
"src/vpn-manager.ts"() {
|
|
1371
1416
|
"use strict";
|
|
1372
1417
|
import_child_process5 = require("child_process");
|
|
1373
1418
|
import_util3 = require("util");
|
|
1374
|
-
|
|
1375
|
-
|
|
1419
|
+
import_fs9 = __toESM(require("fs"));
|
|
1420
|
+
import_path9 = __toESM(require("path"));
|
|
1376
1421
|
import_os6 = __toESM(require("os"));
|
|
1377
1422
|
init_logger();
|
|
1378
1423
|
execAsync = (0, import_util3.promisify)(import_child_process5.exec);
|
|
1379
1424
|
isWindows = process.platform === "win32";
|
|
1380
|
-
VPN_DIR =
|
|
1425
|
+
VPN_DIR = import_path9.default.join(import_os6.default.homedir(), ".crc-agent", "vpn");
|
|
1381
1426
|
}
|
|
1382
1427
|
});
|
|
1383
1428
|
|
|
@@ -1412,7 +1457,7 @@ var init_claude_path = __esm({
|
|
|
1412
1457
|
// src/claude-sessions.ts
|
|
1413
1458
|
async function parseSessionFile(filePath) {
|
|
1414
1459
|
try {
|
|
1415
|
-
const stream =
|
|
1460
|
+
const stream = import_fs10.default.createReadStream(filePath, { encoding: "utf-8" });
|
|
1416
1461
|
const rl = import_readline2.default.createInterface({ input: stream, crlfDelay: Infinity });
|
|
1417
1462
|
let firstMessage = "";
|
|
1418
1463
|
let lastTimestamp = "";
|
|
@@ -1460,17 +1505,17 @@ async function parseSessionFile(filePath) {
|
|
|
1460
1505
|
}
|
|
1461
1506
|
async function listClaudeSessions(filterProjectPath) {
|
|
1462
1507
|
const sessions2 = [];
|
|
1463
|
-
if (!
|
|
1508
|
+
if (!import_fs10.default.existsSync(CLAUDE_PROJECTS_DIR)) return sessions2;
|
|
1464
1509
|
const isDirSafe = (d) => {
|
|
1465
1510
|
try {
|
|
1466
|
-
return
|
|
1511
|
+
return import_fs10.default.statSync(import_path10.default.join(CLAUDE_PROJECTS_DIR, d)).isDirectory();
|
|
1467
1512
|
} catch {
|
|
1468
1513
|
return false;
|
|
1469
1514
|
}
|
|
1470
1515
|
};
|
|
1471
1516
|
let allEntries;
|
|
1472
1517
|
try {
|
|
1473
|
-
allEntries =
|
|
1518
|
+
allEntries = import_fs10.default.readdirSync(CLAUDE_PROJECTS_DIR);
|
|
1474
1519
|
} catch {
|
|
1475
1520
|
return sessions2;
|
|
1476
1521
|
}
|
|
@@ -1483,16 +1528,16 @@ async function listClaudeSessions(filterProjectPath) {
|
|
|
1483
1528
|
projectDirs = allEntries.filter((d) => isDirSafe(d) && !d.startsWith("-private-"));
|
|
1484
1529
|
}
|
|
1485
1530
|
for (const dirName of projectDirs) {
|
|
1486
|
-
const dirPath =
|
|
1531
|
+
const dirPath = import_path10.default.join(CLAUDE_PROJECTS_DIR, dirName);
|
|
1487
1532
|
let files;
|
|
1488
1533
|
try {
|
|
1489
|
-
files =
|
|
1534
|
+
files = import_fs10.default.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl"));
|
|
1490
1535
|
} catch {
|
|
1491
1536
|
continue;
|
|
1492
1537
|
}
|
|
1493
1538
|
for (const file of files) {
|
|
1494
1539
|
const sessionId = file.replace(".jsonl", "");
|
|
1495
|
-
const parsed = await parseSessionFile(
|
|
1540
|
+
const parsed = await parseSessionFile(import_path10.default.join(dirPath, file));
|
|
1496
1541
|
if (!parsed) continue;
|
|
1497
1542
|
const projectPath = parsed.cwd || dirName.replace(/^-/, "/").replace(/-/g, "/");
|
|
1498
1543
|
sessions2.push({
|
|
@@ -1510,31 +1555,31 @@ async function listClaudeSessions(filterProjectPath) {
|
|
|
1510
1555
|
sessions2.sort((a, b) => b.lastTimestamp > a.lastTimestamp ? 1 : -1);
|
|
1511
1556
|
return sessions2;
|
|
1512
1557
|
}
|
|
1513
|
-
var
|
|
1558
|
+
var import_fs10, import_path10, import_os7, import_readline2, CLAUDE_PROJECTS_DIR;
|
|
1514
1559
|
var init_claude_sessions = __esm({
|
|
1515
1560
|
"src/claude-sessions.ts"() {
|
|
1516
1561
|
"use strict";
|
|
1517
|
-
|
|
1518
|
-
|
|
1562
|
+
import_fs10 = __toESM(require("fs"));
|
|
1563
|
+
import_path10 = __toESM(require("path"));
|
|
1519
1564
|
import_os7 = __toESM(require("os"));
|
|
1520
1565
|
import_readline2 = __toESM(require("readline"));
|
|
1521
1566
|
init_logger();
|
|
1522
1567
|
init_claude_path();
|
|
1523
|
-
CLAUDE_PROJECTS_DIR =
|
|
1568
|
+
CLAUDE_PROJECTS_DIR = import_path10.default.join(import_os7.default.homedir(), ".claude", "projects");
|
|
1524
1569
|
}
|
|
1525
1570
|
});
|
|
1526
1571
|
|
|
1527
1572
|
// src/claude-conversation.ts
|
|
1528
1573
|
function findProjectDir(projectPath) {
|
|
1529
1574
|
const encoded = encodeProjectPath(projectPath);
|
|
1530
|
-
const dirPath =
|
|
1531
|
-
if (
|
|
1532
|
-
if (!
|
|
1575
|
+
const dirPath = import_path11.default.join(CLAUDE_PROJECTS_DIR2, encoded);
|
|
1576
|
+
if (import_fs11.default.existsSync(dirPath)) return dirPath;
|
|
1577
|
+
if (!import_fs11.default.existsSync(CLAUDE_PROJECTS_DIR2)) return null;
|
|
1533
1578
|
let allDirs;
|
|
1534
1579
|
try {
|
|
1535
|
-
allDirs =
|
|
1580
|
+
allDirs = import_fs11.default.readdirSync(CLAUDE_PROJECTS_DIR2).filter((d) => {
|
|
1536
1581
|
try {
|
|
1537
|
-
return
|
|
1582
|
+
return import_fs11.default.statSync(import_path11.default.join(CLAUDE_PROJECTS_DIR2, d)).isDirectory();
|
|
1538
1583
|
} catch {
|
|
1539
1584
|
return false;
|
|
1540
1585
|
}
|
|
@@ -1544,23 +1589,23 @@ function findProjectDir(projectPath) {
|
|
|
1544
1589
|
}
|
|
1545
1590
|
const matches = findProjectDirs(allDirs, projectPath);
|
|
1546
1591
|
if (matches.length > 0) {
|
|
1547
|
-
return
|
|
1592
|
+
return import_path11.default.join(CLAUDE_PROJECTS_DIR2, matches[0]);
|
|
1548
1593
|
}
|
|
1549
1594
|
return null;
|
|
1550
1595
|
}
|
|
1551
1596
|
function findSessionFileById(sessionId) {
|
|
1552
1597
|
if (!/^[A-Za-z0-9._-]+$/.test(sessionId)) return null;
|
|
1553
|
-
if (!
|
|
1598
|
+
if (!import_fs11.default.existsSync(CLAUDE_PROJECTS_DIR2)) return null;
|
|
1554
1599
|
let dirs;
|
|
1555
1600
|
try {
|
|
1556
|
-
dirs =
|
|
1601
|
+
dirs = import_fs11.default.readdirSync(CLAUDE_PROJECTS_DIR2);
|
|
1557
1602
|
} catch {
|
|
1558
1603
|
return null;
|
|
1559
1604
|
}
|
|
1560
1605
|
for (const dir of dirs) {
|
|
1561
|
-
const candidate =
|
|
1606
|
+
const candidate = import_path11.default.join(CLAUDE_PROJECTS_DIR2, dir, `${sessionId}.jsonl`);
|
|
1562
1607
|
try {
|
|
1563
|
-
if (
|
|
1608
|
+
if (import_fs11.default.statSync(candidate).isFile()) return candidate;
|
|
1564
1609
|
} catch {
|
|
1565
1610
|
}
|
|
1566
1611
|
}
|
|
@@ -1571,20 +1616,20 @@ function findLatestSessionFile(projectPath) {
|
|
|
1571
1616
|
if (!dirPath) return null;
|
|
1572
1617
|
let entries;
|
|
1573
1618
|
try {
|
|
1574
|
-
entries =
|
|
1619
|
+
entries = import_fs11.default.readdirSync(dirPath);
|
|
1575
1620
|
} catch {
|
|
1576
1621
|
return null;
|
|
1577
1622
|
}
|
|
1578
1623
|
const files = entries.filter((f) => f.endsWith(".jsonl") && !f.includes("/")).map((f) => {
|
|
1579
1624
|
try {
|
|
1580
|
-
return { name: f, mtime:
|
|
1625
|
+
return { name: f, mtime: import_fs11.default.statSync(import_path11.default.join(dirPath, f)).mtimeMs };
|
|
1581
1626
|
} catch {
|
|
1582
1627
|
return null;
|
|
1583
1628
|
}
|
|
1584
1629
|
}).filter((f) => f !== null).sort((a, b) => b.mtime - a.mtime);
|
|
1585
1630
|
if (files.length === 0) return null;
|
|
1586
1631
|
return {
|
|
1587
|
-
filePath:
|
|
1632
|
+
filePath: import_path11.default.join(dirPath, files[0].name),
|
|
1588
1633
|
sessionId: files[0].name.replace(".jsonl", "")
|
|
1589
1634
|
};
|
|
1590
1635
|
}
|
|
@@ -1594,8 +1639,8 @@ async function readConversation(projectPath, afterLine = 0, specificSessionId) {
|
|
|
1594
1639
|
if (specificSessionId) {
|
|
1595
1640
|
sessionId = specificSessionId;
|
|
1596
1641
|
const dirPath = findProjectDir(projectPath);
|
|
1597
|
-
const direct = dirPath ?
|
|
1598
|
-
if (direct &&
|
|
1642
|
+
const direct = dirPath ? import_path11.default.join(dirPath, `${specificSessionId}.jsonl`) : null;
|
|
1643
|
+
if (direct && import_fs11.default.existsSync(direct)) {
|
|
1599
1644
|
filePath = direct;
|
|
1600
1645
|
} else {
|
|
1601
1646
|
const byId = findSessionFileById(specificSessionId);
|
|
@@ -1609,7 +1654,7 @@ async function readConversation(projectPath, afterLine = 0, specificSessionId) {
|
|
|
1609
1654
|
sessionId = found.sessionId;
|
|
1610
1655
|
}
|
|
1611
1656
|
try {
|
|
1612
|
-
const stream =
|
|
1657
|
+
const stream = import_fs11.default.createReadStream(filePath, { encoding: "utf-8" });
|
|
1613
1658
|
const rl = import_readline3.default.createInterface({ input: stream, crlfDelay: Infinity });
|
|
1614
1659
|
const messages = [];
|
|
1615
1660
|
let lineNum = 0;
|
|
@@ -1690,17 +1735,17 @@ async function readConversation(projectPath, afterLine = 0, specificSessionId) {
|
|
|
1690
1735
|
return null;
|
|
1691
1736
|
}
|
|
1692
1737
|
}
|
|
1693
|
-
var
|
|
1738
|
+
var import_fs11, import_path11, import_os8, import_readline3, CLAUDE_PROJECTS_DIR2;
|
|
1694
1739
|
var init_claude_conversation = __esm({
|
|
1695
1740
|
"src/claude-conversation.ts"() {
|
|
1696
1741
|
"use strict";
|
|
1697
|
-
|
|
1698
|
-
|
|
1742
|
+
import_fs11 = __toESM(require("fs"));
|
|
1743
|
+
import_path11 = __toESM(require("path"));
|
|
1699
1744
|
import_os8 = __toESM(require("os"));
|
|
1700
1745
|
import_readline3 = __toESM(require("readline"));
|
|
1701
1746
|
init_logger();
|
|
1702
1747
|
init_claude_path();
|
|
1703
|
-
CLAUDE_PROJECTS_DIR2 =
|
|
1748
|
+
CLAUDE_PROJECTS_DIR2 = import_path11.default.join(import_os8.default.homedir(), ".claude", "projects");
|
|
1704
1749
|
}
|
|
1705
1750
|
});
|
|
1706
1751
|
|
|
@@ -1716,6 +1761,7 @@ var init_index = __esm({
|
|
|
1716
1761
|
init_logger();
|
|
1717
1762
|
init_claude_plugin_installer();
|
|
1718
1763
|
init_local_control();
|
|
1764
|
+
init_pty_helper_fix();
|
|
1719
1765
|
init_tmux();
|
|
1720
1766
|
init_heartbeat();
|
|
1721
1767
|
init_file_explorer();
|
|
@@ -1729,6 +1775,7 @@ var init_index = __esm({
|
|
|
1729
1775
|
}
|
|
1730
1776
|
config = loadConfig();
|
|
1731
1777
|
logger.info({ agentId: config.agentId, serverUrl: config.serverUrl }, "Starting agent");
|
|
1778
|
+
ensurePtyHelperExecutable();
|
|
1732
1779
|
process.on("unhandledRejection", (reason) => {
|
|
1733
1780
|
logger.error({ reason }, "Unhandled promise rejection (agent kept alive)");
|
|
1734
1781
|
});
|