svamp-cli 0.2.44 → 0.2.46
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/{agentCommands-Dlqk61bM.mjs → agentCommands-Bqjcj1EX.mjs} +2 -2
- package/dist/cli.mjs +55 -42
- package/dist/{commands-vzP5AWB0.mjs → commands-B6zZtCuh.mjs} +1 -1
- package/dist/{commands-DYNzHqj8.mjs → commands-Cs5-T_lh.mjs} +12 -3
- package/dist/{commands-DcHNe0bC.mjs → commands-DsCkxa3k.mjs} +4 -4
- package/dist/{frpc-DzRFx60H.mjs → frpc-j60b46eU.mjs} +120 -4
- package/dist/index.mjs +1 -1
- package/dist/{package-bycncAEw.mjs → package-CyXoMaC5.mjs} +1 -1
- package/dist/{run-DwnThKiy.mjs → run-wfhhtkl1.mjs} +373 -62
- package/dist/{run-DBqJkrp6.mjs → run-yJ1mtT8S.mjs} +3 -53
- package/dist/{serveCommands-By_bSGUl.mjs → serveCommands-DhtNhaur.mjs} +4 -4
- package/dist/{serveManager-DOXI2QzY.mjs → serveManager-CUcu_V3q.mjs} +24 -3
- package/dist/{supervisorLock-DwNAn0VN.mjs → supervisorLock-DmfzJx7B.mjs} +5 -3
- package/package.json +1 -1
|
@@ -148,7 +148,7 @@ async function sessionBroadcast(action, args) {
|
|
|
148
148
|
console.log(`Broadcast sent: ${action}`);
|
|
149
149
|
}
|
|
150
150
|
async function connectToMachineService() {
|
|
151
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
151
|
+
const { connectAndGetMachine } = await import('./commands-B6zZtCuh.mjs');
|
|
152
152
|
return connectAndGetMachine();
|
|
153
153
|
}
|
|
154
154
|
async function inboxSend(targetSessionId, opts) {
|
|
@@ -165,7 +165,7 @@ async function inboxSend(targetSessionId, opts) {
|
|
|
165
165
|
}
|
|
166
166
|
const { server, machine } = await connectToMachineService();
|
|
167
167
|
try {
|
|
168
|
-
const { resolveSessionId } = await import('./commands-
|
|
168
|
+
const { resolveSessionId } = await import('./commands-B6zZtCuh.mjs');
|
|
169
169
|
const sessions = await machine.listSessions();
|
|
170
170
|
const match = resolveSessionId(sessions, targetSessionId);
|
|
171
171
|
const fullTargetId = match.sessionId;
|
package/dist/cli.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { s as startDaemon, b as stopDaemon, d as daemonStatus } from './run-
|
|
1
|
+
import { s as startDaemon, b as stopDaemon, d as daemonStatus } from './run-wfhhtkl1.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|
|
@@ -42,7 +42,7 @@ async function main() {
|
|
|
42
42
|
console.error(`svamp daemon restart: ${err.message || err}`);
|
|
43
43
|
process.exit(1);
|
|
44
44
|
}
|
|
45
|
-
const { restartDaemon } = await import('./run-
|
|
45
|
+
const { restartDaemon } = await import('./run-wfhhtkl1.mjs').then(function (n) { return n.o; });
|
|
46
46
|
await restartDaemon();
|
|
47
47
|
process.exit(0);
|
|
48
48
|
}
|
|
@@ -54,6 +54,14 @@ async function main() {
|
|
|
54
54
|
process.exit(1);
|
|
55
55
|
}
|
|
56
56
|
const { spawn } = await import('child_process');
|
|
57
|
+
const { existsSync, mkdirSync, openSync, closeSync, statSync } = await import('fs');
|
|
58
|
+
const { join } = await import('path');
|
|
59
|
+
const os = await import('os');
|
|
60
|
+
const svampHome = process.env.SVAMP_HOME || join(os.homedir(), ".svamp");
|
|
61
|
+
const logsDir = join(svampHome, "logs");
|
|
62
|
+
mkdirSync(logsDir, { recursive: true });
|
|
63
|
+
const bootLogPath = join(logsDir, "daemon-boot.log");
|
|
64
|
+
const bootFd = openSync(bootLogPath, "a");
|
|
57
65
|
const extraArgs = [];
|
|
58
66
|
if (args.includes("--no-auto-continue")) extraArgs.push("--no-auto-continue");
|
|
59
67
|
const child = spawn(process.execPath, [
|
|
@@ -66,17 +74,15 @@ async function main() {
|
|
|
66
74
|
...extraArgs
|
|
67
75
|
], {
|
|
68
76
|
detached: true,
|
|
69
|
-
stdio: "ignore",
|
|
77
|
+
stdio: ["ignore", bootFd, bootFd],
|
|
70
78
|
env: process.env
|
|
71
79
|
});
|
|
80
|
+
try {
|
|
81
|
+
closeSync(bootFd);
|
|
82
|
+
} catch {
|
|
83
|
+
}
|
|
72
84
|
child.unref();
|
|
73
|
-
const
|
|
74
|
-
const { join } = await import('path');
|
|
75
|
-
const os = await import('os');
|
|
76
|
-
const stateFile = join(
|
|
77
|
-
process.env.SVAMP_HOME || join(os.homedir(), ".svamp"),
|
|
78
|
-
"daemon.state.json"
|
|
79
|
-
);
|
|
85
|
+
const stateFile = join(svampHome, "daemon.state.json");
|
|
80
86
|
let started = false;
|
|
81
87
|
for (let i = 0; i < 100; i++) {
|
|
82
88
|
await new Promise((r) => setTimeout(r, 100));
|
|
@@ -88,7 +94,14 @@ async function main() {
|
|
|
88
94
|
if (started) {
|
|
89
95
|
console.log("Daemon started successfully");
|
|
90
96
|
} else {
|
|
91
|
-
|
|
97
|
+
let bootHint = "";
|
|
98
|
+
try {
|
|
99
|
+
const st = statSync(bootLogPath);
|
|
100
|
+
if (st.size > 0) bootHint = `
|
|
101
|
+
Check boot log for errors: ${bootLogPath}`;
|
|
102
|
+
} catch {
|
|
103
|
+
}
|
|
104
|
+
console.error(`Failed to start daemon (timeout waiting for state file)${bootHint}`);
|
|
92
105
|
process.exit(1);
|
|
93
106
|
}
|
|
94
107
|
process.exit(0);
|
|
@@ -115,7 +128,7 @@ async function main() {
|
|
|
115
128
|
releaseSupervisorLock,
|
|
116
129
|
findOrphanedSyncPids,
|
|
117
130
|
killOrphanedSyncs
|
|
118
|
-
} = await import('./supervisorLock-
|
|
131
|
+
} = await import('./supervisorLock-DmfzJx7B.mjs');
|
|
119
132
|
const supervisorPidFile = pathJoin(svampHome, "supervisor.pid");
|
|
120
133
|
const lock = acquireSupervisorLockWithRetry(supervisorPidFile, process.pid);
|
|
121
134
|
if (!lock.acquired) {
|
|
@@ -264,7 +277,7 @@ async function main() {
|
|
|
264
277
|
console.error("svamp service: Service commands are not available in sandboxed sessions.");
|
|
265
278
|
process.exit(1);
|
|
266
279
|
}
|
|
267
|
-
const { handleServiceCommand } = await import('./commands-
|
|
280
|
+
const { handleServiceCommand } = await import('./commands-DsCkxa3k.mjs');
|
|
268
281
|
await handleServiceCommand();
|
|
269
282
|
} else if (subcommand === "serve") {
|
|
270
283
|
const { isSandboxed: isSandboxedServe } = await import('./sandboxDetect-DNTcbgWD.mjs');
|
|
@@ -272,7 +285,7 @@ async function main() {
|
|
|
272
285
|
console.error("svamp serve: Serve commands are not available in sandboxed sessions.");
|
|
273
286
|
process.exit(1);
|
|
274
287
|
}
|
|
275
|
-
const { handleServeCommand } = await import('./serveCommands-
|
|
288
|
+
const { handleServeCommand } = await import('./serveCommands-DhtNhaur.mjs');
|
|
276
289
|
await handleServeCommand();
|
|
277
290
|
process.exit(0);
|
|
278
291
|
} else if (subcommand === "process" || subcommand === "proc") {
|
|
@@ -281,7 +294,7 @@ async function main() {
|
|
|
281
294
|
console.error("svamp process: Process commands are not available in sandboxed sessions.");
|
|
282
295
|
process.exit(1);
|
|
283
296
|
}
|
|
284
|
-
const { processCommand } = await import('./commands-
|
|
297
|
+
const { processCommand } = await import('./commands-Cs5-T_lh.mjs');
|
|
285
298
|
let machineId;
|
|
286
299
|
const processArgs = args.slice(1);
|
|
287
300
|
const mIdx = processArgs.findIndex((a) => a === "--machine" || a === "-m");
|
|
@@ -299,7 +312,7 @@ async function main() {
|
|
|
299
312
|
} else if (!subcommand || subcommand === "start") {
|
|
300
313
|
await handleInteractiveCommand();
|
|
301
314
|
} else if (subcommand === "--version" || subcommand === "-v") {
|
|
302
|
-
const pkg = await import('./package-
|
|
315
|
+
const pkg = await import('./package-CyXoMaC5.mjs').catch(() => ({ default: { version: "unknown" } }));
|
|
303
316
|
console.log(`svamp version: ${pkg.default.version}`);
|
|
304
317
|
} else {
|
|
305
318
|
console.error(`Unknown command: ${subcommand}`);
|
|
@@ -308,7 +321,7 @@ async function main() {
|
|
|
308
321
|
}
|
|
309
322
|
}
|
|
310
323
|
async function handleInteractiveCommand() {
|
|
311
|
-
const { runInteractive } = await import('./run-
|
|
324
|
+
const { runInteractive } = await import('./run-yJ1mtT8S.mjs');
|
|
312
325
|
const interactiveArgs = subcommand === "start" ? args.slice(1) : args;
|
|
313
326
|
let directory = process.cwd();
|
|
314
327
|
let resumeSessionId;
|
|
@@ -353,7 +366,7 @@ async function handleAgentCommand() {
|
|
|
353
366
|
return;
|
|
354
367
|
}
|
|
355
368
|
if (agentArgs[0] === "list") {
|
|
356
|
-
const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-
|
|
369
|
+
const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-wfhhtkl1.mjs').then(function (n) { return n.j; });
|
|
357
370
|
console.log("Known agents:");
|
|
358
371
|
for (const [name, config2] of Object.entries(KNOWN_ACP_AGENTS)) {
|
|
359
372
|
console.log(` ${name.padEnd(12)} ${config2.command} ${config2.args.join(" ")} (ACP)`);
|
|
@@ -365,7 +378,7 @@ async function handleAgentCommand() {
|
|
|
365
378
|
console.log('Use "svamp agent -- <command> [args]" for a custom ACP agent.');
|
|
366
379
|
return;
|
|
367
380
|
}
|
|
368
|
-
const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-
|
|
381
|
+
const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-wfhhtkl1.mjs').then(function (n) { return n.j; });
|
|
369
382
|
let cwd = process.cwd();
|
|
370
383
|
const filteredArgs = [];
|
|
371
384
|
for (let i = 0; i < agentArgs.length; i++) {
|
|
@@ -389,12 +402,12 @@ async function handleAgentCommand() {
|
|
|
389
402
|
console.log(`Starting ${config.agentName} agent in ${cwd}...`);
|
|
390
403
|
let backend;
|
|
391
404
|
if (KNOWN_MCP_AGENTS[config.agentName]) {
|
|
392
|
-
const { CodexMcpBackend } = await import('./run-
|
|
405
|
+
const { CodexMcpBackend } = await import('./run-wfhhtkl1.mjs').then(function (n) { return n.k; });
|
|
393
406
|
backend = new CodexMcpBackend({ cwd, log: logFn });
|
|
394
407
|
} else {
|
|
395
|
-
const { AcpBackend } = await import('./run-
|
|
396
|
-
const { GeminiTransport } = await import('./run-
|
|
397
|
-
const { DefaultTransport } = await import('./run-
|
|
408
|
+
const { AcpBackend } = await import('./run-wfhhtkl1.mjs').then(function (n) { return n.i; });
|
|
409
|
+
const { GeminiTransport } = await import('./run-wfhhtkl1.mjs').then(function (n) { return n.G; });
|
|
410
|
+
const { DefaultTransport } = await import('./run-wfhhtkl1.mjs').then(function (n) { return n.D; });
|
|
398
411
|
const transportHandler = config.agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(config.agentName);
|
|
399
412
|
backend = new AcpBackend({
|
|
400
413
|
agentName: config.agentName,
|
|
@@ -521,7 +534,7 @@ async function handleSessionCommand() {
|
|
|
521
534
|
process.exit(1);
|
|
522
535
|
}
|
|
523
536
|
}
|
|
524
|
-
const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-
|
|
537
|
+
const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-B6zZtCuh.mjs');
|
|
525
538
|
const parseFlagStr = (flag, shortFlag) => {
|
|
526
539
|
for (let i = 1; i < sessionArgs.length; i++) {
|
|
527
540
|
if ((sessionArgs[i] === flag || shortFlag) && i + 1 < sessionArgs.length) {
|
|
@@ -581,7 +594,7 @@ async function handleSessionCommand() {
|
|
|
581
594
|
allowDomain.push(sessionArgs[++i]);
|
|
582
595
|
}
|
|
583
596
|
}
|
|
584
|
-
const { parseShareArg } = await import('./commands-
|
|
597
|
+
const { parseShareArg } = await import('./commands-B6zZtCuh.mjs');
|
|
585
598
|
const shareEntries = share.map((s) => parseShareArg(s));
|
|
586
599
|
await sessionSpawn(agent, dir, targetMachineId, {
|
|
587
600
|
message,
|
|
@@ -667,7 +680,7 @@ async function handleSessionCommand() {
|
|
|
667
680
|
console.error("Usage: svamp session approve <session-id> [request-id] [--json]");
|
|
668
681
|
process.exit(1);
|
|
669
682
|
}
|
|
670
|
-
const { sessionApprove } = await import('./commands-
|
|
683
|
+
const { sessionApprove } = await import('./commands-B6zZtCuh.mjs');
|
|
671
684
|
const approveReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
672
685
|
await sessionApprove(sessionArgs[1], approveReqId, targetMachineId, {
|
|
673
686
|
json: hasFlag("--json")
|
|
@@ -677,7 +690,7 @@ async function handleSessionCommand() {
|
|
|
677
690
|
console.error("Usage: svamp session deny <session-id> [request-id] [--json]");
|
|
678
691
|
process.exit(1);
|
|
679
692
|
}
|
|
680
|
-
const { sessionDeny } = await import('./commands-
|
|
693
|
+
const { sessionDeny } = await import('./commands-B6zZtCuh.mjs');
|
|
681
694
|
const denyReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
682
695
|
await sessionDeny(sessionArgs[1], denyReqId, targetMachineId, {
|
|
683
696
|
json: hasFlag("--json")
|
|
@@ -713,7 +726,7 @@ async function handleSessionCommand() {
|
|
|
713
726
|
console.error("Usage: svamp session set-title <title>");
|
|
714
727
|
process.exit(1);
|
|
715
728
|
}
|
|
716
|
-
const { sessionSetTitle } = await import('./agentCommands-
|
|
729
|
+
const { sessionSetTitle } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
717
730
|
await sessionSetTitle(title);
|
|
718
731
|
} else if (sessionSubcommand === "set-link") {
|
|
719
732
|
const url = sessionArgs[1];
|
|
@@ -722,7 +735,7 @@ async function handleSessionCommand() {
|
|
|
722
735
|
process.exit(1);
|
|
723
736
|
}
|
|
724
737
|
const label = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
725
|
-
const { sessionSetLink } = await import('./agentCommands-
|
|
738
|
+
const { sessionSetLink } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
726
739
|
await sessionSetLink(url, label);
|
|
727
740
|
} else if (sessionSubcommand === "notify") {
|
|
728
741
|
const message = sessionArgs[1];
|
|
@@ -731,7 +744,7 @@ async function handleSessionCommand() {
|
|
|
731
744
|
process.exit(1);
|
|
732
745
|
}
|
|
733
746
|
const level = parseFlagStr("--level") || "info";
|
|
734
|
-
const { sessionNotify } = await import('./agentCommands-
|
|
747
|
+
const { sessionNotify } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
735
748
|
await sessionNotify(message, level);
|
|
736
749
|
} else if (sessionSubcommand === "broadcast") {
|
|
737
750
|
const action = sessionArgs[1];
|
|
@@ -739,7 +752,7 @@ async function handleSessionCommand() {
|
|
|
739
752
|
console.error("Usage: svamp session broadcast <action> [args...]\nActions: open-canvas <url> [label], close-canvas, toast <message>");
|
|
740
753
|
process.exit(1);
|
|
741
754
|
}
|
|
742
|
-
const { sessionBroadcast } = await import('./agentCommands-
|
|
755
|
+
const { sessionBroadcast } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
743
756
|
await sessionBroadcast(action, sessionArgs.slice(2).filter((a) => !a.startsWith("--")));
|
|
744
757
|
} else if (sessionSubcommand === "inbox") {
|
|
745
758
|
const inboxSubcmd = sessionArgs[1];
|
|
@@ -750,7 +763,7 @@ async function handleSessionCommand() {
|
|
|
750
763
|
process.exit(1);
|
|
751
764
|
}
|
|
752
765
|
if (agentSessionId) {
|
|
753
|
-
const { inboxSend } = await import('./agentCommands-
|
|
766
|
+
const { inboxSend } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
754
767
|
await inboxSend(sessionArgs[2], {
|
|
755
768
|
body: sessionArgs[3],
|
|
756
769
|
subject: parseFlagStr("--subject"),
|
|
@@ -765,7 +778,7 @@ async function handleSessionCommand() {
|
|
|
765
778
|
}
|
|
766
779
|
} else if (inboxSubcmd === "list" || inboxSubcmd === "ls") {
|
|
767
780
|
if (agentSessionId && !sessionArgs[2]) {
|
|
768
|
-
const { inboxList } = await import('./agentCommands-
|
|
781
|
+
const { inboxList } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
769
782
|
await inboxList({
|
|
770
783
|
unread: hasFlag("--unread"),
|
|
771
784
|
limit: parseFlagInt("--limit"),
|
|
@@ -787,7 +800,7 @@ async function handleSessionCommand() {
|
|
|
787
800
|
process.exit(1);
|
|
788
801
|
}
|
|
789
802
|
if (agentSessionId && !sessionArgs[3]) {
|
|
790
|
-
const { inboxList } = await import('./agentCommands-
|
|
803
|
+
const { inboxList } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
791
804
|
await sessionInboxRead(agentSessionId, sessionArgs[2], targetMachineId);
|
|
792
805
|
} else if (sessionArgs[3]) {
|
|
793
806
|
await sessionInboxRead(sessionArgs[2], sessionArgs[3], targetMachineId);
|
|
@@ -797,7 +810,7 @@ async function handleSessionCommand() {
|
|
|
797
810
|
}
|
|
798
811
|
} else if (inboxSubcmd === "reply") {
|
|
799
812
|
if (agentSessionId && sessionArgs[2] && sessionArgs[3] && !sessionArgs[4]) {
|
|
800
|
-
const { inboxReply } = await import('./agentCommands-
|
|
813
|
+
const { inboxReply } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
801
814
|
await inboxReply(sessionArgs[2], sessionArgs[3]);
|
|
802
815
|
} else if (sessionArgs[2] && sessionArgs[3] && sessionArgs[4]) {
|
|
803
816
|
await sessionInboxReply(sessionArgs[2], sessionArgs[3], sessionArgs[4], targetMachineId);
|
|
@@ -833,7 +846,7 @@ async function handleMachineCommand() {
|
|
|
833
846
|
return;
|
|
834
847
|
}
|
|
835
848
|
if (machineSubcommand === "share") {
|
|
836
|
-
const { machineShare } = await import('./commands-
|
|
849
|
+
const { machineShare } = await import('./commands-B6zZtCuh.mjs');
|
|
837
850
|
let machineId;
|
|
838
851
|
const shareArgs = [];
|
|
839
852
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
@@ -863,7 +876,7 @@ async function handleMachineCommand() {
|
|
|
863
876
|
}
|
|
864
877
|
await machineShare(machineId, { add, remove, list, configPath, showConfig });
|
|
865
878
|
} else if (machineSubcommand === "exec") {
|
|
866
|
-
const { machineExec } = await import('./commands-
|
|
879
|
+
const { machineExec } = await import('./commands-B6zZtCuh.mjs');
|
|
867
880
|
let machineId;
|
|
868
881
|
let cwd;
|
|
869
882
|
const cmdParts = [];
|
|
@@ -883,7 +896,7 @@ async function handleMachineCommand() {
|
|
|
883
896
|
}
|
|
884
897
|
await machineExec(machineId, command, cwd);
|
|
885
898
|
} else if (machineSubcommand === "info") {
|
|
886
|
-
const { machineInfo } = await import('./commands-
|
|
899
|
+
const { machineInfo } = await import('./commands-B6zZtCuh.mjs');
|
|
887
900
|
let machineId;
|
|
888
901
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
889
902
|
if ((machineArgs[i] === "--machine" || machineArgs[i] === "-m") && i + 1 < machineArgs.length) {
|
|
@@ -903,10 +916,10 @@ async function handleMachineCommand() {
|
|
|
903
916
|
level = machineArgs[++i];
|
|
904
917
|
}
|
|
905
918
|
}
|
|
906
|
-
const { machineNotify } = await import('./agentCommands-
|
|
919
|
+
const { machineNotify } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
907
920
|
await machineNotify(message, level);
|
|
908
921
|
} else if (machineSubcommand === "ls") {
|
|
909
|
-
const { machineLs } = await import('./commands-
|
|
922
|
+
const { machineLs } = await import('./commands-B6zZtCuh.mjs');
|
|
910
923
|
let machineId;
|
|
911
924
|
let showHidden = false;
|
|
912
925
|
let path;
|
|
@@ -1368,7 +1381,7 @@ async function applyClaudeAuthFlags(argv) {
|
|
|
1368
1381
|
"--use-hypha-proxy, --use-claude-login, and --anthropic-base-url/--anthropic-api-key are mutually exclusive"
|
|
1369
1382
|
);
|
|
1370
1383
|
}
|
|
1371
|
-
const mod = await import('./run-
|
|
1384
|
+
const mod = await import('./run-wfhhtkl1.mjs').then(function (n) { return n.n; });
|
|
1372
1385
|
if (hasHypha) {
|
|
1373
1386
|
mod.setClaudeAuthHyphaProxy();
|
|
1374
1387
|
console.log("Claude auth configured: hypha-proxy (uses HYPHA_TOKEN live at each spawn).");
|
|
@@ -1391,7 +1404,7 @@ async function applyClaudeAuthFlags(argv) {
|
|
|
1391
1404
|
}
|
|
1392
1405
|
async function handleDaemonAuthCommand(argv) {
|
|
1393
1406
|
const sub = (argv[0] || "status").toLowerCase();
|
|
1394
|
-
const mod = await import('./run-
|
|
1407
|
+
const mod = await import('./run-wfhhtkl1.mjs').then(function (n) { return n.n; });
|
|
1395
1408
|
if (sub === "--help" || sub === "-h" || sub === "help") {
|
|
1396
1409
|
console.log(`
|
|
1397
1410
|
svamp daemon auth \u2014 Configure how Claude subprocesses authenticate
|
|
@@ -2,7 +2,7 @@ import { existsSync, readFileSync } from 'node:fs';
|
|
|
2
2
|
import { execSync } from 'node:child_process';
|
|
3
3
|
import { resolve, join } from 'node:path';
|
|
4
4
|
import os from 'node:os';
|
|
5
|
-
import { l as loadSecurityContextConfig, e as resolveSecurityContext, f as buildSecurityContextFromFlags, m as mergeSecurityContexts, c as connectToHypha } from './run-
|
|
5
|
+
import { l as loadSecurityContextConfig, e as resolveSecurityContext, f as buildSecurityContextFromFlags, m as mergeSecurityContexts, c as connectToHypha } from './run-wfhhtkl1.mjs';
|
|
6
6
|
import 'os';
|
|
7
7
|
import 'fs/promises';
|
|
8
8
|
import 'fs';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { writeFileSync, readFileSync } from 'fs';
|
|
2
2
|
import { resolve } from 'path';
|
|
3
|
-
import { connectAndGetMachine } from './commands-
|
|
3
|
+
import { connectAndGetMachine } from './commands-B6zZtCuh.mjs';
|
|
4
4
|
import 'node:fs';
|
|
5
5
|
import 'node:child_process';
|
|
6
6
|
import 'node:path';
|
|
7
7
|
import 'node:os';
|
|
8
|
-
import './run-
|
|
8
|
+
import './run-wfhhtkl1.mjs';
|
|
9
9
|
import 'os';
|
|
10
10
|
import 'fs/promises';
|
|
11
11
|
import 'url';
|
|
@@ -186,6 +186,8 @@ function statusIcon(status) {
|
|
|
186
186
|
return "\u231B";
|
|
187
187
|
case "stopping":
|
|
188
188
|
return "\u2193";
|
|
189
|
+
case "crash-loop-backoff":
|
|
190
|
+
return "\u26A0";
|
|
189
191
|
default:
|
|
190
192
|
return "?";
|
|
191
193
|
}
|
|
@@ -211,7 +213,7 @@ function printProcessTable(processes) {
|
|
|
211
213
|
return;
|
|
212
214
|
}
|
|
213
215
|
const cols = ["NAME", "STATUS", "PID", "RESTARTS", "UPTIME", "PROBE", "TTL"];
|
|
214
|
-
const widths = [24,
|
|
216
|
+
const widths = [24, 21, 8, 10, 10, 8, 8];
|
|
215
217
|
const header = cols.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
216
218
|
console.log(header);
|
|
217
219
|
console.log("\u2500".repeat(header.length));
|
|
@@ -239,6 +241,13 @@ Process: ${spec.name}`);
|
|
|
239
241
|
console.log(` Keep-alive: ${spec.keepAlive}${spec.maxRestarts > 0 ? ` (max ${spec.maxRestarts})` : ""}`);
|
|
240
242
|
if (state.restartCount > 0) console.log(` Restarts: ${state.restartCount}`);
|
|
241
243
|
if (state.startedAt) console.log(` Uptime: ${formatUptime(state.startedAt)}`);
|
|
244
|
+
if (state.crashLoopBackOff) {
|
|
245
|
+
const c = state.crashLoopBackOff;
|
|
246
|
+
const ago = Math.round((Date.now() - c.enteredAt) / 1e3);
|
|
247
|
+
const windowS = Math.round((c.enteredAt - c.windowStart) / 1e3);
|
|
248
|
+
console.log(` CrashLoop: \u26A0 ${c.failureCount} failures in ${windowS}s (entered ${ago}s ago)`);
|
|
249
|
+
console.log(` Run 'svamp process restart ${spec.name}' to retry.`);
|
|
250
|
+
}
|
|
242
251
|
if (spec.probe) {
|
|
243
252
|
const p = spec.probe;
|
|
244
253
|
const lp = state.lastProbe;
|
|
@@ -55,7 +55,7 @@ async function serviceExpose(args) {
|
|
|
55
55
|
console.error("Usage: svamp service expose <name> --port <port> [--port <port2>] [options]");
|
|
56
56
|
process.exit(1);
|
|
57
57
|
}
|
|
58
|
-
const { runFrpcTunnel } = await import('./frpc-
|
|
58
|
+
const { runFrpcTunnel } = await import('./frpc-j60b46eU.mjs');
|
|
59
59
|
await runFrpcTunnel(name, ports, void 0, {
|
|
60
60
|
group,
|
|
61
61
|
groupKey,
|
|
@@ -88,7 +88,7 @@ async function serviceServe(args) {
|
|
|
88
88
|
};
|
|
89
89
|
process.on("SIGINT", cleanup);
|
|
90
90
|
process.on("SIGTERM", cleanup);
|
|
91
|
-
const { runFrpcTunnel } = await import('./frpc-
|
|
91
|
+
const { runFrpcTunnel } = await import('./frpc-j60b46eU.mjs');
|
|
92
92
|
await runFrpcTunnel(name, [caddyPort]);
|
|
93
93
|
} catch (err) {
|
|
94
94
|
console.error(`Error serving directory: ${err.message}`);
|
|
@@ -97,7 +97,7 @@ async function serviceServe(args) {
|
|
|
97
97
|
}
|
|
98
98
|
async function serviceList(_args) {
|
|
99
99
|
try {
|
|
100
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
100
|
+
const { connectAndGetMachine } = await import('./commands-B6zZtCuh.mjs');
|
|
101
101
|
const { server, machine } = await connectAndGetMachine();
|
|
102
102
|
try {
|
|
103
103
|
const tunnels = await machine.tunnelList({});
|
|
@@ -126,7 +126,7 @@ async function serviceDelete(args) {
|
|
|
126
126
|
process.exit(1);
|
|
127
127
|
}
|
|
128
128
|
try {
|
|
129
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
129
|
+
const { connectAndGetMachine } = await import('./commands-B6zZtCuh.mjs');
|
|
130
130
|
const { server, machine } = await connectAndGetMachine();
|
|
131
131
|
try {
|
|
132
132
|
await machine.tunnelStop({ name });
|
|
@@ -135,8 +135,12 @@ function generateFrpcConfig(config, proxies) {
|
|
|
135
135
|
"",
|
|
136
136
|
"# Transport",
|
|
137
137
|
...useWSS ? ['transport.protocol = "wss"'] : [],
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
// 15s/45s heartbeat — 2x faster failure detection than the frpc default
|
|
139
|
+
// (30s/90s). With matching server-side frps 0.68.x, dead-peer detection
|
|
140
|
+
// settles in well under a minute, so the daemon-side recreate threshold
|
|
141
|
+
// can be tightened too.
|
|
142
|
+
"transport.heartbeatInterval = 15",
|
|
143
|
+
"transport.heartbeatTimeout = 45",
|
|
140
144
|
"transport.poolCount = 5",
|
|
141
145
|
"",
|
|
142
146
|
"# Don't exit on login failure \u2014 let frpc keep retrying",
|
|
@@ -198,6 +202,11 @@ class FrpcTunnel {
|
|
|
198
202
|
_lastErrorAt = 0;
|
|
199
203
|
_firstErrorAt = 0;
|
|
200
204
|
_restartAttempts = 0;
|
|
205
|
+
// End-to-end probe state (set when options.probeUrl is provided).
|
|
206
|
+
_probeTimer = null;
|
|
207
|
+
_lastProbeOkAt = 0;
|
|
208
|
+
_lastProbeFailAt = 0;
|
|
209
|
+
_probeOk = false;
|
|
201
210
|
constructor(options) {
|
|
202
211
|
this.options = options;
|
|
203
212
|
this.log = options.log || ((msg) => console.log(`[FRPC] ${msg}`));
|
|
@@ -269,7 +278,8 @@ class FrpcTunnel {
|
|
|
269
278
|
this._consecutiveErrors = 0;
|
|
270
279
|
this._firstErrorAt = 0;
|
|
271
280
|
this.options.onConnect?.();
|
|
272
|
-
|
|
281
|
+
const probeConfigured = !!(this.options.probeUrl || this.options.probePath);
|
|
282
|
+
if (!resolved && !probeConfigured) {
|
|
273
283
|
resolved = true;
|
|
274
284
|
resolve();
|
|
275
285
|
}
|
|
@@ -312,6 +322,16 @@ class FrpcTunnel {
|
|
|
312
322
|
}, delay);
|
|
313
323
|
}
|
|
314
324
|
});
|
|
325
|
+
if (this.options.probeUrl || this.options.probePath) {
|
|
326
|
+
this.startProbeLoop({
|
|
327
|
+
onFirstOk: () => {
|
|
328
|
+
if (!resolved) {
|
|
329
|
+
resolved = true;
|
|
330
|
+
resolve();
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
}
|
|
315
335
|
setTimeout(() => {
|
|
316
336
|
if (!resolved) {
|
|
317
337
|
resolved = true;
|
|
@@ -321,10 +341,99 @@ class FrpcTunnel {
|
|
|
321
341
|
}, 3e4);
|
|
322
342
|
});
|
|
323
343
|
}
|
|
344
|
+
/** Resolve the effective probe URL, honoring probeUrl > probePath. */
|
|
345
|
+
resolveProbeUrl() {
|
|
346
|
+
if (this.options.probeUrl) return this.options.probeUrl;
|
|
347
|
+
if (this.options.probePath) {
|
|
348
|
+
const base = this.getUrls().get(this.options.ports[0]);
|
|
349
|
+
if (!base) return null;
|
|
350
|
+
const sep = this.options.probePath.startsWith("/") ? "" : "/";
|
|
351
|
+
return `${base}${sep}${this.options.probePath}`;
|
|
352
|
+
}
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Start an end-to-end probe loop against the resolved probe URL.
|
|
357
|
+
* Updates _probeOk + timestamps and fires onProbeFail on transitions.
|
|
358
|
+
* Called from connect(); cleaned up in destroy().
|
|
359
|
+
*/
|
|
360
|
+
startProbeLoop(opts = {}) {
|
|
361
|
+
const probeUrl = this.resolveProbeUrl();
|
|
362
|
+
if (!probeUrl) return;
|
|
363
|
+
this.stopProbeLoop();
|
|
364
|
+
const intervalMs = this.options.probeIntervalMs ?? 3e4;
|
|
365
|
+
let firstOkFired = false;
|
|
366
|
+
let inFlight = false;
|
|
367
|
+
const runProbe = async () => {
|
|
368
|
+
if (this._destroyed || inFlight) return;
|
|
369
|
+
inFlight = true;
|
|
370
|
+
try {
|
|
371
|
+
const ctrl = new AbortController();
|
|
372
|
+
const timer = setTimeout(() => ctrl.abort(), 1e4);
|
|
373
|
+
let resp;
|
|
374
|
+
try {
|
|
375
|
+
resp = await fetch(probeUrl, {
|
|
376
|
+
method: "GET",
|
|
377
|
+
signal: ctrl.signal,
|
|
378
|
+
// Don't follow redirects — we just want any 2xx/3xx.
|
|
379
|
+
redirect: "manual",
|
|
380
|
+
headers: { "User-Agent": "svamp-frpc-probe/1" }
|
|
381
|
+
});
|
|
382
|
+
} finally {
|
|
383
|
+
clearTimeout(timer);
|
|
384
|
+
}
|
|
385
|
+
if (resp.status < 400) {
|
|
386
|
+
const wasFailing = !this._probeOk;
|
|
387
|
+
this._probeOk = true;
|
|
388
|
+
this._lastProbeOkAt = Date.now();
|
|
389
|
+
if (wasFailing) {
|
|
390
|
+
this.log(`probe ok: ${probeUrl} (${resp.status})`);
|
|
391
|
+
}
|
|
392
|
+
if (!firstOkFired && opts.onFirstOk) {
|
|
393
|
+
firstOkFired = true;
|
|
394
|
+
opts.onFirstOk();
|
|
395
|
+
}
|
|
396
|
+
} else {
|
|
397
|
+
throw new Error(`probe got ${resp.status}`);
|
|
398
|
+
}
|
|
399
|
+
} catch (err) {
|
|
400
|
+
const wasOk = this._probeOk;
|
|
401
|
+
this._probeOk = false;
|
|
402
|
+
this._lastProbeFailAt = Date.now();
|
|
403
|
+
if (wasOk) {
|
|
404
|
+
this.log(`probe failed: ${err?.message || err}`);
|
|
405
|
+
this.options.onProbeFail?.(err instanceof Error ? err : new Error(String(err)));
|
|
406
|
+
}
|
|
407
|
+
} finally {
|
|
408
|
+
inFlight = false;
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
const initialDelays = [500, 2e3, 5e3, 1e4];
|
|
412
|
+
let burstIdx = 0;
|
|
413
|
+
const burstTimer = setInterval(() => {
|
|
414
|
+
if (this._destroyed || firstOkFired || burstIdx >= initialDelays.length) {
|
|
415
|
+
clearInterval(burstTimer);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
burstIdx++;
|
|
419
|
+
void runProbe();
|
|
420
|
+
}, 1500);
|
|
421
|
+
if (intervalMs > 0) {
|
|
422
|
+
this._probeTimer = setInterval(runProbe, intervalMs);
|
|
423
|
+
}
|
|
424
|
+
void runProbe();
|
|
425
|
+
}
|
|
426
|
+
stopProbeLoop() {
|
|
427
|
+
if (this._probeTimer) {
|
|
428
|
+
clearInterval(this._probeTimer);
|
|
429
|
+
this._probeTimer = null;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
324
432
|
/** Disconnect and stop the frpc process. */
|
|
325
433
|
destroy() {
|
|
326
434
|
this._destroyed = true;
|
|
327
435
|
this._connected = false;
|
|
436
|
+
this.stopProbeLoop();
|
|
328
437
|
if (this.process) {
|
|
329
438
|
this.process.kill("SIGTERM");
|
|
330
439
|
const p = this.process;
|
|
@@ -359,7 +468,14 @@ class FrpcTunnel {
|
|
|
359
468
|
lastErrorAt: this._lastErrorAt,
|
|
360
469
|
firstErrorAt: this._firstErrorAt,
|
|
361
470
|
restartAttempts: this._restartAttempts,
|
|
362
|
-
failingDurationMs: this._firstErrorAt > 0 ? Date.now() - this._firstErrorAt : 0
|
|
471
|
+
failingDurationMs: this._firstErrorAt > 0 ? Date.now() - this._firstErrorAt : 0,
|
|
472
|
+
probe: this.resolveProbeUrl() ? {
|
|
473
|
+
url: this.resolveProbeUrl(),
|
|
474
|
+
ok: this._probeOk,
|
|
475
|
+
lastOkAt: this._lastProbeOkAt,
|
|
476
|
+
lastFailAt: this._lastProbeFailAt,
|
|
477
|
+
stalenessMs: this._lastProbeOkAt > 0 ? Date.now() - this._lastProbeOkAt : 0
|
|
478
|
+
} : void 0
|
|
363
479
|
};
|
|
364
480
|
}
|
|
365
481
|
/** Update the Hypha token. Rewrites config; takes effect on next frpc restart. */
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { c as connectToHypha, d as daemonStatus, g as getHyphaServerUrl, r as registerMachineService, a as registerSessionService, s as startDaemon, b as stopDaemon } from './run-
|
|
1
|
+
export { c as connectToHypha, d as daemonStatus, g as getHyphaServerUrl, r as registerMachineService, a as registerSessionService, s as startDaemon, b as stopDaemon } from './run-wfhhtkl1.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|