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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import { randomUUID } from 'node:crypto';
|
|
2
2
|
import os from 'node:os';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { c as connectToHypha, a as registerSessionService } from './run-
|
|
3
|
+
import { resolve, join } from 'node:path';
|
|
4
|
+
import { existsSync, readFileSync, watch } from 'node:fs';
|
|
5
|
+
import { c as connectToHypha, a as registerSessionService, h as generateHookSettings } from './run-wfhhtkl1.mjs';
|
|
6
6
|
import { createServer } from 'node:http';
|
|
7
7
|
import { spawn } from 'node:child_process';
|
|
8
8
|
import { createInterface } from 'node:readline';
|
|
@@ -66,56 +66,6 @@ async function startHookServer(onSessionHook, log) {
|
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
const SVAMP_HOME$1 = process.env.SVAMP_HOME || join(os.homedir(), ".svamp");
|
|
70
|
-
function generateHookSettings(port) {
|
|
71
|
-
const hooksDir = join(SVAMP_HOME$1, "tmp", "hooks");
|
|
72
|
-
mkdirSync(hooksDir, { recursive: true });
|
|
73
|
-
const forwarderPath = join(hooksDir, `forwarder-${process.pid}.cjs`);
|
|
74
|
-
const forwarderCode = `#!/usr/bin/env node
|
|
75
|
-
const http = require('http');
|
|
76
|
-
const port = parseInt(process.argv[2], 10);
|
|
77
|
-
if (!port || isNaN(port)) process.exit(1);
|
|
78
|
-
const chunks = [];
|
|
79
|
-
process.stdin.on('data', c => chunks.push(c));
|
|
80
|
-
process.stdin.on('end', () => {
|
|
81
|
-
const body = Buffer.concat(chunks);
|
|
82
|
-
const req = http.request({
|
|
83
|
-
host: '127.0.0.1', port, method: 'POST',
|
|
84
|
-
path: '/hook/session-start',
|
|
85
|
-
headers: { 'Content-Type': 'application/json', 'Content-Length': body.length }
|
|
86
|
-
}, res => res.resume());
|
|
87
|
-
req.on('error', () => {});
|
|
88
|
-
req.end(body);
|
|
89
|
-
});
|
|
90
|
-
process.stdin.resume();
|
|
91
|
-
`;
|
|
92
|
-
writeFileSync(forwarderPath, forwarderCode, { mode: 493 });
|
|
93
|
-
const settingsPath = join(hooksDir, `session-hook-${process.pid}.json`);
|
|
94
|
-
const hookCommand = `node "${forwarderPath}" ${port}`;
|
|
95
|
-
const settings = {
|
|
96
|
-
hooks: {
|
|
97
|
-
SessionStart: [
|
|
98
|
-
{
|
|
99
|
-
matcher: "*",
|
|
100
|
-
hooks: [{ type: "command", command: hookCommand }]
|
|
101
|
-
}
|
|
102
|
-
]
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
106
|
-
const cleanup = () => {
|
|
107
|
-
try {
|
|
108
|
-
if (existsSync(settingsPath)) unlinkSync(settingsPath);
|
|
109
|
-
} catch {
|
|
110
|
-
}
|
|
111
|
-
try {
|
|
112
|
-
if (existsSync(forwarderPath)) unlinkSync(forwarderPath);
|
|
113
|
-
} catch {
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
return { settingsPath, cleanup };
|
|
117
|
-
}
|
|
118
|
-
|
|
119
69
|
const INTERNAL_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
120
70
|
"file-history-snapshot",
|
|
121
71
|
"change",
|
|
@@ -52,7 +52,7 @@ async function handleServeCommand() {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
async function serveAdd(args, machineId) {
|
|
55
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
55
|
+
const { connectAndGetMachine } = await import('./commands-B6zZtCuh.mjs');
|
|
56
56
|
const pos = positionalArgs(args);
|
|
57
57
|
const name = pos[0];
|
|
58
58
|
if (!name) {
|
|
@@ -84,7 +84,7 @@ async function serveAdd(args, machineId) {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
async function serveRemove(args, machineId) {
|
|
87
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
87
|
+
const { connectAndGetMachine } = await import('./commands-B6zZtCuh.mjs');
|
|
88
88
|
const pos = positionalArgs(args);
|
|
89
89
|
const name = pos[0];
|
|
90
90
|
if (!name) {
|
|
@@ -104,7 +104,7 @@ async function serveRemove(args, machineId) {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
async function serveList(args, machineId) {
|
|
107
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
107
|
+
const { connectAndGetMachine } = await import('./commands-B6zZtCuh.mjs');
|
|
108
108
|
const all = hasFlag(args, "--all", "-a");
|
|
109
109
|
const json = hasFlag(args, "--json");
|
|
110
110
|
const sessionId = getFlag(args, "--session");
|
|
@@ -137,7 +137,7 @@ async function serveList(args, machineId) {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
async function serveInfo(machineId) {
|
|
140
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
140
|
+
const { connectAndGetMachine } = await import('./commands-B6zZtCuh.mjs');
|
|
141
141
|
const { machine, server } = await connectAndGetMachine(machineId);
|
|
142
142
|
try {
|
|
143
143
|
const info = await machine.serveInfo();
|
|
@@ -375,6 +375,7 @@ class ServeManager {
|
|
|
375
375
|
return {
|
|
376
376
|
url: firstUrl,
|
|
377
377
|
port: running ? this.caddy?.port ?? this.port : 0,
|
|
378
|
+
authProxyPort: running ? this.port : 0,
|
|
378
379
|
running,
|
|
379
380
|
mountCount: this.mounts.size,
|
|
380
381
|
mounts: Array.from(this.mounts.values()).map((m) => ({
|
|
@@ -510,6 +511,18 @@ class ServeManager {
|
|
|
510
511
|
basePath = mountName ? url.pathname.slice(`/${mountName}`.length) || "/" : url.pathname;
|
|
511
512
|
}
|
|
512
513
|
const mount = mountName ? this.mounts.get(mountName) : void 0;
|
|
514
|
+
if (basePath === "/__svamp_health" || url.pathname === "/__svamp_health") {
|
|
515
|
+
res.writeHead(200, {
|
|
516
|
+
"Content-Type": "application/json",
|
|
517
|
+
"Cache-Control": "no-store"
|
|
518
|
+
});
|
|
519
|
+
res.end(JSON.stringify({
|
|
520
|
+
ok: true,
|
|
521
|
+
mount: mountName || null,
|
|
522
|
+
ts: Date.now()
|
|
523
|
+
}));
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
513
526
|
if (basePath === "/__login__" || url.pathname === "/__login__") {
|
|
514
527
|
const returnUrl = url.searchParams.get("return") || "/";
|
|
515
528
|
const safeReturn = returnUrl.startsWith("/__login__") ? "/" : returnUrl;
|
|
@@ -634,10 +647,17 @@ class ServeManager {
|
|
|
634
647
|
const subdomainSafe = mountName.toLowerCase().replace(/[^a-z0-9-]/g, "-");
|
|
635
648
|
const tunnelName = `static-${subdomainSafe}`;
|
|
636
649
|
try {
|
|
637
|
-
const { FrpcTunnel } = await import('./frpc-
|
|
638
|
-
|
|
650
|
+
const { FrpcTunnel } = await import('./frpc-j60b46eU.mjs');
|
|
651
|
+
let tunnel;
|
|
652
|
+
tunnel = new FrpcTunnel({
|
|
639
653
|
name: tunnelName,
|
|
640
654
|
ports: [this.port],
|
|
655
|
+
// End-to-end probe: the daemon's health loop watches probe.ok
|
|
656
|
+
// to detect ghosted tunnel registrations (frpc says "connected"
|
|
657
|
+
// but no traffic actually flows). The sentinel route is served
|
|
658
|
+
// by the auth proxy without auth.
|
|
659
|
+
probePath: "/__svamp_health",
|
|
660
|
+
probeIntervalMs: 3e4,
|
|
641
661
|
onError: (err) => this.log(`frpc error [${mountName}]: ${err.message}`),
|
|
642
662
|
onConnect: () => {
|
|
643
663
|
const url2 = tunnel.getUrls().get(this.port);
|
|
@@ -650,7 +670,8 @@ class ServeManager {
|
|
|
650
670
|
this.log(`frpc tunnel connected for '${mountName}'. URL: ${url2}/`);
|
|
651
671
|
}
|
|
652
672
|
},
|
|
653
|
-
onDisconnect: () => this.log(`frpc tunnel for '${mountName}' disconnected, will auto-reconnect...`)
|
|
673
|
+
onDisconnect: () => this.log(`frpc tunnel for '${mountName}' disconnected, will auto-reconnect...`),
|
|
674
|
+
onProbeFail: (err) => this.log(`probe fail [${mountName}]: ${err.message}`)
|
|
654
675
|
});
|
|
655
676
|
await tunnel.connect();
|
|
656
677
|
this.mountTunnels.set(mountName, tunnel);
|
|
@@ -54,15 +54,17 @@ function isPidAlive(pid) {
|
|
|
54
54
|
try {
|
|
55
55
|
process.kill(pid, 0);
|
|
56
56
|
return true;
|
|
57
|
-
} catch {
|
|
58
|
-
return
|
|
57
|
+
} catch (err) {
|
|
58
|
+
return err?.code === "EPERM";
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
function findOrphanedSyncPids(currentSupervisorPid = process.pid) {
|
|
62
62
|
if (process.platform === "win32") return [];
|
|
63
63
|
const pids = [];
|
|
64
64
|
try {
|
|
65
|
-
const
|
|
65
|
+
const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
|
|
66
|
+
const pgrepArgs = uid !== void 0 ? ["-u", String(uid), "-af", "svamp daemon start-sync"] : ["-af", "svamp daemon start-sync"];
|
|
67
|
+
const output = execFileSync("pgrep", pgrepArgs, {
|
|
66
68
|
encoding: "utf-8",
|
|
67
69
|
timeout: 5e3
|
|
68
70
|
});
|