svamp-cli 0.2.78 → 0.2.80

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.
@@ -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-k2E3EJFY.mjs');
151
+ const { connectAndGetMachine } = await import('./commands-C6lrExeN.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-k2E3EJFY.mjs');
168
+ const { resolveSessionId } = await import('./commands-C6lrExeN.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-DDKJ85DU.mjs';
1
+ import { s as startDaemon, b as stopDaemon, d as daemonStatus } from './run-W8JZkXIf.mjs';
2
2
  import 'os';
3
3
  import 'fs/promises';
4
4
  import 'fs';
@@ -44,7 +44,7 @@ async function main() {
44
44
  console.error(`svamp daemon restart: ${err.message || err}`);
45
45
  process.exit(1);
46
46
  }
47
- const { restartDaemon } = await import('./run-DDKJ85DU.mjs').then(function (n) { return n.u; });
47
+ const { restartDaemon } = await import('./run-W8JZkXIf.mjs').then(function (n) { return n.u; });
48
48
  await restartDaemon();
49
49
  process.exit(0);
50
50
  }
@@ -287,7 +287,7 @@ async function main() {
287
287
  console.error("svamp service: Service commands are not available in sandboxed sessions.");
288
288
  process.exit(1);
289
289
  }
290
- const { handleServiceCommand } = await import('./commands-CZWJawtg.mjs');
290
+ const { handleServiceCommand } = await import('./commands-iCbgYseB.mjs');
291
291
  await handleServiceCommand();
292
292
  } else if (subcommand === "serve") {
293
293
  const { isSandboxed: isSandboxedServe } = await import('./sandboxDetect-DNTcbgWD.mjs');
@@ -295,7 +295,7 @@ async function main() {
295
295
  console.error("svamp serve: Serve commands are not available in sandboxed sessions.");
296
296
  process.exit(1);
297
297
  }
298
- const { handleServeCommand } = await import('./serveCommands-j7Igsr-W.mjs');
298
+ const { handleServeCommand } = await import('./serveCommands-DEik3hcu.mjs');
299
299
  await handleServeCommand();
300
300
  process.exit(0);
301
301
  } else if (subcommand === "process" || subcommand === "proc") {
@@ -304,7 +304,7 @@ async function main() {
304
304
  console.error("svamp process: Process commands are not available in sandboxed sessions.");
305
305
  process.exit(1);
306
306
  }
307
- const { processCommand } = await import('./commands-GILVenvg.mjs');
307
+ const { processCommand } = await import('./commands-BKJNCTjq.mjs');
308
308
  let machineId;
309
309
  const processArgs = args.slice(1);
310
310
  const mIdx = processArgs.findIndex((a) => a === "--machine" || a === "-m");
@@ -322,7 +322,7 @@ async function main() {
322
322
  } else if (!subcommand || subcommand === "start") {
323
323
  await handleInteractiveCommand();
324
324
  } else if (subcommand === "--version" || subcommand === "-v") {
325
- const pkg = await import('./package-ike8lo0g.mjs').catch(() => ({ default: { version: "unknown" } }));
325
+ const pkg = await import('./package-C4KoS6-F.mjs').catch(() => ({ default: { version: "unknown" } }));
326
326
  console.log(`svamp version: ${pkg.default.version}`);
327
327
  } else {
328
328
  console.error(`Unknown command: ${subcommand}`);
@@ -331,7 +331,7 @@ async function main() {
331
331
  }
332
332
  }
333
333
  async function handleInteractiveCommand() {
334
- const { runInteractive } = await import('./run-CZEFZgIV.mjs');
334
+ const { runInteractive } = await import('./run-DamsNf6r.mjs');
335
335
  const interactiveArgs = subcommand === "start" ? args.slice(1) : args;
336
336
  let directory = process.cwd();
337
337
  let resumeSessionId;
@@ -376,7 +376,7 @@ async function handleAgentCommand() {
376
376
  return;
377
377
  }
378
378
  if (agentArgs[0] === "list") {
379
- const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-DDKJ85DU.mjs').then(function (n) { return n.p; });
379
+ const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-W8JZkXIf.mjs').then(function (n) { return n.p; });
380
380
  console.log("Known agents:");
381
381
  for (const [name, config2] of Object.entries(KNOWN_ACP_AGENTS)) {
382
382
  console.log(` ${name.padEnd(12)} ${config2.command} ${config2.args.join(" ")} (ACP)`);
@@ -388,7 +388,7 @@ async function handleAgentCommand() {
388
388
  console.log('Use "svamp agent -- <command> [args]" for a custom ACP agent.');
389
389
  return;
390
390
  }
391
- const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-DDKJ85DU.mjs').then(function (n) { return n.p; });
391
+ const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-W8JZkXIf.mjs').then(function (n) { return n.p; });
392
392
  let cwd = process.cwd();
393
393
  const filteredArgs = [];
394
394
  for (let i = 0; i < agentArgs.length; i++) {
@@ -412,12 +412,12 @@ async function handleAgentCommand() {
412
412
  console.log(`Starting ${config.agentName} agent in ${cwd}...`);
413
413
  let backend;
414
414
  if (KNOWN_MCP_AGENTS[config.agentName]) {
415
- const { CodexMcpBackend } = await import('./run-DDKJ85DU.mjs').then(function (n) { return n.q; });
415
+ const { CodexMcpBackend } = await import('./run-W8JZkXIf.mjs').then(function (n) { return n.q; });
416
416
  backend = new CodexMcpBackend({ cwd, log: logFn });
417
417
  } else {
418
- const { AcpBackend } = await import('./run-DDKJ85DU.mjs').then(function (n) { return n.o; });
419
- const { GeminiTransport } = await import('./run-DDKJ85DU.mjs').then(function (n) { return n.G; });
420
- const { DefaultTransport } = await import('./run-DDKJ85DU.mjs').then(function (n) { return n.D; });
418
+ const { AcpBackend } = await import('./run-W8JZkXIf.mjs').then(function (n) { return n.o; });
419
+ const { GeminiTransport } = await import('./run-W8JZkXIf.mjs').then(function (n) { return n.G; });
420
+ const { DefaultTransport } = await import('./run-W8JZkXIf.mjs').then(function (n) { return n.D; });
421
421
  const transportHandler = config.agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(config.agentName);
422
422
  backend = new AcpBackend({
423
423
  agentName: config.agentName,
@@ -544,7 +544,7 @@ async function handleSessionCommand() {
544
544
  process.exit(1);
545
545
  }
546
546
  }
547
- const { sessionList, sessionSpawn, sessionArchive, sessionResume, sessionDelete, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-k2E3EJFY.mjs');
547
+ const { sessionList, sessionSpawn, sessionArchive, sessionResume, sessionDelete, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-C6lrExeN.mjs');
548
548
  const parseFlagStr = (flag, shortFlag) => {
549
549
  for (let i = 1; i < sessionArgs.length; i++) {
550
550
  if ((sessionArgs[i] === flag || shortFlag) && i + 1 < sessionArgs.length) {
@@ -610,7 +610,7 @@ async function handleSessionCommand() {
610
610
  allowDomain.push(sessionArgs[++i]);
611
611
  }
612
612
  }
613
- const { parseShareArg } = await import('./commands-k2E3EJFY.mjs');
613
+ const { parseShareArg } = await import('./commands-C6lrExeN.mjs');
614
614
  const shareEntries = share.map((s) => parseShareArg(s));
615
615
  await sessionSpawn(agent, dir, targetMachineId, {
616
616
  message,
@@ -696,7 +696,7 @@ async function handleSessionCommand() {
696
696
  console.error(" Spawns a stateless Claude session in <directory>, sends <prompt>, prints the answer, then deletes the session.");
697
697
  process.exit(1);
698
698
  }
699
- const { sessionQuery } = await import('./commands-k2E3EJFY.mjs');
699
+ const { sessionQuery } = await import('./commands-C6lrExeN.mjs');
700
700
  await sessionQuery(dir, prompt, targetMachineId, {
701
701
  timeout: parseFlagInt("--timeout"),
702
702
  json: hasFlag("--json"),
@@ -729,7 +729,7 @@ async function handleSessionCommand() {
729
729
  console.error("Usage: svamp session approve <session-id> [request-id] [--json]");
730
730
  process.exit(1);
731
731
  }
732
- const { sessionApprove } = await import('./commands-k2E3EJFY.mjs');
732
+ const { sessionApprove } = await import('./commands-C6lrExeN.mjs');
733
733
  const approveReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
734
734
  await sessionApprove(sessionArgs[1], approveReqId, targetMachineId, {
735
735
  json: hasFlag("--json")
@@ -739,7 +739,7 @@ async function handleSessionCommand() {
739
739
  console.error("Usage: svamp session deny <session-id> [request-id] [--json]");
740
740
  process.exit(1);
741
741
  }
742
- const { sessionDeny } = await import('./commands-k2E3EJFY.mjs');
742
+ const { sessionDeny } = await import('./commands-C6lrExeN.mjs');
743
743
  const denyReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
744
744
  await sessionDeny(sessionArgs[1], denyReqId, targetMachineId, {
745
745
  json: hasFlag("--json")
@@ -775,7 +775,7 @@ async function handleSessionCommand() {
775
775
  console.error("Usage: svamp session set-title <title>");
776
776
  process.exit(1);
777
777
  }
778
- const { sessionSetTitle } = await import('./agentCommands-OplcUdhk.mjs');
778
+ const { sessionSetTitle } = await import('./agentCommands-CcNJ1dcR.mjs');
779
779
  await sessionSetTitle(title);
780
780
  } else if (sessionSubcommand === "set-link") {
781
781
  const url = sessionArgs[1];
@@ -784,7 +784,7 @@ async function handleSessionCommand() {
784
784
  process.exit(1);
785
785
  }
786
786
  const label = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
787
- const { sessionSetLink } = await import('./agentCommands-OplcUdhk.mjs');
787
+ const { sessionSetLink } = await import('./agentCommands-CcNJ1dcR.mjs');
788
788
  await sessionSetLink(url, label);
789
789
  } else if (sessionSubcommand === "notify") {
790
790
  const message = sessionArgs[1];
@@ -793,7 +793,7 @@ async function handleSessionCommand() {
793
793
  process.exit(1);
794
794
  }
795
795
  const level = parseFlagStr("--level") || "info";
796
- const { sessionNotify } = await import('./agentCommands-OplcUdhk.mjs');
796
+ const { sessionNotify } = await import('./agentCommands-CcNJ1dcR.mjs');
797
797
  await sessionNotify(message, level);
798
798
  } else if (sessionSubcommand === "broadcast") {
799
799
  const action = sessionArgs[1];
@@ -801,7 +801,7 @@ async function handleSessionCommand() {
801
801
  console.error("Usage: svamp session broadcast <action> [args...]\nActions: open-canvas <url> [label], close-canvas, toast <message>");
802
802
  process.exit(1);
803
803
  }
804
- const { sessionBroadcast } = await import('./agentCommands-OplcUdhk.mjs');
804
+ const { sessionBroadcast } = await import('./agentCommands-CcNJ1dcR.mjs');
805
805
  await sessionBroadcast(action, sessionArgs.slice(2).filter((a) => !a.startsWith("--")));
806
806
  } else if (sessionSubcommand === "inbox") {
807
807
  const inboxSubcmd = sessionArgs[1];
@@ -812,7 +812,7 @@ async function handleSessionCommand() {
812
812
  process.exit(1);
813
813
  }
814
814
  if (agentSessionId) {
815
- const { inboxSend } = await import('./agentCommands-OplcUdhk.mjs');
815
+ const { inboxSend } = await import('./agentCommands-CcNJ1dcR.mjs');
816
816
  await inboxSend(sessionArgs[2], {
817
817
  body: sessionArgs[3],
818
818
  subject: parseFlagStr("--subject"),
@@ -827,7 +827,7 @@ async function handleSessionCommand() {
827
827
  }
828
828
  } else if (inboxSubcmd === "list" || inboxSubcmd === "ls") {
829
829
  if (agentSessionId && !sessionArgs[2]) {
830
- const { inboxList } = await import('./agentCommands-OplcUdhk.mjs');
830
+ const { inboxList } = await import('./agentCommands-CcNJ1dcR.mjs');
831
831
  await inboxList({
832
832
  unread: hasFlag("--unread"),
833
833
  limit: parseFlagInt("--limit"),
@@ -849,7 +849,7 @@ async function handleSessionCommand() {
849
849
  process.exit(1);
850
850
  }
851
851
  if (agentSessionId && !sessionArgs[3]) {
852
- const { inboxList } = await import('./agentCommands-OplcUdhk.mjs');
852
+ const { inboxList } = await import('./agentCommands-CcNJ1dcR.mjs');
853
853
  await sessionInboxRead(agentSessionId, sessionArgs[2], targetMachineId);
854
854
  } else if (sessionArgs[3]) {
855
855
  await sessionInboxRead(sessionArgs[2], sessionArgs[3], targetMachineId);
@@ -859,7 +859,7 @@ async function handleSessionCommand() {
859
859
  }
860
860
  } else if (inboxSubcmd === "reply") {
861
861
  if (agentSessionId && sessionArgs[2] && sessionArgs[3] && !sessionArgs[4]) {
862
- const { inboxReply } = await import('./agentCommands-OplcUdhk.mjs');
862
+ const { inboxReply } = await import('./agentCommands-CcNJ1dcR.mjs');
863
863
  await inboxReply(sessionArgs[2], sessionArgs[3]);
864
864
  } else if (sessionArgs[2] && sessionArgs[3] && sessionArgs[4]) {
865
865
  await sessionInboxReply(sessionArgs[2], sessionArgs[3], sessionArgs[4], targetMachineId);
@@ -895,7 +895,7 @@ async function handleMachineCommand() {
895
895
  return;
896
896
  }
897
897
  if (machineSubcommand === "share") {
898
- const { machineShare } = await import('./commands-k2E3EJFY.mjs');
898
+ const { machineShare } = await import('./commands-C6lrExeN.mjs');
899
899
  let machineId;
900
900
  const shareArgs = [];
901
901
  for (let i = 1; i < machineArgs.length; i++) {
@@ -925,7 +925,7 @@ async function handleMachineCommand() {
925
925
  }
926
926
  await machineShare(machineId, { add, remove, list, configPath, showConfig });
927
927
  } else if (machineSubcommand === "exec") {
928
- const { machineExec } = await import('./commands-k2E3EJFY.mjs');
928
+ const { machineExec } = await import('./commands-C6lrExeN.mjs');
929
929
  let machineId;
930
930
  let cwd;
931
931
  const cmdParts = [];
@@ -945,7 +945,7 @@ async function handleMachineCommand() {
945
945
  }
946
946
  await machineExec(machineId, command, cwd);
947
947
  } else if (machineSubcommand === "info") {
948
- const { machineInfo } = await import('./commands-k2E3EJFY.mjs');
948
+ const { machineInfo } = await import('./commands-C6lrExeN.mjs');
949
949
  let machineId;
950
950
  for (let i = 1; i < machineArgs.length; i++) {
951
951
  if ((machineArgs[i] === "--machine" || machineArgs[i] === "-m") && i + 1 < machineArgs.length) {
@@ -965,10 +965,10 @@ async function handleMachineCommand() {
965
965
  level = machineArgs[++i];
966
966
  }
967
967
  }
968
- const { machineNotify } = await import('./agentCommands-OplcUdhk.mjs');
968
+ const { machineNotify } = await import('./agentCommands-CcNJ1dcR.mjs');
969
969
  await machineNotify(message, level);
970
970
  } else if (machineSubcommand === "ls") {
971
- const { machineLs } = await import('./commands-k2E3EJFY.mjs');
971
+ const { machineLs } = await import('./commands-C6lrExeN.mjs');
972
972
  let machineId;
973
973
  let showHidden = false;
974
974
  let path;
@@ -1026,24 +1026,24 @@ Examples:
1026
1026
  };
1027
1027
  const hasFlag = (name) => fleetArgs.includes(`--${name}`);
1028
1028
  if (sub === "status") {
1029
- const { fleetStatus } = await import('./fleet-Cp-Ykxc6.mjs');
1029
+ const { fleetStatus } = await import('./fleet-BdWjugcV.mjs');
1030
1030
  await fleetStatus();
1031
1031
  } else if (sub === "exec") {
1032
1032
  const command = fleetArgs.slice(1).filter((a) => !a.startsWith("--")).join(" ");
1033
- const { fleetExec } = await import('./fleet-Cp-Ykxc6.mjs');
1033
+ const { fleetExec } = await import('./fleet-BdWjugcV.mjs');
1034
1034
  await fleetExec(command, { cwd: flag("cwd") });
1035
1035
  } else if (sub === "upgrade-claude") {
1036
- const { fleetUpgradeClaude } = await import('./fleet-Cp-Ykxc6.mjs');
1036
+ const { fleetUpgradeClaude } = await import('./fleet-BdWjugcV.mjs');
1037
1037
  await fleetUpgradeClaude({ version: flag("version", "-v") });
1038
1038
  } else if (sub === "upgrade-svamp") {
1039
- const { fleetUpgradeSvamp } = await import('./fleet-Cp-Ykxc6.mjs');
1039
+ const { fleetUpgradeSvamp } = await import('./fleet-BdWjugcV.mjs');
1040
1040
  await fleetUpgradeSvamp({ version: flag("version", "-v"), excludeSelf: hasFlag("exclude-self") });
1041
1041
  } else if (sub === "daemon-restart") {
1042
- const { fleetDaemonRestart } = await import('./fleet-Cp-Ykxc6.mjs');
1042
+ const { fleetDaemonRestart } = await import('./fleet-BdWjugcV.mjs');
1043
1043
  await fleetDaemonRestart({ graceful: !hasFlag("cleanup") });
1044
1044
  } else if (sub === "push-skill") {
1045
1045
  const name = fleetArgs[1];
1046
- const { fleetPushSkill } = await import('./fleet-Cp-Ykxc6.mjs');
1046
+ const { fleetPushSkill } = await import('./fleet-BdWjugcV.mjs');
1047
1047
  await fleetPushSkill(name);
1048
1048
  } else {
1049
1049
  console.error(`Unknown fleet subcommand: ${sub}`);
@@ -1502,7 +1502,7 @@ async function applyClaudeAuthFlags(argv) {
1502
1502
  "--use-hypha-proxy, --use-claude-login, and --anthropic-base-url/--anthropic-api-key are mutually exclusive"
1503
1503
  );
1504
1504
  }
1505
- const mod = await import('./run-DDKJ85DU.mjs').then(function (n) { return n.t; });
1505
+ const mod = await import('./run-W8JZkXIf.mjs').then(function (n) { return n.t; });
1506
1506
  if (hasHypha) {
1507
1507
  mod.setClaudeAuthHyphaProxy();
1508
1508
  console.log("Claude auth configured: hypha-proxy (uses HYPHA_TOKEN live at each spawn).");
@@ -1540,7 +1540,7 @@ async function applyDaemonShareFlag(argv) {
1540
1540
  }
1541
1541
  }
1542
1542
  if (collected.length === 0) return;
1543
- const { updateEnvFile } = await import('./run-DDKJ85DU.mjs').then(function (n) { return n.t; });
1543
+ const { updateEnvFile } = await import('./run-W8JZkXIf.mjs').then(function (n) { return n.t; });
1544
1544
  const seen = /* @__PURE__ */ new Set();
1545
1545
  const deduped = collected.filter((e) => {
1546
1546
  const k = e.toLowerCase();
@@ -1553,7 +1553,7 @@ async function applyDaemonShareFlag(argv) {
1553
1553
  }
1554
1554
  async function handleDaemonAuthCommand(argv) {
1555
1555
  const sub = (argv[0] || "status").toLowerCase();
1556
- const mod = await import('./run-DDKJ85DU.mjs').then(function (n) { return n.t; });
1556
+ const mod = await import('./run-W8JZkXIf.mjs').then(function (n) { return n.t; });
1557
1557
  if (sub === "--help" || sub === "-h" || sub === "help") {
1558
1558
  console.log(`
1559
1559
  svamp daemon auth \u2014 Configure how Claude subprocesses authenticate
@@ -1,11 +1,11 @@
1
1
  import { writeFileSync, readFileSync } from 'fs';
2
2
  import { resolve } from 'path';
3
- import { connectAndGetMachine } from './commands-k2E3EJFY.mjs';
3
+ import { connectAndGetMachine } from './commands-C6lrExeN.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-DDKJ85DU.mjs';
8
+ import './run-W8JZkXIf.mjs';
9
9
  import 'os';
10
10
  import 'fs/promises';
11
11
  import 'url';
@@ -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 { 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-DDKJ85DU.mjs';
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-W8JZkXIf.mjs';
6
6
  import 'os';
7
7
  import 'fs/promises';
8
8
  import 'fs';
@@ -68,7 +68,7 @@ async function serviceExpose(args) {
68
68
  });
69
69
  return;
70
70
  }
71
- const { connectAndGetMachine } = await import('./commands-k2E3EJFY.mjs');
71
+ const { connectAndGetMachine } = await import('./commands-C6lrExeN.mjs');
72
72
  const { server, machine } = await connectAndGetMachine();
73
73
  try {
74
74
  const status = await machine.tunnelStart({
@@ -132,7 +132,7 @@ async function serviceServe(args) {
132
132
  }
133
133
  async function serviceList(_args) {
134
134
  try {
135
- const { connectAndGetMachine } = await import('./commands-k2E3EJFY.mjs');
135
+ const { connectAndGetMachine } = await import('./commands-C6lrExeN.mjs');
136
136
  const { server, machine } = await connectAndGetMachine();
137
137
  try {
138
138
  const tunnels = await machine.tunnelList({});
@@ -161,7 +161,7 @@ async function serviceDelete(args) {
161
161
  process.exit(1);
162
162
  }
163
163
  try {
164
- const { connectAndGetMachine } = await import('./commands-k2E3EJFY.mjs');
164
+ const { connectAndGetMachine } = await import('./commands-C6lrExeN.mjs');
165
165
  const { server, machine } = await connectAndGetMachine();
166
166
  try {
167
167
  await machine.tunnelStop({ name });
@@ -1,7 +1,7 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import os from 'node:os';
4
- import { c as connectToHypha } from './run-DDKJ85DU.mjs';
4
+ import { c as connectToHypha } from './run-W8JZkXIf.mjs';
5
5
  import { PINNED_CLAUDE_CODE_VERSION } from './pinnedClaudeCode-HydRNEt7.mjs';
6
6
  import 'os';
7
7
  import 'fs/promises';
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-DDKJ85DU.mjs';
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-W8JZkXIf.mjs';
2
2
  import 'os';
3
3
  import 'fs/promises';
4
4
  import 'fs';
@@ -1,5 +1,5 @@
1
1
  var name = "svamp-cli";
2
- var version = "0.2.78";
2
+ var version = "0.2.80";
3
3
  var description = "Svamp CLI — AI workspace daemon on Hypha Cloud";
4
4
  var author = "Amun AI AB";
5
5
  var license = "SEE LICENSE IN LICENSE";
@@ -2,7 +2,7 @@ import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(im
2
2
  import os from 'node:os';
3
3
  import { resolve, join } from 'node:path';
4
4
  import { existsSync, readFileSync, watch } from 'node:fs';
5
- import { c as connectToHypha, a as registerSessionService, k as generateHookSettings } from './run-DDKJ85DU.mjs';
5
+ import { c as connectToHypha, a as registerSessionService, k as generateHookSettings } from './run-W8JZkXIf.mjs';
6
6
  import { createServer } from 'node:http';
7
7
  import { spawn } from 'node:child_process';
8
8
  import { createInterface } from 'node:readline';
@@ -5836,12 +5836,62 @@ btn.addEventListener('click', async () => {
5836
5836
  }
5837
5837
  });
5838
5838
  <\/script>
5839
+ </body></html>`;
5840
+ }
5841
+ /**
5842
+ * Render an "access denied" page for a request that IS authenticated (valid
5843
+ * Hypha token) but whose email is not authorized for the mount — or for a
5844
+ * misconfigured owner mount with no resolvable owner. This is served as a
5845
+ * 403; it deliberately does NOT redirect to the login page, which would
5846
+ * loop forever and tell the user nothing about why they were rejected.
5847
+ */
5848
+ getAccessDeniedHtml(opts) {
5849
+ const { email, access, ownerEmail, misconfigured } = opts;
5850
+ const loginHref = `/__login__?return=${encodeURIComponent(opts.returnUrl || "/")}`;
5851
+ let requirement;
5852
+ if (misconfigured) {
5853
+ requirement = `This resource is set to <b>owner-only</b> access, but the server never resolved an owner email (the daemon authenticated with a token that has no email claim). No account can satisfy this \u2014 it is a server-side misconfiguration, not a problem with your account. Fix it by re-creating the mount with an explicit email allowlist, e.g. <code>access: ["${escapeHtml(email || "you@example.com")}"]</code>.`;
5854
+ } else if (access === "owner") {
5855
+ requirement = `This resource is restricted to its owner${ownerEmail ? ` (<code>${escapeHtml(ownerEmail)}</code>)` : ""}.`;
5856
+ } else if (Array.isArray(access)) {
5857
+ const list = access.map((e) => `<code>${escapeHtml(e)}</code>`).join(", ");
5858
+ requirement = `This resource is restricted to: ${list}.`;
5859
+ } else {
5860
+ requirement = "This resource is restricted.";
5861
+ }
5862
+ const signedInLine = email ? `You are signed in as <code>${escapeHtml(email)}</code>, which is not on the allow list.` : `You are not signed in.`;
5863
+ return `<!DOCTYPE html>
5864
+ <html><head>
5865
+ <meta charset="utf-8">
5866
+ <meta name="viewport" content="width=device-width,initial-scale=1">
5867
+ <title>Access denied \u2014 Svamp File Server</title>
5868
+ <style>
5869
+ *{box-sizing:border-box;margin:0;padding:0}
5870
+ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;background:#f6f8fa;color:#24292f;padding:16px}
5871
+ .card{background:#fff;border:1px solid #d0d7de;border-radius:12px;padding:32px;max-width:480px;width:100%;box-shadow:0 4px 12px rgba(31,35,40,0.06)}
5872
+ h1{font-size:1.25rem;margin-bottom:8px}
5873
+ .lead{color:#cf222e;font-weight:600;margin-bottom:16px}
5874
+ p{color:#3d444d;font-size:0.92rem;line-height:1.5;margin-bottom:14px}
5875
+ code{background:#f6f8fa;border:1px solid #d0d7de;border-radius:6px;padding:1px 6px;font-size:0.85em}
5876
+ a.btn{display:inline-block;background:#0969da;color:#fff;border-radius:8px;padding:10px 20px;font-weight:500;text-decoration:none;margin-top:4px}
5877
+ a.btn:hover{background:#0860c4}
5878
+ </style>
5879
+ </head><body>
5880
+ <div class="card">
5881
+ <h1>${misconfigured ? "\u26D4 Access not possible" : "\u26D4 Access denied"}</h1>
5882
+ <p class="lead">${signedInLine}</p>
5883
+ <p>${requirement}</p>
5884
+ ${misconfigured ? "" : `<a class="btn" href="${loginHref}">Sign in with a different account</a>`}
5885
+ </div>
5839
5886
  </body></html>`;
5840
5887
  }
5841
5888
  destroy() {
5842
5889
  this.cache.clear();
5843
5890
  }
5844
5891
  }
5892
+ function escapeHtml(s) {
5893
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
5894
+ }
5845
5895
 
5846
5896
  const DEFAULT_PROBE_INTERVAL_S = 10;
5847
5897
  const DEFAULT_PROBE_TIMEOUT_S = 5;
@@ -7926,7 +7976,7 @@ async function startDaemon(options) {
7926
7976
  const list = loadExposedTunnels().filter((t) => t.name !== name);
7927
7977
  saveExposedTunnels(list);
7928
7978
  }
7929
- const { ServeManager } = await import('./serveManager-Ba-VINC7.mjs');
7979
+ const { ServeManager } = await import('./serveManager-DTR_TDIp.mjs');
7930
7980
  const serveManager = new ServeManager(SVAMP_HOME, (msg) => logger.log(`[SERVE] ${msg}`), hyphaServerUrl);
7931
7981
  ensureAutoInstalledSkills(logger).catch(() => {
7932
7982
  });
@@ -8037,6 +8087,9 @@ async function startDaemon(options) {
8037
8087
  allowedBashLiterals.add(command);
8038
8088
  }
8039
8089
  }, shouldAutoAllow2 = function(toolName, toolInput) {
8090
+ if (toolName === "AskUserQuestion") {
8091
+ return sessionMetadata.ralphLoop?.active === true;
8092
+ }
8040
8093
  if (toolName === "Bash") {
8041
8094
  const inputObj = toolInput;
8042
8095
  if (inputObj?.command) {
@@ -8228,6 +8281,7 @@ async function startDaemon(options) {
8228
8281
  const allowedBashPrefixes = /* @__PURE__ */ new Set();
8229
8282
  const EDIT_TOOLS = /* @__PURE__ */ new Set(["Edit", "MultiEdit", "Write", "NotebookEdit"]);
8230
8283
  const pendingPermissions = /* @__PURE__ */ new Map();
8284
+ const permRequestIdToCorrelation = /* @__PURE__ */ new Map();
8231
8285
  let backgroundTaskCount = 0;
8232
8286
  let backgroundTaskNames = [];
8233
8287
  let userMessagePending = false;
@@ -8397,7 +8451,8 @@ async function startDaemon(options) {
8397
8451
  const requestId = msg.request_id;
8398
8452
  const toolName = msg.request.tool_name;
8399
8453
  const toolInput = msg.request.input;
8400
- logger.log(`[Session ${sessionId}] Permission request: ${requestId} tool=${toolName}`);
8454
+ const correlationId = msg.request.tool_use_id || requestId;
8455
+ logger.log(`[Session ${sessionId}] Permission request: ${requestId} (corr=${correlationId}) tool=${toolName}`);
8401
8456
  if (shouldAutoAllow2(toolName, toolInput)) {
8402
8457
  logger.log(`[Session ${sessionId}] Auto-allowing ${toolName} (mode=${currentPermissionMode})`);
8403
8458
  if (claudeProcess && !claudeProcess.killed && claudeProcess.stdin) {
@@ -8414,14 +8469,15 @@ async function startDaemon(options) {
8414
8469
  continue;
8415
8470
  }
8416
8471
  const permissionPromise = new Promise((resolve2) => {
8417
- pendingPermissions.set(requestId, { resolve: resolve2, toolName, input: toolInput });
8472
+ pendingPermissions.set(correlationId, { resolve: resolve2, toolName, input: toolInput, requestId });
8473
+ permRequestIdToCorrelation.set(requestId, correlationId);
8418
8474
  });
8419
8475
  const currentRequests = { ...sessionService._agentState?.requests };
8420
8476
  sessionService.updateAgentState({
8421
8477
  controlledByUser: false,
8422
8478
  requests: {
8423
8479
  ...currentRequests,
8424
- [requestId]: {
8480
+ [correlationId]: {
8425
8481
  tool: toolName,
8426
8482
  arguments: toolInput,
8427
8483
  createdAt: Date.now()
@@ -8429,11 +8485,13 @@ async function startDaemon(options) {
8429
8485
  }
8430
8486
  });
8431
8487
  permissionPromise.then((result) => {
8488
+ permRequestIdToCorrelation.delete(requestId);
8432
8489
  if (claudeProcess && !claudeProcess.killed && claudeProcess.stdin) {
8433
8490
  const controlResponse = JSON.stringify({
8434
8491
  type: "control_response",
8435
8492
  response: {
8436
8493
  subtype: "success",
8494
+ // Echo the ORIGINAL request_id — Claude correlates by it.
8437
8495
  request_id: requestId,
8438
8496
  response: result
8439
8497
  }
@@ -8442,13 +8500,13 @@ async function startDaemon(options) {
8442
8500
  claudeProcess.stdin.write(controlResponse + "\n");
8443
8501
  }
8444
8502
  const reqs = { ...sessionService._agentState?.requests };
8445
- delete reqs[requestId];
8503
+ delete reqs[correlationId];
8446
8504
  sessionService.updateAgentState({
8447
8505
  controlledByUser: false,
8448
8506
  requests: reqs,
8449
8507
  completedRequests: {
8450
8508
  ...sessionService._agentState?.completedRequests,
8451
- [requestId]: {
8509
+ [correlationId]: {
8452
8510
  tool: toolName,
8453
8511
  arguments: toolInput,
8454
8512
  completedAt: Date.now(),
@@ -8462,10 +8520,12 @@ async function startDaemon(options) {
8462
8520
  } else if (msg.type === "control_cancel_request") {
8463
8521
  const requestId = msg.request_id;
8464
8522
  logger.log(`[Session ${sessionId}] Permission cancel: ${requestId}`);
8465
- const pending = pendingPermissions.get(requestId);
8523
+ const corr = permRequestIdToCorrelation.get(requestId) || requestId;
8524
+ const pending = pendingPermissions.get(corr);
8466
8525
  if (pending) {
8467
8526
  pending.resolve({ behavior: "deny", message: "Cancelled" });
8468
- pendingPermissions.delete(requestId);
8527
+ pendingPermissions.delete(corr);
8528
+ permRequestIdToCorrelation.delete(requestId);
8469
8529
  }
8470
8530
  } else if (msg.type === "control_response") {
8471
8531
  logger.log(`[Session ${sessionId}] Control response: ${JSON.stringify(msg).slice(0, 200)}`);
@@ -9240,11 +9300,19 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
9240
9300
  }
9241
9301
  if (pending) {
9242
9302
  pendingPermissions.delete(requestId);
9303
+ permRequestIdToCorrelation.delete(pending.requestId);
9243
9304
  if (params.approved) {
9244
- pending.resolve({
9245
- behavior: "allow",
9246
- updatedInput: pending.input || {}
9247
- });
9305
+ let updatedInput = pending.input || {};
9306
+ if (pending.toolName === "AskUserQuestion" && (params.answers || params.response)) {
9307
+ updatedInput = { ...updatedInput };
9308
+ if (params.answers && typeof params.answers === "object") {
9309
+ updatedInput.answers = params.answers;
9310
+ }
9311
+ if (typeof params.response === "string" && params.response.trim()) {
9312
+ updatedInput.response = params.response;
9313
+ }
9314
+ }
9315
+ pending.resolve({ behavior: "allow", updatedInput });
9248
9316
  } else {
9249
9317
  pending.resolve({
9250
9318
  behavior: "deny",
@@ -54,7 +54,7 @@ async function handleServeCommand() {
54
54
  }
55
55
  }
56
56
  async function serveAdd(args, machineId) {
57
- const { connectAndGetMachine } = await import('./commands-k2E3EJFY.mjs');
57
+ const { connectAndGetMachine } = await import('./commands-C6lrExeN.mjs');
58
58
  const pos = positionalArgs(args);
59
59
  const name = pos[0];
60
60
  if (!name) {
@@ -93,7 +93,7 @@ async function serveAdd(args, machineId) {
93
93
  }
94
94
  }
95
95
  async function serveApply(args, machineId) {
96
- const { connectAndGetMachine } = await import('./commands-k2E3EJFY.mjs');
96
+ const { connectAndGetMachine } = await import('./commands-C6lrExeN.mjs');
97
97
  const fs = await import('fs');
98
98
  const yaml = await import('yaml');
99
99
  const file = positionalArgs(args)[0];
@@ -182,7 +182,7 @@ async function serveApply(args, machineId) {
182
182
  }
183
183
  }
184
184
  async function serveRemove(args, machineId) {
185
- const { connectAndGetMachine } = await import('./commands-k2E3EJFY.mjs');
185
+ const { connectAndGetMachine } = await import('./commands-C6lrExeN.mjs');
186
186
  const pos = positionalArgs(args);
187
187
  const name = pos[0];
188
188
  if (!name) {
@@ -202,7 +202,7 @@ async function serveRemove(args, machineId) {
202
202
  }
203
203
  }
204
204
  async function serveList(args, machineId) {
205
- const { connectAndGetMachine } = await import('./commands-k2E3EJFY.mjs');
205
+ const { connectAndGetMachine } = await import('./commands-C6lrExeN.mjs');
206
206
  const all = hasFlag(args, "--all", "-a");
207
207
  const json = hasFlag(args, "--json");
208
208
  const sessionId = getFlag(args, "--session");
@@ -235,7 +235,7 @@ async function serveList(args, machineId) {
235
235
  }
236
236
  }
237
237
  async function serveInfo(machineId) {
238
- const { connectAndGetMachine } = await import('./commands-k2E3EJFY.mjs');
238
+ const { connectAndGetMachine } = await import('./commands-C6lrExeN.mjs');
239
239
  const { machine, server } = await connectAndGetMachine(machineId);
240
240
  try {
241
241
  const info = await machine.serveInfo();
@@ -4,7 +4,7 @@ import * as fs from 'fs';
4
4
  import * as http from 'http';
5
5
  import * as net from 'net';
6
6
  import * as path from 'path';
7
- import { S as ServeAuth, h as hasCookieToken } from './run-DDKJ85DU.mjs';
7
+ import { S as ServeAuth, h as hasCookieToken } from './run-W8JZkXIf.mjs';
8
8
  import 'os';
9
9
  import 'fs/promises';
10
10
  import 'url';
@@ -128,6 +128,9 @@ class ServeManager {
128
128
  await this.removeMount(spec.name);
129
129
  }
130
130
  const access = spec.access ?? "link";
131
+ if (access === "owner" && !spec.ownerEmail) {
132
+ this.log(`\u26A0 Mount '${spec.name}': access='owner' but no owner email could be resolved \u2014 NO ONE will be able to sign in. Use an explicit email allowlist instead, e.g. access: ["you@example.com"].`);
133
+ }
131
134
  const mount = {
132
135
  name: spec.name,
133
136
  directory: resolvedDir,
@@ -542,17 +545,34 @@ class ServeManager {
542
545
  }
543
546
  if (mount && mount.access !== "public" && mount.access !== "link") {
544
547
  const userEmail = this.auth ? await this.auth.authenticate(req).catch(() => null) : null;
548
+ if (mount.access === "owner" && !mount.ownerEmail) {
549
+ this.log(`Auth DENY '${mountName}': owner-only mount but ownerEmail is empty (misconfigured \u2014 the daemon's token has no email claim). Set access to an explicit email allowlist. requester=${userEmail || "anonymous"}`);
550
+ const html = this.auth ? this.auth.getAccessDeniedHtml({ email: userEmail, access: mount.access, ownerEmail: mount.ownerEmail, misconfigured: true, returnUrl: req.url || "/" }) : "Access denied (misconfigured owner mount).";
551
+ res.writeHead(403, { "Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-store" });
552
+ res.end(html);
553
+ return;
554
+ }
545
555
  const allowed = this.auth ? this.auth.isAuthorized(userEmail, mount.access, mount.ownerEmail) : false;
546
556
  if (!allowed) {
547
- const loginUrl = `/__login__?return=${encodeURIComponent(req.url || "/")}`;
548
- const headers = { Location: loginUrl };
549
- if (hasCookieToken(req)) {
550
- headers["Set-Cookie"] = "svamp_serve_token=; Path=/; Max-Age=0; SameSite=Lax";
557
+ if (!userEmail) {
558
+ this.log(`Auth: '${mountName}' requires sign-in (no valid token) \u2014 redirecting to /__login__`);
559
+ const loginUrl = `/__login__?return=${encodeURIComponent(req.url || "/")}`;
560
+ const headers = { Location: loginUrl };
561
+ if (hasCookieToken(req)) {
562
+ headers["Set-Cookie"] = "svamp_serve_token=; Path=/; Max-Age=0; SameSite=Lax";
563
+ }
564
+ res.writeHead(302, headers);
565
+ res.end();
566
+ return;
551
567
  }
552
- res.writeHead(302, headers);
553
- res.end();
568
+ const need = mount.access === "owner" ? `owner (${mount.ownerEmail || "unset"})` : `one of [${mount.access.join(", ")}]`;
569
+ this.log(`Auth DENY '${mountName}': '${userEmail}' is not authorized (requires ${need})`);
570
+ const html = this.auth ? this.auth.getAccessDeniedHtml({ email: userEmail, access: mount.access, ownerEmail: mount.ownerEmail, returnUrl: req.url || "/" }) : `Access denied for ${userEmail}.`;
571
+ res.writeHead(403, { "Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-store" });
572
+ res.end(html);
554
573
  return;
555
574
  }
575
+ this.log(`Auth OK '${mountName}': ${userEmail}`);
556
576
  }
557
577
  if (req.method === "PUT" && mount && mount.directory) {
558
578
  const filePath = path.join(mount.directory, basePath);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svamp-cli",
3
- "version": "0.2.78",
3
+ "version": "0.2.80",
4
4
  "description": "Svamp CLI — AI workspace daemon on Hypha Cloud",
5
5
  "author": "Amun AI AB",
6
6
  "license": "SEE LICENSE IN LICENSE",