svamp-cli 0.1.75 → 0.1.78
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-C6iGblcL.mjs → agentCommands-uNFhhdN1.mjs} +108 -1
- package/dist/cli.mjs +254 -95
- package/dist/{commands-a7p1jW-t.mjs → commands-B6FEeZeP.mjs} +129 -61
- package/dist/{commands-BLjcT1Vl.mjs → commands-BYbuedOK.mjs} +68 -4
- package/dist/{commands-Dq8WSqvt.mjs → commands-Cf3mXxPZ.mjs} +2 -2
- package/dist/{commands-UFi0_ESV.mjs → commands-DJoYOM_1.mjs} +25 -25
- package/dist/index.mjs +1 -1
- package/dist/{package-BFnad6d1.mjs → package-DTOqWYBv.mjs} +4 -4
- package/dist/{run-Dy5lxT3M.mjs → run-DqvxMsWh.mjs} +1 -1
- package/dist/{run-lhAjX4NB.mjs → run-DsXDjwLW.mjs} +369 -84
- package/dist/staticServer-CWcmMF5V.mjs +477 -0
- package/dist/{tunnel-C2kqST5d.mjs → tunnel-BDKdemh0.mjs} +51 -9
- package/package.json +4 -4
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-DsXDjwLW.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|
|
@@ -32,6 +32,8 @@ let daemonSubcommand = args[1];
|
|
|
32
32
|
async function main() {
|
|
33
33
|
if (subcommand === "login") {
|
|
34
34
|
await loginToHypha();
|
|
35
|
+
} else if (subcommand === "logout") {
|
|
36
|
+
await logoutFromHypha();
|
|
35
37
|
} else if (subcommand === "daemon") {
|
|
36
38
|
if (daemonSubcommand === "restart") {
|
|
37
39
|
await stopDaemon();
|
|
@@ -47,7 +49,7 @@ async function main() {
|
|
|
47
49
|
...process.argv.slice(1, 2),
|
|
48
50
|
// the script path
|
|
49
51
|
"daemon",
|
|
50
|
-
"start-
|
|
52
|
+
"start-supervised",
|
|
51
53
|
...extraArgs
|
|
52
54
|
], {
|
|
53
55
|
detached: true,
|
|
@@ -77,6 +79,106 @@ async function main() {
|
|
|
77
79
|
process.exit(1);
|
|
78
80
|
}
|
|
79
81
|
process.exit(0);
|
|
82
|
+
} else if (daemonSubcommand === "start-supervised") {
|
|
83
|
+
const { spawn: spawnChild } = await import('child_process');
|
|
84
|
+
const { appendFileSync, mkdirSync, existsSync: fsExists } = await import('fs');
|
|
85
|
+
const { join: pathJoin } = await import('path');
|
|
86
|
+
const osModule = await import('os');
|
|
87
|
+
const svampHome = process.env.SVAMP_HOME || pathJoin(osModule.homedir(), ".svamp");
|
|
88
|
+
const logsDir = pathJoin(svampHome, "logs");
|
|
89
|
+
mkdirSync(logsDir, { recursive: true });
|
|
90
|
+
const logFile = pathJoin(logsDir, "daemon-supervised.log");
|
|
91
|
+
const log = (msg) => {
|
|
92
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [supervisor] ${msg}
|
|
93
|
+
`;
|
|
94
|
+
try {
|
|
95
|
+
appendFileSync(logFile, line);
|
|
96
|
+
} catch {
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const supervisorPidFile = pathJoin(svampHome, "supervisor.pid");
|
|
100
|
+
try {
|
|
101
|
+
appendFileSync(supervisorPidFile, "");
|
|
102
|
+
} catch {
|
|
103
|
+
}
|
|
104
|
+
const { writeFileSync: wfs } = await import('fs');
|
|
105
|
+
wfs(supervisorPidFile, String(process.pid), "utf-8");
|
|
106
|
+
const extraSyncArgs = [];
|
|
107
|
+
if (args.includes("--no-auto-continue")) extraSyncArgs.push("--no-auto-continue");
|
|
108
|
+
const BASE_DELAY_MS = 2e3;
|
|
109
|
+
const MAX_DELAY_MS = 3e5;
|
|
110
|
+
const BACKOFF_RESET_UPTIME_MS = 6e4;
|
|
111
|
+
let consecutiveRapidCrashes = 0;
|
|
112
|
+
let currentChild = null;
|
|
113
|
+
let stopping = false;
|
|
114
|
+
const onSignal = (sig) => {
|
|
115
|
+
stopping = true;
|
|
116
|
+
if (currentChild && !currentChild.killed) {
|
|
117
|
+
currentChild.kill(sig);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
process.on("SIGTERM", () => onSignal("SIGTERM"));
|
|
121
|
+
process.on("SIGINT", () => onSignal("SIGINT"));
|
|
122
|
+
process.on("SIGUSR1", () => onSignal("SIGUSR1"));
|
|
123
|
+
log("Supervisor started");
|
|
124
|
+
while (!stopping) {
|
|
125
|
+
const startTime = Date.now();
|
|
126
|
+
const exitCode = await new Promise((resolve) => {
|
|
127
|
+
const child = spawnChild(process.execPath, [
|
|
128
|
+
"--no-warnings",
|
|
129
|
+
"--no-deprecation",
|
|
130
|
+
...process.argv.slice(1, 2),
|
|
131
|
+
"daemon",
|
|
132
|
+
"start-sync",
|
|
133
|
+
...extraSyncArgs
|
|
134
|
+
], {
|
|
135
|
+
stdio: ["ignore", "inherit", "inherit"],
|
|
136
|
+
env: { ...process.env, SVAMP_SUPERVISED: "1" }
|
|
137
|
+
});
|
|
138
|
+
currentChild = child;
|
|
139
|
+
child.on("exit", (code) => resolve(code));
|
|
140
|
+
child.on("error", (err) => {
|
|
141
|
+
log(`Failed to spawn daemon: ${err.message}`);
|
|
142
|
+
resolve(1);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
currentChild = null;
|
|
146
|
+
const uptime = Date.now() - startTime;
|
|
147
|
+
if (stopping) {
|
|
148
|
+
log("Supervisor received stop signal, exiting");
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
if (exitCode === 0) {
|
|
152
|
+
log("Daemon exited cleanly (exit 0), not restarting");
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
if (uptime > BACKOFF_RESET_UPTIME_MS) {
|
|
156
|
+
consecutiveRapidCrashes = 0;
|
|
157
|
+
} else {
|
|
158
|
+
consecutiveRapidCrashes++;
|
|
159
|
+
}
|
|
160
|
+
const backoffExp = Math.min(consecutiveRapidCrashes, 10);
|
|
161
|
+
let delay = Math.min(BASE_DELAY_MS * Math.pow(2, backoffExp), MAX_DELAY_MS);
|
|
162
|
+
delay = Math.max(BASE_DELAY_MS, Math.round(delay + (Math.random() * 0.2 - 0.1) * delay));
|
|
163
|
+
log(`Daemon exited with code ${exitCode} (uptime=${Math.round(uptime / 1e3)}s). Restarting in ${Math.round(delay / 1e3)}s...`);
|
|
164
|
+
await new Promise((resolve) => {
|
|
165
|
+
const timer = setTimeout(resolve, delay);
|
|
166
|
+
const checkStop = setInterval(() => {
|
|
167
|
+
if (stopping) {
|
|
168
|
+
clearTimeout(timer);
|
|
169
|
+
clearInterval(checkStop);
|
|
170
|
+
resolve();
|
|
171
|
+
}
|
|
172
|
+
}, 500);
|
|
173
|
+
setTimeout(() => clearInterval(checkStop), delay + 100);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
const { unlinkSync: us } = await import('fs');
|
|
178
|
+
us(supervisorPidFile);
|
|
179
|
+
} catch {
|
|
180
|
+
}
|
|
181
|
+
process.exit(0);
|
|
80
182
|
} else if (daemonSubcommand === "start-sync") {
|
|
81
183
|
const noAutoContinue = args.includes("--no-auto-continue");
|
|
82
184
|
await startDaemon({ noAutoContinue });
|
|
@@ -106,10 +208,10 @@ async function main() {
|
|
|
106
208
|
} else if (subcommand === "skills") {
|
|
107
209
|
await handleSkillsCommand();
|
|
108
210
|
} else if (subcommand === "service" || subcommand === "svc") {
|
|
109
|
-
const { handleServiceCommand } = await import('./commands-
|
|
211
|
+
const { handleServiceCommand } = await import('./commands-BYbuedOK.mjs');
|
|
110
212
|
await handleServiceCommand();
|
|
111
213
|
} else if (subcommand === "process" || subcommand === "proc") {
|
|
112
|
-
const { processCommand } = await import('./commands-
|
|
214
|
+
const { processCommand } = await import('./commands-Cf3mXxPZ.mjs');
|
|
113
215
|
let machineId;
|
|
114
216
|
const processArgs = args.slice(1);
|
|
115
217
|
const mIdx = processArgs.findIndex((a) => a === "--machine" || a === "-m");
|
|
@@ -127,7 +229,7 @@ async function main() {
|
|
|
127
229
|
} else if (!subcommand || subcommand === "start") {
|
|
128
230
|
await handleInteractiveCommand();
|
|
129
231
|
} else if (subcommand === "--version" || subcommand === "-v") {
|
|
130
|
-
const pkg = await import('./package-
|
|
232
|
+
const pkg = await import('./package-DTOqWYBv.mjs').catch(() => ({ default: { version: "unknown" } }));
|
|
131
233
|
console.log(`svamp version: ${pkg.default.version}`);
|
|
132
234
|
} else {
|
|
133
235
|
console.error(`Unknown command: ${subcommand}`);
|
|
@@ -136,7 +238,7 @@ async function main() {
|
|
|
136
238
|
}
|
|
137
239
|
}
|
|
138
240
|
async function handleInteractiveCommand() {
|
|
139
|
-
const { runInteractive } = await import('./run-
|
|
241
|
+
const { runInteractive } = await import('./run-DqvxMsWh.mjs');
|
|
140
242
|
const interactiveArgs = subcommand === "start" ? args.slice(1) : args;
|
|
141
243
|
let directory = process.cwd();
|
|
142
244
|
let resumeSessionId;
|
|
@@ -181,7 +283,7 @@ async function handleAgentCommand() {
|
|
|
181
283
|
return;
|
|
182
284
|
}
|
|
183
285
|
if (agentArgs[0] === "list") {
|
|
184
|
-
const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-
|
|
286
|
+
const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-DsXDjwLW.mjs').then(function (n) { return n.i; });
|
|
185
287
|
console.log("Known agents:");
|
|
186
288
|
for (const [name, config2] of Object.entries(KNOWN_ACP_AGENTS)) {
|
|
187
289
|
console.log(` ${name.padEnd(12)} ${config2.command} ${config2.args.join(" ")} (ACP)`);
|
|
@@ -193,7 +295,7 @@ async function handleAgentCommand() {
|
|
|
193
295
|
console.log('Use "svamp agent -- <command> [args]" for a custom ACP agent.');
|
|
194
296
|
return;
|
|
195
297
|
}
|
|
196
|
-
const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-
|
|
298
|
+
const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-DsXDjwLW.mjs').then(function (n) { return n.i; });
|
|
197
299
|
let cwd = process.cwd();
|
|
198
300
|
const filteredArgs = [];
|
|
199
301
|
for (let i = 0; i < agentArgs.length; i++) {
|
|
@@ -217,12 +319,12 @@ async function handleAgentCommand() {
|
|
|
217
319
|
console.log(`Starting ${config.agentName} agent in ${cwd}...`);
|
|
218
320
|
let backend;
|
|
219
321
|
if (KNOWN_MCP_AGENTS[config.agentName]) {
|
|
220
|
-
const { CodexMcpBackend } = await import('./run-
|
|
322
|
+
const { CodexMcpBackend } = await import('./run-DsXDjwLW.mjs').then(function (n) { return n.j; });
|
|
221
323
|
backend = new CodexMcpBackend({ cwd, log: logFn });
|
|
222
324
|
} else {
|
|
223
|
-
const { AcpBackend } = await import('./run-
|
|
224
|
-
const { GeminiTransport } = await import('./run-
|
|
225
|
-
const { DefaultTransport } = await import('./run-
|
|
325
|
+
const { AcpBackend } = await import('./run-DsXDjwLW.mjs').then(function (n) { return n.h; });
|
|
326
|
+
const { GeminiTransport } = await import('./run-DsXDjwLW.mjs').then(function (n) { return n.G; });
|
|
327
|
+
const { DefaultTransport } = await import('./run-DsXDjwLW.mjs').then(function (n) { return n.D; });
|
|
226
328
|
const transportHandler = config.agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(config.agentName);
|
|
227
329
|
backend = new AcpBackend({
|
|
228
330
|
agentName: config.agentName,
|
|
@@ -340,7 +442,7 @@ async function handleSessionCommand() {
|
|
|
340
442
|
printSessionHelp();
|
|
341
443
|
return;
|
|
342
444
|
}
|
|
343
|
-
const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus,
|
|
445
|
+
const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-B6FEeZeP.mjs');
|
|
344
446
|
const parseFlagStr = (flag, shortFlag) => {
|
|
345
447
|
for (let i = 1; i < sessionArgs.length; i++) {
|
|
346
448
|
if ((sessionArgs[i] === flag || shortFlag) && i + 1 < sessionArgs.length) {
|
|
@@ -400,7 +502,7 @@ async function handleSessionCommand() {
|
|
|
400
502
|
allowDomain.push(sessionArgs[++i]);
|
|
401
503
|
}
|
|
402
504
|
}
|
|
403
|
-
const { parseShareArg } = await import('./commands-
|
|
505
|
+
const { parseShareArg } = await import('./commands-B6FEeZeP.mjs');
|
|
404
506
|
const shareEntries = share.map((s) => parseShareArg(s));
|
|
405
507
|
await sessionSpawn(agent, dir, targetMachineId, {
|
|
406
508
|
message,
|
|
@@ -451,13 +553,15 @@ async function handleSessionCommand() {
|
|
|
451
553
|
await sessionAttach(sessionArgs[1], targetMachineId);
|
|
452
554
|
} else if (sessionSubcommand === "send") {
|
|
453
555
|
if (!sessionArgs[1] || !sessionArgs[2]) {
|
|
454
|
-
console.error(
|
|
556
|
+
console.error('Usage: svamp session send <session-id> <message> [--subject "..."] [--urgency urgent|normal] [--wait] [--timeout N] [--json]');
|
|
455
557
|
process.exit(1);
|
|
456
558
|
}
|
|
457
559
|
await sessionSend(sessionArgs[1], sessionArgs[2], targetMachineId, {
|
|
458
560
|
wait: hasFlag("--wait"),
|
|
459
561
|
timeout: parseFlagInt("--timeout"),
|
|
460
|
-
json: hasFlag("--json")
|
|
562
|
+
json: hasFlag("--json"),
|
|
563
|
+
subject: parseFlagStr("--subject"),
|
|
564
|
+
urgency: parseFlagStr("--urgency")
|
|
461
565
|
});
|
|
462
566
|
} else if (sessionSubcommand === "wait") {
|
|
463
567
|
if (!sessionArgs[1]) {
|
|
@@ -484,7 +588,7 @@ async function handleSessionCommand() {
|
|
|
484
588
|
console.error("Usage: svamp session approve <session-id> [request-id] [--json]");
|
|
485
589
|
process.exit(1);
|
|
486
590
|
}
|
|
487
|
-
const { sessionApprove } = await import('./commands-
|
|
591
|
+
const { sessionApprove } = await import('./commands-B6FEeZeP.mjs');
|
|
488
592
|
const approveReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
489
593
|
await sessionApprove(sessionArgs[1], approveReqId, targetMachineId, {
|
|
490
594
|
json: hasFlag("--json")
|
|
@@ -494,7 +598,7 @@ async function handleSessionCommand() {
|
|
|
494
598
|
console.error("Usage: svamp session deny <session-id> [request-id] [--json]");
|
|
495
599
|
process.exit(1);
|
|
496
600
|
}
|
|
497
|
-
const { sessionDeny } = await import('./commands-
|
|
601
|
+
const { sessionDeny } = await import('./commands-B6FEeZeP.mjs');
|
|
498
602
|
const denyReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
499
603
|
await sessionDeny(sessionArgs[1], denyReqId, targetMachineId, {
|
|
500
604
|
json: hasFlag("--json")
|
|
@@ -530,7 +634,7 @@ async function handleSessionCommand() {
|
|
|
530
634
|
console.error("Usage: svamp session set-title <title>");
|
|
531
635
|
process.exit(1);
|
|
532
636
|
}
|
|
533
|
-
const { sessionSetTitle } = await import('./agentCommands-
|
|
637
|
+
const { sessionSetTitle } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
534
638
|
await sessionSetTitle(title);
|
|
535
639
|
} else if (sessionSubcommand === "set-link") {
|
|
536
640
|
const url = sessionArgs[1];
|
|
@@ -539,7 +643,7 @@ async function handleSessionCommand() {
|
|
|
539
643
|
process.exit(1);
|
|
540
644
|
}
|
|
541
645
|
const label = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
542
|
-
const { sessionSetLink } = await import('./agentCommands-
|
|
646
|
+
const { sessionSetLink } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
543
647
|
await sessionSetLink(url, label);
|
|
544
648
|
} else if (sessionSubcommand === "notify") {
|
|
545
649
|
const message = sessionArgs[1];
|
|
@@ -548,7 +652,7 @@ async function handleSessionCommand() {
|
|
|
548
652
|
process.exit(1);
|
|
549
653
|
}
|
|
550
654
|
const level = parseFlagStr("--level") || "info";
|
|
551
|
-
const { sessionNotify } = await import('./agentCommands-
|
|
655
|
+
const { sessionNotify } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
552
656
|
await sessionNotify(message, level);
|
|
553
657
|
} else if (sessionSubcommand === "broadcast") {
|
|
554
658
|
const action = sessionArgs[1];
|
|
@@ -556,30 +660,83 @@ async function handleSessionCommand() {
|
|
|
556
660
|
console.error("Usage: svamp session broadcast <action> [args...]\nActions: open-canvas <url> [label], close-canvas, toast <message>");
|
|
557
661
|
process.exit(1);
|
|
558
662
|
}
|
|
559
|
-
const { sessionBroadcast } = await import('./agentCommands-
|
|
663
|
+
const { sessionBroadcast } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
560
664
|
await sessionBroadcast(action, sessionArgs.slice(2).filter((a) => !a.startsWith("--")));
|
|
561
|
-
} else if (sessionSubcommand === "
|
|
562
|
-
const
|
|
563
|
-
|
|
665
|
+
} else if (sessionSubcommand === "inbox") {
|
|
666
|
+
const inboxSubcmd = sessionArgs[1];
|
|
667
|
+
const agentSessionId = process.env.SVAMP_SESSION_ID;
|
|
668
|
+
if (inboxSubcmd === "send") {
|
|
564
669
|
if (!sessionArgs[2] || !sessionArgs[3]) {
|
|
565
|
-
console.error('Usage: svamp session
|
|
670
|
+
console.error('Usage: svamp session inbox send <target-session-id> "<body>" [--subject "..."] [--urgency urgent|normal] [--json]');
|
|
566
671
|
process.exit(1);
|
|
567
672
|
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
673
|
+
if (agentSessionId) {
|
|
674
|
+
const { inboxSend } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
675
|
+
await inboxSend(sessionArgs[2], {
|
|
676
|
+
body: sessionArgs[3],
|
|
677
|
+
subject: parseFlagStr("--subject"),
|
|
678
|
+
urgency: parseFlagStr("--urgency")
|
|
679
|
+
});
|
|
680
|
+
} else {
|
|
681
|
+
await sessionInboxSend(sessionArgs[2], sessionArgs[3], targetMachineId, {
|
|
682
|
+
subject: parseFlagStr("--subject"),
|
|
683
|
+
urgency: parseFlagStr("--urgency"),
|
|
684
|
+
json: hasFlag("--json")
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
} else if (inboxSubcmd === "list" || inboxSubcmd === "ls") {
|
|
688
|
+
if (agentSessionId && !sessionArgs[2]) {
|
|
689
|
+
const { inboxList } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
690
|
+
await inboxList({
|
|
691
|
+
unread: hasFlag("--unread"),
|
|
692
|
+
limit: parseFlagInt("--limit"),
|
|
693
|
+
json: hasFlag("--json")
|
|
694
|
+
});
|
|
695
|
+
} else if (sessionArgs[2]) {
|
|
696
|
+
await sessionInboxList(sessionArgs[2], targetMachineId, {
|
|
697
|
+
unread: hasFlag("--unread"),
|
|
698
|
+
limit: parseFlagInt("--limit"),
|
|
699
|
+
json: hasFlag("--json")
|
|
700
|
+
});
|
|
701
|
+
} else {
|
|
702
|
+
console.error("Usage: svamp session inbox list [session-id] [--unread] [--limit N] [--json]");
|
|
572
703
|
process.exit(1);
|
|
573
704
|
}
|
|
574
|
-
|
|
575
|
-
} else if (queueSubcmd === "clear") {
|
|
705
|
+
} else if (inboxSubcmd === "read") {
|
|
576
706
|
if (!sessionArgs[2]) {
|
|
577
|
-
console.error("Usage: svamp session
|
|
707
|
+
console.error("Usage: svamp session inbox read <session-id|message-id> [message-id]");
|
|
708
|
+
process.exit(1);
|
|
709
|
+
}
|
|
710
|
+
if (agentSessionId && !sessionArgs[3]) {
|
|
711
|
+
const { inboxList } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
712
|
+
await sessionInboxRead(agentSessionId, sessionArgs[2], targetMachineId);
|
|
713
|
+
} else if (sessionArgs[3]) {
|
|
714
|
+
await sessionInboxRead(sessionArgs[2], sessionArgs[3], targetMachineId);
|
|
715
|
+
} else {
|
|
716
|
+
console.error("Usage: svamp session inbox read <session-id> <message-id>");
|
|
717
|
+
process.exit(1);
|
|
718
|
+
}
|
|
719
|
+
} else if (inboxSubcmd === "reply") {
|
|
720
|
+
if (agentSessionId && sessionArgs[2] && sessionArgs[3] && !sessionArgs[4]) {
|
|
721
|
+
const { inboxReply } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
722
|
+
await inboxReply(sessionArgs[2], sessionArgs[3]);
|
|
723
|
+
} else if (sessionArgs[2] && sessionArgs[3] && sessionArgs[4]) {
|
|
724
|
+
await sessionInboxReply(sessionArgs[2], sessionArgs[3], sessionArgs[4], targetMachineId);
|
|
725
|
+
} else {
|
|
726
|
+
console.error('Usage: svamp session inbox reply <session-id> <message-id> "<body>"');
|
|
727
|
+
process.exit(1);
|
|
728
|
+
}
|
|
729
|
+
} else if (inboxSubcmd === "clear") {
|
|
730
|
+
if (agentSessionId && !sessionArgs[2]) {
|
|
731
|
+
await sessionInboxClear(agentSessionId, targetMachineId, { all: hasFlag("--all") });
|
|
732
|
+
} else if (sessionArgs[2]) {
|
|
733
|
+
await sessionInboxClear(sessionArgs[2], targetMachineId, { all: hasFlag("--all") });
|
|
734
|
+
} else {
|
|
735
|
+
console.error("Usage: svamp session inbox clear [session-id] [--all]");
|
|
578
736
|
process.exit(1);
|
|
579
737
|
}
|
|
580
|
-
await sessionQueueClear(sessionArgs[2], targetMachineId);
|
|
581
738
|
} else {
|
|
582
|
-
console.error("Usage: svamp session
|
|
739
|
+
console.error("Usage: svamp session inbox <send|list|read|reply|clear> [session-id] [args]");
|
|
583
740
|
process.exit(1);
|
|
584
741
|
}
|
|
585
742
|
} else {
|
|
@@ -597,7 +754,7 @@ async function handleMachineCommand() {
|
|
|
597
754
|
return;
|
|
598
755
|
}
|
|
599
756
|
if (machineSubcommand === "share") {
|
|
600
|
-
const { machineShare } = await import('./commands-
|
|
757
|
+
const { machineShare } = await import('./commands-B6FEeZeP.mjs');
|
|
601
758
|
let machineId;
|
|
602
759
|
const shareArgs = [];
|
|
603
760
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
@@ -627,7 +784,7 @@ async function handleMachineCommand() {
|
|
|
627
784
|
}
|
|
628
785
|
await machineShare(machineId, { add, remove, list, configPath, showConfig });
|
|
629
786
|
} else if (machineSubcommand === "exec") {
|
|
630
|
-
const { machineExec } = await import('./commands-
|
|
787
|
+
const { machineExec } = await import('./commands-B6FEeZeP.mjs');
|
|
631
788
|
let machineId;
|
|
632
789
|
let cwd;
|
|
633
790
|
const cmdParts = [];
|
|
@@ -647,7 +804,7 @@ async function handleMachineCommand() {
|
|
|
647
804
|
}
|
|
648
805
|
await machineExec(machineId, command, cwd);
|
|
649
806
|
} else if (machineSubcommand === "info") {
|
|
650
|
-
const { machineInfo } = await import('./commands-
|
|
807
|
+
const { machineInfo } = await import('./commands-B6FEeZeP.mjs');
|
|
651
808
|
let machineId;
|
|
652
809
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
653
810
|
if ((machineArgs[i] === "--machine" || machineArgs[i] === "-m") && i + 1 < machineArgs.length) {
|
|
@@ -667,10 +824,10 @@ async function handleMachineCommand() {
|
|
|
667
824
|
level = machineArgs[++i];
|
|
668
825
|
}
|
|
669
826
|
}
|
|
670
|
-
const { machineNotify } = await import('./agentCommands-
|
|
827
|
+
const { machineNotify } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
671
828
|
await machineNotify(message, level);
|
|
672
829
|
} else if (machineSubcommand === "ls") {
|
|
673
|
-
const { machineLs } = await import('./commands-
|
|
830
|
+
const { machineLs } = await import('./commands-B6FEeZeP.mjs');
|
|
674
831
|
let machineId;
|
|
675
832
|
let showHidden = false;
|
|
676
833
|
let path;
|
|
@@ -698,7 +855,7 @@ async function handleSkillsCommand() {
|
|
|
698
855
|
printSkillsHelp();
|
|
699
856
|
return;
|
|
700
857
|
}
|
|
701
|
-
const { skillsFind, skillsInstall, skillsList, skillsRemove, skillsPublish } = await import('./commands-
|
|
858
|
+
const { skillsFind, skillsInstall, skillsList, skillsRemove, skillsPublish } = await import('./commands-DJoYOM_1.mjs');
|
|
702
859
|
if (skillsSubcommand === "find" || skillsSubcommand === "search") {
|
|
703
860
|
const query = skillsArgs.slice(1).filter((a) => !a.startsWith("--")).join(" ");
|
|
704
861
|
if (!query) {
|
|
@@ -824,6 +981,41 @@ You can now start the daemon: svamp daemon start`);
|
|
|
824
981
|
process.exit(1);
|
|
825
982
|
}
|
|
826
983
|
}
|
|
984
|
+
async function logoutFromHypha() {
|
|
985
|
+
const os = await import('os');
|
|
986
|
+
const { join } = await import('path');
|
|
987
|
+
const fs = await import('fs');
|
|
988
|
+
const homeDir = process.env.SVAMP_HOME || join(os.homedir(), ".svamp");
|
|
989
|
+
const envFile = join(homeDir, ".env");
|
|
990
|
+
console.log("Stopping daemon...");
|
|
991
|
+
try {
|
|
992
|
+
await stopDaemon();
|
|
993
|
+
} catch {
|
|
994
|
+
}
|
|
995
|
+
if (fs.existsSync(envFile)) {
|
|
996
|
+
const existing = fs.readFileSync(envFile, "utf-8").split("\n");
|
|
997
|
+
const kept = [];
|
|
998
|
+
for (const line of existing) {
|
|
999
|
+
const trimmed = line.trim();
|
|
1000
|
+
if (trimmed.startsWith("HYPHA_TOKEN=") || trimmed.startsWith("HYPHA_WORKSPACE=") || trimmed.startsWith("HYPHA_SERVER_URL=")) {
|
|
1001
|
+
continue;
|
|
1002
|
+
}
|
|
1003
|
+
kept.push(line);
|
|
1004
|
+
}
|
|
1005
|
+
while (kept.length > 0 && kept[kept.length - 1].trim() === "") {
|
|
1006
|
+
kept.pop();
|
|
1007
|
+
}
|
|
1008
|
+
if (kept.length > 0) {
|
|
1009
|
+
fs.writeFileSync(envFile, kept.join("\n") + "\n", "utf-8");
|
|
1010
|
+
} else {
|
|
1011
|
+
fs.unlinkSync(envFile);
|
|
1012
|
+
}
|
|
1013
|
+
console.log("Credentials removed");
|
|
1014
|
+
} else {
|
|
1015
|
+
console.log("No credentials found");
|
|
1016
|
+
}
|
|
1017
|
+
console.log("Logged out successfully");
|
|
1018
|
+
}
|
|
827
1019
|
const LAUNCHD_LABEL = "io.hypha.svamp.daemon";
|
|
828
1020
|
async function installDaemonService() {
|
|
829
1021
|
const os = await import('os');
|
|
@@ -861,18 +1053,10 @@ async function installDaemonService() {
|
|
|
861
1053
|
<array>
|
|
862
1054
|
<string>${svampBinary}</string>
|
|
863
1055
|
<string>daemon</string>
|
|
864
|
-
<string>start-
|
|
1056
|
+
<string>start-supervised</string>
|
|
865
1057
|
</array>
|
|
866
1058
|
<key>RunAtLoad</key>
|
|
867
1059
|
<true/>
|
|
868
|
-
<key>KeepAlive</key>
|
|
869
|
-
<dict>
|
|
870
|
-
<!-- Only restart on crash (non-zero exit). svamp daemon stop exits 0. -->
|
|
871
|
-
<key>SuccessfulExit</key>
|
|
872
|
-
<false/>
|
|
873
|
-
</dict>
|
|
874
|
-
<key>ThrottleInterval</key>
|
|
875
|
-
<integer>10</integer>
|
|
876
1060
|
<key>StandardOutPath</key>
|
|
877
1061
|
<string>${logsDir}/daemon-supervised.log</string>
|
|
878
1062
|
<key>StandardErrorPath</key>
|
|
@@ -883,8 +1067,6 @@ async function installDaemonService() {
|
|
|
883
1067
|
<string>${supervisedPath}</string>
|
|
884
1068
|
<key>SVAMP_HOME</key>
|
|
885
1069
|
<string>${svampHome}</string>
|
|
886
|
-
<key>SVAMP_SUPERVISED</key>
|
|
887
|
-
<string>1</string>
|
|
888
1070
|
</dict>
|
|
889
1071
|
</dict>
|
|
890
1072
|
</plist>
|
|
@@ -923,12 +1105,9 @@ After=network-online.target
|
|
|
923
1105
|
Wants=network-online.target
|
|
924
1106
|
|
|
925
1107
|
[Service]
|
|
926
|
-
ExecStart=${svampBinary} daemon start-
|
|
927
|
-
Restart=on-failure
|
|
928
|
-
RestartSec=10
|
|
1108
|
+
ExecStart=${svampBinary} daemon start-supervised
|
|
929
1109
|
Environment=PATH=${supervisedPath}
|
|
930
1110
|
Environment=SVAMP_HOME=${svampHome}
|
|
931
|
-
Environment=SVAMP_SUPERVISED=1
|
|
932
1111
|
StandardOutput=append:${logsDir}/daemon-supervised.log
|
|
933
1112
|
StandardError=append:${logsDir}/daemon-supervised.log
|
|
934
1113
|
|
|
@@ -948,47 +1127,24 @@ Svamp daemon service installed and started!`);
|
|
|
948
1127
|
To stop the service: svamp daemon stop`);
|
|
949
1128
|
console.log(`To uninstall: svamp daemon uninstall`);
|
|
950
1129
|
} else {
|
|
951
|
-
const wrapperPath = join(svampHome, "daemon-supervisor.sh");
|
|
952
|
-
const wrapper = `#!/bin/sh
|
|
953
|
-
# Svamp daemon supervisor \u2014 restarts on crash. Run this as your container CMD
|
|
954
|
-
# or in a background process. Stop with: svamp daemon stop
|
|
955
|
-
export PATH="${supervisedPath}"
|
|
956
|
-
export SVAMP_HOME="${svampHome}"
|
|
957
|
-
export SVAMP_SUPERVISED=1
|
|
958
|
-
|
|
959
|
-
mkdir -p "${logsDir}"
|
|
960
|
-
echo "[svamp-supervisor] Starting svamp daemon supervisor" >> "${logsDir}/daemon-supervised.log"
|
|
961
|
-
|
|
962
|
-
while true; do
|
|
963
|
-
"${svampBinary}" daemon start-sync >> "${logsDir}/daemon-supervised.log" 2>&1
|
|
964
|
-
EXIT_CODE=$?
|
|
965
|
-
# Exit code 0 = clean stop (svamp daemon stop). Do not restart.
|
|
966
|
-
if [ "$EXIT_CODE" -eq 0 ]; then
|
|
967
|
-
echo "[svamp-supervisor] Daemon stopped cleanly (exit 0). Not restarting." >> "${logsDir}/daemon-supervised.log"
|
|
968
|
-
break
|
|
969
|
-
fi
|
|
970
|
-
echo "[svamp-supervisor] Daemon exited with code $EXIT_CODE. Restarting in 10s..." >> "${logsDir}/daemon-supervised.log"
|
|
971
|
-
sleep 10
|
|
972
|
-
done
|
|
973
|
-
`;
|
|
974
|
-
fs.writeFileSync(wrapperPath, wrapper, { mode: 493 });
|
|
975
1130
|
console.log(`
|
|
976
|
-
|
|
977
|
-
console.log(` Script: ${wrapperPath}`);
|
|
978
|
-
console.log(` Log file: ${logsDir}/daemon-supervised.log`);
|
|
1131
|
+
No systemd detected. The built-in supervisor is cross-platform.`);
|
|
979
1132
|
console.log(`
|
|
980
|
-
|
|
981
|
-
console.log(` ${
|
|
1133
|
+
For Docker, set your container CMD to:`);
|
|
1134
|
+
console.log(` ${svampBinary} daemon start-supervised`);
|
|
982
1135
|
console.log(`
|
|
983
1136
|
Or run in the background:`);
|
|
984
|
-
console.log(`
|
|
1137
|
+
console.log(` svamp daemon start`);
|
|
985
1138
|
console.log(`
|
|
986
1139
|
To stop the daemon: svamp daemon stop`);
|
|
987
1140
|
}
|
|
988
1141
|
} else {
|
|
989
|
-
console.
|
|
990
|
-
|
|
991
|
-
|
|
1142
|
+
console.log(`
|
|
1143
|
+
The built-in supervisor is cross-platform.`);
|
|
1144
|
+
console.log(`
|
|
1145
|
+
Run: svamp daemon start`);
|
|
1146
|
+
console.log(`
|
|
1147
|
+
To stop: svamp daemon stop`);
|
|
992
1148
|
}
|
|
993
1149
|
}
|
|
994
1150
|
async function uninstallDaemonService() {
|
|
@@ -1054,6 +1210,7 @@ Quick start \u2014 spawn an agent to do a task (use -p bypassPermissions to run
|
|
|
1054
1210
|
Commands:
|
|
1055
1211
|
svamp Start interactive Claude session (synced to cloud)
|
|
1056
1212
|
svamp login [url] Login to Hypha (opens browser, stores token)
|
|
1213
|
+
svamp logout Logout (stop daemon, remove credentials)
|
|
1057
1214
|
svamp daemon start Start the background daemon (required for sessions)
|
|
1058
1215
|
svamp daemon status Show daemon status
|
|
1059
1216
|
svamp daemon --help Show all daemon commands
|
|
@@ -1099,8 +1256,8 @@ Usage:
|
|
|
1099
1256
|
svamp daemon stop --cleanup Stop and mark all sessions as stopped
|
|
1100
1257
|
svamp daemon restart Restart daemon (sessions resume seamlessly)
|
|
1101
1258
|
svamp daemon status Show daemon status
|
|
1102
|
-
svamp daemon install Install as
|
|
1103
|
-
svamp daemon uninstall Remove
|
|
1259
|
+
svamp daemon install Install as login service (macOS/Linux) \u2014 auto-start at login
|
|
1260
|
+
svamp daemon uninstall Remove login service
|
|
1104
1261
|
`);
|
|
1105
1262
|
}
|
|
1106
1263
|
function printSessionHelp() {
|
|
@@ -1160,10 +1317,12 @@ COMMANDS:
|
|
|
1160
1317
|
ralph-cancel <id> Cancel loop
|
|
1161
1318
|
ralph-status <id> Show loop status
|
|
1162
1319
|
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1320
|
+
Inbox:
|
|
1321
|
+
inbox send <id> "<body>" [opts] Send a message to session inbox
|
|
1322
|
+
inbox list <id> [--unread] [--json] List inbox messages
|
|
1323
|
+
inbox read <id> <msg-id> Read and mark a message
|
|
1324
|
+
inbox reply <id> <msg-id> "<body>" Reply to sender's session
|
|
1325
|
+
inbox clear <id> [--all] Clear read (or all) messages
|
|
1167
1326
|
|
|
1168
1327
|
SPAWN OPTIONS:
|
|
1169
1328
|
-d, --directory <path> Working directory (REQUIRED for meaningful work)
|