svamp-cli 0.1.58 → 0.1.60
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.mjs +18 -18
- package/dist/{commands-DPZbSIdL.mjs → commands-9Kb21VH-.mjs} +1 -1
- package/dist/{commands-jfZbr1Qh.mjs → commands-BUvYDka4.mjs} +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{package-J1yNZur7.mjs → package-ST5rOzw8.mjs} +1 -1
- package/dist/{run-CtrH9ayy.mjs → run-CWOk5gWn.mjs} +30 -64
- package/dist/{run-BnUNgLTL.mjs → run-DAoPkBhj.mjs} +1 -1
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as stopDaemon, s as startDaemon, d as daemonStatus } from './run-
|
|
1
|
+
import { b as stopDaemon, s as startDaemon, d as daemonStatus } from './run-CWOk5gWn.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|
|
@@ -109,7 +109,7 @@ async function main() {
|
|
|
109
109
|
const { handleServiceCommand } = await import('./commands-Dvftls28.mjs');
|
|
110
110
|
await handleServiceCommand();
|
|
111
111
|
} else if (subcommand === "process" || subcommand === "proc") {
|
|
112
|
-
const { processCommand } = await import('./commands-
|
|
112
|
+
const { processCommand } = await import('./commands-BUvYDka4.mjs');
|
|
113
113
|
let machineId;
|
|
114
114
|
const processArgs = args.slice(1);
|
|
115
115
|
const mIdx = processArgs.findIndex((a) => a === "--machine" || a === "-m");
|
|
@@ -127,7 +127,7 @@ async function main() {
|
|
|
127
127
|
} else if (!subcommand || subcommand === "start") {
|
|
128
128
|
await handleInteractiveCommand();
|
|
129
129
|
} else if (subcommand === "--version" || subcommand === "-v") {
|
|
130
|
-
const pkg = await import('./package-
|
|
130
|
+
const pkg = await import('./package-ST5rOzw8.mjs').catch(() => ({ default: { version: "unknown" } }));
|
|
131
131
|
console.log(`svamp version: ${pkg.default.version}`);
|
|
132
132
|
} else {
|
|
133
133
|
console.error(`Unknown command: ${subcommand}`);
|
|
@@ -136,7 +136,7 @@ async function main() {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
async function handleInteractiveCommand() {
|
|
139
|
-
const { runInteractive } = await import('./run-
|
|
139
|
+
const { runInteractive } = await import('./run-DAoPkBhj.mjs');
|
|
140
140
|
const interactiveArgs = subcommand === "start" ? args.slice(1) : args;
|
|
141
141
|
let directory = process.cwd();
|
|
142
142
|
let resumeSessionId;
|
|
@@ -181,7 +181,7 @@ async function handleAgentCommand() {
|
|
|
181
181
|
return;
|
|
182
182
|
}
|
|
183
183
|
if (agentArgs[0] === "list") {
|
|
184
|
-
const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-
|
|
184
|
+
const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-CWOk5gWn.mjs').then(function (n) { return n.i; });
|
|
185
185
|
console.log("Known agents:");
|
|
186
186
|
for (const [name, config2] of Object.entries(KNOWN_ACP_AGENTS)) {
|
|
187
187
|
console.log(` ${name.padEnd(12)} ${config2.command} ${config2.args.join(" ")} (ACP)`);
|
|
@@ -193,7 +193,7 @@ async function handleAgentCommand() {
|
|
|
193
193
|
console.log('Use "svamp agent -- <command> [args]" for a custom ACP agent.');
|
|
194
194
|
return;
|
|
195
195
|
}
|
|
196
|
-
const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-
|
|
196
|
+
const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-CWOk5gWn.mjs').then(function (n) { return n.i; });
|
|
197
197
|
let cwd = process.cwd();
|
|
198
198
|
const filteredArgs = [];
|
|
199
199
|
for (let i = 0; i < agentArgs.length; i++) {
|
|
@@ -217,12 +217,12 @@ async function handleAgentCommand() {
|
|
|
217
217
|
console.log(`Starting ${config.agentName} agent in ${cwd}...`);
|
|
218
218
|
let backend;
|
|
219
219
|
if (KNOWN_MCP_AGENTS[config.agentName]) {
|
|
220
|
-
const { CodexMcpBackend } = await import('./run-
|
|
220
|
+
const { CodexMcpBackend } = await import('./run-CWOk5gWn.mjs').then(function (n) { return n.j; });
|
|
221
221
|
backend = new CodexMcpBackend({ cwd, log: logFn });
|
|
222
222
|
} else {
|
|
223
|
-
const { AcpBackend } = await import('./run-
|
|
224
|
-
const { GeminiTransport } = await import('./run-
|
|
225
|
-
const { DefaultTransport } = await import('./run-
|
|
223
|
+
const { AcpBackend } = await import('./run-CWOk5gWn.mjs').then(function (n) { return n.h; });
|
|
224
|
+
const { GeminiTransport } = await import('./run-CWOk5gWn.mjs').then(function (n) { return n.G; });
|
|
225
|
+
const { DefaultTransport } = await import('./run-CWOk5gWn.mjs').then(function (n) { return n.D; });
|
|
226
226
|
const transportHandler = config.agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(config.agentName);
|
|
227
227
|
backend = new AcpBackend({
|
|
228
228
|
agentName: config.agentName,
|
|
@@ -340,7 +340,7 @@ async function handleSessionCommand() {
|
|
|
340
340
|
printSessionHelp();
|
|
341
341
|
return;
|
|
342
342
|
}
|
|
343
|
-
const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionQueueAdd, sessionQueueList, sessionQueueClear } = await import('./commands-
|
|
343
|
+
const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionQueueAdd, sessionQueueList, sessionQueueClear } = await import('./commands-9Kb21VH-.mjs');
|
|
344
344
|
const parseFlagStr = (flag, shortFlag) => {
|
|
345
345
|
for (let i = 1; i < sessionArgs.length; i++) {
|
|
346
346
|
if ((sessionArgs[i] === flag || shortFlag) && i + 1 < sessionArgs.length) {
|
|
@@ -400,7 +400,7 @@ async function handleSessionCommand() {
|
|
|
400
400
|
allowDomain.push(sessionArgs[++i]);
|
|
401
401
|
}
|
|
402
402
|
}
|
|
403
|
-
const { parseShareArg } = await import('./commands-
|
|
403
|
+
const { parseShareArg } = await import('./commands-9Kb21VH-.mjs');
|
|
404
404
|
const shareEntries = share.map((s) => parseShareArg(s));
|
|
405
405
|
await sessionSpawn(agent, dir, targetMachineId, {
|
|
406
406
|
message,
|
|
@@ -484,7 +484,7 @@ async function handleSessionCommand() {
|
|
|
484
484
|
console.error("Usage: svamp session approve <session-id> [request-id] [--json]");
|
|
485
485
|
process.exit(1);
|
|
486
486
|
}
|
|
487
|
-
const { sessionApprove } = await import('./commands-
|
|
487
|
+
const { sessionApprove } = await import('./commands-9Kb21VH-.mjs');
|
|
488
488
|
const approveReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
489
489
|
await sessionApprove(sessionArgs[1], approveReqId, targetMachineId, {
|
|
490
490
|
json: hasFlag("--json")
|
|
@@ -494,7 +494,7 @@ async function handleSessionCommand() {
|
|
|
494
494
|
console.error("Usage: svamp session deny <session-id> [request-id] [--json]");
|
|
495
495
|
process.exit(1);
|
|
496
496
|
}
|
|
497
|
-
const { sessionDeny } = await import('./commands-
|
|
497
|
+
const { sessionDeny } = await import('./commands-9Kb21VH-.mjs');
|
|
498
498
|
const denyReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
499
499
|
await sessionDeny(sessionArgs[1], denyReqId, targetMachineId, {
|
|
500
500
|
json: hasFlag("--json")
|
|
@@ -563,7 +563,7 @@ async function handleMachineCommand() {
|
|
|
563
563
|
return;
|
|
564
564
|
}
|
|
565
565
|
if (machineSubcommand === "share") {
|
|
566
|
-
const { machineShare } = await import('./commands-
|
|
566
|
+
const { machineShare } = await import('./commands-9Kb21VH-.mjs');
|
|
567
567
|
let machineId;
|
|
568
568
|
const shareArgs = [];
|
|
569
569
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
@@ -593,7 +593,7 @@ async function handleMachineCommand() {
|
|
|
593
593
|
}
|
|
594
594
|
await machineShare(machineId, { add, remove, list, configPath, showConfig });
|
|
595
595
|
} else if (machineSubcommand === "exec") {
|
|
596
|
-
const { machineExec } = await import('./commands-
|
|
596
|
+
const { machineExec } = await import('./commands-9Kb21VH-.mjs');
|
|
597
597
|
let machineId;
|
|
598
598
|
let cwd;
|
|
599
599
|
const cmdParts = [];
|
|
@@ -613,7 +613,7 @@ async function handleMachineCommand() {
|
|
|
613
613
|
}
|
|
614
614
|
await machineExec(machineId, command, cwd);
|
|
615
615
|
} else if (machineSubcommand === "info") {
|
|
616
|
-
const { machineInfo } = await import('./commands-
|
|
616
|
+
const { machineInfo } = await import('./commands-9Kb21VH-.mjs');
|
|
617
617
|
let machineId;
|
|
618
618
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
619
619
|
if ((machineArgs[i] === "--machine" || machineArgs[i] === "-m") && i + 1 < machineArgs.length) {
|
|
@@ -622,7 +622,7 @@ async function handleMachineCommand() {
|
|
|
622
622
|
}
|
|
623
623
|
await machineInfo(machineId);
|
|
624
624
|
} else if (machineSubcommand === "ls") {
|
|
625
|
-
const { machineLs } = await import('./commands-
|
|
625
|
+
const { machineLs } = await import('./commands-9Kb21VH-.mjs');
|
|
626
626
|
let machineId;
|
|
627
627
|
let showHidden = false;
|
|
628
628
|
let path;
|
|
@@ -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-CWOk5gWn.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-9Kb21VH-.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-CWOk5gWn.mjs';
|
|
9
9
|
import 'os';
|
|
10
10
|
import 'fs/promises';
|
|
11
11
|
import 'url';
|
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-CWOk5gWn.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|
|
@@ -4985,7 +4985,20 @@ async function startDaemon(options) {
|
|
|
4985
4985
|
logger.log(`Hypha connection permanently lost: ${reason}`);
|
|
4986
4986
|
requestShutdown("hypha-disconnected", String(reason));
|
|
4987
4987
|
});
|
|
4988
|
+
let lastHyphaMessageAt = Date.now();
|
|
4989
|
+
const attachMessageTimestampListener = () => {
|
|
4990
|
+
const conn = server.rpc?._connection;
|
|
4991
|
+
const ws = conn?._websocket;
|
|
4992
|
+
if (ws) {
|
|
4993
|
+
ws.addEventListener("message", () => {
|
|
4994
|
+
lastHyphaMessageAt = Date.now();
|
|
4995
|
+
});
|
|
4996
|
+
lastHyphaMessageAt = Date.now();
|
|
4997
|
+
}
|
|
4998
|
+
};
|
|
4999
|
+
attachMessageTimestampListener();
|
|
4988
5000
|
server.on("services_registered", () => {
|
|
5001
|
+
attachMessageTimestampListener();
|
|
4989
5002
|
if (consecutiveHeartbeatFailures > 0) {
|
|
4990
5003
|
logger.log(`Hypha reconnection successful \u2014 services re-registered (resetting ${consecutiveHeartbeatFailures} failures)`);
|
|
4991
5004
|
consecutiveHeartbeatFailures = 0;
|
|
@@ -6734,7 +6747,7 @@ The automated loop has finished. Review the progress above and let me know if yo
|
|
|
6734
6747
|
console.log(` Service: svamp-machine-${machineId}`);
|
|
6735
6748
|
console.log(` Log file: ${logger.logFilePath}`);
|
|
6736
6749
|
const HEARTBEAT_INTERVAL_MS = 1e4;
|
|
6737
|
-
const
|
|
6750
|
+
const GHOST_TIMEOUT_MS = 6e4;
|
|
6738
6751
|
const MAX_FAILURES = 60;
|
|
6739
6752
|
const POST_RECONNECT_GRACE_MS = 2e4;
|
|
6740
6753
|
let heartbeatRunning = false;
|
|
@@ -6765,79 +6778,32 @@ The automated loop has finished. Review the progress above and let me know if yo
|
|
|
6765
6778
|
}
|
|
6766
6779
|
} catch {
|
|
6767
6780
|
}
|
|
6768
|
-
for (const [key, session] of pidToTrackedSession) {
|
|
6769
|
-
const child = session.childProcess;
|
|
6770
|
-
if (child && child.pid) {
|
|
6771
|
-
try {
|
|
6772
|
-
process.kill(child.pid, 0);
|
|
6773
|
-
} catch {
|
|
6774
|
-
logger.log(`Removing stale session (child PID ${child.pid} dead): ${session.svampSessionId}`);
|
|
6775
|
-
session.hyphaService?.disconnect().catch(() => {
|
|
6776
|
-
});
|
|
6777
|
-
pidToTrackedSession.delete(key);
|
|
6778
|
-
}
|
|
6779
|
-
}
|
|
6780
|
-
}
|
|
6781
6781
|
const inGrace = lastReconnectAt > 0 && Date.now() - lastReconnectAt < POST_RECONNECT_GRACE_MS;
|
|
6782
|
-
|
|
6783
|
-
|
|
6784
|
-
|
|
6785
|
-
|
|
6786
|
-
|
|
6787
|
-
const ws = conn?._websocket;
|
|
6788
|
-
if (!ws || ws.readyState !== 1) {
|
|
6789
|
-
reject(new Error("WebSocket not open"));
|
|
6790
|
-
return;
|
|
6791
|
-
}
|
|
6792
|
-
const timer = setTimeout(() => {
|
|
6793
|
-
ws.removeEventListener("message", onMsg);
|
|
6794
|
-
reject(new Error("Ping timed out"));
|
|
6795
|
-
}, PING_TIMEOUT_MS);
|
|
6796
|
-
const onMsg = (event) => {
|
|
6797
|
-
try {
|
|
6798
|
-
const d = typeof event.data === "string" ? JSON.parse(event.data) : null;
|
|
6799
|
-
if (d?.type === "pong") {
|
|
6800
|
-
clearTimeout(timer);
|
|
6801
|
-
ws.removeEventListener("message", onMsg);
|
|
6802
|
-
resolve2();
|
|
6803
|
-
}
|
|
6804
|
-
} catch {
|
|
6805
|
-
}
|
|
6806
|
-
};
|
|
6807
|
-
ws.addEventListener("message", onMsg);
|
|
6808
|
-
ws.send(JSON.stringify({ type: "ping" }));
|
|
6809
|
-
});
|
|
6810
|
-
const pingMs = Date.now() - pingStart;
|
|
6811
|
-
if (pingMs > 1e3) {
|
|
6812
|
-
logger.log(`Slow ping: ${pingMs}ms`);
|
|
6813
|
-
}
|
|
6814
|
-
if (consecutiveHeartbeatFailures > 0) {
|
|
6815
|
-
logger.log(`Heartbeat recovered after ${consecutiveHeartbeatFailures} failures`);
|
|
6816
|
-
consecutiveHeartbeatFailures = 0;
|
|
6817
|
-
}
|
|
6818
|
-
} catch (err) {
|
|
6782
|
+
const timeSinceMsg = Date.now() - lastHyphaMessageAt;
|
|
6783
|
+
if (!inGrace && timeSinceMsg > GHOST_TIMEOUT_MS) {
|
|
6784
|
+
const conn = server.rpc?._connection;
|
|
6785
|
+
const ws = conn?._websocket;
|
|
6786
|
+
if (ws?.readyState === 1) {
|
|
6819
6787
|
consecutiveHeartbeatFailures++;
|
|
6820
6788
|
if (consecutiveHeartbeatFailures === 1) {
|
|
6821
|
-
logger.log(`
|
|
6789
|
+
logger.log(`No message from server in ${Math.round(timeSinceMsg / 1e3)}s \u2014 ghost connection, force-closing WebSocket`);
|
|
6822
6790
|
} else if (consecutiveHeartbeatFailures % 6 === 0) {
|
|
6823
|
-
logger.log(`
|
|
6791
|
+
logger.log(`Still reconnecting \u2014 ${consecutiveHeartbeatFailures} failures (${consecutiveHeartbeatFailures * HEARTBEAT_INTERVAL_MS / 1e3}s)`);
|
|
6824
6792
|
}
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
if (ws?.readyState === 1) {
|
|
6829
|
-
logger.log("Force-closing stale WebSocket to trigger reconnection");
|
|
6830
|
-
try {
|
|
6831
|
-
ws.close(4e3, "Stale connection");
|
|
6832
|
-
} catch {
|
|
6833
|
-
}
|
|
6834
|
-
}
|
|
6793
|
+
try {
|
|
6794
|
+
ws.close(4e3, "Ghost connection");
|
|
6795
|
+
} catch {
|
|
6835
6796
|
}
|
|
6836
6797
|
if (consecutiveHeartbeatFailures >= MAX_FAILURES) {
|
|
6837
6798
|
logger.log(`Heartbeat failed ${MAX_FAILURES} times. Shutting down.`);
|
|
6838
|
-
requestShutdown("heartbeat-timeout",
|
|
6799
|
+
requestShutdown("heartbeat-timeout", `No messages for ${Math.round(timeSinceMsg / 1e3)}s`);
|
|
6839
6800
|
}
|
|
6801
|
+
} else {
|
|
6802
|
+
lastHyphaMessageAt = Date.now();
|
|
6840
6803
|
}
|
|
6804
|
+
} else if (consecutiveHeartbeatFailures > 0 && timeSinceMsg < GHOST_TIMEOUT_MS / 2) {
|
|
6805
|
+
logger.log(`Heartbeat recovered after ${consecutiveHeartbeatFailures} failures`);
|
|
6806
|
+
consecutiveHeartbeatFailures = 0;
|
|
6841
6807
|
}
|
|
6842
6808
|
} finally {
|
|
6843
6809
|
heartbeatRunning = false;
|
|
@@ -2,7 +2,7 @@ import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(im
|
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import { join, resolve } from 'node:path';
|
|
4
4
|
import { mkdirSync, writeFileSync, existsSync, unlinkSync, readFileSync, watch } from 'node:fs';
|
|
5
|
-
import { c as connectToHypha, a as registerSessionService } from './run-
|
|
5
|
+
import { c as connectToHypha, a as registerSessionService } from './run-CWOk5gWn.mjs';
|
|
6
6
|
import { createServer } from 'node:http';
|
|
7
7
|
import { spawn } from 'node:child_process';
|
|
8
8
|
import { createInterface } from 'node:readline';
|