svamp-cli 0.2.48 → 0.2.49
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-BuGwfYhd.mjs → agentCommands-CpR_jpWk.mjs} +2 -2
- package/dist/cli.mjs +68 -33
- package/dist/{commands-TyAIFJx-.mjs → commands-BswZUToD.mjs} +2 -2
- package/dist/{commands-JWrmpGcs.mjs → commands-CTQAVadm.mjs} +46 -32
- package/dist/{commands-BJR_98XX.mjs → commands-DmxhoO5X.mjs} +2 -2
- package/dist/index.mjs +1 -1
- package/dist/package-DnTJGm-n.mjs +63 -0
- package/dist/{run-6umeTX-K.mjs → run-V2qpcN7f.mjs} +378 -8
- package/dist/{run-DR7E3IZL.mjs → run-mXTPYgtc.mjs} +1 -1
- package/dist/{serveCommands-FUE8m232.mjs → serveCommands-Cj-P-FeY.mjs} +5 -5
- package/dist/{serveManager-RvRL-weX.mjs → serveManager-BhWfboEx.mjs} +17 -230
- package/package.json +2 -2
- package/dist/package-DVfaovNL.mjs +0 -63
|
@@ -148,7 +148,7 @@ async function sessionBroadcast(action, args) {
|
|
|
148
148
|
console.log(`Broadcast sent: ${action}`);
|
|
149
149
|
}
|
|
150
150
|
async function connectToMachineService() {
|
|
151
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
151
|
+
const { connectAndGetMachine } = await import('./commands-CTQAVadm.mjs');
|
|
152
152
|
return connectAndGetMachine();
|
|
153
153
|
}
|
|
154
154
|
async function inboxSend(targetSessionId, opts) {
|
|
@@ -165,7 +165,7 @@ async function inboxSend(targetSessionId, opts) {
|
|
|
165
165
|
}
|
|
166
166
|
const { server, machine } = await connectToMachineService();
|
|
167
167
|
try {
|
|
168
|
-
const { resolveSessionId } = await import('./commands-
|
|
168
|
+
const { resolveSessionId } = await import('./commands-CTQAVadm.mjs');
|
|
169
169
|
const sessions = await machine.listSessions();
|
|
170
170
|
const match = resolveSessionId(sessions, targetSessionId);
|
|
171
171
|
const fullTargetId = match.sessionId;
|
package/dist/cli.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { s as startDaemon, b as stopDaemon, d as daemonStatus } from './run-
|
|
1
|
+
import { s as startDaemon, b as stopDaemon, d as daemonStatus } from './run-V2qpcN7f.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|
|
@@ -38,17 +38,19 @@ async function main() {
|
|
|
38
38
|
if (daemonSubcommand === "restart") {
|
|
39
39
|
try {
|
|
40
40
|
await applyClaudeAuthFlags(args);
|
|
41
|
+
await applyDaemonShareFlag(args);
|
|
41
42
|
} catch (err) {
|
|
42
43
|
console.error(`svamp daemon restart: ${err.message || err}`);
|
|
43
44
|
process.exit(1);
|
|
44
45
|
}
|
|
45
|
-
const { restartDaemon } = await import('./run-
|
|
46
|
+
const { restartDaemon } = await import('./run-V2qpcN7f.mjs').then(function (n) { return n.u; });
|
|
46
47
|
await restartDaemon();
|
|
47
48
|
process.exit(0);
|
|
48
49
|
}
|
|
49
50
|
if (daemonSubcommand === "start") {
|
|
50
51
|
try {
|
|
51
52
|
await applyClaudeAuthFlags(args);
|
|
53
|
+
await applyDaemonShareFlag(args);
|
|
52
54
|
} catch (err) {
|
|
53
55
|
console.error(`svamp daemon start: ${err.message || err}`);
|
|
54
56
|
process.exit(1);
|
|
@@ -277,7 +279,7 @@ async function main() {
|
|
|
277
279
|
console.error("svamp service: Service commands are not available in sandboxed sessions.");
|
|
278
280
|
process.exit(1);
|
|
279
281
|
}
|
|
280
|
-
const { handleServiceCommand } = await import('./commands-
|
|
282
|
+
const { handleServiceCommand } = await import('./commands-BswZUToD.mjs');
|
|
281
283
|
await handleServiceCommand();
|
|
282
284
|
} else if (subcommand === "serve") {
|
|
283
285
|
const { isSandboxed: isSandboxedServe } = await import('./sandboxDetect-DNTcbgWD.mjs');
|
|
@@ -285,7 +287,7 @@ async function main() {
|
|
|
285
287
|
console.error("svamp serve: Serve commands are not available in sandboxed sessions.");
|
|
286
288
|
process.exit(1);
|
|
287
289
|
}
|
|
288
|
-
const { handleServeCommand } = await import('./serveCommands-
|
|
290
|
+
const { handleServeCommand } = await import('./serveCommands-Cj-P-FeY.mjs');
|
|
289
291
|
await handleServeCommand();
|
|
290
292
|
process.exit(0);
|
|
291
293
|
} else if (subcommand === "process" || subcommand === "proc") {
|
|
@@ -294,7 +296,7 @@ async function main() {
|
|
|
294
296
|
console.error("svamp process: Process commands are not available in sandboxed sessions.");
|
|
295
297
|
process.exit(1);
|
|
296
298
|
}
|
|
297
|
-
const { processCommand } = await import('./commands-
|
|
299
|
+
const { processCommand } = await import('./commands-DmxhoO5X.mjs');
|
|
298
300
|
let machineId;
|
|
299
301
|
const processArgs = args.slice(1);
|
|
300
302
|
const mIdx = processArgs.findIndex((a) => a === "--machine" || a === "-m");
|
|
@@ -312,7 +314,7 @@ async function main() {
|
|
|
312
314
|
} else if (!subcommand || subcommand === "start") {
|
|
313
315
|
await handleInteractiveCommand();
|
|
314
316
|
} else if (subcommand === "--version" || subcommand === "-v") {
|
|
315
|
-
const pkg = await import('./package-
|
|
317
|
+
const pkg = await import('./package-DnTJGm-n.mjs').catch(() => ({ default: { version: "unknown" } }));
|
|
316
318
|
console.log(`svamp version: ${pkg.default.version}`);
|
|
317
319
|
} else {
|
|
318
320
|
console.error(`Unknown command: ${subcommand}`);
|
|
@@ -321,7 +323,7 @@ async function main() {
|
|
|
321
323
|
}
|
|
322
324
|
}
|
|
323
325
|
async function handleInteractiveCommand() {
|
|
324
|
-
const { runInteractive } = await import('./run-
|
|
326
|
+
const { runInteractive } = await import('./run-mXTPYgtc.mjs');
|
|
325
327
|
const interactiveArgs = subcommand === "start" ? args.slice(1) : args;
|
|
326
328
|
let directory = process.cwd();
|
|
327
329
|
let resumeSessionId;
|
|
@@ -366,7 +368,7 @@ async function handleAgentCommand() {
|
|
|
366
368
|
return;
|
|
367
369
|
}
|
|
368
370
|
if (agentArgs[0] === "list") {
|
|
369
|
-
const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-
|
|
371
|
+
const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-V2qpcN7f.mjs').then(function (n) { return n.p; });
|
|
370
372
|
console.log("Known agents:");
|
|
371
373
|
for (const [name, config2] of Object.entries(KNOWN_ACP_AGENTS)) {
|
|
372
374
|
console.log(` ${name.padEnd(12)} ${config2.command} ${config2.args.join(" ")} (ACP)`);
|
|
@@ -378,7 +380,7 @@ async function handleAgentCommand() {
|
|
|
378
380
|
console.log('Use "svamp agent -- <command> [args]" for a custom ACP agent.');
|
|
379
381
|
return;
|
|
380
382
|
}
|
|
381
|
-
const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-
|
|
383
|
+
const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-V2qpcN7f.mjs').then(function (n) { return n.p; });
|
|
382
384
|
let cwd = process.cwd();
|
|
383
385
|
const filteredArgs = [];
|
|
384
386
|
for (let i = 0; i < agentArgs.length; i++) {
|
|
@@ -402,12 +404,12 @@ async function handleAgentCommand() {
|
|
|
402
404
|
console.log(`Starting ${config.agentName} agent in ${cwd}...`);
|
|
403
405
|
let backend;
|
|
404
406
|
if (KNOWN_MCP_AGENTS[config.agentName]) {
|
|
405
|
-
const { CodexMcpBackend } = await import('./run-
|
|
407
|
+
const { CodexMcpBackend } = await import('./run-V2qpcN7f.mjs').then(function (n) { return n.q; });
|
|
406
408
|
backend = new CodexMcpBackend({ cwd, log: logFn });
|
|
407
409
|
} else {
|
|
408
|
-
const { AcpBackend } = await import('./run-
|
|
409
|
-
const { GeminiTransport } = await import('./run-
|
|
410
|
-
const { DefaultTransport } = await import('./run-
|
|
410
|
+
const { AcpBackend } = await import('./run-V2qpcN7f.mjs').then(function (n) { return n.o; });
|
|
411
|
+
const { GeminiTransport } = await import('./run-V2qpcN7f.mjs').then(function (n) { return n.G; });
|
|
412
|
+
const { DefaultTransport } = await import('./run-V2qpcN7f.mjs').then(function (n) { return n.D; });
|
|
411
413
|
const transportHandler = config.agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(config.agentName);
|
|
412
414
|
backend = new AcpBackend({
|
|
413
415
|
agentName: config.agentName,
|
|
@@ -534,7 +536,7 @@ async function handleSessionCommand() {
|
|
|
534
536
|
process.exit(1);
|
|
535
537
|
}
|
|
536
538
|
}
|
|
537
|
-
const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-
|
|
539
|
+
const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-CTQAVadm.mjs');
|
|
538
540
|
const parseFlagStr = (flag, shortFlag) => {
|
|
539
541
|
for (let i = 1; i < sessionArgs.length; i++) {
|
|
540
542
|
if ((sessionArgs[i] === flag || shortFlag) && i + 1 < sessionArgs.length) {
|
|
@@ -594,7 +596,7 @@ async function handleSessionCommand() {
|
|
|
594
596
|
allowDomain.push(sessionArgs[++i]);
|
|
595
597
|
}
|
|
596
598
|
}
|
|
597
|
-
const { parseShareArg } = await import('./commands-
|
|
599
|
+
const { parseShareArg } = await import('./commands-CTQAVadm.mjs');
|
|
598
600
|
const shareEntries = share.map((s) => parseShareArg(s));
|
|
599
601
|
await sessionSpawn(agent, dir, targetMachineId, {
|
|
600
602
|
message,
|
|
@@ -680,7 +682,7 @@ async function handleSessionCommand() {
|
|
|
680
682
|
console.error("Usage: svamp session approve <session-id> [request-id] [--json]");
|
|
681
683
|
process.exit(1);
|
|
682
684
|
}
|
|
683
|
-
const { sessionApprove } = await import('./commands-
|
|
685
|
+
const { sessionApprove } = await import('./commands-CTQAVadm.mjs');
|
|
684
686
|
const approveReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
685
687
|
await sessionApprove(sessionArgs[1], approveReqId, targetMachineId, {
|
|
686
688
|
json: hasFlag("--json")
|
|
@@ -690,7 +692,7 @@ async function handleSessionCommand() {
|
|
|
690
692
|
console.error("Usage: svamp session deny <session-id> [request-id] [--json]");
|
|
691
693
|
process.exit(1);
|
|
692
694
|
}
|
|
693
|
-
const { sessionDeny } = await import('./commands-
|
|
695
|
+
const { sessionDeny } = await import('./commands-CTQAVadm.mjs');
|
|
694
696
|
const denyReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
695
697
|
await sessionDeny(sessionArgs[1], denyReqId, targetMachineId, {
|
|
696
698
|
json: hasFlag("--json")
|
|
@@ -726,7 +728,7 @@ async function handleSessionCommand() {
|
|
|
726
728
|
console.error("Usage: svamp session set-title <title>");
|
|
727
729
|
process.exit(1);
|
|
728
730
|
}
|
|
729
|
-
const { sessionSetTitle } = await import('./agentCommands-
|
|
731
|
+
const { sessionSetTitle } = await import('./agentCommands-CpR_jpWk.mjs');
|
|
730
732
|
await sessionSetTitle(title);
|
|
731
733
|
} else if (sessionSubcommand === "set-link") {
|
|
732
734
|
const url = sessionArgs[1];
|
|
@@ -735,7 +737,7 @@ async function handleSessionCommand() {
|
|
|
735
737
|
process.exit(1);
|
|
736
738
|
}
|
|
737
739
|
const label = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
738
|
-
const { sessionSetLink } = await import('./agentCommands-
|
|
740
|
+
const { sessionSetLink } = await import('./agentCommands-CpR_jpWk.mjs');
|
|
739
741
|
await sessionSetLink(url, label);
|
|
740
742
|
} else if (sessionSubcommand === "notify") {
|
|
741
743
|
const message = sessionArgs[1];
|
|
@@ -744,7 +746,7 @@ async function handleSessionCommand() {
|
|
|
744
746
|
process.exit(1);
|
|
745
747
|
}
|
|
746
748
|
const level = parseFlagStr("--level") || "info";
|
|
747
|
-
const { sessionNotify } = await import('./agentCommands-
|
|
749
|
+
const { sessionNotify } = await import('./agentCommands-CpR_jpWk.mjs');
|
|
748
750
|
await sessionNotify(message, level);
|
|
749
751
|
} else if (sessionSubcommand === "broadcast") {
|
|
750
752
|
const action = sessionArgs[1];
|
|
@@ -752,7 +754,7 @@ async function handleSessionCommand() {
|
|
|
752
754
|
console.error("Usage: svamp session broadcast <action> [args...]\nActions: open-canvas <url> [label], close-canvas, toast <message>");
|
|
753
755
|
process.exit(1);
|
|
754
756
|
}
|
|
755
|
-
const { sessionBroadcast } = await import('./agentCommands-
|
|
757
|
+
const { sessionBroadcast } = await import('./agentCommands-CpR_jpWk.mjs');
|
|
756
758
|
await sessionBroadcast(action, sessionArgs.slice(2).filter((a) => !a.startsWith("--")));
|
|
757
759
|
} else if (sessionSubcommand === "inbox") {
|
|
758
760
|
const inboxSubcmd = sessionArgs[1];
|
|
@@ -763,7 +765,7 @@ async function handleSessionCommand() {
|
|
|
763
765
|
process.exit(1);
|
|
764
766
|
}
|
|
765
767
|
if (agentSessionId) {
|
|
766
|
-
const { inboxSend } = await import('./agentCommands-
|
|
768
|
+
const { inboxSend } = await import('./agentCommands-CpR_jpWk.mjs');
|
|
767
769
|
await inboxSend(sessionArgs[2], {
|
|
768
770
|
body: sessionArgs[3],
|
|
769
771
|
subject: parseFlagStr("--subject"),
|
|
@@ -778,7 +780,7 @@ async function handleSessionCommand() {
|
|
|
778
780
|
}
|
|
779
781
|
} else if (inboxSubcmd === "list" || inboxSubcmd === "ls") {
|
|
780
782
|
if (agentSessionId && !sessionArgs[2]) {
|
|
781
|
-
const { inboxList } = await import('./agentCommands-
|
|
783
|
+
const { inboxList } = await import('./agentCommands-CpR_jpWk.mjs');
|
|
782
784
|
await inboxList({
|
|
783
785
|
unread: hasFlag("--unread"),
|
|
784
786
|
limit: parseFlagInt("--limit"),
|
|
@@ -800,7 +802,7 @@ async function handleSessionCommand() {
|
|
|
800
802
|
process.exit(1);
|
|
801
803
|
}
|
|
802
804
|
if (agentSessionId && !sessionArgs[3]) {
|
|
803
|
-
const { inboxList } = await import('./agentCommands-
|
|
805
|
+
const { inboxList } = await import('./agentCommands-CpR_jpWk.mjs');
|
|
804
806
|
await sessionInboxRead(agentSessionId, sessionArgs[2], targetMachineId);
|
|
805
807
|
} else if (sessionArgs[3]) {
|
|
806
808
|
await sessionInboxRead(sessionArgs[2], sessionArgs[3], targetMachineId);
|
|
@@ -810,7 +812,7 @@ async function handleSessionCommand() {
|
|
|
810
812
|
}
|
|
811
813
|
} else if (inboxSubcmd === "reply") {
|
|
812
814
|
if (agentSessionId && sessionArgs[2] && sessionArgs[3] && !sessionArgs[4]) {
|
|
813
|
-
const { inboxReply } = await import('./agentCommands-
|
|
815
|
+
const { inboxReply } = await import('./agentCommands-CpR_jpWk.mjs');
|
|
814
816
|
await inboxReply(sessionArgs[2], sessionArgs[3]);
|
|
815
817
|
} else if (sessionArgs[2] && sessionArgs[3] && sessionArgs[4]) {
|
|
816
818
|
await sessionInboxReply(sessionArgs[2], sessionArgs[3], sessionArgs[4], targetMachineId);
|
|
@@ -846,7 +848,7 @@ async function handleMachineCommand() {
|
|
|
846
848
|
return;
|
|
847
849
|
}
|
|
848
850
|
if (machineSubcommand === "share") {
|
|
849
|
-
const { machineShare } = await import('./commands-
|
|
851
|
+
const { machineShare } = await import('./commands-CTQAVadm.mjs');
|
|
850
852
|
let machineId;
|
|
851
853
|
const shareArgs = [];
|
|
852
854
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
@@ -876,7 +878,7 @@ async function handleMachineCommand() {
|
|
|
876
878
|
}
|
|
877
879
|
await machineShare(machineId, { add, remove, list, configPath, showConfig });
|
|
878
880
|
} else if (machineSubcommand === "exec") {
|
|
879
|
-
const { machineExec } = await import('./commands-
|
|
881
|
+
const { machineExec } = await import('./commands-CTQAVadm.mjs');
|
|
880
882
|
let machineId;
|
|
881
883
|
let cwd;
|
|
882
884
|
const cmdParts = [];
|
|
@@ -896,7 +898,7 @@ async function handleMachineCommand() {
|
|
|
896
898
|
}
|
|
897
899
|
await machineExec(machineId, command, cwd);
|
|
898
900
|
} else if (machineSubcommand === "info") {
|
|
899
|
-
const { machineInfo } = await import('./commands-
|
|
901
|
+
const { machineInfo } = await import('./commands-CTQAVadm.mjs');
|
|
900
902
|
let machineId;
|
|
901
903
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
902
904
|
if ((machineArgs[i] === "--machine" || machineArgs[i] === "-m") && i + 1 < machineArgs.length) {
|
|
@@ -916,10 +918,10 @@ async function handleMachineCommand() {
|
|
|
916
918
|
level = machineArgs[++i];
|
|
917
919
|
}
|
|
918
920
|
}
|
|
919
|
-
const { machineNotify } = await import('./agentCommands-
|
|
921
|
+
const { machineNotify } = await import('./agentCommands-CpR_jpWk.mjs');
|
|
920
922
|
await machineNotify(message, level);
|
|
921
923
|
} else if (machineSubcommand === "ls") {
|
|
922
|
-
const { machineLs } = await import('./commands-
|
|
924
|
+
const { machineLs } = await import('./commands-CTQAVadm.mjs');
|
|
923
925
|
let machineId;
|
|
924
926
|
let showHidden = false;
|
|
925
927
|
let path;
|
|
@@ -1366,6 +1368,11 @@ Claude auth flags (take effect on next start/restart):
|
|
|
1366
1368
|
svamp daemon start --use-hypha-proxy
|
|
1367
1369
|
svamp daemon start --use-claude-login
|
|
1368
1370
|
svamp daemon start --anthropic-base-url URL --anthropic-api-key KEY
|
|
1371
|
+
|
|
1372
|
+
Machine sharing (seed at boot \u2014 equivalent to running 'svamp machine share --add'
|
|
1373
|
+
for each email; idempotent, never removes):
|
|
1374
|
+
svamp daemon start --share alice@example.com,bob@example.com
|
|
1375
|
+
svamp daemon start --share alice@example.com --share bob@example.com
|
|
1369
1376
|
`);
|
|
1370
1377
|
}
|
|
1371
1378
|
async function applyClaudeAuthFlags(argv) {
|
|
@@ -1381,7 +1388,7 @@ async function applyClaudeAuthFlags(argv) {
|
|
|
1381
1388
|
"--use-hypha-proxy, --use-claude-login, and --anthropic-base-url/--anthropic-api-key are mutually exclusive"
|
|
1382
1389
|
);
|
|
1383
1390
|
}
|
|
1384
|
-
const mod = await import('./run-
|
|
1391
|
+
const mod = await import('./run-V2qpcN7f.mjs').then(function (n) { return n.t; });
|
|
1385
1392
|
if (hasHypha) {
|
|
1386
1393
|
mod.setClaudeAuthHyphaProxy();
|
|
1387
1394
|
console.log("Claude auth configured: hypha-proxy (uses HYPHA_TOKEN live at each spawn).");
|
|
@@ -1402,9 +1409,37 @@ async function applyClaudeAuthFlags(argv) {
|
|
|
1402
1409
|
mod.setClaudeAuthCustom(baseUrl, apiKey);
|
|
1403
1410
|
console.log(`Claude auth configured: custom (base URL ${baseUrl}).`);
|
|
1404
1411
|
}
|
|
1412
|
+
const DAEMON_SHARE_ENV_KEY = "SVAMP_SHARE_EMAILS";
|
|
1413
|
+
async function applyDaemonShareFlag(argv) {
|
|
1414
|
+
const collected = [];
|
|
1415
|
+
for (let i = 0; i < argv.length; i++) {
|
|
1416
|
+
if (argv[i] === "--share" && i + 1 < argv.length) {
|
|
1417
|
+
const value = argv[++i];
|
|
1418
|
+
for (const part of value.split(",")) {
|
|
1419
|
+
const email = part.trim();
|
|
1420
|
+
if (!email) continue;
|
|
1421
|
+
if (!email.includes("@")) {
|
|
1422
|
+
throw new Error(`--share value "${email}" is not a valid email address`);
|
|
1423
|
+
}
|
|
1424
|
+
collected.push(email);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
if (collected.length === 0) return;
|
|
1429
|
+
const { updateEnvFile } = await import('./run-V2qpcN7f.mjs').then(function (n) { return n.t; });
|
|
1430
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1431
|
+
const deduped = collected.filter((e) => {
|
|
1432
|
+
const k = e.toLowerCase();
|
|
1433
|
+
if (seen.has(k)) return false;
|
|
1434
|
+
seen.add(k);
|
|
1435
|
+
return true;
|
|
1436
|
+
});
|
|
1437
|
+
updateEnvFile({ [DAEMON_SHARE_ENV_KEY]: deduped.join(",") });
|
|
1438
|
+
console.log(`Machine sharing seed updated: ${deduped.join(", ")} (will be added at next daemon start).`);
|
|
1439
|
+
}
|
|
1405
1440
|
async function handleDaemonAuthCommand(argv) {
|
|
1406
1441
|
const sub = (argv[0] || "status").toLowerCase();
|
|
1407
|
-
const mod = await import('./run-
|
|
1442
|
+
const mod = await import('./run-V2qpcN7f.mjs').then(function (n) { return n.t; });
|
|
1408
1443
|
if (sub === "--help" || sub === "-h" || sub === "help") {
|
|
1409
1444
|
console.log(`
|
|
1410
1445
|
svamp daemon auth \u2014 Configure how Claude subprocesses authenticate
|
|
@@ -1559,7 +1594,7 @@ PERMISSION WORKFLOW (only relevant for "default" and "acceptEdits" modes):
|
|
|
1559
1594
|
ISOLATION & SHARING OPTIONS (for spawn):
|
|
1560
1595
|
--isolate Force OS-level sandbox (even without sharing)
|
|
1561
1596
|
--security-context <path> Apply security context config (JSON file)
|
|
1562
|
-
--share <email>
|
|
1597
|
+
--share <email> Share session with user (repeatable). Added users have full access; the legacy :role suffix is accepted but ignored.
|
|
1563
1598
|
--deny-network Block all network access
|
|
1564
1599
|
--deny-read <path> Deny reading path (repeatable)
|
|
1565
1600
|
--allow-write <path> Allow writing path (repeatable)
|
|
@@ -97,7 +97,7 @@ async function serviceServe(args) {
|
|
|
97
97
|
}
|
|
98
98
|
async function serviceList(_args) {
|
|
99
99
|
try {
|
|
100
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
100
|
+
const { connectAndGetMachine } = await import('./commands-CTQAVadm.mjs');
|
|
101
101
|
const { server, machine } = await connectAndGetMachine();
|
|
102
102
|
try {
|
|
103
103
|
const tunnels = await machine.tunnelList({});
|
|
@@ -126,7 +126,7 @@ async function serviceDelete(args) {
|
|
|
126
126
|
process.exit(1);
|
|
127
127
|
}
|
|
128
128
|
try {
|
|
129
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
129
|
+
const { connectAndGetMachine } = await import('./commands-CTQAVadm.mjs');
|
|
130
130
|
const { server, machine } = await connectAndGetMachine();
|
|
131
131
|
try {
|
|
132
132
|
await machine.tunnelStop({ name });
|
|
@@ -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 { n as normalizeAllowedUser, l as loadSecurityContextConfig, e as resolveSecurityContext, f as buildSecurityContextFromFlags, m as mergeSecurityContexts, c as connectToHypha, i as buildSessionShareUrl, j as buildMachineShareUrl } from './run-V2qpcN7f.mjs';
|
|
6
6
|
import 'os';
|
|
7
7
|
import 'fs/promises';
|
|
8
8
|
import 'fs';
|
|
@@ -894,11 +894,16 @@ function createWorktree(baseDir) {
|
|
|
894
894
|
function parseShareArg(arg) {
|
|
895
895
|
const parts = arg.split(":");
|
|
896
896
|
const email = parts[0];
|
|
897
|
-
const
|
|
898
|
-
if (
|
|
899
|
-
|
|
897
|
+
const suppliedRole = parts[1];
|
|
898
|
+
if (suppliedRole) {
|
|
899
|
+
if (!["view", "interact", "admin"].includes(suppliedRole)) {
|
|
900
|
+
throw new Error(`Invalid role "${suppliedRole}" in --share ${arg}. Per-user roles are deprecated; omit the :role suffix.`);
|
|
901
|
+
}
|
|
902
|
+
if (suppliedRole !== "admin") {
|
|
903
|
+
console.warn(`Note: per-user role "${suppliedRole}" is deprecated. Added users have full (owner-equivalent) access.`);
|
|
904
|
+
}
|
|
900
905
|
}
|
|
901
|
-
return { email, role };
|
|
906
|
+
return { email, role: "admin" };
|
|
902
907
|
}
|
|
903
908
|
async function sessionSpawn(agent, directory, machineId, opts) {
|
|
904
909
|
const { server, machine } = await connectAndGetMachine(machineId);
|
|
@@ -909,12 +914,9 @@ async function sessionSpawn(agent, directory, machineId, opts) {
|
|
|
909
914
|
enabled: true,
|
|
910
915
|
owner: "",
|
|
911
916
|
// will be auto-set by machine service from Hypha context
|
|
912
|
-
allowedUsers: opts.share.map(
|
|
913
|
-
email: s.email,
|
|
914
|
-
|
|
915
|
-
addedAt: Date.now(),
|
|
916
|
-
addedBy: "cli"
|
|
917
|
-
}))
|
|
917
|
+
allowedUsers: opts.share.map(
|
|
918
|
+
(s) => normalizeAllowedUser({ email: s.email, addedBy: "cli" }, "cli")
|
|
919
|
+
)
|
|
918
920
|
};
|
|
919
921
|
}
|
|
920
922
|
let securityContext;
|
|
@@ -983,7 +985,7 @@ async function sessionSpawn(agent, directory, machineId, opts) {
|
|
|
983
985
|
console.log(`Security context: ${JSON.stringify(securityContext, null, 2)}`);
|
|
984
986
|
}
|
|
985
987
|
if (sharing) {
|
|
986
|
-
console.log(`Sharing with: ${sharing.allowedUsers.map((u) =>
|
|
988
|
+
console.log(`Sharing with: ${sharing.allowedUsers.map((u) => u.email).join(", ")} (full access)`);
|
|
987
989
|
}
|
|
988
990
|
const result = await machine.spawnSession({
|
|
989
991
|
directory,
|
|
@@ -1441,9 +1443,9 @@ async function sessionShare(sessionIdPartial, machineId, opts) {
|
|
|
1441
1443
|
if (sharing.allowedUsers.length === 0) {
|
|
1442
1444
|
console.log("No shared users.");
|
|
1443
1445
|
} else {
|
|
1444
|
-
console.log("Shared users:");
|
|
1446
|
+
console.log("Shared users (each has full access):");
|
|
1445
1447
|
for (const u of sharing.allowedUsers) {
|
|
1446
|
-
console.log(` ${u.email.padEnd(30)}
|
|
1448
|
+
console.log(` ${u.email.padEnd(30)} (added ${new Date(u.addedAt).toISOString().slice(0, 10)})`);
|
|
1447
1449
|
}
|
|
1448
1450
|
}
|
|
1449
1451
|
const secCtx = metaResult.metadata?.securityContext;
|
|
@@ -1452,10 +1454,16 @@ async function sessionShare(sessionIdPartial, machineId, opts) {
|
|
|
1452
1454
|
Security context:`);
|
|
1453
1455
|
console.log(JSON.stringify(secCtx, null, 2));
|
|
1454
1456
|
}
|
|
1457
|
+
console.log(`
|
|
1458
|
+
Share link: ${buildSessionShareUrl({
|
|
1459
|
+
sessionId: fullId,
|
|
1460
|
+
workspace: server.config?.workspace,
|
|
1461
|
+
machineServiceId: machine.id || `${server.config?.workspace}/${server.config?.client_id}:default`
|
|
1462
|
+
})}`);
|
|
1455
1463
|
return;
|
|
1456
1464
|
}
|
|
1457
1465
|
if (opts.add) {
|
|
1458
|
-
const { email
|
|
1466
|
+
const { email } = parseShareArg(opts.add);
|
|
1459
1467
|
const metaResult = await svc.getMetadata();
|
|
1460
1468
|
let sharing = metaResult.metadata?.sharing || {
|
|
1461
1469
|
enabled: true,
|
|
@@ -1466,14 +1474,15 @@ Security context:`);
|
|
|
1466
1474
|
sharing.allowedUsers = sharing.allowedUsers.filter(
|
|
1467
1475
|
(u) => u.email.toLowerCase() !== email.toLowerCase()
|
|
1468
1476
|
);
|
|
1469
|
-
sharing.allowedUsers.push({
|
|
1470
|
-
email,
|
|
1471
|
-
role,
|
|
1472
|
-
addedAt: Date.now(),
|
|
1473
|
-
addedBy: "cli"
|
|
1474
|
-
});
|
|
1477
|
+
sharing.allowedUsers.push(normalizeAllowedUser({ email, addedBy: "cli" }, "cli"));
|
|
1475
1478
|
await svc.updateSharing(sharing);
|
|
1476
|
-
|
|
1479
|
+
const shareUrl = buildSessionShareUrl({
|
|
1480
|
+
sessionId: fullId,
|
|
1481
|
+
workspace: server.config?.workspace,
|
|
1482
|
+
machineServiceId: machine.id || `${server.config?.workspace}/${server.config?.client_id}:default`
|
|
1483
|
+
});
|
|
1484
|
+
console.log(`Shared session ${fullId.slice(0, 8)} with ${email} (full access).`);
|
|
1485
|
+
console.log(`Share link: ${shareUrl}`);
|
|
1477
1486
|
return;
|
|
1478
1487
|
}
|
|
1479
1488
|
if (opts.remove) {
|
|
@@ -1544,11 +1553,16 @@ async function machineShare(machineId, opts) {
|
|
|
1544
1553
|
if (sharing.allowedUsers.length === 0) {
|
|
1545
1554
|
console.log("No shared users.");
|
|
1546
1555
|
} else {
|
|
1547
|
-
console.log("Shared users:");
|
|
1556
|
+
console.log("Shared users (each has full machine access):");
|
|
1548
1557
|
for (const u of sharing.allowedUsers) {
|
|
1549
|
-
console.log(` ${u.email.padEnd(30)}
|
|
1558
|
+
console.log(` ${u.email.padEnd(30)} (added ${new Date(u.addedAt).toISOString().slice(0, 10)})`);
|
|
1550
1559
|
}
|
|
1551
1560
|
}
|
|
1561
|
+
console.log(`
|
|
1562
|
+
Share link: ${buildMachineShareUrl({
|
|
1563
|
+
machineId: info.machineId,
|
|
1564
|
+
workspace: server.config?.workspace
|
|
1565
|
+
})}`);
|
|
1552
1566
|
}
|
|
1553
1567
|
const iso = info.metadata?.isolationCapabilities;
|
|
1554
1568
|
if (iso) {
|
|
@@ -1584,7 +1598,7 @@ Isolation: ${iso.available.length > 0 ? iso.available.join(", ") : "none availab
|
|
|
1584
1598
|
return;
|
|
1585
1599
|
}
|
|
1586
1600
|
if (opts.add) {
|
|
1587
|
-
const { email
|
|
1601
|
+
const { email } = parseShareArg(opts.add);
|
|
1588
1602
|
const info = await machine.getMachineInfo();
|
|
1589
1603
|
let sharing = info.metadata?.sharing || {
|
|
1590
1604
|
enabled: true,
|
|
@@ -1595,14 +1609,14 @@ Isolation: ${iso.available.length > 0 ? iso.available.join(", ") : "none availab
|
|
|
1595
1609
|
sharing.allowedUsers = sharing.allowedUsers.filter(
|
|
1596
1610
|
(u) => u.email.toLowerCase() !== email.toLowerCase()
|
|
1597
1611
|
);
|
|
1598
|
-
sharing.allowedUsers.push({
|
|
1599
|
-
email,
|
|
1600
|
-
role,
|
|
1601
|
-
addedAt: Date.now(),
|
|
1602
|
-
addedBy: "cli"
|
|
1603
|
-
});
|
|
1612
|
+
sharing.allowedUsers.push(normalizeAllowedUser({ email, addedBy: "cli" }, "cli"));
|
|
1604
1613
|
await machine.updateSharing(sharing);
|
|
1605
|
-
|
|
1614
|
+
const shareUrl = buildMachineShareUrl({
|
|
1615
|
+
machineId: info.machineId,
|
|
1616
|
+
workspace: server.config?.workspace
|
|
1617
|
+
});
|
|
1618
|
+
console.log(`Shared machine with ${email} (full access).`);
|
|
1619
|
+
console.log(`Share link: ${shareUrl}`);
|
|
1606
1620
|
return;
|
|
1607
1621
|
}
|
|
1608
1622
|
if (opts.remove) {
|
|
@@ -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-CTQAVadm.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-V2qpcN7f.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-V2qpcN7f.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
var name = "svamp-cli";
|
|
2
|
+
var version = "0.2.49";
|
|
3
|
+
var description = "Svamp CLI — AI workspace daemon on Hypha Cloud";
|
|
4
|
+
var author = "Amun AI AB";
|
|
5
|
+
var license = "SEE LICENSE IN LICENSE";
|
|
6
|
+
var type = "module";
|
|
7
|
+
var bin = {
|
|
8
|
+
svamp: "./bin/svamp.mjs"
|
|
9
|
+
};
|
|
10
|
+
var files = [
|
|
11
|
+
"dist",
|
|
12
|
+
"bin"
|
|
13
|
+
];
|
|
14
|
+
var main = "./dist/index.mjs";
|
|
15
|
+
var exports$1 = {
|
|
16
|
+
".": "./dist/index.mjs",
|
|
17
|
+
"./cli": "./dist/cli.mjs"
|
|
18
|
+
};
|
|
19
|
+
var scripts = {
|
|
20
|
+
build: "rm -rf dist && tsc --noEmit && pkgroll",
|
|
21
|
+
typecheck: "tsc --noEmit",
|
|
22
|
+
test: "npx tsx test/test-authorize.mjs && npx tsx test/test-normalize-allowed-user.mjs && npx tsx test/test-share-url.mjs && npx tsx test/test-update-sharing-normalization.mjs && npx tsx test/test-staged-homes-sweep.mjs && npx tsx test/test-session-helpers.mjs && npx tsx test/test-cli-routing.mjs && npx tsx test/test-security-context.mjs && npx tsx test/test-isolation-decision.mjs && npx tsx test/test-ralph-loop.mjs && npx tsx test/test-message-helpers.mjs && npx tsx test/test-agent-config.mjs && npx tsx test/test-wrap-command.mjs && npx tsx test/test-credential-staging.mjs && npx tsx test/test-claude-auth.mjs && npx tsx test/test-output-formatters.mjs && npx tsx test/test-agent-types.mjs && npx tsx test/test-transport.mjs && npx tsx test/test-session-update-handlers.mjs && npx tsx test/test-session-scanner.mjs && npx tsx test/test-hypha-client.mjs && npx tsx test/test-hook-settings.mjs && npx tsx test/test-session-service-logic.mjs && npx tsx test/test-daemon-persistence.mjs && npx tsx test/test-detect-isolation.mjs && npx tsx test/test-machine-service-logic.mjs && npx tsx test/test-interactive-helpers.mjs && npx tsx test/test-codex-backend.mjs && npx tsx test/test-acp-backend.mjs && npx tsx test/test-acp-bridge.mjs && npx tsx test/test-hook-server.mjs && npx tsx test/test-session-commands.mjs && npx tsx test/test-interactive-console.mjs && npx tsx test/test-session-messages.mjs && npx tsx test/test-skills.mjs && npx tsx test/test-agent-grouping.mjs && npx tsx test/test-ralph-loop-integration.mjs && npx tsx test/test-ralph-loop-modes.mjs && npx tsx test/test-machine-list-directory.mjs && npx tsx test/test-service-commands.mjs && npx tsx test/test-supervisor.mjs && npx tsx test/test-supervisor-lock.mjs && npx tsx test/test-clear-detection.mjs && npx tsx test/test-session-consolidation.mjs && npx tsx test/test-inbox.mjs && npx tsx test/test-session-rpc-dispatch.mjs && npx tsx test/test-sandbox-cli.mjs && npx tsx test/test-serve-manager.mjs && npx tsx test/test-serve-stability.mjs && npx tsx test/test-frpc-e2e.mjs --unit-only",
|
|
23
|
+
"test:hypha": "node --no-warnings test/test-hypha-service.mjs",
|
|
24
|
+
dev: "tsx src/cli.ts",
|
|
25
|
+
"dev:daemon": "tsx src/cli.ts daemon start-sync",
|
|
26
|
+
"test:e2e": "node --no-warnings test/e2e-session-tests.mjs",
|
|
27
|
+
"test:frpc": "npx tsx test/test-frpc-e2e.mjs"
|
|
28
|
+
};
|
|
29
|
+
var dependencies = {
|
|
30
|
+
"@agentclientprotocol/sdk": "^0.14.1",
|
|
31
|
+
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
32
|
+
"hypha-rpc": "0.21.40",
|
|
33
|
+
"node-pty": "1.2.0-beta.11",
|
|
34
|
+
ws: "^8.18.0",
|
|
35
|
+
yaml: "^2.8.2",
|
|
36
|
+
zod: "^3.24.4"
|
|
37
|
+
};
|
|
38
|
+
var devDependencies = {
|
|
39
|
+
"@types/node": ">=20",
|
|
40
|
+
"@types/ws": "^8.5.14",
|
|
41
|
+
pkgroll: "^2.14.2",
|
|
42
|
+
tsx: "^4.20.6",
|
|
43
|
+
typescript: "5.9.3"
|
|
44
|
+
};
|
|
45
|
+
var packageManager = "yarn@1.22.22";
|
|
46
|
+
var _package = {
|
|
47
|
+
name: name,
|
|
48
|
+
version: version,
|
|
49
|
+
description: description,
|
|
50
|
+
author: author,
|
|
51
|
+
license: license,
|
|
52
|
+
type: type,
|
|
53
|
+
bin: bin,
|
|
54
|
+
files: files,
|
|
55
|
+
main: main,
|
|
56
|
+
exports: exports$1,
|
|
57
|
+
scripts: scripts,
|
|
58
|
+
dependencies: dependencies,
|
|
59
|
+
devDependencies: devDependencies,
|
|
60
|
+
packageManager: packageManager
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export { author, bin, _package as default, dependencies, description, devDependencies, exports$1 as exports, files, license, main, name, packageManager, scripts, type, version };
|