svamp-cli 0.1.76 → 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-NVZzP_Vo.mjs → agentCommands-uNFhhdN1.mjs} +16 -51
- package/dist/cli.mjs +82 -30
- package/dist/{commands-lJ8V7MJE.mjs → commands-B6FEeZeP.mjs} +32 -36
- package/dist/{commands-CADr1mQg.mjs → commands-BYbuedOK.mjs} +4 -4
- package/dist/{commands-7Iw1nFwf.mjs → commands-Cf3mXxPZ.mjs} +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{package-Dpz1MLO4.mjs → package-DTOqWYBv.mjs} +2 -2
- package/dist/{run-B29grSMh.mjs → run-DqvxMsWh.mjs} +1 -1
- package/dist/{run-BnFGIK0c.mjs → run-DsXDjwLW.mjs} +199 -50
- package/dist/staticServer-CWcmMF5V.mjs +477 -0
- package/dist/{tunnel-C2kqST5d.mjs → tunnel-BDKdemh0.mjs} +51 -9
- package/package.json +2 -2
- package/dist/staticServer-B-S9sl6E.mjs +0 -198
|
@@ -144,47 +144,9 @@ async function sessionBroadcast(action, args) {
|
|
|
144
144
|
});
|
|
145
145
|
console.log(`Broadcast sent: ${action}`);
|
|
146
146
|
}
|
|
147
|
-
async function
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
const lines = readFileSync(ENV_FILE, "utf-8").split("\n");
|
|
151
|
-
for (const line of lines) {
|
|
152
|
-
const m = line.match(/^([A-Z_]+)=(.*)/);
|
|
153
|
-
if (m && !process.env[m[1]]) process.env[m[1]] = m[2].replace(/^["']|["']$/g, "");
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
const serverUrl = process.env.HYPHA_SERVER_URL;
|
|
157
|
-
const token = process.env.HYPHA_TOKEN;
|
|
158
|
-
if (!serverUrl || !token) {
|
|
159
|
-
console.error('No Hypha credentials. Run "svamp login" first.');
|
|
160
|
-
process.exit(1);
|
|
161
|
-
}
|
|
162
|
-
const origLog = console.log;
|
|
163
|
-
const origWarn = console.warn;
|
|
164
|
-
const origInfo = console.info;
|
|
165
|
-
console.log = () => {
|
|
166
|
-
};
|
|
167
|
-
console.warn = () => {
|
|
168
|
-
};
|
|
169
|
-
console.info = () => {
|
|
170
|
-
};
|
|
171
|
-
let server;
|
|
172
|
-
try {
|
|
173
|
-
const mod = await import('hypha-rpc');
|
|
174
|
-
const connectToServer = mod.connectToServer || mod.default?.connectToServer;
|
|
175
|
-
server = await connectToServer({ server_url: serverUrl, token, name: "svamp-agent-inbox" });
|
|
176
|
-
} catch (err) {
|
|
177
|
-
console.log = origLog;
|
|
178
|
-
console.warn = origWarn;
|
|
179
|
-
console.info = origInfo;
|
|
180
|
-
console.error(`Failed to connect to Hypha: ${err.message}`);
|
|
181
|
-
process.exit(1);
|
|
182
|
-
}
|
|
183
|
-
console.log = origLog;
|
|
184
|
-
console.warn = origWarn;
|
|
185
|
-
console.info = origInfo;
|
|
186
|
-
const svc = await server.getService(`svamp-session-${sessionId}`);
|
|
187
|
-
return { server, svc };
|
|
147
|
+
async function connectToMachineService() {
|
|
148
|
+
const { connectAndGetMachine } = await import('./commands-B6FEeZeP.mjs');
|
|
149
|
+
return connectAndGetMachine();
|
|
188
150
|
}
|
|
189
151
|
async function inboxSend(targetSessionId, opts) {
|
|
190
152
|
const sessionId = process.env.SVAMP_SESSION_ID;
|
|
@@ -197,8 +159,12 @@ async function inboxSend(targetSessionId, opts) {
|
|
|
197
159
|
console.error("Message body is required.");
|
|
198
160
|
process.exit(1);
|
|
199
161
|
}
|
|
200
|
-
const { server,
|
|
162
|
+
const { server, machine } = await connectToMachineService();
|
|
201
163
|
try {
|
|
164
|
+
const { resolveSessionId } = await import('./commands-B6FEeZeP.mjs');
|
|
165
|
+
const sessions = await machine.listSessions();
|
|
166
|
+
const match = resolveSessionId(sessions, targetSessionId);
|
|
167
|
+
const fullTargetId = match.sessionId;
|
|
202
168
|
const { randomUUID } = await import('node:crypto');
|
|
203
169
|
const message = {
|
|
204
170
|
messageId: randomUUID(),
|
|
@@ -207,12 +173,12 @@ async function inboxSend(targetSessionId, opts) {
|
|
|
207
173
|
read: false,
|
|
208
174
|
from: `agent:${sessionId}`,
|
|
209
175
|
fromSession: sessionId,
|
|
210
|
-
to:
|
|
176
|
+
to: fullTargetId,
|
|
211
177
|
subject: opts?.subject,
|
|
212
178
|
urgency: opts?.urgency || "normal"
|
|
213
179
|
};
|
|
214
|
-
const result = await
|
|
215
|
-
console.log(`Inbox message sent to ${
|
|
180
|
+
const result = await machine.sessionRPC(fullTargetId, "sendInboxMessage", [message]);
|
|
181
|
+
console.log(`Inbox message sent to ${fullTargetId.slice(0, 8)} (id: ${result.messageId.slice(0, 8)})`);
|
|
216
182
|
} finally {
|
|
217
183
|
await server.disconnect();
|
|
218
184
|
}
|
|
@@ -223,9 +189,9 @@ async function inboxList(opts) {
|
|
|
223
189
|
console.error("SVAMP_SESSION_ID not set. This command must be run inside a Svamp session.");
|
|
224
190
|
process.exit(1);
|
|
225
191
|
}
|
|
226
|
-
const { server,
|
|
192
|
+
const { server, machine } = await connectToMachineService();
|
|
227
193
|
try {
|
|
228
|
-
const result = await
|
|
194
|
+
const result = await machine.sessionRPC(sessionId, "getInbox", [{ unread: opts?.unread, limit: opts?.limit }]);
|
|
229
195
|
const messages = result.messages;
|
|
230
196
|
if (opts?.json) {
|
|
231
197
|
console.log(JSON.stringify({ messages }, null, 2));
|
|
@@ -253,9 +219,9 @@ async function inboxReply(messageId, body) {
|
|
|
253
219
|
console.error("SVAMP_SESSION_ID not set. This command must be run inside a Svamp session.");
|
|
254
220
|
process.exit(1);
|
|
255
221
|
}
|
|
256
|
-
const { server,
|
|
222
|
+
const { server, machine } = await connectToMachineService();
|
|
257
223
|
try {
|
|
258
|
-
const result = await
|
|
224
|
+
const result = await machine.sessionRPC(sessionId, "getInbox", []);
|
|
259
225
|
const original = result.messages.find((m) => m.messageId === messageId || m.messageId.startsWith(messageId));
|
|
260
226
|
if (!original) {
|
|
261
227
|
console.error(`Message ${messageId} not found in inbox.`);
|
|
@@ -265,7 +231,6 @@ async function inboxReply(messageId, body) {
|
|
|
265
231
|
console.error("Cannot reply: original message has no fromSession.");
|
|
266
232
|
process.exit(1);
|
|
267
233
|
}
|
|
268
|
-
const targetSvc = await server.getService(`svamp-session-${original.fromSession}`);
|
|
269
234
|
const { randomUUID } = await import('node:crypto');
|
|
270
235
|
const reply = {
|
|
271
236
|
messageId: randomUUID(),
|
|
@@ -280,7 +245,7 @@ async function inboxReply(messageId, body) {
|
|
|
280
245
|
replyTo: original.messageId,
|
|
281
246
|
threadId: original.threadId || original.messageId
|
|
282
247
|
};
|
|
283
|
-
const sendResult = await
|
|
248
|
+
const sendResult = await machine.sessionRPC(original.fromSession, "sendInboxMessage", [reply]);
|
|
284
249
|
console.log(`Reply sent to ${original.fromSession.slice(0, 8)} (id: ${sendResult.messageId.slice(0, 8)})`);
|
|
285
250
|
} finally {
|
|
286
251
|
await server.disconnect();
|
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();
|
|
@@ -94,6 +96,13 @@ async function main() {
|
|
|
94
96
|
} catch {
|
|
95
97
|
}
|
|
96
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");
|
|
97
106
|
const extraSyncArgs = [];
|
|
98
107
|
if (args.includes("--no-auto-continue")) extraSyncArgs.push("--no-auto-continue");
|
|
99
108
|
const BASE_DELAY_MS = 2e3;
|
|
@@ -164,6 +173,11 @@ async function main() {
|
|
|
164
173
|
setTimeout(() => clearInterval(checkStop), delay + 100);
|
|
165
174
|
});
|
|
166
175
|
}
|
|
176
|
+
try {
|
|
177
|
+
const { unlinkSync: us } = await import('fs');
|
|
178
|
+
us(supervisorPidFile);
|
|
179
|
+
} catch {
|
|
180
|
+
}
|
|
167
181
|
process.exit(0);
|
|
168
182
|
} else if (daemonSubcommand === "start-sync") {
|
|
169
183
|
const noAutoContinue = args.includes("--no-auto-continue");
|
|
@@ -194,10 +208,10 @@ async function main() {
|
|
|
194
208
|
} else if (subcommand === "skills") {
|
|
195
209
|
await handleSkillsCommand();
|
|
196
210
|
} else if (subcommand === "service" || subcommand === "svc") {
|
|
197
|
-
const { handleServiceCommand } = await import('./commands-
|
|
211
|
+
const { handleServiceCommand } = await import('./commands-BYbuedOK.mjs');
|
|
198
212
|
await handleServiceCommand();
|
|
199
213
|
} else if (subcommand === "process" || subcommand === "proc") {
|
|
200
|
-
const { processCommand } = await import('./commands-
|
|
214
|
+
const { processCommand } = await import('./commands-Cf3mXxPZ.mjs');
|
|
201
215
|
let machineId;
|
|
202
216
|
const processArgs = args.slice(1);
|
|
203
217
|
const mIdx = processArgs.findIndex((a) => a === "--machine" || a === "-m");
|
|
@@ -215,7 +229,7 @@ async function main() {
|
|
|
215
229
|
} else if (!subcommand || subcommand === "start") {
|
|
216
230
|
await handleInteractiveCommand();
|
|
217
231
|
} else if (subcommand === "--version" || subcommand === "-v") {
|
|
218
|
-
const pkg = await import('./package-
|
|
232
|
+
const pkg = await import('./package-DTOqWYBv.mjs').catch(() => ({ default: { version: "unknown" } }));
|
|
219
233
|
console.log(`svamp version: ${pkg.default.version}`);
|
|
220
234
|
} else {
|
|
221
235
|
console.error(`Unknown command: ${subcommand}`);
|
|
@@ -224,7 +238,7 @@ async function main() {
|
|
|
224
238
|
}
|
|
225
239
|
}
|
|
226
240
|
async function handleInteractiveCommand() {
|
|
227
|
-
const { runInteractive } = await import('./run-
|
|
241
|
+
const { runInteractive } = await import('./run-DqvxMsWh.mjs');
|
|
228
242
|
const interactiveArgs = subcommand === "start" ? args.slice(1) : args;
|
|
229
243
|
let directory = process.cwd();
|
|
230
244
|
let resumeSessionId;
|
|
@@ -269,7 +283,7 @@ async function handleAgentCommand() {
|
|
|
269
283
|
return;
|
|
270
284
|
}
|
|
271
285
|
if (agentArgs[0] === "list") {
|
|
272
|
-
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; });
|
|
273
287
|
console.log("Known agents:");
|
|
274
288
|
for (const [name, config2] of Object.entries(KNOWN_ACP_AGENTS)) {
|
|
275
289
|
console.log(` ${name.padEnd(12)} ${config2.command} ${config2.args.join(" ")} (ACP)`);
|
|
@@ -281,7 +295,7 @@ async function handleAgentCommand() {
|
|
|
281
295
|
console.log('Use "svamp agent -- <command> [args]" for a custom ACP agent.');
|
|
282
296
|
return;
|
|
283
297
|
}
|
|
284
|
-
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; });
|
|
285
299
|
let cwd = process.cwd();
|
|
286
300
|
const filteredArgs = [];
|
|
287
301
|
for (let i = 0; i < agentArgs.length; i++) {
|
|
@@ -305,12 +319,12 @@ async function handleAgentCommand() {
|
|
|
305
319
|
console.log(`Starting ${config.agentName} agent in ${cwd}...`);
|
|
306
320
|
let backend;
|
|
307
321
|
if (KNOWN_MCP_AGENTS[config.agentName]) {
|
|
308
|
-
const { CodexMcpBackend } = await import('./run-
|
|
322
|
+
const { CodexMcpBackend } = await import('./run-DsXDjwLW.mjs').then(function (n) { return n.j; });
|
|
309
323
|
backend = new CodexMcpBackend({ cwd, log: logFn });
|
|
310
324
|
} else {
|
|
311
|
-
const { AcpBackend } = await import('./run-
|
|
312
|
-
const { GeminiTransport } = await import('./run-
|
|
313
|
-
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; });
|
|
314
328
|
const transportHandler = config.agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(config.agentName);
|
|
315
329
|
backend = new AcpBackend({
|
|
316
330
|
agentName: config.agentName,
|
|
@@ -428,7 +442,7 @@ async function handleSessionCommand() {
|
|
|
428
442
|
printSessionHelp();
|
|
429
443
|
return;
|
|
430
444
|
}
|
|
431
|
-
const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-
|
|
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');
|
|
432
446
|
const parseFlagStr = (flag, shortFlag) => {
|
|
433
447
|
for (let i = 1; i < sessionArgs.length; i++) {
|
|
434
448
|
if ((sessionArgs[i] === flag || shortFlag) && i + 1 < sessionArgs.length) {
|
|
@@ -488,7 +502,7 @@ async function handleSessionCommand() {
|
|
|
488
502
|
allowDomain.push(sessionArgs[++i]);
|
|
489
503
|
}
|
|
490
504
|
}
|
|
491
|
-
const { parseShareArg } = await import('./commands-
|
|
505
|
+
const { parseShareArg } = await import('./commands-B6FEeZeP.mjs');
|
|
492
506
|
const shareEntries = share.map((s) => parseShareArg(s));
|
|
493
507
|
await sessionSpawn(agent, dir, targetMachineId, {
|
|
494
508
|
message,
|
|
@@ -539,13 +553,15 @@ async function handleSessionCommand() {
|
|
|
539
553
|
await sessionAttach(sessionArgs[1], targetMachineId);
|
|
540
554
|
} else if (sessionSubcommand === "send") {
|
|
541
555
|
if (!sessionArgs[1] || !sessionArgs[2]) {
|
|
542
|
-
console.error(
|
|
556
|
+
console.error('Usage: svamp session send <session-id> <message> [--subject "..."] [--urgency urgent|normal] [--wait] [--timeout N] [--json]');
|
|
543
557
|
process.exit(1);
|
|
544
558
|
}
|
|
545
559
|
await sessionSend(sessionArgs[1], sessionArgs[2], targetMachineId, {
|
|
546
560
|
wait: hasFlag("--wait"),
|
|
547
561
|
timeout: parseFlagInt("--timeout"),
|
|
548
|
-
json: hasFlag("--json")
|
|
562
|
+
json: hasFlag("--json"),
|
|
563
|
+
subject: parseFlagStr("--subject"),
|
|
564
|
+
urgency: parseFlagStr("--urgency")
|
|
549
565
|
});
|
|
550
566
|
} else if (sessionSubcommand === "wait") {
|
|
551
567
|
if (!sessionArgs[1]) {
|
|
@@ -572,7 +588,7 @@ async function handleSessionCommand() {
|
|
|
572
588
|
console.error("Usage: svamp session approve <session-id> [request-id] [--json]");
|
|
573
589
|
process.exit(1);
|
|
574
590
|
}
|
|
575
|
-
const { sessionApprove } = await import('./commands-
|
|
591
|
+
const { sessionApprove } = await import('./commands-B6FEeZeP.mjs');
|
|
576
592
|
const approveReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
577
593
|
await sessionApprove(sessionArgs[1], approveReqId, targetMachineId, {
|
|
578
594
|
json: hasFlag("--json")
|
|
@@ -582,7 +598,7 @@ async function handleSessionCommand() {
|
|
|
582
598
|
console.error("Usage: svamp session deny <session-id> [request-id] [--json]");
|
|
583
599
|
process.exit(1);
|
|
584
600
|
}
|
|
585
|
-
const { sessionDeny } = await import('./commands-
|
|
601
|
+
const { sessionDeny } = await import('./commands-B6FEeZeP.mjs');
|
|
586
602
|
const denyReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
587
603
|
await sessionDeny(sessionArgs[1], denyReqId, targetMachineId, {
|
|
588
604
|
json: hasFlag("--json")
|
|
@@ -618,7 +634,7 @@ async function handleSessionCommand() {
|
|
|
618
634
|
console.error("Usage: svamp session set-title <title>");
|
|
619
635
|
process.exit(1);
|
|
620
636
|
}
|
|
621
|
-
const { sessionSetTitle } = await import('./agentCommands-
|
|
637
|
+
const { sessionSetTitle } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
622
638
|
await sessionSetTitle(title);
|
|
623
639
|
} else if (sessionSubcommand === "set-link") {
|
|
624
640
|
const url = sessionArgs[1];
|
|
@@ -627,7 +643,7 @@ async function handleSessionCommand() {
|
|
|
627
643
|
process.exit(1);
|
|
628
644
|
}
|
|
629
645
|
const label = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
630
|
-
const { sessionSetLink } = await import('./agentCommands-
|
|
646
|
+
const { sessionSetLink } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
631
647
|
await sessionSetLink(url, label);
|
|
632
648
|
} else if (sessionSubcommand === "notify") {
|
|
633
649
|
const message = sessionArgs[1];
|
|
@@ -636,7 +652,7 @@ async function handleSessionCommand() {
|
|
|
636
652
|
process.exit(1);
|
|
637
653
|
}
|
|
638
654
|
const level = parseFlagStr("--level") || "info";
|
|
639
|
-
const { sessionNotify } = await import('./agentCommands-
|
|
655
|
+
const { sessionNotify } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
640
656
|
await sessionNotify(message, level);
|
|
641
657
|
} else if (sessionSubcommand === "broadcast") {
|
|
642
658
|
const action = sessionArgs[1];
|
|
@@ -644,7 +660,7 @@ async function handleSessionCommand() {
|
|
|
644
660
|
console.error("Usage: svamp session broadcast <action> [args...]\nActions: open-canvas <url> [label], close-canvas, toast <message>");
|
|
645
661
|
process.exit(1);
|
|
646
662
|
}
|
|
647
|
-
const { sessionBroadcast } = await import('./agentCommands-
|
|
663
|
+
const { sessionBroadcast } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
648
664
|
await sessionBroadcast(action, sessionArgs.slice(2).filter((a) => !a.startsWith("--")));
|
|
649
665
|
} else if (sessionSubcommand === "inbox") {
|
|
650
666
|
const inboxSubcmd = sessionArgs[1];
|
|
@@ -655,7 +671,7 @@ async function handleSessionCommand() {
|
|
|
655
671
|
process.exit(1);
|
|
656
672
|
}
|
|
657
673
|
if (agentSessionId) {
|
|
658
|
-
const { inboxSend } = await import('./agentCommands-
|
|
674
|
+
const { inboxSend } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
659
675
|
await inboxSend(sessionArgs[2], {
|
|
660
676
|
body: sessionArgs[3],
|
|
661
677
|
subject: parseFlagStr("--subject"),
|
|
@@ -670,7 +686,7 @@ async function handleSessionCommand() {
|
|
|
670
686
|
}
|
|
671
687
|
} else if (inboxSubcmd === "list" || inboxSubcmd === "ls") {
|
|
672
688
|
if (agentSessionId && !sessionArgs[2]) {
|
|
673
|
-
const { inboxList } = await import('./agentCommands-
|
|
689
|
+
const { inboxList } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
674
690
|
await inboxList({
|
|
675
691
|
unread: hasFlag("--unread"),
|
|
676
692
|
limit: parseFlagInt("--limit"),
|
|
@@ -692,7 +708,7 @@ async function handleSessionCommand() {
|
|
|
692
708
|
process.exit(1);
|
|
693
709
|
}
|
|
694
710
|
if (agentSessionId && !sessionArgs[3]) {
|
|
695
|
-
const { inboxList } = await import('./agentCommands-
|
|
711
|
+
const { inboxList } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
696
712
|
await sessionInboxRead(agentSessionId, sessionArgs[2], targetMachineId);
|
|
697
713
|
} else if (sessionArgs[3]) {
|
|
698
714
|
await sessionInboxRead(sessionArgs[2], sessionArgs[3], targetMachineId);
|
|
@@ -702,7 +718,7 @@ async function handleSessionCommand() {
|
|
|
702
718
|
}
|
|
703
719
|
} else if (inboxSubcmd === "reply") {
|
|
704
720
|
if (agentSessionId && sessionArgs[2] && sessionArgs[3] && !sessionArgs[4]) {
|
|
705
|
-
const { inboxReply } = await import('./agentCommands-
|
|
721
|
+
const { inboxReply } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
706
722
|
await inboxReply(sessionArgs[2], sessionArgs[3]);
|
|
707
723
|
} else if (sessionArgs[2] && sessionArgs[3] && sessionArgs[4]) {
|
|
708
724
|
await sessionInboxReply(sessionArgs[2], sessionArgs[3], sessionArgs[4], targetMachineId);
|
|
@@ -738,7 +754,7 @@ async function handleMachineCommand() {
|
|
|
738
754
|
return;
|
|
739
755
|
}
|
|
740
756
|
if (machineSubcommand === "share") {
|
|
741
|
-
const { machineShare } = await import('./commands-
|
|
757
|
+
const { machineShare } = await import('./commands-B6FEeZeP.mjs');
|
|
742
758
|
let machineId;
|
|
743
759
|
const shareArgs = [];
|
|
744
760
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
@@ -768,7 +784,7 @@ async function handleMachineCommand() {
|
|
|
768
784
|
}
|
|
769
785
|
await machineShare(machineId, { add, remove, list, configPath, showConfig });
|
|
770
786
|
} else if (machineSubcommand === "exec") {
|
|
771
|
-
const { machineExec } = await import('./commands-
|
|
787
|
+
const { machineExec } = await import('./commands-B6FEeZeP.mjs');
|
|
772
788
|
let machineId;
|
|
773
789
|
let cwd;
|
|
774
790
|
const cmdParts = [];
|
|
@@ -788,7 +804,7 @@ async function handleMachineCommand() {
|
|
|
788
804
|
}
|
|
789
805
|
await machineExec(machineId, command, cwd);
|
|
790
806
|
} else if (machineSubcommand === "info") {
|
|
791
|
-
const { machineInfo } = await import('./commands-
|
|
807
|
+
const { machineInfo } = await import('./commands-B6FEeZeP.mjs');
|
|
792
808
|
let machineId;
|
|
793
809
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
794
810
|
if ((machineArgs[i] === "--machine" || machineArgs[i] === "-m") && i + 1 < machineArgs.length) {
|
|
@@ -808,10 +824,10 @@ async function handleMachineCommand() {
|
|
|
808
824
|
level = machineArgs[++i];
|
|
809
825
|
}
|
|
810
826
|
}
|
|
811
|
-
const { machineNotify } = await import('./agentCommands-
|
|
827
|
+
const { machineNotify } = await import('./agentCommands-uNFhhdN1.mjs');
|
|
812
828
|
await machineNotify(message, level);
|
|
813
829
|
} else if (machineSubcommand === "ls") {
|
|
814
|
-
const { machineLs } = await import('./commands-
|
|
830
|
+
const { machineLs } = await import('./commands-B6FEeZeP.mjs');
|
|
815
831
|
let machineId;
|
|
816
832
|
let showHidden = false;
|
|
817
833
|
let path;
|
|
@@ -965,6 +981,41 @@ You can now start the daemon: svamp daemon start`);
|
|
|
965
981
|
process.exit(1);
|
|
966
982
|
}
|
|
967
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
|
+
}
|
|
968
1019
|
const LAUNCHD_LABEL = "io.hypha.svamp.daemon";
|
|
969
1020
|
async function installDaemonService() {
|
|
970
1021
|
const os = await import('os');
|
|
@@ -1159,6 +1210,7 @@ Quick start \u2014 spawn an agent to do a task (use -p bypassPermissions to run
|
|
|
1159
1210
|
Commands:
|
|
1160
1211
|
svamp Start interactive Claude session (synced to cloud)
|
|
1161
1212
|
svamp login [url] Login to Hypha (opens browser, stores token)
|
|
1213
|
+
svamp logout Logout (stop daemon, remove credentials)
|
|
1162
1214
|
svamp daemon start Start the background daemon (required for sessions)
|
|
1163
1215
|
svamp daemon status Show daemon status
|
|
1164
1216
|
svamp daemon --help Show all daemon commands
|
|
@@ -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-DsXDjwLW.mjs';
|
|
6
6
|
import 'os';
|
|
7
7
|
import 'fs/promises';
|
|
8
8
|
import 'fs';
|
|
@@ -613,12 +613,11 @@ function extractMessageText(msg) {
|
|
|
613
613
|
createdAt: msg.createdAt || 0
|
|
614
614
|
};
|
|
615
615
|
}
|
|
616
|
-
async function waitForIdle(
|
|
617
|
-
const svc = await server.getService(`svamp-session-${sessionId}`);
|
|
616
|
+
async function waitForIdle(machine, sessionId, timeoutMs) {
|
|
618
617
|
const pollInterval = 2e3;
|
|
619
618
|
const deadline = Date.now() + timeoutMs;
|
|
620
619
|
while (Date.now() < deadline) {
|
|
621
|
-
const activity = await
|
|
620
|
+
const activity = await machine.sessionRPC(sessionId, "getActivityState", []);
|
|
622
621
|
if (activity?.pendingPermissions?.length > 0) {
|
|
623
622
|
return { idle: false, pendingPermissions: activity.pendingPermissions };
|
|
624
623
|
}
|
|
@@ -629,14 +628,13 @@ async function waitForIdle(server, sessionId, timeoutMs) {
|
|
|
629
628
|
}
|
|
630
629
|
throw new Error("Timeout waiting for agent to become idle");
|
|
631
630
|
}
|
|
632
|
-
async function waitForBusyThenIdle(
|
|
633
|
-
const svc = await server.getService(`svamp-session-${sessionId}`);
|
|
631
|
+
async function waitForBusyThenIdle(machine, sessionId, timeoutMs = 3e5, busyTimeoutMs = 1e4) {
|
|
634
632
|
const pollInterval = 2e3;
|
|
635
633
|
const deadline = Date.now() + timeoutMs;
|
|
636
634
|
const busyDeadline = Date.now() + busyTimeoutMs;
|
|
637
635
|
let sawBusy = false;
|
|
638
636
|
while (Date.now() < deadline) {
|
|
639
|
-
const activity = await
|
|
637
|
+
const activity = await machine.sessionRPC(sessionId, "getActivityState", []);
|
|
640
638
|
if (activity?.pendingPermissions?.length > 0) {
|
|
641
639
|
return { idle: false, pendingPermissions: activity.pendingPermissions };
|
|
642
640
|
}
|
|
@@ -934,7 +932,7 @@ async function sessionSpawn(agent, directory, machineId, opts) {
|
|
|
934
932
|
console.log(`Message sent (seq: ${sendResult.seq})`);
|
|
935
933
|
if (opts.wait) {
|
|
936
934
|
console.log("Waiting for agent to become idle...");
|
|
937
|
-
await waitForBusyThenIdle(
|
|
935
|
+
await waitForBusyThenIdle(machine, result.sessionId);
|
|
938
936
|
console.log("Agent is idle.");
|
|
939
937
|
}
|
|
940
938
|
}
|
|
@@ -1268,18 +1266,22 @@ async function sessionSend(sessionId, message, machineId, opts) {
|
|
|
1268
1266
|
const sessions = await machine.listSessions();
|
|
1269
1267
|
const match = resolveSessionId(sessions, sessionId);
|
|
1270
1268
|
const fullId = match.sessionId;
|
|
1271
|
-
const
|
|
1272
|
-
const
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1269
|
+
const { randomUUID } = await import('node:crypto');
|
|
1270
|
+
const inboxMessage = {
|
|
1271
|
+
messageId: randomUUID(),
|
|
1272
|
+
body: message,
|
|
1273
|
+
timestamp: Date.now(),
|
|
1274
|
+
read: false,
|
|
1275
|
+
from: `cli:${os.userInfo().username}`,
|
|
1276
|
+
to: fullId,
|
|
1277
|
+
subject: opts?.subject,
|
|
1278
|
+
urgency: opts?.urgency || "urgent"
|
|
1279
|
+
};
|
|
1280
|
+
const result = await machine.sessionRPC(fullId, "sendInboxMessage", [inboxMessage]);
|
|
1279
1281
|
let waitResult;
|
|
1280
1282
|
if (opts?.wait) {
|
|
1281
1283
|
const timeoutMs = (opts.timeout || 300) * 1e3;
|
|
1282
|
-
waitResult = await waitForBusyThenIdle(
|
|
1284
|
+
waitResult = await waitForBusyThenIdle(machine, fullId, timeoutMs);
|
|
1283
1285
|
}
|
|
1284
1286
|
if (waitResult?.pendingPermissions?.length) {
|
|
1285
1287
|
if (opts?.json) {
|
|
@@ -1287,12 +1289,12 @@ async function sessionSend(sessionId, message, machineId, opts) {
|
|
|
1287
1289
|
sessionId: fullId,
|
|
1288
1290
|
message,
|
|
1289
1291
|
sent: true,
|
|
1290
|
-
|
|
1292
|
+
messageId: result.messageId,
|
|
1291
1293
|
status: "permission-pending",
|
|
1292
1294
|
pendingPermissions: waitResult.pendingPermissions
|
|
1293
1295
|
}));
|
|
1294
1296
|
} else {
|
|
1295
|
-
console.log(`Message sent to session ${fullId.slice(0, 8)} (
|
|
1297
|
+
console.log(`Message sent to session ${fullId.slice(0, 8)} (id: ${result.messageId.slice(0, 8)})`);
|
|
1296
1298
|
console.log("Agent is waiting for permission approval:");
|
|
1297
1299
|
for (const p of waitResult.pendingPermissions) {
|
|
1298
1300
|
const argsStr = JSON.stringify(p.arguments || {}).slice(0, 120);
|
|
@@ -1307,12 +1309,12 @@ Use: svamp session approve ${fullId.slice(0, 8)}`);
|
|
|
1307
1309
|
sessionId: fullId,
|
|
1308
1310
|
message,
|
|
1309
1311
|
sent: true,
|
|
1310
|
-
|
|
1312
|
+
messageId: result.messageId,
|
|
1311
1313
|
waited: !!opts.wait,
|
|
1312
1314
|
status: opts.wait ? "idle" : "sent"
|
|
1313
1315
|
}));
|
|
1314
1316
|
} else {
|
|
1315
|
-
console.log(`Message sent to session ${fullId.slice(0, 8)} (
|
|
1317
|
+
console.log(`Message sent to session ${fullId.slice(0, 8)} (id: ${result.messageId.slice(0, 8)})`);
|
|
1316
1318
|
if (opts?.wait) {
|
|
1317
1319
|
console.log("Agent is idle.");
|
|
1318
1320
|
}
|
|
@@ -1328,7 +1330,7 @@ async function sessionWait(sessionId, machineId, opts) {
|
|
|
1328
1330
|
const match = resolveSessionId(sessions, sessionId);
|
|
1329
1331
|
const fullId = match.sessionId;
|
|
1330
1332
|
const timeoutMs = (opts?.timeout || 300) * 1e3;
|
|
1331
|
-
const result = await waitForIdle(
|
|
1333
|
+
const result = await waitForIdle(machine, fullId, timeoutMs);
|
|
1332
1334
|
if (result.pendingPermissions?.length) {
|
|
1333
1335
|
if (opts?.json) {
|
|
1334
1336
|
console.log(formatJson({
|
|
@@ -1712,7 +1714,6 @@ async function sessionInboxSend(sessionIdPartial, body, machineId, opts) {
|
|
|
1712
1714
|
const sessions = await machine.listSessions();
|
|
1713
1715
|
const match = resolveSessionId(sessions, sessionIdPartial);
|
|
1714
1716
|
const fullId = match.sessionId;
|
|
1715
|
-
const svc = await server.getService(`svamp-session-${fullId}`);
|
|
1716
1717
|
const { randomUUID } = await import('node:crypto');
|
|
1717
1718
|
const message = {
|
|
1718
1719
|
messageId: randomUUID(),
|
|
@@ -1726,7 +1727,7 @@ async function sessionInboxSend(sessionIdPartial, body, machineId, opts) {
|
|
|
1726
1727
|
replyTo: opts?.replyTo,
|
|
1727
1728
|
threadId: opts?.threadId
|
|
1728
1729
|
};
|
|
1729
|
-
const result = await
|
|
1730
|
+
const result = await machine.sessionRPC(fullId, "sendInboxMessage", [message]);
|
|
1730
1731
|
if (opts?.json) {
|
|
1731
1732
|
console.log(formatJson({ sessionId: fullId, messageId: result.messageId, sent: true }));
|
|
1732
1733
|
} else {
|
|
@@ -1742,8 +1743,7 @@ async function sessionInboxList(sessionIdPartial, machineId, opts) {
|
|
|
1742
1743
|
const sessions = await machine.listSessions();
|
|
1743
1744
|
const match = resolveSessionId(sessions, sessionIdPartial);
|
|
1744
1745
|
const fullId = match.sessionId;
|
|
1745
|
-
const
|
|
1746
|
-
const result = await svc.getInbox({ unread: opts?.unread, limit: opts?.limit });
|
|
1746
|
+
const result = await machine.sessionRPC(fullId, "getInbox", [{ unread: opts?.unread, limit: opts?.limit }]);
|
|
1747
1747
|
const messages = result.messages;
|
|
1748
1748
|
if (opts?.json) {
|
|
1749
1749
|
console.log(formatJson({ sessionId: fullId, messages }));
|
|
@@ -1778,15 +1778,14 @@ async function sessionInboxRead(sessionIdPartial, messageId, machineId) {
|
|
|
1778
1778
|
const sessions = await machine.listSessions();
|
|
1779
1779
|
const match = resolveSessionId(sessions, sessionIdPartial);
|
|
1780
1780
|
const fullId = match.sessionId;
|
|
1781
|
-
const
|
|
1782
|
-
const result = await svc.getInbox();
|
|
1781
|
+
const result = await machine.sessionRPC(fullId, "getInbox", []);
|
|
1783
1782
|
const msg = result.messages.find((m) => m.messageId === messageId || m.messageId.startsWith(messageId));
|
|
1784
1783
|
if (!msg) {
|
|
1785
1784
|
console.error(`Message ${messageId} not found in inbox.`);
|
|
1786
1785
|
process.exit(1);
|
|
1787
1786
|
}
|
|
1788
1787
|
if (!msg.read) {
|
|
1789
|
-
await
|
|
1788
|
+
await machine.sessionRPC(fullId, "markInboxRead", [msg.messageId]);
|
|
1790
1789
|
}
|
|
1791
1790
|
console.log(`From: ${msg.from || "(unknown)"}`);
|
|
1792
1791
|
if (msg.subject) console.log(`Subject: ${msg.subject}`);
|
|
@@ -1806,8 +1805,7 @@ async function sessionInboxReply(sessionIdPartial, messageId, body, machineId) {
|
|
|
1806
1805
|
const sessions = await machine.listSessions();
|
|
1807
1806
|
const match = resolveSessionId(sessions, sessionIdPartial);
|
|
1808
1807
|
const fullId = match.sessionId;
|
|
1809
|
-
const
|
|
1810
|
-
const result = await svc.getInbox();
|
|
1808
|
+
const result = await machine.sessionRPC(fullId, "getInbox", []);
|
|
1811
1809
|
const original = result.messages.find((m) => m.messageId === messageId || m.messageId.startsWith(messageId));
|
|
1812
1810
|
if (!original) {
|
|
1813
1811
|
console.error(`Message ${messageId} not found in inbox.`);
|
|
@@ -1817,7 +1815,6 @@ async function sessionInboxReply(sessionIdPartial, messageId, body, machineId) {
|
|
|
1817
1815
|
console.error("Cannot reply: original message has no fromSession.");
|
|
1818
1816
|
process.exit(1);
|
|
1819
1817
|
}
|
|
1820
|
-
const targetSvc = await server.getService(`svamp-session-${original.fromSession}`);
|
|
1821
1818
|
const { randomUUID } = await import('node:crypto');
|
|
1822
1819
|
const reply = {
|
|
1823
1820
|
messageId: randomUUID(),
|
|
@@ -1832,7 +1829,7 @@ async function sessionInboxReply(sessionIdPartial, messageId, body, machineId) {
|
|
|
1832
1829
|
replyTo: original.messageId,
|
|
1833
1830
|
threadId: original.threadId || original.messageId
|
|
1834
1831
|
};
|
|
1835
|
-
const sendResult = await
|
|
1832
|
+
const sendResult = await machine.sessionRPC(original.fromSession, "sendInboxMessage", [reply]);
|
|
1836
1833
|
console.log(`Reply sent to session ${original.fromSession.slice(0, 8)} (id: ${sendResult.messageId.slice(0, 8)})`);
|
|
1837
1834
|
} finally {
|
|
1838
1835
|
await server.disconnect();
|
|
@@ -1844,9 +1841,8 @@ async function sessionInboxClear(sessionIdPartial, machineId, opts) {
|
|
|
1844
1841
|
const sessions = await machine.listSessions();
|
|
1845
1842
|
const match = resolveSessionId(sessions, sessionIdPartial);
|
|
1846
1843
|
const fullId = match.sessionId;
|
|
1847
|
-
const
|
|
1848
|
-
|
|
1849
|
-
console.log(`Cleared ${result.removed} message(s) from inbox on session ${fullId.slice(0, 8)}`);
|
|
1844
|
+
const result = await machine.sessionRPC(fullId, "clearInbox", [{ all: opts?.all }]);
|
|
1845
|
+
console.log(`Cleared inbox on session ${fullId.slice(0, 8)} (${result.remaining} remaining)`);
|
|
1850
1846
|
} finally {
|
|
1851
1847
|
await server.disconnect();
|
|
1852
1848
|
}
|