svamp-cli 0.1.47 → 0.1.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { b as stopDaemon, s as startDaemon, d as daemonStatus } from './run-Ckyg9-fm.mjs';
1
+ import { b as stopDaemon, s as startDaemon, d as daemonStatus } from './run-ByOVDgvx.mjs';
2
2
  import 'os';
3
3
  import 'fs/promises';
4
4
  import 'fs';
@@ -110,7 +110,7 @@ async function main() {
110
110
  } else if (!subcommand || subcommand === "start") {
111
111
  await handleInteractiveCommand();
112
112
  } else if (subcommand === "--version" || subcommand === "-v") {
113
- const pkg = await import('./package-DG0AkZdm.mjs').catch(() => ({ default: { version: "unknown" } }));
113
+ const pkg = await import('./package-BaGfG8vL.mjs').catch(() => ({ default: { version: "unknown" } }));
114
114
  console.log(`svamp version: ${pkg.default.version}`);
115
115
  } else {
116
116
  console.error(`Unknown command: ${subcommand}`);
@@ -119,7 +119,7 @@ async function main() {
119
119
  }
120
120
  }
121
121
  async function handleInteractiveCommand() {
122
- const { runInteractive } = await import('./run-6dwQnoBL.mjs');
122
+ const { runInteractive } = await import('./run-BjZ6SyFy.mjs');
123
123
  const interactiveArgs = subcommand === "start" ? args.slice(1) : args;
124
124
  let directory = process.cwd();
125
125
  let resumeSessionId;
@@ -164,7 +164,7 @@ async function handleAgentCommand() {
164
164
  return;
165
165
  }
166
166
  if (agentArgs[0] === "list") {
167
- const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-Ckyg9-fm.mjs').then(function (n) { return n.i; });
167
+ const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-ByOVDgvx.mjs').then(function (n) { return n.i; });
168
168
  console.log("Known agents:");
169
169
  for (const [name, config2] of Object.entries(KNOWN_ACP_AGENTS)) {
170
170
  console.log(` ${name.padEnd(12)} ${config2.command} ${config2.args.join(" ")} (ACP)`);
@@ -176,7 +176,7 @@ async function handleAgentCommand() {
176
176
  console.log('Use "svamp agent -- <command> [args]" for a custom ACP agent.');
177
177
  return;
178
178
  }
179
- const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-Ckyg9-fm.mjs').then(function (n) { return n.i; });
179
+ const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-ByOVDgvx.mjs').then(function (n) { return n.i; });
180
180
  let cwd = process.cwd();
181
181
  const filteredArgs = [];
182
182
  for (let i = 0; i < agentArgs.length; i++) {
@@ -200,12 +200,12 @@ async function handleAgentCommand() {
200
200
  console.log(`Starting ${config.agentName} agent in ${cwd}...`);
201
201
  let backend;
202
202
  if (KNOWN_MCP_AGENTS[config.agentName]) {
203
- const { CodexMcpBackend } = await import('./run-Ckyg9-fm.mjs').then(function (n) { return n.j; });
203
+ const { CodexMcpBackend } = await import('./run-ByOVDgvx.mjs').then(function (n) { return n.j; });
204
204
  backend = new CodexMcpBackend({ cwd, log: logFn });
205
205
  } else {
206
- const { AcpBackend } = await import('./run-Ckyg9-fm.mjs').then(function (n) { return n.h; });
207
- const { GeminiTransport } = await import('./run-Ckyg9-fm.mjs').then(function (n) { return n.G; });
208
- const { DefaultTransport } = await import('./run-Ckyg9-fm.mjs').then(function (n) { return n.D; });
206
+ const { AcpBackend } = await import('./run-ByOVDgvx.mjs').then(function (n) { return n.h; });
207
+ const { GeminiTransport } = await import('./run-ByOVDgvx.mjs').then(function (n) { return n.G; });
208
+ const { DefaultTransport } = await import('./run-ByOVDgvx.mjs').then(function (n) { return n.D; });
209
209
  const transportHandler = config.agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(config.agentName);
210
210
  backend = new AcpBackend({
211
211
  agentName: config.agentName,
@@ -323,7 +323,7 @@ async function handleSessionCommand() {
323
323
  printSessionHelp();
324
324
  return;
325
325
  }
326
- const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionQueueAdd, sessionQueueList, sessionQueueClear } = await import('./commands-DsIoygTL.mjs');
326
+ const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionQueueAdd, sessionQueueList, sessionQueueClear } = await import('./commands-C9TdN_El.mjs');
327
327
  const parseFlagStr = (flag, shortFlag) => {
328
328
  for (let i = 1; i < sessionArgs.length; i++) {
329
329
  if ((sessionArgs[i] === flag || shortFlag) && i + 1 < sessionArgs.length) {
@@ -357,13 +357,21 @@ async function handleSessionCommand() {
357
357
  }
358
358
  const message = parseFlagStr("--message");
359
359
  const wait = hasFlag("--wait");
360
+ const worktree = hasFlag("--worktree");
360
361
  const isolate = hasFlag("--isolate");
362
+ const permissionMode = parseFlagStr("--permission-mode") || parseFlagStr("-p");
361
363
  const securityContextPath = parseFlagStr("--security-context");
362
364
  const denyNetwork = hasFlag("--deny-network");
365
+ const parentSessionId = parseFlagStr("--parent");
366
+ const tagsFlag = parseFlagStr("--tags");
363
367
  const share = [];
364
368
  const denyRead = [];
365
369
  const allowWrite = [];
366
370
  const allowDomain = [];
371
+ const tags = [];
372
+ if (tagsFlag) {
373
+ tags.push(...tagsFlag.split(",").map((t) => t.trim()).filter(Boolean));
374
+ }
367
375
  for (let i = 1; i < sessionArgs.length; i++) {
368
376
  if (sessionArgs[i] === "--share" && i + 1 < sessionArgs.length) {
369
377
  share.push(sessionArgs[++i]);
@@ -375,18 +383,22 @@ async function handleSessionCommand() {
375
383
  allowDomain.push(sessionArgs[++i]);
376
384
  }
377
385
  }
378
- const { parseShareArg } = await import('./commands-DsIoygTL.mjs');
386
+ const { parseShareArg } = await import('./commands-C9TdN_El.mjs');
379
387
  const shareEntries = share.map((s) => parseShareArg(s));
380
388
  await sessionSpawn(agent, dir, targetMachineId, {
381
389
  message,
382
390
  wait,
391
+ worktree,
383
392
  isolate,
393
+ permissionMode,
384
394
  securityContextPath,
385
395
  share: shareEntries.length > 0 ? shareEntries : void 0,
386
396
  denyRead: denyRead.length > 0 ? denyRead : void 0,
387
397
  allowWrite: allowWrite.length > 0 ? allowWrite : void 0,
388
398
  denyNetwork,
389
- allowDomain: allowDomain.length > 0 ? allowDomain : void 0
399
+ allowDomain: allowDomain.length > 0 ? allowDomain : void 0,
400
+ tags: tags.length > 0 ? tags : void 0,
401
+ parentSessionId
390
402
  });
391
403
  } else if (sessionSubcommand === "stop") {
392
404
  if (!sessionArgs[1]) {
@@ -404,12 +416,13 @@ async function handleSessionCommand() {
404
416
  });
405
417
  } else if (sessionSubcommand === "messages" || sessionSubcommand === "msgs") {
406
418
  if (!sessionArgs[1]) {
407
- console.error("Usage: svamp session messages <session-id> [--last N] [--json] [--after N] [--limit N]");
419
+ console.error("Usage: svamp session messages <session-id> [--last N] [--json] [--raw] [--after N] [--limit N]");
408
420
  process.exit(1);
409
421
  }
410
422
  await sessionMessages(sessionArgs[1], targetMachineId, {
411
423
  last: parseFlagInt("--last"),
412
424
  json: hasFlag("--json"),
425
+ raw: hasFlag("--raw"),
413
426
  after: parseFlagInt("--after"),
414
427
  limit: parseFlagInt("--limit")
415
428
  });
@@ -431,11 +444,12 @@ async function handleSessionCommand() {
431
444
  });
432
445
  } else if (sessionSubcommand === "wait") {
433
446
  if (!sessionArgs[1]) {
434
- console.error("Usage: svamp session wait <session-id> [--timeout N]");
447
+ console.error("Usage: svamp session wait <session-id> [--timeout N] [--json]");
435
448
  process.exit(1);
436
449
  }
437
450
  await sessionWait(sessionArgs[1], targetMachineId, {
438
- timeout: parseFlagInt("--timeout")
451
+ timeout: parseFlagInt("--timeout"),
452
+ json: hasFlag("--json")
439
453
  });
440
454
  } else if (sessionSubcommand === "share") {
441
455
  if (!sessionArgs[1]) {
@@ -448,6 +462,26 @@ async function handleSessionCommand() {
448
462
  list: hasFlag("--list"),
449
463
  public: parseFlagStr("--public")
450
464
  });
465
+ } else if (sessionSubcommand === "approve") {
466
+ if (!sessionArgs[1]) {
467
+ console.error("Usage: svamp session approve <session-id> [request-id] [--json]");
468
+ process.exit(1);
469
+ }
470
+ const { sessionApprove } = await import('./commands-C9TdN_El.mjs');
471
+ const approveReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
472
+ await sessionApprove(sessionArgs[1], approveReqId, targetMachineId, {
473
+ json: hasFlag("--json")
474
+ });
475
+ } else if (sessionSubcommand === "deny") {
476
+ if (!sessionArgs[1]) {
477
+ console.error("Usage: svamp session deny <session-id> [request-id] [--json]");
478
+ process.exit(1);
479
+ }
480
+ const { sessionDeny } = await import('./commands-C9TdN_El.mjs');
481
+ const denyReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
482
+ await sessionDeny(sessionArgs[1], denyReqId, targetMachineId, {
483
+ json: hasFlag("--json")
484
+ });
451
485
  } else if (sessionSubcommand === "ralph-start" || sessionSubcommand === "ralph") {
452
486
  if (!sessionArgs[1] || !sessionArgs[2]) {
453
487
  console.error('Usage: svamp session ralph-start <session-id> "<task>" [--completion-promise TEXT] [--max-iterations N]');
@@ -508,7 +542,7 @@ async function handleMachineCommand() {
508
542
  return;
509
543
  }
510
544
  if (machineSubcommand === "share") {
511
- const { machineShare } = await import('./commands-DsIoygTL.mjs');
545
+ const { machineShare } = await import('./commands-C9TdN_El.mjs');
512
546
  let machineId;
513
547
  const shareArgs = [];
514
548
  for (let i = 1; i < machineArgs.length; i++) {
@@ -551,7 +585,7 @@ async function handleSkillsCommand() {
551
585
  printSkillsHelp();
552
586
  return;
553
587
  }
554
- const { skillsFind, skillsInstall, skillsList, skillsRemove, skillsPublish } = await import('./commands-BEhSQqTp.mjs');
588
+ const { skillsFind, skillsInstall, skillsList, skillsRemove, skillsPublish } = await import('./commands-BVuE0VQU.mjs');
555
589
  if (skillsSubcommand === "find" || skillsSubcommand === "search") {
556
590
  const query = skillsArgs.slice(1).filter((a) => !a.startsWith("--")).join(" ");
557
591
  if (!query) {
@@ -898,28 +932,34 @@ function printHelp() {
898
932
  svamp \u2014 AI workspace on Hypha Cloud
899
933
 
900
934
  Usage:
901
- svamp Start interactive Claude session (synced to cloud)
902
- svamp start [-d <path>] Same as above, with explicit directory
903
- svamp login [url] Login to Hypha (opens browser, stores token)
904
- svamp daemon start Start the daemon (detached)
905
- svamp daemon stop Stop the daemon (sessions preserved for restart)
906
- svamp daemon restart Restart the daemon (sessions resume seamlessly)
907
- svamp daemon status Show daemon status
908
- svamp daemon install Install as system service (launchd/systemd/wrapper)
909
- svamp session list List active sessions
910
- svamp session spawn Spawn a new session on the daemon
911
- svamp session share <id> Manage session sharing
912
- svamp session attach <id> Attach to a session
913
- svamp session --help Show all session commands
914
- svamp machine share Manage machine sharing & security contexts
915
- svamp machine --help Show all machine commands
916
- svamp skills find <query> Search the skills marketplace
917
- svamp skills install <n> Install a skill from the marketplace
918
- svamp skills --help Show all skill commands
919
- svamp agent list List known agents
920
- svamp agent <name> Start local agent session (gemini, codex)
921
- svamp --version Show version
922
- svamp --help Show this help
935
+ svamp Start interactive Claude session (synced to cloud)
936
+ svamp start [-d <path>] Same as above, with explicit directory
937
+ svamp login [url] Login to Hypha (opens browser, stores token)
938
+ svamp daemon start Start the daemon (detached)
939
+ svamp daemon stop Stop the daemon (sessions preserved for restart)
940
+ svamp daemon restart Restart the daemon (sessions resume seamlessly)
941
+ svamp daemon status Show daemon status
942
+ svamp daemon install Install as system service (launchd/systemd/wrapper)
943
+ svamp session list List active sessions
944
+ svamp session spawn Spawn a new session on the daemon
945
+ svamp session send <id> <m> Send message to a session
946
+ svamp session wait <id> Wait for agent to become idle
947
+ svamp session info <id> Show session status & pending permissions
948
+ svamp session messages <id> Show message history
949
+ svamp session approve <id> Approve pending permission request
950
+ svamp session deny <id> Deny pending permission request
951
+ svamp session attach <id> Attach to a session (interactive terminal)
952
+ svamp session share <id> Manage session sharing
953
+ svamp session --help Show all session commands
954
+ svamp machine share Manage machine sharing & security contexts
955
+ svamp machine --help Show all machine commands
956
+ svamp skills find <query> Search the skills marketplace
957
+ svamp skills install <n> Install a skill from the marketplace
958
+ svamp skills --help Show all skill commands
959
+ svamp agent list List known agents
960
+ svamp agent <name> Start local agent session (gemini, codex)
961
+ svamp --version Show version
962
+ svamp --help Show this help
923
963
 
924
964
  Interactive mode:
925
965
  When you run 'svamp' with no arguments, Claude starts in your terminal
@@ -954,19 +994,75 @@ function printSessionHelp() {
954
994
  console.log(`
955
995
  svamp session \u2014 Manage daemon sessions (Claude, Gemini, Codex)
956
996
 
957
- Usage:
958
- svamp session list [--active] [--json] List sessions (alias: ls)
959
- svamp session machines List discoverable machines
960
- svamp session spawn <agent> [-d <path>] [--message <msg>] [--wait]
961
- Spawn a new session
962
- svamp session stop <id> Stop a session
963
- svamp session info <id> [--json] Show session metadata + activity
997
+ Commands:
998
+ svamp session list [--active] [--json] List sessions (alias: ls)
999
+ svamp session machines List discoverable machines
1000
+ svamp session spawn <agent> [-d <path>] [options] Spawn a new session
1001
+ svamp session stop <id> Stop a session
1002
+ svamp session info <id> [--json] Show status, activity & pending permissions
964
1003
  svamp session send <id> <message> [--wait] [--timeout N] [--json]
965
- Send a message to a session
966
- svamp session wait <id> [--timeout N] Wait for agent to become idle
967
- svamp session messages <id> [--last N] [--json] [--after N] [--limit N]
968
- Show messages (alias: msgs)
969
- svamp session attach <id> Attach to session (interactive)
1004
+ Send a message to a session
1005
+ svamp session wait <id> [--timeout N] [--json] Wait for agent to become idle
1006
+ svamp session messages <id> [--last N] [--json] [--raw] [--after N] [--limit N]
1007
+ Show messages (alias: msgs)
1008
+ svamp session attach <id> Attach to session (interactive terminal)
1009
+ svamp session approve <id> [request-id] [--json] Approve pending permission(s)
1010
+ svamp session deny <id> [request-id] [--json] Deny pending permission(s)
1011
+
1012
+ Spawn options:
1013
+ -d, --directory <path> Working directory (default: cwd)
1014
+ -p, --permission-mode <mode> Agent permission mode (see "Permission modes" below)
1015
+ --message <msg> Send initial message after spawn
1016
+ --wait Wait for agent to become idle before returning
1017
+ --worktree Create a git worktree branch (at .dev/worktree/<name>)
1018
+ --isolate Force OS-level sandbox isolation
1019
+ --security-context <path> Apply security context config (JSON file)
1020
+ --share <email>[:<role>] Share with user (repeatable). Role: view, interact, admin
1021
+ --deny-network Block all network access
1022
+ --deny-read <path> Deny reading path (repeatable)
1023
+ --allow-write <path> Allow writing path (repeatable)
1024
+ --allow-domain <domain> Allow network domain (repeatable)
1025
+
1026
+ Permission modes (-p, --permission-mode):
1027
+ default Prompt for each tool use (default)
1028
+ acceptEdits Auto-approve file edits, prompt for bash/dangerous tools
1029
+ bypassPermissions Auto-approve all tools (no prompts)
1030
+
1031
+ Permission workflow:
1032
+ When an agent runs with 'default' or 'acceptEdits' permission mode, it pauses
1033
+ when it needs to use a tool that requires approval. Use these commands to manage:
1034
+
1035
+ 1. Check status: svamp session info <id> --json
1036
+ \u2192 shows pendingPermissions array when agent is blocked
1037
+ 2. Wait & detect: svamp session wait <id> --json
1038
+ \u2192 exits with code 2 if permission pending (see exit codes)
1039
+ 3. Approve: svamp session approve <id> (approve all pending)
1040
+ svamp session approve <id> <rid> (approve specific request)
1041
+ 4. Deny: svamp session deny <id> (deny all pending)
1042
+ svamp session deny <id> <rid> (deny specific request)
1043
+
1044
+ Request IDs support prefix matching (e.g., "abc1" matches "abc12345-...").
1045
+
1046
+ Messages options:
1047
+ --last N Show only the last N messages
1048
+ --after N Start after sequence number N
1049
+ --limit N Max messages to fetch from server (default: 1000, cap: 500 per page)
1050
+ --json Output as JSON (FormattedMessage: id, seq, role, text, createdAt)
1051
+ --raw With --json: output full raw message objects (includes tool_use args,
1052
+ tool_result content, thinking blocks \u2014 use for programmatic parsing)
1053
+
1054
+ Exit codes (wait, send --wait, spawn --wait):
1055
+ 0 Agent is idle (task completed)
1056
+ 1 Error (timeout, connection failure, session not found)
1057
+ 2 Agent is waiting for permission approval \u2014 use approve/deny to continue
1058
+
1059
+ Global options:
1060
+ --machine <id>, -m <id> Target a specific machine (prefix match supported)
1061
+
1062
+ Agents: claude (default), gemini, codex
1063
+ Session and machine IDs support prefix matching (e.g., "abc1" matches "abc12345-...").
1064
+
1065
+ Sharing:
970
1066
  svamp session share <id> --list List shared users
971
1067
  svamp session share <id> --add <email>[:<role>] Share with user
972
1068
  svamp session share <id> --remove <email> Remove shared user
@@ -975,6 +1071,10 @@ Usage:
975
1071
  Options:
976
1072
  --machine <id>, -m <id> Target a specific machine (prefix match supported)
977
1073
 
1074
+ Spawn options:
1075
+ -p, --permission-mode <mode> Agent permission mode: default, acceptEdits, bypassPermissions
1076
+ --worktree Create a git worktree branch as working directory
1077
+
978
1078
  Spawn isolation options:
979
1079
  --share <email>[:<role>] Share session (repeatable). Role: view, interact, admin
980
1080
  --security-context <path> Path to security context JSON config file
@@ -984,39 +1084,56 @@ Spawn isolation options:
984
1084
  --deny-network Deny all network access
985
1085
  --allow-domain <domain> Allow network access to domain (repeatable)
986
1086
 
1087
+ Spawn grouping options:
1088
+ --tags <tag1,tag2> Comma-separated tags
1089
+ --parent <sessionId> Set parent session (auto-detected from SVAMP_SESSION_ID)
1090
+
987
1091
  Agents: claude (default), gemini, codex
988
1092
 
989
1093
  Session and machine IDs can be abbreviated (prefix match, like Docker).
990
1094
 
1095
+ NOTE: By default, spawned agents run with 'default' permission mode, which means
1096
+ the agent may pause to request permission for tool use (file edits, bash, etc.).
1097
+ Use -p bypassPermissions to run without approval prompts.
1098
+
991
1099
  Attach commands:
992
1100
  /quit, /detach Detach (session keeps running)
993
1101
  /abort, /cancel Cancel current agent turn
994
1102
  /kill Stop the session
995
1103
  /info Show session status
996
1104
 
997
- Examples:
998
- svamp session spawn claude -d ~/projects/myapp --message "Fix the bug" --wait
999
- svamp session spawn claude -d /tmp/sandbox --isolate --deny-network
1000
- svamp session spawn claude -d /tmp/proj --share alice@example.com:admin --deny-read /etc
1001
- svamp session spawn claude --security-context ./security.json
1002
- svamp session share abc12345 --add bob@example.com:view
1003
- svamp session share abc12345 --public view
1004
- svamp session share abc12345 --list
1005
-
1006
- Ralph Loop (iterative task loop):
1105
+ Ralph Loop (iterative task automation):
1007
1106
  svamp session ralph-start <id> "<task>" [--completion-promise TEXT] [--max-iterations N]
1008
- Start a Ralph loop
1009
- svamp session ralph-cancel <id> Cancel active Ralph loop
1010
- svamp session ralph-status <id> Show Ralph loop status
1107
+ svamp session ralph-cancel <id>
1108
+ svamp session ralph-status <id>
1011
1109
 
1012
1110
  Message Queue:
1013
- svamp session queue add <id> "<message>" Add message to queue
1014
- svamp session queue list <id> List queued messages
1015
- svamp session queue clear <id> Clear the queue
1111
+ svamp session queue add <id> "<message>"
1112
+ svamp session queue list <id>
1113
+ svamp session queue clear <id>
1114
+
1115
+ Examples:
1116
+ # Spawn with bypassed permissions (no prompts)
1117
+ svamp session spawn claude -d ./proj -p bypassPermissions --message "fix tests" --wait
1118
+
1119
+ # Spawn with default permissions, handle approval via CLI
1120
+ svamp session spawn claude -d ./proj --message "refactor auth"
1121
+ svamp session wait abc1 --json # exits with code 2 if permission pending
1122
+ svamp session approve abc1 # approve all pending permissions
1123
+ svamp session wait abc1 # wait for completion
1124
+
1125
+ # Monitor session messages (raw for full tool details)
1126
+ svamp session messages abc1 --last 10 --json --raw
1127
+
1128
+ # Send message and wait for completion
1129
+ svamp session send abc1 "run the tests" --wait --json
1130
+
1131
+ # Isolation & sharing
1132
+ svamp session spawn claude -d /tmp/sandbox --isolate --deny-network
1133
+ svamp session spawn claude -d /tmp/proj --share alice@example.com:admin
1016
1134
 
1017
- Ralph Loop Examples:
1018
- svamp session ralph-start abc12 "Fix all linting errors" --completion-promise "All linting errors fixed" --max-iterations 10
1019
- svamp session ralph-cancel abc12
1135
+ # Ralph Loop
1136
+ svamp session ralph-start abc1 "Fix all linting errors" --max-iterations 10
1020
1137
  `);
1021
1138
  }
1022
1139
  function printMachineHelp() {