svamp-cli 0.2.102 → 0.2.103

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,6 +1,6 @@
1
1
  ---
2
2
  name: loop
3
- version: 0.2.0
3
+ version: 0.2.1
4
4
  description: Run a task as a reliable, self-verifying loop — iterate until objective exit conditions are met, with an independent evaluator instead of self-judging. Use when a task needs repeated iterations until "done" (fix until tests pass, refactor until clean, build until a spec is met, autonomous long-running work).
5
5
  ---
6
6
 
@@ -31,6 +31,10 @@ const evaluatorOn = args.evaluator !== 'off';
31
31
  const model = typeof args.model === 'string' ? args.model : null;
32
32
  const task = typeof args.task === 'string' ? args.task : '(describe the task here)';
33
33
  const criteria = typeof args.criteria === 'string' ? args.criteria : null;
34
+ // Owning session id, stamped into loop-state.json so the daemon can scope
35
+ // "loop active" (auto-approve / AskUserQuestion auto-dismiss / loop resume) to the
36
+ // session that started the loop instead of every session sharing this directory.
37
+ const sessionId = typeof args.session === 'string' ? args.session : null;
34
38
 
35
39
  const loopDir = join(dir, '.claude', 'loop');
36
40
  const binDir = join(loopDir, 'bin');
@@ -60,6 +64,7 @@ writeFileSync(join(loopDir, 'loop.config.json'), JSON.stringify(config, null, 2)
60
64
  // 3. loop-state.json (machine state, daemon/gate-owned)
61
65
  writeFileSync(join(loopDir, 'loop-state.json'), JSON.stringify({
62
66
  active: true, iteration: 0, phase: 'running', started_at: new Date().toISOString(),
67
+ ...(sessionId ? { session_id: sessionId } : {}),
63
68
  }, null, 2));
64
69
 
65
70
  // 4. LOOP.md (agent + human editable) — only if not present
@@ -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-DpRXzSr9.mjs');
151
+ const { connectAndGetMachine } = await import('./commands-C_DlMpl7.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-DpRXzSr9.mjs');
168
+ const { resolveSessionId } = await import('./commands-C_DlMpl7.mjs');
169
169
  const sessions = await machine.listSessions();
170
170
  const match = resolveSessionId(sessions, targetSessionId);
171
171
  const fullTargetId = match.sessionId;
@@ -235,10 +235,7 @@ async function inboxReply(messageId, body) {
235
235
  }
236
236
  if (original.channelId && original.correlationId) {
237
237
  const rr = await machine.sessionRPC(sessionId, "channelReply", {
238
- channel: original.channelId,
239
- correlationId: original.correlationId,
240
- to: original.from,
241
- body
238
+ params: { channel: original.channelId, correlationId: original.correlationId, to: original.from, body }
242
239
  });
243
240
  if (rr?.error) {
244
241
  console.error(`Channel reply failed: ${rr.error}`);
@@ -1,4 +1,4 @@
1
- import { E as resolveModel } from './run-B_FyvS11.mjs';
1
+ import { E as resolveModel } from './run-BmZjAEob.mjs';
2
2
  import 'os';
3
3
  import 'fs/promises';
4
4
  import 'fs';
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-B_FyvS11.mjs';
1
+ import { e as clearStopMarker, f as stopMarkerExists, s as startDaemon, b as stopDaemon, d as daemonStatus } from './run-BmZjAEob.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-B_FyvS11.mjs').then(function (n) { return n.Y; });
37
+ const { getLoadedConfig } = await import('./run-BmZjAEob.mjs').then(function (n) { return n.Y; });
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-B_FyvS11.mjs').then(function (n) { return n._; });
54
+ const { restartDaemon } = await import('./run-BmZjAEob.mjs').then(function (n) { return n._; });
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-h6yGJuJw.mjs');
347
+ const { handleServiceCommand } = await import('./commands-BvJ_Dl1l.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-O2px1za0.mjs');
355
+ const { handleServeCommand } = await import('./serveCommands-zFOjNs-0.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-Clj_0eV6.mjs');
364
+ const { processCommand } = await import('./commands-BXFukv2v.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-DNxxgy4V.mjs');
378
+ const { routineCommand } = await import('./commands-BGE6zFa1.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-BsbKsOb_.mjs').catch(() => ({ default: { version: "unknown" } }));
389
+ const pkg = await import('./package-fu3Jsw1q.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-CW6bkzDX.mjs');
398
+ const { runInteractive } = await import('./run-DTOSfKSH.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-B_FyvS11.mjs').then(function (n) { return n.U; });
443
+ const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-BmZjAEob.mjs').then(function (n) { return n.U; });
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-B_FyvS11.mjs').then(function (n) { return n.U; });
455
+ const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-BmZjAEob.mjs').then(function (n) { return n.U; });
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-B_FyvS11.mjs').then(function (n) { return n.V; });
479
+ const { CodexMcpBackend } = await import('./run-BmZjAEob.mjs').then(function (n) { return n.V; });
480
480
  backend = new CodexMcpBackend({ cwd, log: logFn });
481
481
  } else {
482
- const { AcpBackend } = await import('./run-B_FyvS11.mjs').then(function (n) { return n.T; });
483
- const { GeminiTransport } = await import('./run-B_FyvS11.mjs').then(function (n) { return n.W; });
484
- const { DefaultTransport } = await import('./run-B_FyvS11.mjs').then(function (n) { return n.Q; });
482
+ const { AcpBackend } = await import('./run-BmZjAEob.mjs').then(function (n) { return n.T; });
483
+ const { GeminiTransport } = await import('./run-BmZjAEob.mjs').then(function (n) { return n.W; });
484
+ const { DefaultTransport } = await import('./run-BmZjAEob.mjs').then(function (n) { return n.Q; });
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, sessionLoopStart, sessionLoopCancel, sessionLoopStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-DpRXzSr9.mjs');
611
+ const { sessionList, sessionWhoami, sessionSpawn, sessionArchive, sessionResume, sessionDelete, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionLoopStart, sessionLoopCancel, sessionLoopStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-C_DlMpl7.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-DpRXzSr9.mjs');
679
+ const { parseShareArg } = await import('./commands-C_DlMpl7.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-DpRXzSr9.mjs');
766
+ const { sessionQuery } = await import('./commands-C_DlMpl7.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-DpRXzSr9.mjs');
799
+ const { sessionApprove } = await import('./commands-C_DlMpl7.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-DpRXzSr9.mjs');
809
+ const { sessionDeny } = await import('./commands-C_DlMpl7.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")
@@ -841,7 +841,7 @@ async function handleSessionCommand() {
841
841
  console.error("Usage: svamp session set-title <title>");
842
842
  process.exit(1);
843
843
  }
844
- const { sessionSetTitle } = await import('./agentCommands-Cm-Cu_9Z.mjs');
844
+ const { sessionSetTitle } = await import('./agentCommands-oHt9FQJt.mjs');
845
845
  await sessionSetTitle(title);
846
846
  } else if (sessionSubcommand === "set-link") {
847
847
  const url = sessionArgs[1];
@@ -850,7 +850,7 @@ async function handleSessionCommand() {
850
850
  process.exit(1);
851
851
  }
852
852
  const label = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
853
- const { sessionSetLink } = await import('./agentCommands-Cm-Cu_9Z.mjs');
853
+ const { sessionSetLink } = await import('./agentCommands-oHt9FQJt.mjs');
854
854
  await sessionSetLink(url, label);
855
855
  } else if (sessionSubcommand === "notify") {
856
856
  const message = sessionArgs[1];
@@ -859,7 +859,7 @@ async function handleSessionCommand() {
859
859
  process.exit(1);
860
860
  }
861
861
  const level = parseFlagStr("--level") || "info";
862
- const { sessionNotify } = await import('./agentCommands-Cm-Cu_9Z.mjs');
862
+ const { sessionNotify } = await import('./agentCommands-oHt9FQJt.mjs');
863
863
  await sessionNotify(message, level);
864
864
  } else if (sessionSubcommand === "broadcast") {
865
865
  const action = sessionArgs[1];
@@ -867,7 +867,7 @@ async function handleSessionCommand() {
867
867
  console.error("Usage: svamp session broadcast <action> [args...]\nActions: open-canvas <url> [label], close-canvas, toast <message>");
868
868
  process.exit(1);
869
869
  }
870
- const { sessionBroadcast } = await import('./agentCommands-Cm-Cu_9Z.mjs');
870
+ const { sessionBroadcast } = await import('./agentCommands-oHt9FQJt.mjs');
871
871
  await sessionBroadcast(action, sessionArgs.slice(2).filter((a) => !a.startsWith("--")));
872
872
  } else if (sessionSubcommand === "inbox") {
873
873
  const inboxSubcmd = sessionArgs[1];
@@ -878,7 +878,7 @@ async function handleSessionCommand() {
878
878
  process.exit(1);
879
879
  }
880
880
  if (agentSessionId) {
881
- const { inboxSend } = await import('./agentCommands-Cm-Cu_9Z.mjs');
881
+ const { inboxSend } = await import('./agentCommands-oHt9FQJt.mjs');
882
882
  await inboxSend(sessionArgs[2], {
883
883
  body: sessionArgs[3],
884
884
  subject: parseFlagStr("--subject"),
@@ -893,7 +893,7 @@ async function handleSessionCommand() {
893
893
  }
894
894
  } else if (inboxSubcmd === "list" || inboxSubcmd === "ls") {
895
895
  if (agentSessionId && !sessionArgs[2]) {
896
- const { inboxList } = await import('./agentCommands-Cm-Cu_9Z.mjs');
896
+ const { inboxList } = await import('./agentCommands-oHt9FQJt.mjs');
897
897
  await inboxList({
898
898
  unread: hasFlag("--unread"),
899
899
  limit: parseFlagInt("--limit"),
@@ -915,7 +915,7 @@ async function handleSessionCommand() {
915
915
  process.exit(1);
916
916
  }
917
917
  if (agentSessionId && !sessionArgs[3]) {
918
- const { inboxList } = await import('./agentCommands-Cm-Cu_9Z.mjs');
918
+ const { inboxList } = await import('./agentCommands-oHt9FQJt.mjs');
919
919
  await sessionInboxRead(agentSessionId, sessionArgs[2], targetMachineId);
920
920
  } else if (sessionArgs[3]) {
921
921
  await sessionInboxRead(sessionArgs[2], sessionArgs[3], targetMachineId);
@@ -925,7 +925,7 @@ async function handleSessionCommand() {
925
925
  }
926
926
  } else if (inboxSubcmd === "reply") {
927
927
  if (agentSessionId && sessionArgs[2] && sessionArgs[3] && !sessionArgs[4]) {
928
- const { inboxReply } = await import('./agentCommands-Cm-Cu_9Z.mjs');
928
+ const { inboxReply } = await import('./agentCommands-oHt9FQJt.mjs');
929
929
  await inboxReply(sessionArgs[2], sessionArgs[3]);
930
930
  } else if (sessionArgs[2] && sessionArgs[3] && sessionArgs[4]) {
931
931
  await sessionInboxReply(sessionArgs[2], sessionArgs[3], sessionArgs[4], targetMachineId);
@@ -961,7 +961,7 @@ async function handleMachineCommand() {
961
961
  return;
962
962
  }
963
963
  if (machineSubcommand === "share") {
964
- const { machineShare } = await import('./commands-DpRXzSr9.mjs');
964
+ const { machineShare } = await import('./commands-C_DlMpl7.mjs');
965
965
  let machineId;
966
966
  const shareArgs = [];
967
967
  for (let i = 1; i < machineArgs.length; i++) {
@@ -991,7 +991,7 @@ async function handleMachineCommand() {
991
991
  }
992
992
  await machineShare(machineId, { add, remove, list, configPath, showConfig });
993
993
  } else if (machineSubcommand === "exec") {
994
- const { machineExec } = await import('./commands-DpRXzSr9.mjs');
994
+ const { machineExec } = await import('./commands-C_DlMpl7.mjs');
995
995
  let machineId;
996
996
  let cwd;
997
997
  const cmdParts = [];
@@ -1011,7 +1011,7 @@ async function handleMachineCommand() {
1011
1011
  }
1012
1012
  await machineExec(machineId, command, cwd);
1013
1013
  } else if (machineSubcommand === "info") {
1014
- const { machineInfo } = await import('./commands-DpRXzSr9.mjs');
1014
+ const { machineInfo } = await import('./commands-C_DlMpl7.mjs');
1015
1015
  let machineId;
1016
1016
  for (let i = 1; i < machineArgs.length; i++) {
1017
1017
  if ((machineArgs[i] === "--machine" || machineArgs[i] === "-m") && i + 1 < machineArgs.length) {
@@ -1031,10 +1031,10 @@ async function handleMachineCommand() {
1031
1031
  level = machineArgs[++i];
1032
1032
  }
1033
1033
  }
1034
- const { machineNotify } = await import('./agentCommands-Cm-Cu_9Z.mjs');
1034
+ const { machineNotify } = await import('./agentCommands-oHt9FQJt.mjs');
1035
1035
  await machineNotify(message, level);
1036
1036
  } else if (machineSubcommand === "ls") {
1037
- const { machineLs } = await import('./commands-DpRXzSr9.mjs');
1037
+ const { machineLs } = await import('./commands-C_DlMpl7.mjs');
1038
1038
  let machineId;
1039
1039
  let showHidden = false;
1040
1040
  let path;
@@ -1092,24 +1092,24 @@ Examples:
1092
1092
  };
1093
1093
  const hasFlag = (name) => fleetArgs.includes(`--${name}`);
1094
1094
  if (sub === "status") {
1095
- const { fleetStatus } = await import('./fleet-Cilkj57K.mjs');
1095
+ const { fleetStatus } = await import('./fleet-BlrT4zSC.mjs');
1096
1096
  await fleetStatus();
1097
1097
  } else if (sub === "exec") {
1098
1098
  const command = fleetArgs.slice(1).filter((a) => !a.startsWith("--")).join(" ");
1099
- const { fleetExec } = await import('./fleet-Cilkj57K.mjs');
1099
+ const { fleetExec } = await import('./fleet-BlrT4zSC.mjs');
1100
1100
  await fleetExec(command, { cwd: flag("cwd") });
1101
1101
  } else if (sub === "upgrade-claude") {
1102
- const { fleetUpgradeClaude } = await import('./fleet-Cilkj57K.mjs');
1102
+ const { fleetUpgradeClaude } = await import('./fleet-BlrT4zSC.mjs');
1103
1103
  await fleetUpgradeClaude({ version: flag("version", "-v") });
1104
1104
  } else if (sub === "upgrade-svamp") {
1105
- const { fleetUpgradeSvamp } = await import('./fleet-Cilkj57K.mjs');
1105
+ const { fleetUpgradeSvamp } = await import('./fleet-BlrT4zSC.mjs');
1106
1106
  await fleetUpgradeSvamp({ version: flag("version", "-v"), excludeSelf: hasFlag("exclude-self") });
1107
1107
  } else if (sub === "daemon-restart") {
1108
- const { fleetDaemonRestart } = await import('./fleet-Cilkj57K.mjs');
1108
+ const { fleetDaemonRestart } = await import('./fleet-BlrT4zSC.mjs');
1109
1109
  await fleetDaemonRestart({ graceful: !hasFlag("cleanup") });
1110
1110
  } else if (sub === "push-skill") {
1111
1111
  const name = fleetArgs[1];
1112
- const { fleetPushSkill } = await import('./fleet-Cilkj57K.mjs');
1112
+ const { fleetPushSkill } = await import('./fleet-BlrT4zSC.mjs');
1113
1113
  await fleetPushSkill(name);
1114
1114
  } else {
1115
1115
  console.error(`Unknown fleet subcommand: ${sub}`);
@@ -1125,7 +1125,7 @@ async function handleSkillsCommand() {
1125
1125
  await printSkillsHelp();
1126
1126
  return;
1127
1127
  }
1128
- const { skillsFind, skillsInstall, skillsList, skillsRemove, skillsPublish } = await import('./commands-x1wznXLf.mjs');
1128
+ const { skillsFind, skillsInstall, skillsList, skillsRemove, skillsPublish } = await import('./commands-C_B8GNUT.mjs');
1129
1129
  if (skillsSubcommand === "find" || skillsSubcommand === "search") {
1130
1130
  const query = skillsArgs.slice(1).filter((a) => !a.startsWith("--")).join(" ");
1131
1131
  if (!query) {
@@ -1172,7 +1172,7 @@ async function loginToHypha() {
1172
1172
  process.exit(1);
1173
1173
  }
1174
1174
  const anchor = anchorArg.replace(/\/+$/, "");
1175
- const { loadInstanceConfig } = await import('./run-B_FyvS11.mjs').then(function (n) { return n.Y; });
1175
+ const { loadInstanceConfig } = await import('./run-BmZjAEob.mjs').then(function (n) { return n.Y; });
1176
1176
  let cfg = null;
1177
1177
  try {
1178
1178
  cfg = await loadInstanceConfig({ anchor, force: true });
@@ -1283,7 +1283,7 @@ async function logoutFromHypha() {
1283
1283
  } catch {
1284
1284
  }
1285
1285
  try {
1286
- const { clearInstanceConfigCache } = await import('./run-B_FyvS11.mjs').then(function (n) { return n.Y; });
1286
+ const { clearInstanceConfigCache } = await import('./run-BmZjAEob.mjs').then(function (n) { return n.Y; });
1287
1287
  clearInstanceConfigCache();
1288
1288
  } catch {
1289
1289
  }
@@ -1614,7 +1614,7 @@ async function applyClaudeAuthFlags(argv) {
1614
1614
  "--use-hypha-proxy, --use-claude-login, and --anthropic-base-url/--anthropic-api-key are mutually exclusive"
1615
1615
  );
1616
1616
  }
1617
- const mod = await import('./run-B_FyvS11.mjs').then(function (n) { return n.X; });
1617
+ const mod = await import('./run-BmZjAEob.mjs').then(function (n) { return n.X; });
1618
1618
  if (hasHypha) {
1619
1619
  let url;
1620
1620
  const hyphaIdx = argv.indexOf("--use-hypha-proxy");
@@ -1668,7 +1668,7 @@ async function applyDaemonShareFlag(argv) {
1668
1668
  }
1669
1669
  }
1670
1670
  if (collected.length === 0) return;
1671
- const { updateEnvFile } = await import('./run-B_FyvS11.mjs').then(function (n) { return n.X; });
1671
+ const { updateEnvFile } = await import('./run-BmZjAEob.mjs').then(function (n) { return n.X; });
1672
1672
  const seen = /* @__PURE__ */ new Set();
1673
1673
  const deduped = collected.filter((e) => {
1674
1674
  const k = e.toLowerCase();
@@ -1701,7 +1701,7 @@ async function handleWiseAgentCommand(rest) {
1701
1701
  }
1702
1702
  });
1703
1703
  const message = rest.slice(1).map((a, idx) => ({ a, idx: idx + 1 })).filter(({ a, idx }) => !a.startsWith("-") && !consumed.has(String(idx))).map(({ a }) => a).join(" ");
1704
- const { wiseAskCli } = await import('./commands-DpRXzSr9.mjs');
1704
+ const { wiseAskCli } = await import('./commands-C_DlMpl7.mjs');
1705
1705
  await wiseAskCli(machineId, message, sessionId, { json });
1706
1706
  return;
1707
1707
  }
@@ -1713,7 +1713,7 @@ async function handleWiseAgentCommand(rest) {
1713
1713
  }
1714
1714
  return void 0;
1715
1715
  };
1716
- const { runWiseVoiceCli } = await import('./headlessCli-CZEbwp47.mjs');
1716
+ const { runWiseVoiceCli } = await import('./headlessCli-D7NXB73S.mjs');
1717
1717
  await runWiseVoiceCli({ voice: valueOf(["--voice"]), wakeKeywordPath: valueOf(["--wake"]), model: valueOf(["--model"]) });
1718
1718
  return;
1719
1719
  }
@@ -1755,7 +1755,7 @@ If none is set, hitting a WISE Agent channel returns a clear "not configured" er
1755
1755
  return;
1756
1756
  }
1757
1757
  const authArgs = rest.slice(1);
1758
- const mod = await import('./auth-BwHB9Upd.mjs');
1758
+ const mod = await import('./auth-Dg0s5H5y.mjs');
1759
1759
  let action;
1760
1760
  try {
1761
1761
  action = mod.parseWiseAgentAuthArgs(authArgs);
@@ -1765,7 +1765,7 @@ If none is set, hitting a WISE Agent channel returns a clear "not configured" er
1765
1765
  return;
1766
1766
  }
1767
1767
  if (action) {
1768
- const { updateEnvFile } = await import('./run-B_FyvS11.mjs').then(function (n) { return n.X; });
1768
+ const { updateEnvFile } = await import('./run-BmZjAEob.mjs').then(function (n) { return n.X; });
1769
1769
  const updates = mod.buildWiseAgentEnvUpdates(action);
1770
1770
  updateEnvFile(updates);
1771
1771
  for (const [k, v] of Object.entries(updates)) {
@@ -1779,7 +1779,7 @@ If none is set, hitting a WISE Agent channel returns a clear "not configured" er
1779
1779
  }
1780
1780
  async function handleDaemonAuthCommand(argv) {
1781
1781
  const sub = (argv[0] || "status").toLowerCase();
1782
- const mod = await import('./run-B_FyvS11.mjs').then(function (n) { return n.X; });
1782
+ const mod = await import('./run-BmZjAEob.mjs').then(function (n) { return n.X; });
1783
1783
  if (sub === "--help" || sub === "-h" || sub === "help") {
1784
1784
  console.log(`
1785
1785
  svamp daemon auth \u2014 Configure how Claude subprocesses authenticate
@@ -2082,7 +2082,7 @@ Examples:
2082
2082
  async function printSkillsHelp() {
2083
2083
  let browseUrl = "<HYPHA_SERVER_URL>/<workspace>/artifacts/marketplace (set HYPHA_SERVER_URL)";
2084
2084
  try {
2085
- const { getArtifactBaseUrl, getSkillsCollectionName } = await import('./run-B_FyvS11.mjs').then(function (n) { return n.Z; });
2085
+ const { getArtifactBaseUrl, getSkillsCollectionName } = await import('./run-BmZjAEob.mjs').then(function (n) { return n.Z; });
2086
2086
  browseUrl = `${getArtifactBaseUrl()}/${getSkillsCollectionName()}`;
2087
2087
  } catch {
2088
2088
  }
@@ -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-B_FyvS11.mjs';
3
+ import { R as RoutineStore, m as RoutineRunner } from './run-BmZjAEob.mjs';
4
4
  import 'os';
5
5
  import 'fs/promises';
6
6
  import 'fs';
@@ -1,11 +1,11 @@
1
1
  import { writeFileSync, readFileSync } from 'fs';
2
2
  import { resolve } from 'path';
3
- import { connectAndGetMachine } from './commands-DpRXzSr9.mjs';
3
+ import { connectAndGetMachine } from './commands-C_DlMpl7.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-B_FyvS11.mjs';
8
+ import './run-BmZjAEob.mjs';
9
9
  import 'os';
10
10
  import 'fs/promises';
11
11
  import 'url';
@@ -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-cJUGFtWY.mjs');
61
+ const { runFrpcTunnel } = await import('./frpc-Dn5pmk_f.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-DpRXzSr9.mjs');
71
+ const { connectAndGetMachine } = await import('./commands-C_DlMpl7.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-cJUGFtWY.mjs');
126
+ const { runFrpcTunnel } = await import('./frpc-Dn5pmk_f.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-DpRXzSr9.mjs');
135
+ const { connectAndGetMachine } = await import('./commands-C_DlMpl7.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-DpRXzSr9.mjs');
164
+ const { connectAndGetMachine } = await import('./commands-C_DlMpl7.mjs');
165
165
  const { server, machine } = await connectAndGetMachine();
166
166
  try {
167
167
  await machine.tunnelStop({ name });
@@ -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-B_FyvS11.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-BmZjAEob.mjs';
5
5
  import 'fs/promises';
6
6
  import 'url';
7
7
  import 'child_process';
@@ -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 { F as normalizeAllowedUser, G as loadSecurityContextConfig, H as resolveSecurityContext, I as buildSecurityContextFromFlags, J as mergeSecurityContexts, c as connectToHypha, K as buildSessionShareUrl, L as computeOutboundHop, M as buildMachineShareUrl } from './run-B_FyvS11.mjs';
5
+ import { F as normalizeAllowedUser, G as loadSecurityContextConfig, H as resolveSecurityContext, I as buildSecurityContextFromFlags, J as mergeSecurityContexts, c as connectToHypha, K as buildSessionShareUrl, L as computeOutboundHop, M as buildMachineShareUrl } from './run-BmZjAEob.mjs';
6
6
  import 'os';
7
7
  import 'fs/promises';
8
8
  import 'fs';
@@ -2420,8 +2420,17 @@ async function sessionInboxReply(sessionIdPartial, messageId, body, machineId) {
2420
2420
  console.error(`Message ${messageId} not found in inbox.`);
2421
2421
  process.exit(1);
2422
2422
  }
2423
+ if (original.channelId && original.correlationId) {
2424
+ const rr = await machine.sessionRPC(fullId, "channelReply", { params: { channel: original.channelId, correlationId: original.correlationId, to: original.from, body } });
2425
+ if (rr?.error) {
2426
+ console.error(`Channel reply failed: ${rr.error}`);
2427
+ process.exit(1);
2428
+ }
2429
+ console.log(`Reply queued to "${original.from}" on channel ${original.channelId} (correlation ${original.correlationId}).`);
2430
+ return;
2431
+ }
2423
2432
  if (!original.fromSession) {
2424
- console.error("Cannot reply: original message has no fromSession.");
2433
+ console.error("Cannot reply: original message has no fromSession (and not a channel message).");
2425
2434
  process.exit(1);
2426
2435
  }
2427
2436
  const { randomUUID } = await import('node:crypto');
@@ -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-B_FyvS11.mjs';
4
+ import { c as connectToHypha } from './run-BmZjAEob.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-B_FyvS11.mjs';
6
+ import { h as getFrpsSubdomainHost, i as getFrpsServerPort, j as getFrpsServerAddr } from './run-BmZjAEob.mjs';
7
7
  import 'fs/promises';
8
8
  import 'url';
9
9
  import 'node:fs';
@@ -1,5 +1,5 @@
1
- import { E as resolveModel, N as describeMisconfiguration, O as buildMachineDeps } from './run-B_FyvS11.mjs';
2
- import { handleRealtimeEvent, initMachineVoiceSession } from './sideband-DYhbiCEA.mjs';
1
+ import { E as resolveModel, N as describeMisconfiguration, O as buildMachineDeps } from './run-BmZjAEob.mjs';
2
+ import { handleRealtimeEvent, initMachineVoiceSession } from './sideband-CNyGVxRy.mjs';
3
3
  import { WebSocket } from 'ws';
4
4
  import { execSync, spawn } from 'child_process';
5
5
  import 'os';
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { c as connectToHypha, a as createSessionStore, d as daemonStatus, g as getHyphaServerUrl, r as registerMachineService, s as startDaemon, b as stopDaemon } from './run-B_FyvS11.mjs';
1
+ export { c as connectToHypha, a as createSessionStore, d as daemonStatus, g as getHyphaServerUrl, r as registerMachineService, s as startDaemon, b as stopDaemon } from './run-BmZjAEob.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.102";
2
+ var version = "0.2.103";
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";
@@ -2166,7 +2166,7 @@ async function registerMachineService(server, machineId, metadata, daemonState,
2166
2166
  const tunnels = handlers.tunnels;
2167
2167
  if (!tunnels) throw new Error("Tunnel management not available");
2168
2168
  if (tunnels.has(params.name)) throw new Error(`Tunnel '${params.name}' already running`);
2169
- const { FrpcTunnel } = await import('./frpc-cJUGFtWY.mjs');
2169
+ const { FrpcTunnel } = await import('./frpc-Dn5pmk_f.mjs');
2170
2170
  const tunnel = new FrpcTunnel({
2171
2171
  name: params.name,
2172
2172
  ports: params.ports,
@@ -2427,7 +2427,7 @@ QUESTION: ${params.question || "Summarize this concisely."}` }
2427
2427
  }
2428
2428
  const deps = buildSessionDeps(rpc, { cwd, ownerEmail: owner });
2429
2429
  const sender = { name: context?.user?.email || context?.user?.id || "user", kind: "user", verified: true };
2430
- const { toolsForRole } = await import('./sideband-DYhbiCEA.mjs');
2430
+ const { toolsForRole } = await import('./sideband-CNyGVxRy.mjs');
2431
2431
  const r2 = await runWiseAgent({ message: params.message, sender, config: { tools: toolsForRole(role2) }, deps, transport, model: resolved.model });
2432
2432
  return fmt(r2);
2433
2433
  }
@@ -9546,6 +9546,17 @@ function isLoopActive(directory) {
9546
9546
  const s = readLoopState(directory);
9547
9547
  return !!s && s.active !== false && s.phase !== "done" && s.phase !== "gave_up" && s.phase !== "cancelled";
9548
9548
  }
9549
+ function loopOwnerSession(directory) {
9550
+ const s = readLoopState(directory);
9551
+ if (!s || s.active === false || s.phase === "done" || s.phase === "gave_up" || s.phase === "cancelled") return null;
9552
+ return typeof s.session_id === "string" ? s.session_id : null;
9553
+ }
9554
+ function isLoopActiveForSession(directory, sessionId) {
9555
+ const s = readLoopState(directory);
9556
+ if (!s || s.active === false || s.phase === "done" || s.phase === "gave_up" || s.phase === "cancelled") return false;
9557
+ if (typeof s.session_id !== "string") return true;
9558
+ return s.session_id === sessionId;
9559
+ }
9549
9560
  function resolveLoopInit() {
9550
9561
  const candidates = [
9551
9562
  join(CLAUDE_SKILLS_DIR, "loop", "bin", "loop-init.mjs"),
@@ -9563,6 +9574,7 @@ function initLoop(directory, cfg) {
9563
9574
  if (typeof cfg.maxIterations === "number") args.push("--max", String(cfg.maxIterations));
9564
9575
  args.push("--evaluator", cfg.evaluator === false ? "off" : "on");
9565
9576
  if (cfg.model) args.push("--model", cfg.model);
9577
+ if (cfg.sessionId) args.push("--session", cfg.sessionId);
9566
9578
  const res = spawnSync(process.execPath, args, { encoding: "utf-8", timeout: 3e4 });
9567
9579
  return res.status === 0;
9568
9580
  }
@@ -9664,7 +9676,8 @@ function createSvampConfigChecker(directory, sessionId, getMetadata, setMetadata
9664
9676
  criteria: typeof lp.criteria === "string" && lp.criteria.trim() ? lp.criteria.trim() : void 0,
9665
9677
  oracle,
9666
9678
  maxIterations,
9667
- evaluator
9679
+ evaluator,
9680
+ sessionId
9668
9681
  });
9669
9682
  if (ok) {
9670
9683
  const existingQueue = getMetadata().messageQueue || [];
@@ -10126,7 +10139,7 @@ async function startDaemon(options) {
10126
10139
  const list = loadExposedTunnels().filter((t) => t.name !== name);
10127
10140
  saveExposedTunnels(list);
10128
10141
  }
10129
- const { ServeManager } = await import('./serveManager-B757hHGd.mjs');
10142
+ const { ServeManager } = await import('./serveManager-D6lGn8jh.mjs');
10130
10143
  const serveManager = new ServeManager(SVAMP_HOME, (msg) => logger.log(`[SERVE] ${msg}`), hyphaServerUrl);
10131
10144
  ensureAutoInstalledSkills(logger).catch(() => {
10132
10145
  });
@@ -10238,7 +10251,7 @@ async function startDaemon(options) {
10238
10251
  }
10239
10252
  }, shouldAutoAllow2 = function(toolName, toolInput) {
10240
10253
  if (toolName === "AskUserQuestion") {
10241
- return isLoopActive(directory);
10254
+ return isLoopActiveForSession(directory, sessionId);
10242
10255
  }
10243
10256
  if (toolName === "Bash") {
10244
10257
  const inputObj = toolInput;
@@ -10251,7 +10264,7 @@ async function startDaemon(options) {
10251
10264
  } else if (allowedTools.has(toolName)) {
10252
10265
  return true;
10253
10266
  }
10254
- if (isLoopActive(directory)) return true;
10267
+ if (isLoopActiveForSession(directory, sessionId)) return true;
10255
10268
  if (currentPermissionMode === "bypassPermissions" || currentPermissionMode === "yolo") return true;
10256
10269
  if ((currentPermissionMode === "acceptEdits" || currentPermissionMode === "safe-yolo") && EDIT_TOOLS.has(toolName)) return true;
10257
10270
  return false;
@@ -10616,6 +10629,12 @@ async function startDaemon(options) {
10616
10629
  logger.log(`[Session ${sessionId}] Permission request: ${requestId} (corr=${correlationId}) tool=${toolName}`);
10617
10630
  if (shouldAutoAllow2(toolName, toolInput)) {
10618
10631
  logger.log(`[Session ${sessionId}] Auto-allowing ${toolName} (mode=${currentPermissionMode})`);
10632
+ if (toolName === "AskUserQuestion") {
10633
+ sessionService.pushMessage(
10634
+ { type: "message", message: "\u{1F501} Question auto-dismissed \u2014 a loop is running, so there is no human to prompt. The agent will proceed as if the questions were skipped.", level: "warning" },
10635
+ "event"
10636
+ );
10637
+ }
10619
10638
  if (claudeProcess && !claudeProcess.killed && claudeProcess.stdin) {
10620
10639
  const controlResponse = JSON.stringify({
10621
10640
  type: "control_response",
@@ -11693,7 +11712,7 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
11693
11712
  } else if (allowedTools.has(toolName)) {
11694
11713
  return true;
11695
11714
  }
11696
- if (isLoopActive(directory)) return true;
11715
+ if (isLoopActiveForSession(directory, sessionId)) return true;
11697
11716
  if (currentPermissionMode === "bypassPermissions" || currentPermissionMode === "yolo") return true;
11698
11717
  if ((currentPermissionMode === "acceptEdits" || currentPermissionMode === "safe-yolo") && EDIT_TOOLS.has(toolName)) return true;
11699
11718
  return false;
@@ -12441,7 +12460,7 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
12441
12460
  const specs = loadExposedTunnels();
12442
12461
  if (specs.length === 0) return;
12443
12462
  logger.log(`[exposed-tunnels] Restoring ${specs.length} tunnel(s) from ${EXPOSED_TUNNELS_FILE}`);
12444
- const { FrpcTunnel } = await import('./frpc-cJUGFtWY.mjs');
12463
+ const { FrpcTunnel } = await import('./frpc-Dn5pmk_f.mjs');
12445
12464
  for (const spec of specs) {
12446
12465
  if (tunnels.has(spec.name)) continue;
12447
12466
  try {
@@ -12523,6 +12542,19 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
12523
12542
  }
12524
12543
  const sessionsToAutoContinue = [];
12525
12544
  const sessionsToLoopResume = [];
12545
+ {
12546
+ const knownSessionIds = new Set(persistedSessions.map((p) => p.sessionId));
12547
+ const sweptDirs = /* @__PURE__ */ new Set();
12548
+ for (const p of persistedSessions) {
12549
+ if (sweptDirs.has(p.directory)) continue;
12550
+ sweptDirs.add(p.directory);
12551
+ const owner = loopOwnerSession(p.directory);
12552
+ if (owner && !knownSessionIds.has(owner)) {
12553
+ deactivateLoop(p.directory);
12554
+ logger.log(`[loop] Deactivated stale loop-state in ${p.directory} (owner session ${owner} no longer known)`);
12555
+ }
12556
+ }
12557
+ }
12526
12558
  if (persistedSessions.length > 0) {
12527
12559
  logger.log(`Restoring ${persistedSessions.length} persisted session(s)...`);
12528
12560
  for (const persisted of persistedSessions) {
@@ -12567,7 +12599,7 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
12567
12599
  if (persisted.wasProcessing && persisted.claudeResumeId && !isOrphaned) {
12568
12600
  sessionsToAutoContinue.push(persisted.sessionId);
12569
12601
  }
12570
- if (!isOrphaned && !persisted.wasProcessing && isLoopActive(persisted.directory)) {
12602
+ if (!isOrphaned && !persisted.wasProcessing && isLoopActiveForSession(persisted.directory, persisted.sessionId)) {
12571
12603
  sessionsToLoopResume.push({ sessionId: persisted.sessionId, directory: persisted.directory });
12572
12604
  }
12573
12605
  } else {
@@ -12614,7 +12646,7 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
12614
12646
  }
12615
12647
  setTimeout(async () => {
12616
12648
  try {
12617
- if (!isLoopActive(sessDir)) return;
12649
+ if (!isLoopActiveForSession(sessDir, sessionId)) return;
12618
12650
  const prompt = "Continue the loop. Read LOOP.md and keep working toward the exit conditions until the Stop gate confirms completion.";
12619
12651
  await rpc.sendMessage(
12620
12652
  JSON.stringify({
@@ -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 createSessionStore, r as registerMachineService, P as generateHookSettings } from './run-B_FyvS11.mjs';
5
+ import { c as connectToHypha, a as createSessionStore, r as registerMachineService, P as generateHookSettings } from './run-BmZjAEob.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-DpRXzSr9.mjs');
57
+ const { connectAndGetMachine } = await import('./commands-C_DlMpl7.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-DpRXzSr9.mjs');
96
+ const { connectAndGetMachine } = await import('./commands-C_DlMpl7.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-DpRXzSr9.mjs');
185
+ const { connectAndGetMachine } = await import('./commands-C_DlMpl7.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-DpRXzSr9.mjs');
205
+ const { connectAndGetMachine } = await import('./commands-C_DlMpl7.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-DpRXzSr9.mjs');
238
+ const { connectAndGetMachine } = await import('./commands-C_DlMpl7.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-B_FyvS11.mjs';
7
+ import { k as getHyphaServerUrl, S as ServeAuth, l as hasCookieToken } from './run-BmZjAEob.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-cJUGFtWY.mjs');
716
+ const { FrpcTunnel } = await import('./frpc-Dn5pmk_f.mjs');
717
717
  let tunnel;
718
718
  tunnel = new FrpcTunnel({
719
719
  name: tunnelName,
@@ -1,4 +1,4 @@
1
- import { z as READ_ONLY_TOOLS, A as loadMachineContext, B as buildMachineInstructions, C as machineToolsForRole, D as buildMachineTools } from './run-B_FyvS11.mjs';
1
+ import { z as READ_ONLY_TOOLS, A as loadMachineContext, B as buildMachineInstructions, C as machineToolsForRole, D as buildMachineTools } from './run-BmZjAEob.mjs';
2
2
  import 'node:child_process';
3
3
  import 'os';
4
4
  import 'fs/promises';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svamp-cli",
3
- "version": "0.2.102",
3
+ "version": "0.2.103",
4
4
  "description": "Svamp CLI — AI workspace daemon on Hypha Cloud",
5
5
  "author": "Amun AI AB",
6
6
  "license": "SEE LICENSE IN LICENSE",