svamp-cli 0.2.89 → 0.2.90

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-DY1ciMPa.mjs');
151
+ const { connectAndGetMachine } = await import('./commands-mlxYf-v-.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-DY1ciMPa.mjs');
168
+ const { resolveSessionId } = await import('./commands-mlxYf-v-.mjs');
169
169
  const sessions = await machine.listSessions();
170
170
  const match = resolveSessionId(sessions, targetSessionId);
171
171
  const fullTargetId = match.sessionId;
@@ -1,4 +1,4 @@
1
- import { z as resolveModel } from './run-C4i9N-F6.mjs';
1
+ import { z as resolveModel } from './run-1BK4-WPo.mjs';
2
2
  import 'os';
3
3
  import 'fs/promises';
4
4
  import 'fs';
@@ -29,6 +29,10 @@ function buildWiseAgentEnvUpdates(action) {
29
29
  return { WISE_AGENT_PROVIDER: "hypha-proxy", ...action.url ? { SVAMP_HYPHA_PROXY_URL: action.url } : {} };
30
30
  case "use-claude-haiku":
31
31
  return { WISE_AGENT_PROVIDER: "claude-haiku", WISE_AGENT_MODEL: void 0, ...action.url ? { SVAMP_HYPHA_PROXY_URL: action.url } : {} };
32
+ case "set":
33
+ return { WISE_AGENT_PROVIDER: "openai", WISE_AGENT_BASE_URL: action.url, WISE_AGENT_API_KEY: action.key };
34
+ case "set-key":
35
+ return { WISE_AGENT_API_KEY: action.key };
32
36
  case "set-model":
33
37
  return { WISE_AGENT_MODEL: action.model };
34
38
  case "set-base-url":
@@ -59,6 +63,12 @@ function parseWiseAgentAuthArgs(args) {
59
63
  return { kind: "use-hypha-proxy", url: rest[0] };
60
64
  case "use-claude-haiku":
61
65
  return { kind: "use-claude-haiku", url: rest[0] };
66
+ case "set":
67
+ if (!rest[0] || !rest[1]) throw new Error("Usage: svamp wise-agent auth set <BASE_URL> <KEY>");
68
+ return { kind: "set", url: rest[0], key: rest[1] };
69
+ case "set-key":
70
+ if (!rest[0]) throw new Error("Usage: svamp wise-agent auth set-key <KEY>");
71
+ return { kind: "set-key", key: rest[0] };
62
72
  case "set-model":
63
73
  if (!rest[0]) throw new Error("Usage: svamp wise-agent auth set-model <model>");
64
74
  return { kind: "set-model", model: rest[0] };
@@ -66,7 +76,7 @@ function parseWiseAgentAuthArgs(args) {
66
76
  if (!rest[0]) throw new Error("Usage: svamp wise-agent auth set-base-url <url>");
67
77
  return { kind: "set-base-url", url: rest[0] };
68
78
  default:
69
- throw new Error(`Unknown wise-agent auth command "${sub}". Try: status | use-openai [KEY] | use-hypha-proxy [URL] | use-claude-haiku [URL] | set-model <m> | set-base-url <url>`);
79
+ throw new Error(`Unknown wise-agent auth command "${sub}". Try: status | use-openai [KEY] | use-hypha-proxy [URL] | use-claude-haiku [URL] | set <URL> <KEY> | set-key <KEY> | set-model <m> | set-base-url <url>`);
70
80
  }
71
81
  }
72
82
 
package/dist/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { e as clearStopMarker, f as stopMarkerExists, s as startDaemon, b as stopDaemon, d as daemonStatus } from './run-C4i9N-F6.mjs';
1
+ import { e as clearStopMarker, f as stopMarkerExists, s as startDaemon, b as stopDaemon, d as daemonStatus } from './run-1BK4-WPo.mjs';
2
2
  import { ensureSupervisorViaServiceManager, LAUNCHD_LABEL } from './serviceManager-hlOVxkhW.mjs';
3
3
  import 'os';
4
4
  import 'fs/promises';
@@ -34,7 +34,7 @@ const subcommand = args[0];
34
34
  let daemonSubcommand = args[1];
35
35
  async function main() {
36
36
  try {
37
- const { getLoadedConfig } = await import('./run-C4i9N-F6.mjs').then(function (n) { return n.O; });
37
+ const { getLoadedConfig } = await import('./run-1BK4-WPo.mjs').then(function (n) { return n.O; });
38
38
  getLoadedConfig();
39
39
  } catch {
40
40
  }
@@ -51,7 +51,7 @@ async function main() {
51
51
  console.error(`svamp daemon restart: ${err.message || err}`);
52
52
  process.exit(1);
53
53
  }
54
- const { restartDaemon } = await import('./run-C4i9N-F6.mjs').then(function (n) { return n.Q; });
54
+ const { restartDaemon } = await import('./run-1BK4-WPo.mjs').then(function (n) { return n.Q; });
55
55
  await restartDaemon();
56
56
  process.exit(0);
57
57
  }
@@ -344,7 +344,7 @@ async function main() {
344
344
  console.error("svamp service: Service commands are not available in sandboxed sessions.");
345
345
  process.exit(1);
346
346
  }
347
- const { handleServiceCommand } = await import('./commands-25hlQVK5.mjs');
347
+ const { handleServiceCommand } = await import('./commands-C-5cSioE.mjs');
348
348
  await handleServiceCommand();
349
349
  } else if (subcommand === "serve") {
350
350
  const { isSandboxed: isSandboxedServe } = await import('./sandboxDetect-DNTcbgWD.mjs');
@@ -352,7 +352,7 @@ async function main() {
352
352
  console.error("svamp serve: Serve commands are not available in sandboxed sessions.");
353
353
  process.exit(1);
354
354
  }
355
- const { handleServeCommand } = await import('./serveCommands-B2brwRfz.mjs');
355
+ const { handleServeCommand } = await import('./serveCommands-BXn2hnJ0.mjs');
356
356
  await handleServeCommand();
357
357
  process.exit(0);
358
358
  } else if (subcommand === "process" || subcommand === "proc") {
@@ -361,7 +361,7 @@ async function main() {
361
361
  console.error("svamp process: Process commands are not available in sandboxed sessions.");
362
362
  process.exit(1);
363
363
  }
364
- const { processCommand } = await import('./commands-CVPCcCqU.mjs');
364
+ const { processCommand } = await import('./commands-XrfOgVzR.mjs');
365
365
  let machineId;
366
366
  const processArgs = args.slice(1);
367
367
  const mIdx = processArgs.findIndex((a) => a === "--machine" || a === "-m");
@@ -375,7 +375,7 @@ async function main() {
375
375
  }), machineId);
376
376
  process.exit(0);
377
377
  } else if (subcommand === "routine" || subcommand === "routines") {
378
- const { routineCommand } = await import('./commands-CA-A0G2y.mjs');
378
+ const { routineCommand } = await import('./commands-sQMe36dC.mjs');
379
379
  await routineCommand(args.slice(1));
380
380
  process.exit(0);
381
381
  } else if (subcommand === "wise-agent" || subcommand === "wise") {
@@ -386,7 +386,7 @@ async function main() {
386
386
  } else if (!subcommand || subcommand === "start") {
387
387
  await handleInteractiveCommand();
388
388
  } else if (subcommand === "--version" || subcommand === "-v") {
389
- const pkg = await import('./package-jHkQchZL.mjs').catch(() => ({ default: { version: "unknown" } }));
389
+ const pkg = await import('./package-DR--K5aO.mjs').catch(() => ({ default: { version: "unknown" } }));
390
390
  console.log(`svamp version: ${pkg.default.version}`);
391
391
  } else {
392
392
  console.error(`Unknown command: ${subcommand}`);
@@ -395,7 +395,7 @@ async function main() {
395
395
  }
396
396
  }
397
397
  async function handleInteractiveCommand() {
398
- const { runInteractive } = await import('./run-DLtX5Yom.mjs');
398
+ const { runInteractive } = await import('./run-DrC7KnK3.mjs');
399
399
  const interactiveArgs = subcommand === "start" ? args.slice(1) : args;
400
400
  let directory = process.cwd();
401
401
  let resumeSessionId;
@@ -440,7 +440,7 @@ async function handleAgentCommand() {
440
440
  return;
441
441
  }
442
442
  if (agentArgs[0] === "list") {
443
- const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-C4i9N-F6.mjs').then(function (n) { return n.K; });
443
+ const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-1BK4-WPo.mjs').then(function (n) { return n.K; });
444
444
  console.log("Known agents:");
445
445
  for (const [name, config2] of Object.entries(KNOWN_ACP_AGENTS)) {
446
446
  console.log(` ${name.padEnd(12)} ${config2.command} ${config2.args.join(" ")} (ACP)`);
@@ -452,7 +452,7 @@ async function handleAgentCommand() {
452
452
  console.log('Use "svamp agent -- <command> [args]" for a custom ACP agent.');
453
453
  return;
454
454
  }
455
- const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-C4i9N-F6.mjs').then(function (n) { return n.K; });
455
+ const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-1BK4-WPo.mjs').then(function (n) { return n.K; });
456
456
  let cwd = process.cwd();
457
457
  const filteredArgs = [];
458
458
  for (let i = 0; i < agentArgs.length; i++) {
@@ -476,12 +476,12 @@ async function handleAgentCommand() {
476
476
  console.log(`Starting ${config.agentName} agent in ${cwd}...`);
477
477
  let backend;
478
478
  if (KNOWN_MCP_AGENTS[config.agentName]) {
479
- const { CodexMcpBackend } = await import('./run-C4i9N-F6.mjs').then(function (n) { return n.L; });
479
+ const { CodexMcpBackend } = await import('./run-1BK4-WPo.mjs').then(function (n) { return n.L; });
480
480
  backend = new CodexMcpBackend({ cwd, log: logFn });
481
481
  } else {
482
- const { AcpBackend } = await import('./run-C4i9N-F6.mjs').then(function (n) { return n.J; });
483
- const { GeminiTransport } = await import('./run-C4i9N-F6.mjs').then(function (n) { return n.M; });
484
- const { DefaultTransport } = await import('./run-C4i9N-F6.mjs').then(function (n) { return n.I; });
482
+ const { AcpBackend } = await import('./run-1BK4-WPo.mjs').then(function (n) { return n.J; });
483
+ const { GeminiTransport } = await import('./run-1BK4-WPo.mjs').then(function (n) { return n.M; });
484
+ const { DefaultTransport } = await import('./run-1BK4-WPo.mjs').then(function (n) { return n.I; });
485
485
  const transportHandler = config.agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(config.agentName);
486
486
  backend = new AcpBackend({
487
487
  agentName: config.agentName,
@@ -608,7 +608,7 @@ async function handleSessionCommand() {
608
608
  process.exit(1);
609
609
  }
610
610
  }
611
- const { sessionList, sessionWhoami, sessionSpawn, sessionArchive, sessionResume, sessionDelete, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-DY1ciMPa.mjs');
611
+ const { sessionList, sessionWhoami, sessionSpawn, sessionArchive, sessionResume, sessionDelete, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-mlxYf-v-.mjs');
612
612
  const parseFlagStr = (flag, shortFlag) => {
613
613
  for (let i = 1; i < sessionArgs.length; i++) {
614
614
  if ((sessionArgs[i] === flag || shortFlag) && i + 1 < sessionArgs.length) {
@@ -676,7 +676,7 @@ async function handleSessionCommand() {
676
676
  allowDomain.push(sessionArgs[++i]);
677
677
  }
678
678
  }
679
- const { parseShareArg } = await import('./commands-DY1ciMPa.mjs');
679
+ const { parseShareArg } = await import('./commands-mlxYf-v-.mjs');
680
680
  const shareEntries = share.map((s) => parseShareArg(s));
681
681
  await sessionSpawn(agent, dir, targetMachineId, {
682
682
  message,
@@ -763,7 +763,7 @@ async function handleSessionCommand() {
763
763
  console.error(" Spawns a stateless Claude session in <directory>, sends <prompt>, prints the answer, then deletes the session.");
764
764
  process.exit(1);
765
765
  }
766
- const { sessionQuery } = await import('./commands-DY1ciMPa.mjs');
766
+ const { sessionQuery } = await import('./commands-mlxYf-v-.mjs');
767
767
  await sessionQuery(dir, prompt, targetMachineId, {
768
768
  timeout: parseFlagInt("--timeout"),
769
769
  json: hasFlag("--json"),
@@ -796,7 +796,7 @@ async function handleSessionCommand() {
796
796
  console.error("Usage: svamp session approve <session-id> [request-id] [--json]");
797
797
  process.exit(1);
798
798
  }
799
- const { sessionApprove } = await import('./commands-DY1ciMPa.mjs');
799
+ const { sessionApprove } = await import('./commands-mlxYf-v-.mjs');
800
800
  const approveReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
801
801
  await sessionApprove(sessionArgs[1], approveReqId, targetMachineId, {
802
802
  json: hasFlag("--json")
@@ -806,7 +806,7 @@ async function handleSessionCommand() {
806
806
  console.error("Usage: svamp session deny <session-id> [request-id] [--json]");
807
807
  process.exit(1);
808
808
  }
809
- const { sessionDeny } = await import('./commands-DY1ciMPa.mjs');
809
+ const { sessionDeny } = await import('./commands-mlxYf-v-.mjs');
810
810
  const denyReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
811
811
  await sessionDeny(sessionArgs[1], denyReqId, targetMachineId, {
812
812
  json: hasFlag("--json")
@@ -842,7 +842,7 @@ async function handleSessionCommand() {
842
842
  console.error("Usage: svamp session set-title <title>");
843
843
  process.exit(1);
844
844
  }
845
- const { sessionSetTitle } = await import('./agentCommands-7zzJYIzN.mjs');
845
+ const { sessionSetTitle } = await import('./agentCommands-BjhBmutV.mjs');
846
846
  await sessionSetTitle(title);
847
847
  } else if (sessionSubcommand === "set-link") {
848
848
  const url = sessionArgs[1];
@@ -851,7 +851,7 @@ async function handleSessionCommand() {
851
851
  process.exit(1);
852
852
  }
853
853
  const label = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
854
- const { sessionSetLink } = await import('./agentCommands-7zzJYIzN.mjs');
854
+ const { sessionSetLink } = await import('./agentCommands-BjhBmutV.mjs');
855
855
  await sessionSetLink(url, label);
856
856
  } else if (sessionSubcommand === "notify") {
857
857
  const message = sessionArgs[1];
@@ -860,7 +860,7 @@ async function handleSessionCommand() {
860
860
  process.exit(1);
861
861
  }
862
862
  const level = parseFlagStr("--level") || "info";
863
- const { sessionNotify } = await import('./agentCommands-7zzJYIzN.mjs');
863
+ const { sessionNotify } = await import('./agentCommands-BjhBmutV.mjs');
864
864
  await sessionNotify(message, level);
865
865
  } else if (sessionSubcommand === "broadcast") {
866
866
  const action = sessionArgs[1];
@@ -868,7 +868,7 @@ async function handleSessionCommand() {
868
868
  console.error("Usage: svamp session broadcast <action> [args...]\nActions: open-canvas <url> [label], close-canvas, toast <message>");
869
869
  process.exit(1);
870
870
  }
871
- const { sessionBroadcast } = await import('./agentCommands-7zzJYIzN.mjs');
871
+ const { sessionBroadcast } = await import('./agentCommands-BjhBmutV.mjs');
872
872
  await sessionBroadcast(action, sessionArgs.slice(2).filter((a) => !a.startsWith("--")));
873
873
  } else if (sessionSubcommand === "inbox") {
874
874
  const inboxSubcmd = sessionArgs[1];
@@ -879,7 +879,7 @@ async function handleSessionCommand() {
879
879
  process.exit(1);
880
880
  }
881
881
  if (agentSessionId) {
882
- const { inboxSend } = await import('./agentCommands-7zzJYIzN.mjs');
882
+ const { inboxSend } = await import('./agentCommands-BjhBmutV.mjs');
883
883
  await inboxSend(sessionArgs[2], {
884
884
  body: sessionArgs[3],
885
885
  subject: parseFlagStr("--subject"),
@@ -894,7 +894,7 @@ async function handleSessionCommand() {
894
894
  }
895
895
  } else if (inboxSubcmd === "list" || inboxSubcmd === "ls") {
896
896
  if (agentSessionId && !sessionArgs[2]) {
897
- const { inboxList } = await import('./agentCommands-7zzJYIzN.mjs');
897
+ const { inboxList } = await import('./agentCommands-BjhBmutV.mjs');
898
898
  await inboxList({
899
899
  unread: hasFlag("--unread"),
900
900
  limit: parseFlagInt("--limit"),
@@ -916,7 +916,7 @@ async function handleSessionCommand() {
916
916
  process.exit(1);
917
917
  }
918
918
  if (agentSessionId && !sessionArgs[3]) {
919
- const { inboxList } = await import('./agentCommands-7zzJYIzN.mjs');
919
+ const { inboxList } = await import('./agentCommands-BjhBmutV.mjs');
920
920
  await sessionInboxRead(agentSessionId, sessionArgs[2], targetMachineId);
921
921
  } else if (sessionArgs[3]) {
922
922
  await sessionInboxRead(sessionArgs[2], sessionArgs[3], targetMachineId);
@@ -926,7 +926,7 @@ async function handleSessionCommand() {
926
926
  }
927
927
  } else if (inboxSubcmd === "reply") {
928
928
  if (agentSessionId && sessionArgs[2] && sessionArgs[3] && !sessionArgs[4]) {
929
- const { inboxReply } = await import('./agentCommands-7zzJYIzN.mjs');
929
+ const { inboxReply } = await import('./agentCommands-BjhBmutV.mjs');
930
930
  await inboxReply(sessionArgs[2], sessionArgs[3]);
931
931
  } else if (sessionArgs[2] && sessionArgs[3] && sessionArgs[4]) {
932
932
  await sessionInboxReply(sessionArgs[2], sessionArgs[3], sessionArgs[4], targetMachineId);
@@ -962,7 +962,7 @@ async function handleMachineCommand() {
962
962
  return;
963
963
  }
964
964
  if (machineSubcommand === "share") {
965
- const { machineShare } = await import('./commands-DY1ciMPa.mjs');
965
+ const { machineShare } = await import('./commands-mlxYf-v-.mjs');
966
966
  let machineId;
967
967
  const shareArgs = [];
968
968
  for (let i = 1; i < machineArgs.length; i++) {
@@ -992,7 +992,7 @@ async function handleMachineCommand() {
992
992
  }
993
993
  await machineShare(machineId, { add, remove, list, configPath, showConfig });
994
994
  } else if (machineSubcommand === "exec") {
995
- const { machineExec } = await import('./commands-DY1ciMPa.mjs');
995
+ const { machineExec } = await import('./commands-mlxYf-v-.mjs');
996
996
  let machineId;
997
997
  let cwd;
998
998
  const cmdParts = [];
@@ -1012,7 +1012,7 @@ async function handleMachineCommand() {
1012
1012
  }
1013
1013
  await machineExec(machineId, command, cwd);
1014
1014
  } else if (machineSubcommand === "info") {
1015
- const { machineInfo } = await import('./commands-DY1ciMPa.mjs');
1015
+ const { machineInfo } = await import('./commands-mlxYf-v-.mjs');
1016
1016
  let machineId;
1017
1017
  for (let i = 1; i < machineArgs.length; i++) {
1018
1018
  if ((machineArgs[i] === "--machine" || machineArgs[i] === "-m") && i + 1 < machineArgs.length) {
@@ -1032,10 +1032,10 @@ async function handleMachineCommand() {
1032
1032
  level = machineArgs[++i];
1033
1033
  }
1034
1034
  }
1035
- const { machineNotify } = await import('./agentCommands-7zzJYIzN.mjs');
1035
+ const { machineNotify } = await import('./agentCommands-BjhBmutV.mjs');
1036
1036
  await machineNotify(message, level);
1037
1037
  } else if (machineSubcommand === "ls") {
1038
- const { machineLs } = await import('./commands-DY1ciMPa.mjs');
1038
+ const { machineLs } = await import('./commands-mlxYf-v-.mjs');
1039
1039
  let machineId;
1040
1040
  let showHidden = false;
1041
1041
  let path;
@@ -1093,24 +1093,24 @@ Examples:
1093
1093
  };
1094
1094
  const hasFlag = (name) => fleetArgs.includes(`--${name}`);
1095
1095
  if (sub === "status") {
1096
- const { fleetStatus } = await import('./fleet-B_HW0j1E.mjs');
1096
+ const { fleetStatus } = await import('./fleet-Dts-Z6LV.mjs');
1097
1097
  await fleetStatus();
1098
1098
  } else if (sub === "exec") {
1099
1099
  const command = fleetArgs.slice(1).filter((a) => !a.startsWith("--")).join(" ");
1100
- const { fleetExec } = await import('./fleet-B_HW0j1E.mjs');
1100
+ const { fleetExec } = await import('./fleet-Dts-Z6LV.mjs');
1101
1101
  await fleetExec(command, { cwd: flag("cwd") });
1102
1102
  } else if (sub === "upgrade-claude") {
1103
- const { fleetUpgradeClaude } = await import('./fleet-B_HW0j1E.mjs');
1103
+ const { fleetUpgradeClaude } = await import('./fleet-Dts-Z6LV.mjs');
1104
1104
  await fleetUpgradeClaude({ version: flag("version", "-v") });
1105
1105
  } else if (sub === "upgrade-svamp") {
1106
- const { fleetUpgradeSvamp } = await import('./fleet-B_HW0j1E.mjs');
1106
+ const { fleetUpgradeSvamp } = await import('./fleet-Dts-Z6LV.mjs');
1107
1107
  await fleetUpgradeSvamp({ version: flag("version", "-v"), excludeSelf: hasFlag("exclude-self") });
1108
1108
  } else if (sub === "daemon-restart") {
1109
- const { fleetDaemonRestart } = await import('./fleet-B_HW0j1E.mjs');
1109
+ const { fleetDaemonRestart } = await import('./fleet-Dts-Z6LV.mjs');
1110
1110
  await fleetDaemonRestart({ graceful: !hasFlag("cleanup") });
1111
1111
  } else if (sub === "push-skill") {
1112
1112
  const name = fleetArgs[1];
1113
- const { fleetPushSkill } = await import('./fleet-B_HW0j1E.mjs');
1113
+ const { fleetPushSkill } = await import('./fleet-Dts-Z6LV.mjs');
1114
1114
  await fleetPushSkill(name);
1115
1115
  } else {
1116
1116
  console.error(`Unknown fleet subcommand: ${sub}`);
@@ -1126,7 +1126,7 @@ async function handleSkillsCommand() {
1126
1126
  await printSkillsHelp();
1127
1127
  return;
1128
1128
  }
1129
- const { skillsFind, skillsInstall, skillsList, skillsRemove, skillsPublish } = await import('./commands-BIsNPVCT.mjs');
1129
+ const { skillsFind, skillsInstall, skillsList, skillsRemove, skillsPublish } = await import('./commands-Bg7NZ6PK.mjs');
1130
1130
  if (skillsSubcommand === "find" || skillsSubcommand === "search") {
1131
1131
  const query = skillsArgs.slice(1).filter((a) => !a.startsWith("--")).join(" ");
1132
1132
  if (!query) {
@@ -1173,7 +1173,7 @@ async function loginToHypha() {
1173
1173
  process.exit(1);
1174
1174
  }
1175
1175
  const anchor = anchorArg.replace(/\/+$/, "");
1176
- const { loadInstanceConfig } = await import('./run-C4i9N-F6.mjs').then(function (n) { return n.O; });
1176
+ const { loadInstanceConfig } = await import('./run-1BK4-WPo.mjs').then(function (n) { return n.O; });
1177
1177
  let cfg = null;
1178
1178
  try {
1179
1179
  cfg = await loadInstanceConfig({ anchor, force: true });
@@ -1284,7 +1284,7 @@ async function logoutFromHypha() {
1284
1284
  } catch {
1285
1285
  }
1286
1286
  try {
1287
- const { clearInstanceConfigCache } = await import('./run-C4i9N-F6.mjs').then(function (n) { return n.O; });
1287
+ const { clearInstanceConfigCache } = await import('./run-1BK4-WPo.mjs').then(function (n) { return n.O; });
1288
1288
  clearInstanceConfigCache();
1289
1289
  } catch {
1290
1290
  }
@@ -1615,7 +1615,7 @@ async function applyClaudeAuthFlags(argv) {
1615
1615
  "--use-hypha-proxy, --use-claude-login, and --anthropic-base-url/--anthropic-api-key are mutually exclusive"
1616
1616
  );
1617
1617
  }
1618
- const mod = await import('./run-C4i9N-F6.mjs').then(function (n) { return n.N; });
1618
+ const mod = await import('./run-1BK4-WPo.mjs').then(function (n) { return n.N; });
1619
1619
  if (hasHypha) {
1620
1620
  let url;
1621
1621
  const hyphaIdx = argv.indexOf("--use-hypha-proxy");
@@ -1669,7 +1669,7 @@ async function applyDaemonShareFlag(argv) {
1669
1669
  }
1670
1670
  }
1671
1671
  if (collected.length === 0) return;
1672
- const { updateEnvFile } = await import('./run-C4i9N-F6.mjs').then(function (n) { return n.N; });
1672
+ const { updateEnvFile } = await import('./run-1BK4-WPo.mjs').then(function (n) { return n.N; });
1673
1673
  const seen = /* @__PURE__ */ new Set();
1674
1674
  const deduped = collected.filter((e) => {
1675
1675
  const k = e.toLowerCase();
@@ -1691,10 +1691,17 @@ Configure the server-side WISE Agent's fast model (text companion to the deep ag
1691
1691
  use-openai [KEY] Route via OpenAI (default provider). Optional API key.
1692
1692
  use-hypha-proxy [URL] Route via the Hypha LLM proxy (quota-governed).
1693
1693
  use-claude-haiku [URL] Fallback: Claude Haiku via the proxy (no OpenAI key).
1694
+ set <BASE_URL> <KEY> Custom OpenAI-compatible gateway: base URL + key together.
1695
+ set-key <KEY> Set just the API key.
1694
1696
  set-model <model> Override the model id (e.g. gpt-5-mini).
1695
1697
  set-base-url <url> Override the OpenAI-compatible base URL.
1696
1698
 
1697
- Persisted to ~/.svamp/.env. Run \`svamp daemon restart\` afterwards to apply.`);
1699
+ Env equivalents (read from ~/.svamp/.env or the daemon's environment):
1700
+ OPENAI_API_KEY / WISE_AGENT_API_KEY \xB7 OPENAI_BASE_URL / WISE_AGENT_BASE_URL
1701
+ WISE_AGENT_PROVIDER \xB7 WISE_AGENT_MODEL \xB7 SVAMP_HYPHA_PROXY_URL \xB7 HYPHA_TOKEN
1702
+
1703
+ Persisted to ~/.svamp/.env. Run \`svamp daemon restart\` afterwards to apply.
1704
+ If none is set, hitting a WISE Agent channel returns a clear "not configured" error.`);
1698
1705
  return;
1699
1706
  }
1700
1707
  if (rest[0] && rest[0] !== "auth") {
@@ -1703,7 +1710,7 @@ Persisted to ~/.svamp/.env. Run \`svamp daemon restart\` afterwards to apply.`);
1703
1710
  return;
1704
1711
  }
1705
1712
  const authArgs = rest.slice(1);
1706
- const mod = await import('./auth-BRm_dfqc.mjs');
1713
+ const mod = await import('./auth-LB4hwDfW.mjs');
1707
1714
  let action;
1708
1715
  try {
1709
1716
  action = mod.parseWiseAgentAuthArgs(authArgs);
@@ -1713,7 +1720,7 @@ Persisted to ~/.svamp/.env. Run \`svamp daemon restart\` afterwards to apply.`);
1713
1720
  return;
1714
1721
  }
1715
1722
  if (action) {
1716
- const { updateEnvFile } = await import('./run-C4i9N-F6.mjs').then(function (n) { return n.N; });
1723
+ const { updateEnvFile } = await import('./run-1BK4-WPo.mjs').then(function (n) { return n.N; });
1717
1724
  const updates = mod.buildWiseAgentEnvUpdates(action);
1718
1725
  updateEnvFile(updates);
1719
1726
  for (const [k, v] of Object.entries(updates)) {
@@ -1727,7 +1734,7 @@ Persisted to ~/.svamp/.env. Run \`svamp daemon restart\` afterwards to apply.`);
1727
1734
  }
1728
1735
  async function handleDaemonAuthCommand(argv) {
1729
1736
  const sub = (argv[0] || "status").toLowerCase();
1730
- const mod = await import('./run-C4i9N-F6.mjs').then(function (n) { return n.N; });
1737
+ const mod = await import('./run-1BK4-WPo.mjs').then(function (n) { return n.N; });
1731
1738
  if (sub === "--help" || sub === "-h" || sub === "help") {
1732
1739
  console.log(`
1733
1740
  svamp daemon auth \u2014 Configure how Claude subprocesses authenticate
@@ -2024,7 +2031,7 @@ Examples:
2024
2031
  async function printSkillsHelp() {
2025
2032
  let browseUrl = "<HYPHA_SERVER_URL>/<workspace>/artifacts/marketplace (set HYPHA_SERVER_URL)";
2026
2033
  try {
2027
- const { getArtifactBaseUrl, getSkillsCollectionName } = await import('./run-C4i9N-F6.mjs').then(function (n) { return n.P; });
2034
+ const { getArtifactBaseUrl, getSkillsCollectionName } = await import('./run-1BK4-WPo.mjs').then(function (n) { return n.P; });
2028
2035
  browseUrl = `${getArtifactBaseUrl()}/${getSkillsCollectionName()}`;
2029
2036
  } catch {
2030
2037
  }
@@ -1,7 +1,7 @@
1
1
  import os from 'os';
2
2
  import fs__default from 'fs';
3
3
  import { resolve, join, relative } from 'path';
4
- import { p as parseFrontmatter, n as getSkillsServer, o as getSkillsWorkspaceName, q as getSkillsCollectionName, t as fetchWithTimeout, u as searchSkills, v as SKILLS_DIR, w as getSkillInfo, x as downloadSkillFile, y as listSkillFiles } from './run-C4i9N-F6.mjs';
4
+ import { p as parseFrontmatter, n as getSkillsServer, o as getSkillsWorkspaceName, q as getSkillsCollectionName, t as fetchWithTimeout, u as searchSkills, v as SKILLS_DIR, w as getSkillInfo, x as downloadSkillFile, y as listSkillFiles } from './run-1BK4-WPo.mjs';
5
5
  import 'fs/promises';
6
6
  import 'url';
7
7
  import 'child_process';
@@ -58,7 +58,7 @@ async function serviceExpose(args) {
58
58
  process.exit(1);
59
59
  }
60
60
  if (foreground) {
61
- const { runFrpcTunnel } = await import('./frpc-BiazjxzU.mjs');
61
+ const { runFrpcTunnel } = await import('./frpc-DTA0--Z7.mjs');
62
62
  await runFrpcTunnel(name, ports, void 0, {
63
63
  group,
64
64
  groupKey,
@@ -68,7 +68,7 @@ async function serviceExpose(args) {
68
68
  });
69
69
  return;
70
70
  }
71
- const { connectAndGetMachine } = await import('./commands-DY1ciMPa.mjs');
71
+ const { connectAndGetMachine } = await import('./commands-mlxYf-v-.mjs');
72
72
  const { server, machine } = await connectAndGetMachine();
73
73
  try {
74
74
  const status = await machine.tunnelStart({
@@ -123,7 +123,7 @@ async function serviceServe(args) {
123
123
  };
124
124
  process.on("SIGINT", cleanup);
125
125
  process.on("SIGTERM", cleanup);
126
- const { runFrpcTunnel } = await import('./frpc-BiazjxzU.mjs');
126
+ const { runFrpcTunnel } = await import('./frpc-DTA0--Z7.mjs');
127
127
  await runFrpcTunnel(name, [caddyPort]);
128
128
  } catch (err) {
129
129
  console.error(`Error serving directory: ${err.message}`);
@@ -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-DY1ciMPa.mjs');
135
+ const { connectAndGetMachine } = await import('./commands-mlxYf-v-.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-DY1ciMPa.mjs');
164
+ const { connectAndGetMachine } = await import('./commands-mlxYf-v-.mjs');
165
165
  const { server, machine } = await connectAndGetMachine();
166
166
  try {
167
167
  await machine.tunnelStop({ name });
@@ -1,11 +1,11 @@
1
1
  import { writeFileSync, readFileSync } from 'fs';
2
2
  import { resolve } from 'path';
3
- import { connectAndGetMachine } from './commands-DY1ciMPa.mjs';
3
+ import { connectAndGetMachine } from './commands-mlxYf-v-.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-C4i9N-F6.mjs';
8
+ import './run-1BK4-WPo.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 { basename, resolve, join } from 'node:path';
4
4
  import os from 'node:os';
5
- import { A as normalizeAllowedUser, B as loadSecurityContextConfig, C as resolveSecurityContext, D as buildSecurityContextFromFlags, E as mergeSecurityContexts, c as connectToHypha, F as buildSessionShareUrl, G as buildMachineShareUrl } from './run-C4i9N-F6.mjs';
5
+ import { A as normalizeAllowedUser, B as loadSecurityContextConfig, C as resolveSecurityContext, D as buildSecurityContextFromFlags, E as mergeSecurityContexts, c as connectToHypha, F as buildSessionShareUrl, G as buildMachineShareUrl } from './run-1BK4-WPo.mjs';
6
6
  import 'os';
7
7
  import 'fs/promises';
8
8
  import 'fs';
@@ -1,6 +1,6 @@
1
1
  import { execFileSync } from 'node:child_process';
2
2
  import { createServer } from 'node:http';
3
- import { R as RoutineStore, m as RoutineRunner } from './run-C4i9N-F6.mjs';
3
+ import { R as RoutineStore, m as RoutineRunner } from './run-1BK4-WPo.mjs';
4
4
  import 'os';
5
5
  import 'fs/promises';
6
6
  import 'fs';
@@ -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-C4i9N-F6.mjs';
4
+ import { c as connectToHypha } from './run-1BK4-WPo.mjs';
5
5
  import { PINNED_CLAUDE_CODE_VERSION } from './pinnedClaudeCode-HydRNEt7.mjs';
6
6
  import 'os';
7
7
  import 'fs/promises';
@@ -3,7 +3,7 @@ import { mkdirSync, writeFileSync, unlinkSync, existsSync, chmodSync, readFileSy
3
3
  import { join } from 'path';
4
4
  import { homedir, platform, arch } from 'os';
5
5
  import { createHash, randomUUID } from 'crypto';
6
- import { h as getFrpsSubdomainHost, i as getFrpsServerPort, j as getFrpsServerAddr } from './run-C4i9N-F6.mjs';
6
+ import { h as getFrpsSubdomainHost, i as getFrpsServerPort, j as getFrpsServerAddr } from './run-1BK4-WPo.mjs';
7
7
  import 'fs/promises';
8
8
  import 'url';
9
9
  import 'node:fs';
@@ -0,0 +1,101 @@
1
+ import { createServer } from 'node:http';
2
+
3
+ async function findOwner(deps, channelId) {
4
+ for (const sid of deps.getSessionIds()) {
5
+ const rpc = deps.getSessionRPCHandlers(sid);
6
+ if (!rpc?.channelList) continue;
7
+ try {
8
+ const r = await rpc.channelList();
9
+ if ((r?.channels || []).some((c) => c.id === channelId)) return rpc;
10
+ } catch {
11
+ }
12
+ }
13
+ return void 0;
14
+ }
15
+ function createChannelHttpServer(deps) {
16
+ return createServer((req, res) => {
17
+ const u = new URL(req.url || "/", "http://localhost");
18
+ const json = (code, obj) => {
19
+ res.writeHead(code, { "content-type": "application/json" }).end(JSON.stringify(obj));
20
+ };
21
+ (async () => {
22
+ if (u.pathname === "/" || u.pathname === "/health") {
23
+ res.writeHead(200).end("channels ok");
24
+ return;
25
+ }
26
+ if (u.pathname === "/channels") {
27
+ const out = [];
28
+ for (const sid of deps.getSessionIds()) {
29
+ const rpc2 = deps.getSessionRPCHandlers(sid);
30
+ if (!rpc2?.channelList) continue;
31
+ try {
32
+ const r = await rpc2.channelList();
33
+ for (const c of r?.channels || []) out.push(c);
34
+ } catch {
35
+ }
36
+ }
37
+ json(200, out);
38
+ return;
39
+ }
40
+ let m = u.pathname.match(/^\/channel\/([\w.-]+)\/skill\.md$/);
41
+ if (m) {
42
+ const rpc2 = await findOwner(deps, m[1]);
43
+ if (!rpc2?.channelDescribe) {
44
+ res.writeHead(404).end("not found");
45
+ return;
46
+ }
47
+ const d = await rpc2.channelDescribe(m[1]);
48
+ if (d?.error) {
49
+ res.writeHead(404).end("not found");
50
+ return;
51
+ }
52
+ res.writeHead(200, { "content-type": "text/markdown" }).end(d.skill?.body || "");
53
+ return;
54
+ }
55
+ m = u.pathname.match(/^\/channel\/([\w.-]+)$/);
56
+ if (!m) {
57
+ json(404, { error: "not found" });
58
+ return;
59
+ }
60
+ const channelId = m[1];
61
+ const rpc = await findOwner(deps, channelId);
62
+ if (!rpc?.channelSend) {
63
+ json(404, { error: "channel not found" });
64
+ return;
65
+ }
66
+ if (req.method === "GET" && !u.searchParams.get("message")) {
67
+ const d = await rpc.channelDescribe(channelId);
68
+ json(200, d);
69
+ return;
70
+ }
71
+ let chunks = "";
72
+ req.on("data", (d) => {
73
+ chunks += d;
74
+ if (chunks.length > 1e6) req.destroy();
75
+ });
76
+ req.on("end", async () => {
77
+ let body = {};
78
+ try {
79
+ body = chunks ? JSON.parse(chunks) : {};
80
+ } catch {
81
+ }
82
+ const key = (req.headers.authorization || "").replace(/^Bearer\s+/i, "") || u.searchParams.get("key") || void 0;
83
+ const message = body.message ?? u.searchParams.get("message") ?? "";
84
+ const from = body.from ?? u.searchParams.get("from") ?? void 0;
85
+ try {
86
+ const out = await rpc.channelSend({ channel: channelId, message, from, key });
87
+ json(out?.error ? 400 : 200, out);
88
+ } catch (e) {
89
+ json(500, { error: e?.message || String(e) });
90
+ }
91
+ });
92
+ })().catch((e) => {
93
+ try {
94
+ json(500, { error: e?.message || String(e) });
95
+ } catch {
96
+ }
97
+ });
98
+ });
99
+ }
100
+
101
+ export { createChannelHttpServer };
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-C4i9N-F6.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-1BK4-WPo.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.89";
2
+ var version = "0.2.90";
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";
@@ -19,7 +19,7 @@ var exports$1 = {
19
19
  var scripts = {
20
20
  build: "rm -rf dist bin/skills && mkdir -p bin/skills && cp -r ../../skills/artifact bin/skills/artifact && tsc --noEmit && pkgroll",
21
21
  typecheck: "tsc --noEmit",
22
- test: "npx tsx test/test-context-window.mjs && npx tsx test/test-instance-config.mjs && 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-session-send-query.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 && node test/test-supervisor-restart.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 && node test/pinnedClaudeCode.test.mjs && node test/fleet.test.mjs && npx tsx test/test-routine.mjs && npx tsx test/test-routine-rpc.mjs && npx tsx test/test-session-file.mjs && npx tsx test/test-channel-rpc.mjs && npx tsx test/test-wise-agent.mjs && npx tsx test/test-channel-agent.mjs && npx tsx test/test-channels-service.mjs && npx tsx test/test-wise-runjs.mjs && npx tsx test/test-wise-agent-auth.mjs",
22
+ test: "npx tsx test/test-context-window.mjs && npx tsx test/test-instance-config.mjs && 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-session-send-query.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 && node test/test-supervisor-restart.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 && node test/pinnedClaudeCode.test.mjs && node test/fleet.test.mjs && npx tsx test/test-routine.mjs && npx tsx test/test-routine-rpc.mjs && npx tsx test/test-session-file.mjs && npx tsx test/test-channel-rpc.mjs && npx tsx test/test-wise-agent.mjs && npx tsx test/test-channel-agent.mjs && npx tsx test/test-channels-service.mjs && npx tsx test/test-wise-runjs.mjs && npx tsx test/test-wise-agent-auth.mjs && npx tsx test/test-channel-http.mjs",
23
23
  "test:hypha": "node --no-warnings test/test-hypha-service.mjs",
24
24
  dev: "tsx src/cli.ts",
25
25
  "dev:daemon": "tsx src/cli.ts daemon start-sync",
@@ -1394,7 +1394,7 @@ async function registerMachineService(server, machineId, metadata, daemonState,
1394
1394
  const tunnels = handlers.tunnels;
1395
1395
  if (!tunnels) throw new Error("Tunnel management not available");
1396
1396
  if (tunnels.has(params.name)) throw new Error(`Tunnel '${params.name}' already running`);
1397
- const { FrpcTunnel } = await import('./frpc-BiazjxzU.mjs');
1397
+ const { FrpcTunnel } = await import('./frpc-DTA0--Z7.mjs');
1398
1398
  const tunnel = new FrpcTunnel({
1399
1399
  name: params.name,
1400
1400
  ports: params.ports,
@@ -1993,12 +1993,16 @@ class ChannelStore {
1993
1993
  dir;
1994
1994
  constructor(projectDir) {
1995
1995
  this.dir = join$1(projectDir, ".svamp", "channels");
1996
- mkdirSync$1(this.dir, { recursive: true });
1996
+ try {
1997
+ mkdirSync$1(this.dir, { recursive: true });
1998
+ } catch {
1999
+ }
1997
2000
  }
1998
2001
  _path(id) {
1999
2002
  return join$1(this.dir, `${id}.json`);
2000
2003
  }
2001
2004
  list() {
2005
+ if (!existsSync(this.dir)) return [];
2002
2006
  return readdirSync(this.dir).filter((f) => f.endsWith(".json")).map((f) => {
2003
2007
  try {
2004
2008
  return JSON.parse(readFileSync(join$1(this.dir, f), "utf8"));
@@ -2019,6 +2023,7 @@ class ChannelStore {
2019
2023
  if (!c.id) c.id = genId();
2020
2024
  const errs = validateChannel(c);
2021
2025
  if (errs.length) throw new Error("invalid channel: " + errs.join("; "));
2026
+ mkdirSync$1(this.dir, { recursive: true });
2022
2027
  const tmp = this._path(c.id) + ".tmp";
2023
2028
  writeFileSync$1(tmp, JSON.stringify(c, null, 2));
2024
2029
  renameSync$1(tmp, this._path(c.id));
@@ -2061,7 +2066,7 @@ function generateSkillBody(channel, urlBase) {
2061
2066
  const isAgent = channel.action?.kind === "agent";
2062
2067
  const replyNote = isAgent ? `
2063
2068
  This is a WISE Agent channel: send() runs a fast assistant against the session's tools/skills and **returns its answer synchronously** in the result \`reply\`.` : `
2064
- Delivery is fire-and-forget; the receiving agent sees an <inbound-message> tag.`;
2069
+ Delivery is fire-and-forget; the message lands in the agent's inbox tagged with your identity (from/verified).`;
2065
2070
  return `---
2066
2071
  name: ${channel.skill?.name || channel.name}
2067
2072
  description: ${channel.skill?.description || channel.description || `Send a message to the "${channel.name}" channel.`}
@@ -2387,21 +2392,42 @@ const DEFAULTS = {
2387
2392
  // Fallback when no OpenAI access — Claude Haiku via the same proxy path.
2388
2393
  "claude-haiku": { baseUrl: "", model: "claude-haiku-4-5" }
2389
2394
  };
2395
+ const DEFAULT_OPENAI_BASE = "https://api.openai.com";
2390
2396
  function resolveModel(config, env) {
2391
2397
  const provider = config?.provider || env.WISE_AGENT_PROVIDER || "openai";
2392
2398
  const d = DEFAULTS[provider] || DEFAULTS.openai;
2393
2399
  const model = config?.model || env.WISE_AGENT_MODEL || d.model;
2394
- let baseUrl = env.WISE_AGENT_BASE_URL || d.baseUrl;
2400
+ let baseUrl = env.WISE_AGENT_BASE_URL || "";
2395
2401
  let apiKey = env.WISE_AGENT_API_KEY || "";
2396
2402
  if (provider === "openai") {
2403
+ baseUrl = baseUrl || env.OPENAI_BASE_URL || env.OPENAI_API_BASE || d.baseUrl;
2397
2404
  apiKey = apiKey || env.OPENAI_API_KEY || "";
2398
2405
  } else if (provider === "hypha-proxy" || provider === "claude-haiku") {
2399
2406
  baseUrl = baseUrl || (env.SVAMP_HYPHA_PROXY_URL || "").replace(/\/+$/, "");
2400
2407
  apiKey = apiKey || env.HYPHA_TOKEN || "";
2408
+ } else {
2409
+ baseUrl = baseUrl || d.baseUrl;
2401
2410
  }
2402
2411
  baseUrl = baseUrl.replace(/\/v1\/?$/, "");
2403
2412
  return { provider, baseUrl, apiKey, model };
2404
2413
  }
2414
+ function describeMisconfiguration(resolved) {
2415
+ const { provider, baseUrl, apiKey } = resolved;
2416
+ if (!baseUrl) {
2417
+ if (provider === "hypha-proxy" || provider === "claude-haiku") {
2418
+ return `WISE Agent (${provider}) is not configured: no proxy base URL. Run \`svamp wise-agent auth use-hypha-proxy <URL>\` (or set SVAMP_HYPHA_PROXY_URL), then \`svamp daemon restart\`.`;
2419
+ }
2420
+ return "WISE Agent is not configured: no base URL. Run `svamp wise-agent auth set <URL> <KEY>` (or set WISE_AGENT_BASE_URL / OPENAI_BASE_URL), then `svamp daemon restart`.";
2421
+ }
2422
+ if (provider === "hypha-proxy" || provider === "claude-haiku") {
2423
+ if (!apiKey) return `WISE Agent (${provider}) is not configured: no auth token. Ensure HYPHA_TOKEN is set (\`svamp login\`), then \`svamp daemon restart\`.`;
2424
+ return null;
2425
+ }
2426
+ if (!apiKey && baseUrl.replace(/\/v1\/?$/, "") === DEFAULT_OPENAI_BASE) {
2427
+ return "WISE Agent is not configured: no OpenAI API key. Run `svamp wise-agent auth use-openai <KEY>` (or set OPENAI_API_KEY / WISE_AGENT_API_KEY), then `svamp daemon restart`.";
2428
+ }
2429
+ return null;
2430
+ }
2405
2431
  function makeHttpTransport(resolved, fetchImpl = fetch) {
2406
2432
  return async (req) => {
2407
2433
  if (!resolved.baseUrl) throw new Error(`WISE Agent: no base URL for provider "${resolved.provider}" (set WISE_AGENT_BASE_URL or SVAMP_HYPHA_PROXY_URL)`);
@@ -2509,6 +2535,10 @@ let _testTransport;
2509
2535
  async function dispatchAgentChannel(a) {
2510
2536
  const config = a.channel.action?.kind === "agent" ? a.channel.action.agent || {} : {};
2511
2537
  const resolved = resolveModel(config, a.env);
2538
+ if (!a.transport && !_testTransport) {
2539
+ const err = describeMisconfiguration(resolved);
2540
+ if (err) return { status: "error", reply: "", toolCalls: [], error: err };
2541
+ }
2512
2542
  const transport = a.transport || _testTransport || makeHttpTransport(resolved);
2513
2543
  return runWiseAgent({
2514
2544
  message: a.message,
@@ -2575,7 +2605,7 @@ function channelPublicView(c) {
2575
2605
  return { id: c.id, name: c.name, description: c.description, identity: { mode: c.identity?.mode }, action: c.action?.kind };
2576
2606
  }
2577
2607
  function isStructuredMessage(msg) {
2578
- return !!(msg.from || msg.fromSession || msg.subject || msg.replyTo || msg.threadId);
2608
+ return !!(msg.from || msg.fromSession || msg.subject || msg.replyTo || msg.threadId || msg.channel);
2579
2609
  }
2580
2610
  function escapeXml(s) {
2581
2611
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
@@ -2584,6 +2614,8 @@ function formatInboxMessageXml(msg) {
2584
2614
  if (!isStructuredMessage(msg)) return msg.body;
2585
2615
  const attrs = [`message-id="${escapeXml(msg.messageId)}"`];
2586
2616
  if (msg.from) attrs.push(`from="${escapeXml(msg.from)}"`);
2617
+ if (msg.channel) attrs.push(`channel="${escapeXml(msg.channel)}"`);
2618
+ if (msg.verified !== void 0) attrs.push(`verified="${msg.verified === true}"`);
2587
2619
  if (msg.fromSession) attrs.push(`from-session="${escapeXml(msg.fromSession)}"`);
2588
2620
  if (msg.to) attrs.push(`to="${escapeXml(msg.to)}"`);
2589
2621
  if (msg.subject) attrs.push(`subject="${escapeXml(msg.subject)}"`);
@@ -2704,6 +2736,9 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
2704
2736
  replyTo: m.replyTo,
2705
2737
  cc: m.cc,
2706
2738
  threadId: m.threadId,
2739
+ // Channel provenance so the inbox UI can show who/verified.
2740
+ ...m.verified !== void 0 ? { verified: m.verified } : {},
2741
+ ...m.channel ? { channel: m.channel } : {},
2707
2742
  ...m.displayText ? { displayText: m.displayText } : {}
2708
2743
  }));
2709
2744
  metadataVersion++;
@@ -3032,11 +3067,11 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
3032
3067
  });
3033
3068
  if (r.error || !r.sender) return { error: r.error || "unauthorized" };
3034
3069
  const callId = "call_" + randomUUID().slice(0, 10);
3035
- const rendered = renderMessage(c, { sender: r.sender, body: { message: params.message }, callId });
3036
3070
  const ownerEmail = metadata.sharing?.owner;
3037
3071
  const ownerCtx = ownerEmail ? { user: { email: ownerEmail, id: ownerEmail } } : void 0;
3038
3072
  try {
3039
3073
  if (c.action?.kind === "agent") {
3074
+ const rendered = renderMessage(c, { sender: r.sender, body: { message: params.message }, callId });
3040
3075
  const deps = buildSessionDeps(rpcHandlers, {
3041
3076
  cwd: metadata.path,
3042
3077
  ownerEmail,
@@ -3048,7 +3083,17 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
3048
3083
  return { ok: result.status === "completed", call_id: callId, status: result.status, reply: result.reply, tool_calls: result.toolCalls, error: result.error };
3049
3084
  }
3050
3085
  if (c.action?.kind === "loop") return { error: "loop channels are served by the channel server, not channelSend" };
3051
- await rpcHandlers.sendMessage(rendered, void 0, { sentFrom: "channel" }, ownerCtx);
3086
+ const inboxMsg = {
3087
+ messageId: callId,
3088
+ body: xmlEscape(String(params.message ?? "").slice(0, 16 * 1024)),
3089
+ timestamp: Date.now(),
3090
+ read: false,
3091
+ from: r.sender.name,
3092
+ verified: r.sender.verified,
3093
+ channel: c.name,
3094
+ subject: c.name
3095
+ };
3096
+ await rpcHandlers.sendInboxMessage(inboxMsg, ownerCtx);
3052
3097
  channelStore.recordCall(c.id, { sender: r.sender.name, verified: r.sender.verified, callId, outcome: "delivered" });
3053
3098
  syncChannelsToMetadata();
3054
3099
  return { ok: true, call_id: callId, status: "accepted" };
@@ -9535,7 +9580,7 @@ async function startDaemon(options) {
9535
9580
  const list = loadExposedTunnels().filter((t) => t.name !== name);
9536
9581
  saveExposedTunnels(list);
9537
9582
  }
9538
- const { ServeManager } = await import('./serveManager-DHJy5C0z.mjs');
9583
+ const { ServeManager } = await import('./serveManager-Cd2gJI7J.mjs');
9539
9584
  const serveManager = new ServeManager(SVAMP_HOME, (msg) => logger.log(`[SERVE] ${msg}`), hyphaServerUrl);
9540
9585
  ensureAutoInstalledSkills(logger).catch(() => {
9541
9586
  });
@@ -12110,11 +12155,31 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
12110
12155
  }
12111
12156
  );
12112
12157
  logger.log(`Machine service registered: svamp-machine-${machineId}`);
12158
+ const channelHttpPort = Number(process.env.SVAMP_CHANNEL_HTTP_PORT) || 0;
12159
+ if (channelHttpPort > 0) {
12160
+ try {
12161
+ const { createChannelHttpServer } = await import('./httpServer-wwHHk1EM.mjs');
12162
+ const channelHttpServer = createChannelHttpServer({
12163
+ getSessionIds: () => {
12164
+ const ids = [];
12165
+ for (const [, s] of pidToTrackedSession) if (s.svampSessionId && !s.stopped && s.sessionRPCHandlers) ids.push(s.svampSessionId);
12166
+ return ids;
12167
+ },
12168
+ getSessionRPCHandlers: (sid) => {
12169
+ for (const [, s] of pidToTrackedSession) if (s.svampSessionId === sid && !s.stopped && s.sessionRPCHandlers) return s.sessionRPCHandlers;
12170
+ return void 0;
12171
+ }
12172
+ });
12173
+ channelHttpServer.listen(channelHttpPort, () => logger.log(`[channels] HTTP ingress on :${channelHttpPort} (POST /channel/<id>)`));
12174
+ } catch (e) {
12175
+ logger.error(`[channels] HTTP ingress failed to start: ${e.message}`);
12176
+ }
12177
+ }
12113
12178
  (async () => {
12114
12179
  const specs = loadExposedTunnels();
12115
12180
  if (specs.length === 0) return;
12116
12181
  logger.log(`[exposed-tunnels] Restoring ${specs.length} tunnel(s) from ${EXPOSED_TUNNELS_FILE}`);
12117
- const { FrpcTunnel } = await import('./frpc-BiazjxzU.mjs');
12182
+ const { FrpcTunnel } = await import('./frpc-DTA0--Z7.mjs');
12118
12183
  for (const spec of specs) {
12119
12184
  if (tunnels.has(spec.name)) continue;
12120
12185
  try {
@@ -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, H as generateHookSettings } from './run-C4i9N-F6.mjs';
5
+ import { c as connectToHypha, a as registerSessionService, H as generateHookSettings } from './run-1BK4-WPo.mjs';
6
6
  import { createServer } from 'node:http';
7
7
  import { spawn } from 'node:child_process';
8
8
  import { createInterface } from 'node:readline';
@@ -54,7 +54,7 @@ async function handleServeCommand() {
54
54
  }
55
55
  }
56
56
  async function serveAdd(args, machineId) {
57
- const { connectAndGetMachine } = await import('./commands-DY1ciMPa.mjs');
57
+ const { connectAndGetMachine } = await import('./commands-mlxYf-v-.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-DY1ciMPa.mjs');
96
+ const { connectAndGetMachine } = await import('./commands-mlxYf-v-.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-DY1ciMPa.mjs');
185
+ const { connectAndGetMachine } = await import('./commands-mlxYf-v-.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-DY1ciMPa.mjs');
205
+ const { connectAndGetMachine } = await import('./commands-mlxYf-v-.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-DY1ciMPa.mjs');
238
+ const { connectAndGetMachine } = await import('./commands-mlxYf-v-.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 { k as getHyphaServerUrl, S as ServeAuth, l as hasCookieToken } from './run-C4i9N-F6.mjs';
7
+ import { k as getHyphaServerUrl, S as ServeAuth, l as hasCookieToken } from './run-1BK4-WPo.mjs';
8
8
  import 'os';
9
9
  import 'fs/promises';
10
10
  import 'url';
@@ -713,7 +713,7 @@ class ServeManager {
713
713
  const mount = this.mounts.get(mountName);
714
714
  const subdomainOverride = mount?.access === "link" && mount.linkToken ? /* @__PURE__ */ new Map([[this.port, `static-${subdomainSafe}-${mount.linkToken}`]]) : void 0;
715
715
  try {
716
- const { FrpcTunnel } = await import('./frpc-BiazjxzU.mjs');
716
+ const { FrpcTunnel } = await import('./frpc-DTA0--Z7.mjs');
717
717
  let tunnel;
718
718
  tunnel = new FrpcTunnel({
719
719
  name: tunnelName,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svamp-cli",
3
- "version": "0.2.89",
3
+ "version": "0.2.90",
4
4
  "description": "Svamp CLI — AI workspace daemon on Hypha Cloud",
5
5
  "author": "Amun AI AB",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -20,7 +20,7 @@
20
20
  "scripts": {
21
21
  "build": "rm -rf dist bin/skills && mkdir -p bin/skills && cp -r ../../skills/artifact bin/skills/artifact && tsc --noEmit && pkgroll",
22
22
  "typecheck": "tsc --noEmit",
23
- "test": "npx tsx test/test-context-window.mjs && npx tsx test/test-instance-config.mjs && 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-session-send-query.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 && node test/test-supervisor-restart.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 && node test/pinnedClaudeCode.test.mjs && node test/fleet.test.mjs && npx tsx test/test-routine.mjs && npx tsx test/test-routine-rpc.mjs && npx tsx test/test-session-file.mjs && npx tsx test/test-channel-rpc.mjs && npx tsx test/test-wise-agent.mjs && npx tsx test/test-channel-agent.mjs && npx tsx test/test-channels-service.mjs && npx tsx test/test-wise-runjs.mjs && npx tsx test/test-wise-agent-auth.mjs",
23
+ "test": "npx tsx test/test-context-window.mjs && npx tsx test/test-instance-config.mjs && 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-session-send-query.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 && node test/test-supervisor-restart.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 && node test/pinnedClaudeCode.test.mjs && node test/fleet.test.mjs && npx tsx test/test-routine.mjs && npx tsx test/test-routine-rpc.mjs && npx tsx test/test-session-file.mjs && npx tsx test/test-channel-rpc.mjs && npx tsx test/test-wise-agent.mjs && npx tsx test/test-channel-agent.mjs && npx tsx test/test-channels-service.mjs && npx tsx test/test-wise-runjs.mjs && npx tsx test/test-wise-agent-auth.mjs && npx tsx test/test-channel-http.mjs",
24
24
  "test:hypha": "node --no-warnings test/test-hypha-service.mjs",
25
25
  "dev": "tsx src/cli.ts",
26
26
  "dev:daemon": "tsx src/cli.ts daemon start-sync",