svamp-cli 0.2.11 → 0.2.13

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.
@@ -1,7 +1,7 @@
1
1
  import { existsSync, readFileSync, mkdirSync, writeFileSync, renameSync } from 'node:fs';
2
2
  import { join, dirname } from 'node:path';
3
3
  import os from 'node:os';
4
- import { requireNotSandboxed } from './sandboxDetect-BWA3zQlA.mjs';
4
+ import { requireNotSandboxed } from './sandboxDetect-DNTcbgWD.mjs';
5
5
 
6
6
  const SVAMP_HOME = process.env.SVAMP_HOME || join(os.homedir(), ".svamp");
7
7
  function getConfigPath(sessionId) {
@@ -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-DsBtNTwb.mjs');
151
+ const { connectAndGetMachine } = await import('./commands-8ZF7ClgV.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-DsBtNTwb.mjs');
168
+ const { resolveSessionId } = await import('./commands-8ZF7ClgV.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 { b as stopDaemon, s as startDaemon, d as daemonStatus } from './run-BRElsMCe.mjs';
1
+ import { s as startDaemon, b as stopDaemon, d as daemonStatus } from './run-CPph8_9U.mjs';
2
2
  import 'os';
3
3
  import 'fs/promises';
4
4
  import 'fs';
@@ -36,8 +36,9 @@ async function main() {
36
36
  await logoutFromHypha();
37
37
  } else if (subcommand === "daemon") {
38
38
  if (daemonSubcommand === "restart") {
39
- await stopDaemon();
40
- daemonSubcommand = "start";
39
+ const { restartDaemon } = await import('./run-CPph8_9U.mjs').then(function (n) { return n.k; });
40
+ await restartDaemon();
41
+ process.exit(0);
41
42
  }
42
43
  if (daemonSubcommand === "start") {
43
44
  const { spawn } = await import('child_process');
@@ -111,6 +112,7 @@ async function main() {
111
112
  let consecutiveRapidCrashes = 0;
112
113
  let currentChild = null;
113
114
  let stopping = false;
115
+ let restarting = false;
114
116
  const onSignal = (sig) => {
115
117
  stopping = true;
116
118
  if (currentChild && !currentChild.killed) {
@@ -120,6 +122,13 @@ async function main() {
120
122
  process.on("SIGTERM", () => onSignal("SIGTERM"));
121
123
  process.on("SIGINT", () => onSignal("SIGINT"));
122
124
  process.on("SIGUSR1", () => onSignal("SIGUSR1"));
125
+ process.on("SIGUSR2", () => {
126
+ restarting = true;
127
+ log("Received SIGUSR2 \u2014 graceful restart requested");
128
+ if (currentChild && !currentChild.killed) {
129
+ currentChild.kill("SIGTERM");
130
+ }
131
+ });
123
132
  log("Supervisor started");
124
133
  while (!stopping) {
125
134
  const startTime = Date.now();
@@ -148,6 +157,12 @@ async function main() {
148
157
  log("Supervisor received stop signal, exiting");
149
158
  break;
150
159
  }
160
+ if (restarting) {
161
+ restarting = false;
162
+ consecutiveRapidCrashes = 0;
163
+ log("Graceful restart: respawning daemon with new binary from disk");
164
+ continue;
165
+ }
151
166
  if (exitCode === 0) {
152
167
  log("Daemon exited cleanly (exit 0), not restarting");
153
168
  break;
@@ -204,21 +219,21 @@ async function main() {
204
219
  } else if (subcommand === "session") {
205
220
  await handleSessionCommand();
206
221
  } else if (subcommand === "machine") {
207
- const { isSandboxed } = await import('./sandboxDetect-BWA3zQlA.mjs');
222
+ const { isSandboxed } = await import('./sandboxDetect-DNTcbgWD.mjs');
208
223
  if (isSandboxed()) {
209
224
  console.error("svamp machine: Machine commands are not available in sandboxed sessions.");
210
225
  process.exit(1);
211
226
  }
212
227
  await handleMachineCommand();
213
228
  } else if (subcommand === "skills") {
214
- const { isSandboxed } = await import('./sandboxDetect-BWA3zQlA.mjs');
229
+ const { isSandboxed } = await import('./sandboxDetect-DNTcbgWD.mjs');
215
230
  if (isSandboxed()) {
216
231
  console.error("svamp skills: Skills commands are not available in sandboxed sessions.");
217
232
  process.exit(1);
218
233
  }
219
234
  await handleSkillsCommand();
220
235
  } else if (subcommand === "service" || subcommand === "svc") {
221
- const { isSandboxed } = await import('./sandboxDetect-BWA3zQlA.mjs');
236
+ const { isSandboxed } = await import('./sandboxDetect-DNTcbgWD.mjs');
222
237
  if (isSandboxed()) {
223
238
  console.error("svamp service: Service commands are not available in sandboxed sessions.");
224
239
  process.exit(1);
@@ -226,21 +241,21 @@ async function main() {
226
241
  const { handleServiceCommand } = await import('./commands-BJJTEZD4.mjs');
227
242
  await handleServiceCommand();
228
243
  } else if (subcommand === "serve") {
229
- const { isSandboxed: isSandboxedServe } = await import('./sandboxDetect-BWA3zQlA.mjs');
244
+ const { isSandboxed: isSandboxedServe } = await import('./sandboxDetect-DNTcbgWD.mjs');
230
245
  if (isSandboxedServe()) {
231
246
  console.error("svamp serve: Serve commands are not available in sandboxed sessions.");
232
247
  process.exit(1);
233
248
  }
234
- const { handleServeCommand } = await import('./serveCommands-B3lrLh1f.mjs');
249
+ const { handleServeCommand } = await import('./serveCommands-D4N5g4Ra.mjs');
235
250
  await handleServeCommand();
236
251
  process.exit(0);
237
252
  } else if (subcommand === "process" || subcommand === "proc") {
238
- const { isSandboxed: isSandboxedProc } = await import('./sandboxDetect-BWA3zQlA.mjs');
253
+ const { isSandboxed: isSandboxedProc } = await import('./sandboxDetect-DNTcbgWD.mjs');
239
254
  if (isSandboxedProc()) {
240
255
  console.error("svamp process: Process commands are not available in sandboxed sessions.");
241
256
  process.exit(1);
242
257
  }
243
- const { processCommand } = await import('./commands-DC-GHo_-.mjs');
258
+ const { processCommand } = await import('./commands-CUIMdAqM.mjs');
244
259
  let machineId;
245
260
  const processArgs = args.slice(1);
246
261
  const mIdx = processArgs.findIndex((a) => a === "--machine" || a === "-m");
@@ -258,7 +273,7 @@ async function main() {
258
273
  } else if (!subcommand || subcommand === "start") {
259
274
  await handleInteractiveCommand();
260
275
  } else if (subcommand === "--version" || subcommand === "-v") {
261
- const pkg = await import('./package-O_s35H8q.mjs').catch(() => ({ default: { version: "unknown" } }));
276
+ const pkg = await import('./package-CqP3TZT8.mjs').catch(() => ({ default: { version: "unknown" } }));
262
277
  console.log(`svamp version: ${pkg.default.version}`);
263
278
  } else {
264
279
  console.error(`Unknown command: ${subcommand}`);
@@ -267,7 +282,7 @@ async function main() {
267
282
  }
268
283
  }
269
284
  async function handleInteractiveCommand() {
270
- const { runInteractive } = await import('./run-sFMF1JIF.mjs');
285
+ const { runInteractive } = await import('./run-BLQXjuUi.mjs');
271
286
  const interactiveArgs = subcommand === "start" ? args.slice(1) : args;
272
287
  let directory = process.cwd();
273
288
  let resumeSessionId;
@@ -312,7 +327,7 @@ async function handleAgentCommand() {
312
327
  return;
313
328
  }
314
329
  if (agentArgs[0] === "list") {
315
- const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-BRElsMCe.mjs').then(function (n) { return n.i; });
330
+ const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-CPph8_9U.mjs').then(function (n) { return n.i; });
316
331
  console.log("Known agents:");
317
332
  for (const [name, config2] of Object.entries(KNOWN_ACP_AGENTS)) {
318
333
  console.log(` ${name.padEnd(12)} ${config2.command} ${config2.args.join(" ")} (ACP)`);
@@ -324,7 +339,7 @@ async function handleAgentCommand() {
324
339
  console.log('Use "svamp agent -- <command> [args]" for a custom ACP agent.');
325
340
  return;
326
341
  }
327
- const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-BRElsMCe.mjs').then(function (n) { return n.i; });
342
+ const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-CPph8_9U.mjs').then(function (n) { return n.i; });
328
343
  let cwd = process.cwd();
329
344
  const filteredArgs = [];
330
345
  for (let i = 0; i < agentArgs.length; i++) {
@@ -348,12 +363,12 @@ async function handleAgentCommand() {
348
363
  console.log(`Starting ${config.agentName} agent in ${cwd}...`);
349
364
  let backend;
350
365
  if (KNOWN_MCP_AGENTS[config.agentName]) {
351
- const { CodexMcpBackend } = await import('./run-BRElsMCe.mjs').then(function (n) { return n.j; });
366
+ const { CodexMcpBackend } = await import('./run-CPph8_9U.mjs').then(function (n) { return n.j; });
352
367
  backend = new CodexMcpBackend({ cwd, log: logFn });
353
368
  } else {
354
- const { AcpBackend } = await import('./run-BRElsMCe.mjs').then(function (n) { return n.h; });
355
- const { GeminiTransport } = await import('./run-BRElsMCe.mjs').then(function (n) { return n.G; });
356
- const { DefaultTransport } = await import('./run-BRElsMCe.mjs').then(function (n) { return n.D; });
369
+ const { AcpBackend } = await import('./run-CPph8_9U.mjs').then(function (n) { return n.h; });
370
+ const { GeminiTransport } = await import('./run-CPph8_9U.mjs').then(function (n) { return n.G; });
371
+ const { DefaultTransport } = await import('./run-CPph8_9U.mjs').then(function (n) { return n.D; });
357
372
  const transportHandler = config.agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(config.agentName);
358
373
  backend = new AcpBackend({
359
374
  agentName: config.agentName,
@@ -473,14 +488,14 @@ async function handleSessionCommand() {
473
488
  }
474
489
  const SANDBOX_SAFE_SESSION_CMDS = /* @__PURE__ */ new Set(["set-title", "set-link"]);
475
490
  if (!SANDBOX_SAFE_SESSION_CMDS.has(sessionSubcommand)) {
476
- const { isSandboxed } = await import('./sandboxDetect-BWA3zQlA.mjs');
491
+ const { isSandboxed } = await import('./sandboxDetect-DNTcbgWD.mjs');
477
492
  if (isSandboxed()) {
478
493
  console.error(`svamp session ${sessionSubcommand}: This command is not available in sandboxed sessions.`);
479
494
  console.error("Available commands: set-title, set-link");
480
495
  process.exit(1);
481
496
  }
482
497
  }
483
- const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-DsBtNTwb.mjs');
498
+ const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-8ZF7ClgV.mjs');
484
499
  const parseFlagStr = (flag, shortFlag) => {
485
500
  for (let i = 1; i < sessionArgs.length; i++) {
486
501
  if ((sessionArgs[i] === flag || shortFlag) && i + 1 < sessionArgs.length) {
@@ -540,7 +555,7 @@ async function handleSessionCommand() {
540
555
  allowDomain.push(sessionArgs[++i]);
541
556
  }
542
557
  }
543
- const { parseShareArg } = await import('./commands-DsBtNTwb.mjs');
558
+ const { parseShareArg } = await import('./commands-8ZF7ClgV.mjs');
544
559
  const shareEntries = share.map((s) => parseShareArg(s));
545
560
  await sessionSpawn(agent, dir, targetMachineId, {
546
561
  message,
@@ -626,7 +641,7 @@ async function handleSessionCommand() {
626
641
  console.error("Usage: svamp session approve <session-id> [request-id] [--json]");
627
642
  process.exit(1);
628
643
  }
629
- const { sessionApprove } = await import('./commands-DsBtNTwb.mjs');
644
+ const { sessionApprove } = await import('./commands-8ZF7ClgV.mjs');
630
645
  const approveReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
631
646
  await sessionApprove(sessionArgs[1], approveReqId, targetMachineId, {
632
647
  json: hasFlag("--json")
@@ -636,7 +651,7 @@ async function handleSessionCommand() {
636
651
  console.error("Usage: svamp session deny <session-id> [request-id] [--json]");
637
652
  process.exit(1);
638
653
  }
639
- const { sessionDeny } = await import('./commands-DsBtNTwb.mjs');
654
+ const { sessionDeny } = await import('./commands-8ZF7ClgV.mjs');
640
655
  const denyReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
641
656
  await sessionDeny(sessionArgs[1], denyReqId, targetMachineId, {
642
657
  json: hasFlag("--json")
@@ -672,7 +687,7 @@ async function handleSessionCommand() {
672
687
  console.error("Usage: svamp session set-title <title>");
673
688
  process.exit(1);
674
689
  }
675
- const { sessionSetTitle } = await import('./agentCommands-CUCjwaSG.mjs');
690
+ const { sessionSetTitle } = await import('./agentCommands-Cy1676fh.mjs');
676
691
  await sessionSetTitle(title);
677
692
  } else if (sessionSubcommand === "set-link") {
678
693
  const url = sessionArgs[1];
@@ -681,7 +696,7 @@ async function handleSessionCommand() {
681
696
  process.exit(1);
682
697
  }
683
698
  const label = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
684
- const { sessionSetLink } = await import('./agentCommands-CUCjwaSG.mjs');
699
+ const { sessionSetLink } = await import('./agentCommands-Cy1676fh.mjs');
685
700
  await sessionSetLink(url, label);
686
701
  } else if (sessionSubcommand === "notify") {
687
702
  const message = sessionArgs[1];
@@ -690,7 +705,7 @@ async function handleSessionCommand() {
690
705
  process.exit(1);
691
706
  }
692
707
  const level = parseFlagStr("--level") || "info";
693
- const { sessionNotify } = await import('./agentCommands-CUCjwaSG.mjs');
708
+ const { sessionNotify } = await import('./agentCommands-Cy1676fh.mjs');
694
709
  await sessionNotify(message, level);
695
710
  } else if (sessionSubcommand === "broadcast") {
696
711
  const action = sessionArgs[1];
@@ -698,7 +713,7 @@ async function handleSessionCommand() {
698
713
  console.error("Usage: svamp session broadcast <action> [args...]\nActions: open-canvas <url> [label], close-canvas, toast <message>");
699
714
  process.exit(1);
700
715
  }
701
- const { sessionBroadcast } = await import('./agentCommands-CUCjwaSG.mjs');
716
+ const { sessionBroadcast } = await import('./agentCommands-Cy1676fh.mjs');
702
717
  await sessionBroadcast(action, sessionArgs.slice(2).filter((a) => !a.startsWith("--")));
703
718
  } else if (sessionSubcommand === "inbox") {
704
719
  const inboxSubcmd = sessionArgs[1];
@@ -709,7 +724,7 @@ async function handleSessionCommand() {
709
724
  process.exit(1);
710
725
  }
711
726
  if (agentSessionId) {
712
- const { inboxSend } = await import('./agentCommands-CUCjwaSG.mjs');
727
+ const { inboxSend } = await import('./agentCommands-Cy1676fh.mjs');
713
728
  await inboxSend(sessionArgs[2], {
714
729
  body: sessionArgs[3],
715
730
  subject: parseFlagStr("--subject"),
@@ -724,7 +739,7 @@ async function handleSessionCommand() {
724
739
  }
725
740
  } else if (inboxSubcmd === "list" || inboxSubcmd === "ls") {
726
741
  if (agentSessionId && !sessionArgs[2]) {
727
- const { inboxList } = await import('./agentCommands-CUCjwaSG.mjs');
742
+ const { inboxList } = await import('./agentCommands-Cy1676fh.mjs');
728
743
  await inboxList({
729
744
  unread: hasFlag("--unread"),
730
745
  limit: parseFlagInt("--limit"),
@@ -746,7 +761,7 @@ async function handleSessionCommand() {
746
761
  process.exit(1);
747
762
  }
748
763
  if (agentSessionId && !sessionArgs[3]) {
749
- const { inboxList } = await import('./agentCommands-CUCjwaSG.mjs');
764
+ const { inboxList } = await import('./agentCommands-Cy1676fh.mjs');
750
765
  await sessionInboxRead(agentSessionId, sessionArgs[2], targetMachineId);
751
766
  } else if (sessionArgs[3]) {
752
767
  await sessionInboxRead(sessionArgs[2], sessionArgs[3], targetMachineId);
@@ -756,7 +771,7 @@ async function handleSessionCommand() {
756
771
  }
757
772
  } else if (inboxSubcmd === "reply") {
758
773
  if (agentSessionId && sessionArgs[2] && sessionArgs[3] && !sessionArgs[4]) {
759
- const { inboxReply } = await import('./agentCommands-CUCjwaSG.mjs');
774
+ const { inboxReply } = await import('./agentCommands-Cy1676fh.mjs');
760
775
  await inboxReply(sessionArgs[2], sessionArgs[3]);
761
776
  } else if (sessionArgs[2] && sessionArgs[3] && sessionArgs[4]) {
762
777
  await sessionInboxReply(sessionArgs[2], sessionArgs[3], sessionArgs[4], targetMachineId);
@@ -792,7 +807,7 @@ async function handleMachineCommand() {
792
807
  return;
793
808
  }
794
809
  if (machineSubcommand === "share") {
795
- const { machineShare } = await import('./commands-DsBtNTwb.mjs');
810
+ const { machineShare } = await import('./commands-8ZF7ClgV.mjs');
796
811
  let machineId;
797
812
  const shareArgs = [];
798
813
  for (let i = 1; i < machineArgs.length; i++) {
@@ -822,7 +837,7 @@ async function handleMachineCommand() {
822
837
  }
823
838
  await machineShare(machineId, { add, remove, list, configPath, showConfig });
824
839
  } else if (machineSubcommand === "exec") {
825
- const { machineExec } = await import('./commands-DsBtNTwb.mjs');
840
+ const { machineExec } = await import('./commands-8ZF7ClgV.mjs');
826
841
  let machineId;
827
842
  let cwd;
828
843
  const cmdParts = [];
@@ -842,7 +857,7 @@ async function handleMachineCommand() {
842
857
  }
843
858
  await machineExec(machineId, command, cwd);
844
859
  } else if (machineSubcommand === "info") {
845
- const { machineInfo } = await import('./commands-DsBtNTwb.mjs');
860
+ const { machineInfo } = await import('./commands-8ZF7ClgV.mjs');
846
861
  let machineId;
847
862
  for (let i = 1; i < machineArgs.length; i++) {
848
863
  if ((machineArgs[i] === "--machine" || machineArgs[i] === "-m") && i + 1 < machineArgs.length) {
@@ -862,10 +877,10 @@ async function handleMachineCommand() {
862
877
  level = machineArgs[++i];
863
878
  }
864
879
  }
865
- const { machineNotify } = await import('./agentCommands-CUCjwaSG.mjs');
880
+ const { machineNotify } = await import('./agentCommands-Cy1676fh.mjs');
866
881
  await machineNotify(message, level);
867
882
  } else if (machineSubcommand === "ls") {
868
- const { machineLs } = await import('./commands-DsBtNTwb.mjs');
883
+ const { machineLs } = await import('./commands-8ZF7ClgV.mjs');
869
884
  let machineId;
870
885
  let showHidden = false;
871
886
  let path;
@@ -1299,7 +1314,7 @@ Usage:
1299
1314
  svamp daemon start --no-auto-continue Start without auto-continuing interrupted sessions
1300
1315
  svamp daemon stop Stop the daemon (sessions preserved for restart)
1301
1316
  svamp daemon stop --cleanup Stop and mark all sessions as stopped
1302
- svamp daemon restart Restart daemon (sessions resume seamlessly)
1317
+ svamp daemon restart Graceful restart \u2014 picks up new binary, sessions resume seamlessly
1303
1318
  svamp daemon status Show daemon status
1304
1319
  svamp daemon install Install as login service (macOS/Linux) \u2014 auto-start at login
1305
1320
  svamp daemon uninstall Remove login service
@@ -2,7 +2,7 @@ import { existsSync, readFileSync } from 'node:fs';
2
2
  import { execSync } from 'node:child_process';
3
3
  import { resolve, join } from 'node:path';
4
4
  import os from 'node:os';
5
- import { l as loadSecurityContextConfig, e as resolveSecurityContext, f as buildSecurityContextFromFlags, m as mergeSecurityContexts, c as connectToHypha } from './run-BRElsMCe.mjs';
5
+ import { l as loadSecurityContextConfig, e as resolveSecurityContext, f as buildSecurityContextFromFlags, m as mergeSecurityContexts, c as connectToHypha } from './run-CPph8_9U.mjs';
6
6
  import 'os';
7
7
  import 'fs/promises';
8
8
  import 'fs';
@@ -1,11 +1,11 @@
1
1
  import { writeFileSync, readFileSync } from 'fs';
2
2
  import { resolve } from 'path';
3
- import { connectAndGetMachine } from './commands-DsBtNTwb.mjs';
3
+ import { connectAndGetMachine } from './commands-8ZF7ClgV.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-BRElsMCe.mjs';
8
+ import './run-CPph8_9U.mjs';
9
9
  import 'os';
10
10
  import 'fs/promises';
11
11
  import 'url';
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { c as connectToHypha, d as daemonStatus, g as getHyphaServerUrl, r as registerMachineService, a as registerSessionService, s as startDaemon, b as stopDaemon } from './run-BRElsMCe.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-CPph8_9U.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.11";
2
+ var version = "0.2.13";
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 { join, resolve } from 'node:path';
4
4
  import { mkdirSync, writeFileSync, existsSync, unlinkSync, readFileSync, watch } from 'node:fs';
5
- import { c as connectToHypha, a as registerSessionService } from './run-BRElsMCe.mjs';
5
+ import { c as connectToHypha, a as registerSessionService } from './run-CPph8_9U.mjs';
6
6
  import { createServer } from 'node:http';
7
7
  import { spawn } from 'node:child_process';
8
8
  import { createInterface } from 'node:readline';
@@ -6537,6 +6537,7 @@ async function startDaemon(options) {
6537
6537
  let spawnEnv = { ...process.env, ...extraEnv };
6538
6538
  delete spawnEnv.CLAUDECODE;
6539
6539
  spawnEnv.SVAMP_SESSION_ID = sessionId;
6540
+ delete spawnEnv.SVAMP_SANDBOXED;
6540
6541
  if (sessionMetadata.sharing?.enabled && stagedCredentials) {
6541
6542
  Object.assign(spawnEnv, stagedCredentials.env);
6542
6543
  const filtered = {};
@@ -6545,6 +6546,10 @@ async function startDaemon(options) {
6545
6546
  }
6546
6547
  spawnEnv = sanitizeEnvForSharing(filtered);
6547
6548
  logger.log(`[Session ${sessionId}] Credential staging: HOME=${stagedCredentials.homePath}`);
6549
+ if (sessionMetadata.securityContext) {
6550
+ spawnEnv.SVAMP_SANDBOXED = "1";
6551
+ logger.log(`[Session ${sessionId}] Sandbox mode: ON (securityContext present)`);
6552
+ }
6548
6553
  }
6549
6554
  const child = spawn$1(spawnCommand, spawnArgs, {
6550
6555
  cwd: directory,
@@ -6717,7 +6722,8 @@ async function startDaemon(options) {
6717
6722
  }
6718
6723
  }
6719
6724
  if (msg.type === "result") {
6720
- if (!turnInitiatedByUser) {
6725
+ const ralphActive = !!readRalphState(getRalphStateFilePath(directory, sessionId));
6726
+ if (!turnInitiatedByUser && !ralphActive) {
6721
6727
  logger.log(`[Session ${sessionId}] Skipping stale result from SDK-initiated turn`);
6722
6728
  const hasBackgroundTasks = backgroundTaskCount > 0;
6723
6729
  if (hasBackgroundTasks) {
@@ -6742,6 +6748,10 @@ async function startDaemon(options) {
6742
6748
  turnInitiatedByUser = true;
6743
6749
  continue;
6744
6750
  }
6751
+ if (!turnInitiatedByUser && ralphActive) {
6752
+ logger.log(`[Session ${sessionId}] SDK-initiated result during active Ralph loop \u2014 processing anyway to avoid stalling`);
6753
+ turnInitiatedByUser = true;
6754
+ }
6745
6755
  if (msg.session_id) {
6746
6756
  claudeResumeId = msg.session_id;
6747
6757
  }
@@ -8864,6 +8874,85 @@ async function stopDaemon(options) {
8864
8874
  } catch {
8865
8875
  }
8866
8876
  }
8877
+ async function restartDaemon() {
8878
+ const supervisorPidFile = join(SVAMP_HOME, "supervisor.pid");
8879
+ let supervisorPid = null;
8880
+ try {
8881
+ if (existsSync$1(supervisorPidFile)) {
8882
+ supervisorPid = parseInt(readFileSync$1(supervisorPidFile, "utf-8").trim(), 10);
8883
+ if (isNaN(supervisorPid)) supervisorPid = null;
8884
+ if (supervisorPid) {
8885
+ try {
8886
+ process.kill(supervisorPid, 0);
8887
+ } catch {
8888
+ supervisorPid = null;
8889
+ }
8890
+ }
8891
+ }
8892
+ } catch {
8893
+ }
8894
+ const doFullRestart = async (reason) => {
8895
+ console.log(`${reason} \u2014 doing full stop + start`);
8896
+ await stopDaemon();
8897
+ const { spawn: spawn2 } = await import('child_process');
8898
+ const child = spawn2(process.execPath, [
8899
+ "--no-warnings",
8900
+ "--no-deprecation",
8901
+ ...process.argv.slice(1, 2),
8902
+ "daemon",
8903
+ "start-supervised"
8904
+ ], {
8905
+ detached: true,
8906
+ stdio: "ignore",
8907
+ env: process.env
8908
+ });
8909
+ child.unref();
8910
+ const stateFile2 = join(SVAMP_HOME, "daemon.state.json");
8911
+ for (let i = 0; i < 100; i++) {
8912
+ await new Promise((r) => setTimeout(r, 100));
8913
+ if (existsSync$1(stateFile2)) {
8914
+ console.log("Daemon restarted successfully");
8915
+ return;
8916
+ }
8917
+ }
8918
+ console.error("Failed to restart daemon (timeout waiting for state file)");
8919
+ process.exit(1);
8920
+ };
8921
+ if (!supervisorPid) {
8922
+ await doFullRestart("No supervisor process found");
8923
+ return;
8924
+ }
8925
+ const oldState = readDaemonStateFile();
8926
+ const oldPid = oldState?.pid;
8927
+ console.log(`Sending SIGUSR2 to supervisor (PID ${supervisorPid}) \u2014 graceful restart`);
8928
+ try {
8929
+ process.kill(supervisorPid, "SIGUSR2");
8930
+ } catch {
8931
+ await doFullRestart("Failed to signal supervisor");
8932
+ return;
8933
+ }
8934
+ const stateFile = join(SVAMP_HOME, "daemon.state.json");
8935
+ for (let i = 0; i < 300; i++) {
8936
+ await new Promise((r) => setTimeout(r, 100));
8937
+ try {
8938
+ process.kill(supervisorPid, 0);
8939
+ } catch {
8940
+ await doFullRestart("Supervisor exited (old binary without SIGUSR2 support?)");
8941
+ return;
8942
+ }
8943
+ const newState = readDaemonStateFile();
8944
+ if (newState && newState.pid !== oldPid) {
8945
+ console.log("Daemon restarted successfully (new binary in effect)");
8946
+ return;
8947
+ }
8948
+ }
8949
+ if (existsSync$1(stateFile)) {
8950
+ console.log("Daemon restarted (state file present)");
8951
+ } else {
8952
+ console.error("Daemon restart may have failed \u2014 no state file after 30s. Falling back to full restart.");
8953
+ await doFullRestart("Graceful restart timed out");
8954
+ }
8955
+ }
8867
8956
  function daemonStatus() {
8868
8957
  const state = readDaemonStateFile();
8869
8958
  if (!state) {
@@ -8895,4 +8984,12 @@ function daemonStatus() {
8895
8984
  }
8896
8985
  }
8897
8986
 
8898
- export { DefaultTransport$1 as D, GeminiTransport$1 as G, registerSessionService as a, stopDaemon as b, connectToHypha as c, daemonStatus as d, resolveSecurityContext as e, buildSecurityContextFromFlags as f, getHyphaServerUrl as g, acpBackend as h, acpAgentConfig as i, codexMcpBackend as j, loadSecurityContextConfig as l, mergeSecurityContexts as m, registerMachineService as r, startDaemon as s };
8987
+ var run = /*#__PURE__*/Object.freeze({
8988
+ __proto__: null,
8989
+ daemonStatus: daemonStatus,
8990
+ restartDaemon: restartDaemon,
8991
+ startDaemon: startDaemon,
8992
+ stopDaemon: stopDaemon
8993
+ });
8994
+
8995
+ export { DefaultTransport$1 as D, GeminiTransport$1 as G, registerSessionService as a, stopDaemon as b, connectToHypha as c, daemonStatus as d, resolveSecurityContext as e, buildSecurityContextFromFlags as f, getHyphaServerUrl as g, acpBackend as h, acpAgentConfig as i, codexMcpBackend as j, run as k, loadSecurityContextConfig as l, mergeSecurityContexts as m, registerMachineService as r, startDaemon as s };
@@ -0,0 +1,12 @@
1
+ function isSandboxed() {
2
+ return process.env.SVAMP_SANDBOXED === "1";
3
+ }
4
+ const SANDBOX_BLOCKED_MSG = "This command is not available in sandboxed sessions. Available commands: set-title, set-link";
5
+ function requireNotSandboxed(commandName) {
6
+ if (isSandboxed()) {
7
+ console.error(`${commandName}: ${SANDBOX_BLOCKED_MSG}`);
8
+ process.exit(1);
9
+ }
10
+ }
11
+
12
+ export { SANDBOX_BLOCKED_MSG, isSandboxed, requireNotSandboxed };
@@ -52,7 +52,7 @@ async function handleServeCommand() {
52
52
  }
53
53
  }
54
54
  async function serveAdd(args, machineId) {
55
- const { connectAndGetMachine } = await import('./commands-DsBtNTwb.mjs');
55
+ const { connectAndGetMachine } = await import('./commands-8ZF7ClgV.mjs');
56
56
  const pos = positionalArgs(args);
57
57
  const name = pos[0];
58
58
  if (!name) {
@@ -84,7 +84,7 @@ async function serveAdd(args, machineId) {
84
84
  }
85
85
  }
86
86
  async function serveRemove(args, machineId) {
87
- const { connectAndGetMachine } = await import('./commands-DsBtNTwb.mjs');
87
+ const { connectAndGetMachine } = await import('./commands-8ZF7ClgV.mjs');
88
88
  const pos = positionalArgs(args);
89
89
  const name = pos[0];
90
90
  if (!name) {
@@ -104,7 +104,7 @@ async function serveRemove(args, machineId) {
104
104
  }
105
105
  }
106
106
  async function serveList(args, machineId) {
107
- const { connectAndGetMachine } = await import('./commands-DsBtNTwb.mjs');
107
+ const { connectAndGetMachine } = await import('./commands-8ZF7ClgV.mjs');
108
108
  const all = hasFlag(args, "--all", "-a");
109
109
  const json = hasFlag(args, "--json");
110
110
  const sessionId = getFlag(args, "--session");
@@ -137,7 +137,7 @@ async function serveList(args, machineId) {
137
137
  }
138
138
  }
139
139
  async function serveInfo(machineId) {
140
- const { connectAndGetMachine } = await import('./commands-DsBtNTwb.mjs');
140
+ const { connectAndGetMachine } = await import('./commands-8ZF7ClgV.mjs');
141
141
  const { machine, server } = await connectAndGetMachine(machineId);
142
142
  try {
143
143
  const info = await machine.serveInfo({ _rkwargs: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svamp-cli",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "Svamp CLI — AI workspace daemon on Hypha Cloud",
5
5
  "author": "Amun AI AB",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -1,27 +0,0 @@
1
- import { existsSync, readFileSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import os from 'node:os';
4
-
5
- function isSandboxed() {
6
- if (!process.env.SVAMP_SESSION_ID) return false;
7
- if (process.env.HYPHA_TOKEN) return false;
8
- const svampHome = process.env.SVAMP_HOME || join(os.homedir(), ".svamp");
9
- const envFile = join(svampHome, ".env");
10
- try {
11
- if (existsSync(envFile)) {
12
- const content = readFileSync(envFile, "utf-8");
13
- if (content.includes("HYPHA_TOKEN=")) return false;
14
- }
15
- } catch {
16
- }
17
- return true;
18
- }
19
- const SANDBOX_BLOCKED_MSG = "This command is not available in sandboxed sessions. Available commands: set-title, set-link";
20
- function requireNotSandboxed(commandName) {
21
- if (isSandboxed()) {
22
- console.error(`${commandName}: ${SANDBOX_BLOCKED_MSG}`);
23
- process.exit(1);
24
- }
25
- }
26
-
27
- export { SANDBOX_BLOCKED_MSG, isSandboxed, requireNotSandboxed };