svamp-cli 0.2.45 → 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-dlpOoDcq.mjs → agentCommands-Bqjcj1EX.mjs} +2 -2
- package/dist/cli.mjs +32 -32
- package/dist/{commands-Cd_I1MXo.mjs → commands-B6zZtCuh.mjs} +1 -1
- package/dist/{commands-0xDVhPKr.mjs → commands-Cs5-T_lh.mjs} +12 -3
- package/dist/{commands-C6D6TMSl.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-Cx2tEoke.mjs → package-CyXoMaC5.mjs} +1 -1
- package/dist/{run-D59qJKn_.mjs → run-wfhhtkl1.mjs} +372 -61
- package/dist/{run-DZhogQUH.mjs → run-yJ1mtT8S.mjs} +3 -53
- package/dist/{serveCommands-DtKlt1DY.mjs → serveCommands-DhtNhaur.mjs} +4 -4
- package/dist/{serveManager-DOXI2QzY.mjs → serveManager-CUcu_V3q.mjs} +24 -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
|
}
|
|
@@ -277,7 +277,7 @@ async function main() {
|
|
|
277
277
|
console.error("svamp service: Service commands are not available in sandboxed sessions.");
|
|
278
278
|
process.exit(1);
|
|
279
279
|
}
|
|
280
|
-
const { handleServiceCommand } = await import('./commands-
|
|
280
|
+
const { handleServiceCommand } = await import('./commands-DsCkxa3k.mjs');
|
|
281
281
|
await handleServiceCommand();
|
|
282
282
|
} else if (subcommand === "serve") {
|
|
283
283
|
const { isSandboxed: isSandboxedServe } = await import('./sandboxDetect-DNTcbgWD.mjs');
|
|
@@ -285,7 +285,7 @@ async function main() {
|
|
|
285
285
|
console.error("svamp serve: Serve commands are not available in sandboxed sessions.");
|
|
286
286
|
process.exit(1);
|
|
287
287
|
}
|
|
288
|
-
const { handleServeCommand } = await import('./serveCommands-
|
|
288
|
+
const { handleServeCommand } = await import('./serveCommands-DhtNhaur.mjs');
|
|
289
289
|
await handleServeCommand();
|
|
290
290
|
process.exit(0);
|
|
291
291
|
} else if (subcommand === "process" || subcommand === "proc") {
|
|
@@ -294,7 +294,7 @@ async function main() {
|
|
|
294
294
|
console.error("svamp process: Process commands are not available in sandboxed sessions.");
|
|
295
295
|
process.exit(1);
|
|
296
296
|
}
|
|
297
|
-
const { processCommand } = await import('./commands-
|
|
297
|
+
const { processCommand } = await import('./commands-Cs5-T_lh.mjs');
|
|
298
298
|
let machineId;
|
|
299
299
|
const processArgs = args.slice(1);
|
|
300
300
|
const mIdx = processArgs.findIndex((a) => a === "--machine" || a === "-m");
|
|
@@ -312,7 +312,7 @@ async function main() {
|
|
|
312
312
|
} else if (!subcommand || subcommand === "start") {
|
|
313
313
|
await handleInteractiveCommand();
|
|
314
314
|
} else if (subcommand === "--version" || subcommand === "-v") {
|
|
315
|
-
const pkg = await import('./package-
|
|
315
|
+
const pkg = await import('./package-CyXoMaC5.mjs').catch(() => ({ default: { version: "unknown" } }));
|
|
316
316
|
console.log(`svamp version: ${pkg.default.version}`);
|
|
317
317
|
} else {
|
|
318
318
|
console.error(`Unknown command: ${subcommand}`);
|
|
@@ -321,7 +321,7 @@ async function main() {
|
|
|
321
321
|
}
|
|
322
322
|
}
|
|
323
323
|
async function handleInteractiveCommand() {
|
|
324
|
-
const { runInteractive } = await import('./run-
|
|
324
|
+
const { runInteractive } = await import('./run-yJ1mtT8S.mjs');
|
|
325
325
|
const interactiveArgs = subcommand === "start" ? args.slice(1) : args;
|
|
326
326
|
let directory = process.cwd();
|
|
327
327
|
let resumeSessionId;
|
|
@@ -366,7 +366,7 @@ async function handleAgentCommand() {
|
|
|
366
366
|
return;
|
|
367
367
|
}
|
|
368
368
|
if (agentArgs[0] === "list") {
|
|
369
|
-
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; });
|
|
370
370
|
console.log("Known agents:");
|
|
371
371
|
for (const [name, config2] of Object.entries(KNOWN_ACP_AGENTS)) {
|
|
372
372
|
console.log(` ${name.padEnd(12)} ${config2.command} ${config2.args.join(" ")} (ACP)`);
|
|
@@ -378,7 +378,7 @@ async function handleAgentCommand() {
|
|
|
378
378
|
console.log('Use "svamp agent -- <command> [args]" for a custom ACP agent.');
|
|
379
379
|
return;
|
|
380
380
|
}
|
|
381
|
-
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; });
|
|
382
382
|
let cwd = process.cwd();
|
|
383
383
|
const filteredArgs = [];
|
|
384
384
|
for (let i = 0; i < agentArgs.length; i++) {
|
|
@@ -402,12 +402,12 @@ async function handleAgentCommand() {
|
|
|
402
402
|
console.log(`Starting ${config.agentName} agent in ${cwd}...`);
|
|
403
403
|
let backend;
|
|
404
404
|
if (KNOWN_MCP_AGENTS[config.agentName]) {
|
|
405
|
-
const { CodexMcpBackend } = await import('./run-
|
|
405
|
+
const { CodexMcpBackend } = await import('./run-wfhhtkl1.mjs').then(function (n) { return n.k; });
|
|
406
406
|
backend = new CodexMcpBackend({ cwd, log: logFn });
|
|
407
407
|
} else {
|
|
408
|
-
const { AcpBackend } = await import('./run-
|
|
409
|
-
const { GeminiTransport } = await import('./run-
|
|
410
|
-
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; });
|
|
411
411
|
const transportHandler = config.agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(config.agentName);
|
|
412
412
|
backend = new AcpBackend({
|
|
413
413
|
agentName: config.agentName,
|
|
@@ -534,7 +534,7 @@ async function handleSessionCommand() {
|
|
|
534
534
|
process.exit(1);
|
|
535
535
|
}
|
|
536
536
|
}
|
|
537
|
-
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');
|
|
538
538
|
const parseFlagStr = (flag, shortFlag) => {
|
|
539
539
|
for (let i = 1; i < sessionArgs.length; i++) {
|
|
540
540
|
if ((sessionArgs[i] === flag || shortFlag) && i + 1 < sessionArgs.length) {
|
|
@@ -594,7 +594,7 @@ async function handleSessionCommand() {
|
|
|
594
594
|
allowDomain.push(sessionArgs[++i]);
|
|
595
595
|
}
|
|
596
596
|
}
|
|
597
|
-
const { parseShareArg } = await import('./commands-
|
|
597
|
+
const { parseShareArg } = await import('./commands-B6zZtCuh.mjs');
|
|
598
598
|
const shareEntries = share.map((s) => parseShareArg(s));
|
|
599
599
|
await sessionSpawn(agent, dir, targetMachineId, {
|
|
600
600
|
message,
|
|
@@ -680,7 +680,7 @@ async function handleSessionCommand() {
|
|
|
680
680
|
console.error("Usage: svamp session approve <session-id> [request-id] [--json]");
|
|
681
681
|
process.exit(1);
|
|
682
682
|
}
|
|
683
|
-
const { sessionApprove } = await import('./commands-
|
|
683
|
+
const { sessionApprove } = await import('./commands-B6zZtCuh.mjs');
|
|
684
684
|
const approveReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
685
685
|
await sessionApprove(sessionArgs[1], approveReqId, targetMachineId, {
|
|
686
686
|
json: hasFlag("--json")
|
|
@@ -690,7 +690,7 @@ async function handleSessionCommand() {
|
|
|
690
690
|
console.error("Usage: svamp session deny <session-id> [request-id] [--json]");
|
|
691
691
|
process.exit(1);
|
|
692
692
|
}
|
|
693
|
-
const { sessionDeny } = await import('./commands-
|
|
693
|
+
const { sessionDeny } = await import('./commands-B6zZtCuh.mjs');
|
|
694
694
|
const denyReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
695
695
|
await sessionDeny(sessionArgs[1], denyReqId, targetMachineId, {
|
|
696
696
|
json: hasFlag("--json")
|
|
@@ -726,7 +726,7 @@ async function handleSessionCommand() {
|
|
|
726
726
|
console.error("Usage: svamp session set-title <title>");
|
|
727
727
|
process.exit(1);
|
|
728
728
|
}
|
|
729
|
-
const { sessionSetTitle } = await import('./agentCommands-
|
|
729
|
+
const { sessionSetTitle } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
730
730
|
await sessionSetTitle(title);
|
|
731
731
|
} else if (sessionSubcommand === "set-link") {
|
|
732
732
|
const url = sessionArgs[1];
|
|
@@ -735,7 +735,7 @@ async function handleSessionCommand() {
|
|
|
735
735
|
process.exit(1);
|
|
736
736
|
}
|
|
737
737
|
const label = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
738
|
-
const { sessionSetLink } = await import('./agentCommands-
|
|
738
|
+
const { sessionSetLink } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
739
739
|
await sessionSetLink(url, label);
|
|
740
740
|
} else if (sessionSubcommand === "notify") {
|
|
741
741
|
const message = sessionArgs[1];
|
|
@@ -744,7 +744,7 @@ async function handleSessionCommand() {
|
|
|
744
744
|
process.exit(1);
|
|
745
745
|
}
|
|
746
746
|
const level = parseFlagStr("--level") || "info";
|
|
747
|
-
const { sessionNotify } = await import('./agentCommands-
|
|
747
|
+
const { sessionNotify } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
748
748
|
await sessionNotify(message, level);
|
|
749
749
|
} else if (sessionSubcommand === "broadcast") {
|
|
750
750
|
const action = sessionArgs[1];
|
|
@@ -752,7 +752,7 @@ async function handleSessionCommand() {
|
|
|
752
752
|
console.error("Usage: svamp session broadcast <action> [args...]\nActions: open-canvas <url> [label], close-canvas, toast <message>");
|
|
753
753
|
process.exit(1);
|
|
754
754
|
}
|
|
755
|
-
const { sessionBroadcast } = await import('./agentCommands-
|
|
755
|
+
const { sessionBroadcast } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
756
756
|
await sessionBroadcast(action, sessionArgs.slice(2).filter((a) => !a.startsWith("--")));
|
|
757
757
|
} else if (sessionSubcommand === "inbox") {
|
|
758
758
|
const inboxSubcmd = sessionArgs[1];
|
|
@@ -763,7 +763,7 @@ async function handleSessionCommand() {
|
|
|
763
763
|
process.exit(1);
|
|
764
764
|
}
|
|
765
765
|
if (agentSessionId) {
|
|
766
|
-
const { inboxSend } = await import('./agentCommands-
|
|
766
|
+
const { inboxSend } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
767
767
|
await inboxSend(sessionArgs[2], {
|
|
768
768
|
body: sessionArgs[3],
|
|
769
769
|
subject: parseFlagStr("--subject"),
|
|
@@ -778,7 +778,7 @@ async function handleSessionCommand() {
|
|
|
778
778
|
}
|
|
779
779
|
} else if (inboxSubcmd === "list" || inboxSubcmd === "ls") {
|
|
780
780
|
if (agentSessionId && !sessionArgs[2]) {
|
|
781
|
-
const { inboxList } = await import('./agentCommands-
|
|
781
|
+
const { inboxList } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
782
782
|
await inboxList({
|
|
783
783
|
unread: hasFlag("--unread"),
|
|
784
784
|
limit: parseFlagInt("--limit"),
|
|
@@ -800,7 +800,7 @@ async function handleSessionCommand() {
|
|
|
800
800
|
process.exit(1);
|
|
801
801
|
}
|
|
802
802
|
if (agentSessionId && !sessionArgs[3]) {
|
|
803
|
-
const { inboxList } = await import('./agentCommands-
|
|
803
|
+
const { inboxList } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
804
804
|
await sessionInboxRead(agentSessionId, sessionArgs[2], targetMachineId);
|
|
805
805
|
} else if (sessionArgs[3]) {
|
|
806
806
|
await sessionInboxRead(sessionArgs[2], sessionArgs[3], targetMachineId);
|
|
@@ -810,7 +810,7 @@ async function handleSessionCommand() {
|
|
|
810
810
|
}
|
|
811
811
|
} else if (inboxSubcmd === "reply") {
|
|
812
812
|
if (agentSessionId && sessionArgs[2] && sessionArgs[3] && !sessionArgs[4]) {
|
|
813
|
-
const { inboxReply } = await import('./agentCommands-
|
|
813
|
+
const { inboxReply } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
814
814
|
await inboxReply(sessionArgs[2], sessionArgs[3]);
|
|
815
815
|
} else if (sessionArgs[2] && sessionArgs[3] && sessionArgs[4]) {
|
|
816
816
|
await sessionInboxReply(sessionArgs[2], sessionArgs[3], sessionArgs[4], targetMachineId);
|
|
@@ -846,7 +846,7 @@ async function handleMachineCommand() {
|
|
|
846
846
|
return;
|
|
847
847
|
}
|
|
848
848
|
if (machineSubcommand === "share") {
|
|
849
|
-
const { machineShare } = await import('./commands-
|
|
849
|
+
const { machineShare } = await import('./commands-B6zZtCuh.mjs');
|
|
850
850
|
let machineId;
|
|
851
851
|
const shareArgs = [];
|
|
852
852
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
@@ -876,7 +876,7 @@ async function handleMachineCommand() {
|
|
|
876
876
|
}
|
|
877
877
|
await machineShare(machineId, { add, remove, list, configPath, showConfig });
|
|
878
878
|
} else if (machineSubcommand === "exec") {
|
|
879
|
-
const { machineExec } = await import('./commands-
|
|
879
|
+
const { machineExec } = await import('./commands-B6zZtCuh.mjs');
|
|
880
880
|
let machineId;
|
|
881
881
|
let cwd;
|
|
882
882
|
const cmdParts = [];
|
|
@@ -896,7 +896,7 @@ async function handleMachineCommand() {
|
|
|
896
896
|
}
|
|
897
897
|
await machineExec(machineId, command, cwd);
|
|
898
898
|
} else if (machineSubcommand === "info") {
|
|
899
|
-
const { machineInfo } = await import('./commands-
|
|
899
|
+
const { machineInfo } = await import('./commands-B6zZtCuh.mjs');
|
|
900
900
|
let machineId;
|
|
901
901
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
902
902
|
if ((machineArgs[i] === "--machine" || machineArgs[i] === "-m") && i + 1 < machineArgs.length) {
|
|
@@ -916,10 +916,10 @@ async function handleMachineCommand() {
|
|
|
916
916
|
level = machineArgs[++i];
|
|
917
917
|
}
|
|
918
918
|
}
|
|
919
|
-
const { machineNotify } = await import('./agentCommands-
|
|
919
|
+
const { machineNotify } = await import('./agentCommands-Bqjcj1EX.mjs');
|
|
920
920
|
await machineNotify(message, level);
|
|
921
921
|
} else if (machineSubcommand === "ls") {
|
|
922
|
-
const { machineLs } = await import('./commands-
|
|
922
|
+
const { machineLs } = await import('./commands-B6zZtCuh.mjs');
|
|
923
923
|
let machineId;
|
|
924
924
|
let showHidden = false;
|
|
925
925
|
let path;
|
|
@@ -1381,7 +1381,7 @@ async function applyClaudeAuthFlags(argv) {
|
|
|
1381
1381
|
"--use-hypha-proxy, --use-claude-login, and --anthropic-base-url/--anthropic-api-key are mutually exclusive"
|
|
1382
1382
|
);
|
|
1383
1383
|
}
|
|
1384
|
-
const mod = await import('./run-
|
|
1384
|
+
const mod = await import('./run-wfhhtkl1.mjs').then(function (n) { return n.n; });
|
|
1385
1385
|
if (hasHypha) {
|
|
1386
1386
|
mod.setClaudeAuthHyphaProxy();
|
|
1387
1387
|
console.log("Claude auth configured: hypha-proxy (uses HYPHA_TOKEN live at each spawn).");
|
|
@@ -1404,7 +1404,7 @@ async function applyClaudeAuthFlags(argv) {
|
|
|
1404
1404
|
}
|
|
1405
1405
|
async function handleDaemonAuthCommand(argv) {
|
|
1406
1406
|
const sub = (argv[0] || "status").toLowerCase();
|
|
1407
|
-
const mod = await import('./run-
|
|
1407
|
+
const mod = await import('./run-wfhhtkl1.mjs').then(function (n) { return n.n; });
|
|
1408
1408
|
if (sub === "--help" || sub === "-h" || sub === "help") {
|
|
1409
1409
|
console.log(`
|
|
1410
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';
|