svamp-cli 0.2.86 → 0.2.89

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.
@@ -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-BfBqHN33.mjs');
61
+ const { runFrpcTunnel } = await import('./frpc-BiazjxzU.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-Dj7Be8dw.mjs');
71
+ const { connectAndGetMachine } = await import('./commands-DY1ciMPa.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-BfBqHN33.mjs');
126
+ const { runFrpcTunnel } = await import('./frpc-BiazjxzU.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-Dj7Be8dw.mjs');
135
+ const { connectAndGetMachine } = await import('./commands-DY1ciMPa.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-Dj7Be8dw.mjs');
164
+ const { connectAndGetMachine } = await import('./commands-DY1ciMPa.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, l as getSkillsServer, m as getSkillsWorkspaceName, n as getSkillsCollectionName, o as fetchWithTimeout, q as searchSkills, t as SKILLS_DIR, u as getSkillInfo, v as downloadSkillFile, w as listSkillFiles } from './run-rWXfNd7e.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-C4i9N-F6.mjs';
5
5
  import 'fs/promises';
6
6
  import 'url';
7
7
  import 'child_process';
@@ -11,6 +11,7 @@ import 'util';
11
11
  import 'node:crypto';
12
12
  import 'node:path';
13
13
  import 'node:os';
14
+ import 'node:vm';
14
15
  import 'node:child_process';
15
16
  import '@agentclientprotocol/sdk';
16
17
  import '@modelcontextprotocol/sdk/client/index.js';
@@ -1,6 +1,6 @@
1
1
  import { execFileSync } from 'node:child_process';
2
2
  import { createServer } from 'node:http';
3
- import { R as RoutineStore, k as RoutineRunner } from './run-rWXfNd7e.mjs';
3
+ import { R as RoutineStore, m as RoutineRunner } from './run-C4i9N-F6.mjs';
4
4
  import 'os';
5
5
  import 'fs/promises';
6
6
  import 'fs';
@@ -13,6 +13,7 @@ import 'util';
13
13
  import 'node:crypto';
14
14
  import 'node:path';
15
15
  import 'node:os';
16
+ import 'node:vm';
16
17
  import '@agentclientprotocol/sdk';
17
18
  import '@modelcontextprotocol/sdk/client/index.js';
18
19
  import '@modelcontextprotocol/sdk/client/stdio.js';
@@ -1,11 +1,11 @@
1
1
  import { writeFileSync, readFileSync } from 'fs';
2
2
  import { resolve } from 'path';
3
- import { connectAndGetMachine } from './commands-Dj7Be8dw.mjs';
3
+ import { connectAndGetMachine } from './commands-DY1ciMPa.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-rWXfNd7e.mjs';
8
+ import './run-C4i9N-F6.mjs';
9
9
  import 'os';
10
10
  import 'fs/promises';
11
11
  import 'url';
@@ -13,6 +13,7 @@ import 'child_process';
13
13
  import 'crypto';
14
14
  import 'util';
15
15
  import 'node:crypto';
16
+ import 'node:vm';
16
17
  import '@agentclientprotocol/sdk';
17
18
  import '@modelcontextprotocol/sdk/client/index.js';
18
19
  import '@modelcontextprotocol/sdk/client/stdio.js';
@@ -1,8 +1,8 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
2
  import { execSync } from 'node:child_process';
3
- import { resolve, join } from 'node:path';
3
+ import { basename, resolve, join } from 'node:path';
4
4
  import os from 'node:os';
5
- import { x as normalizeAllowedUser, y as loadSecurityContextConfig, z as resolveSecurityContext, A as buildSecurityContextFromFlags, B as mergeSecurityContexts, c as connectToHypha, C as buildSessionShareUrl, D as buildMachineShareUrl } from './run-rWXfNd7e.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-C4i9N-F6.mjs';
6
6
  import 'os';
7
7
  import 'fs/promises';
8
8
  import 'fs';
@@ -12,6 +12,7 @@ import 'child_process';
12
12
  import 'crypto';
13
13
  import 'util';
14
14
  import 'node:crypto';
15
+ import 'node:vm';
15
16
  import '@agentclientprotocol/sdk';
16
17
  import '@modelcontextprotocol/sdk/client/index.js';
17
18
  import '@modelcontextprotocol/sdk/client/stdio.js';
@@ -33,6 +34,15 @@ function formatTime(ts) {
33
34
  const diffDay = Math.floor(diffHr / 24);
34
35
  return `${diffDay}d ago`;
35
36
  }
37
+ function resolveDisplayName(meta, directory) {
38
+ const m = meta || {};
39
+ const customTitle = typeof m.customTitle === "string" ? m.customTitle.trim() : "";
40
+ const summary = typeof m.summary?.text === "string" ? m.summary.text.trim() : "";
41
+ const name = typeof m.name === "string" ? m.name.trim() : "";
42
+ const dir = (directory || m.path || "").replace(/[/\\]+$/, "");
43
+ const dirName = dir ? basename(dir) : "";
44
+ return customTitle || summary || name || dirName || "untitled";
45
+ }
36
46
  function toMarkdownInline(value) {
37
47
  const escaped = value.replace(/`/g, "\\`");
38
48
  return `\`${escaped}\``;
@@ -44,8 +54,8 @@ function formatSessionStatus(data) {
44
54
  `- Session ID: ${toMarkdownInline(data.sessionId)}`,
45
55
  `- Agent: ${data.flavor}`
46
56
  ];
47
- if (data.name) lines.push(`- Name: ${data.name}`);
48
- if (data.summary) lines.push(`- Summary: ${data.summary}`);
57
+ if (data.name) lines.push(`- Title: ${data.name}`);
58
+ if (data.summary && data.summary !== data.name) lines.push(`- Summary: ${data.summary}`);
49
59
  if (data.path) lines.push(`- Path: ${data.path}`);
50
60
  if (data.host) lines.push(`- Host: ${data.host}`);
51
61
  if (data.lifecycleState) lines.push(`- Lifecycle: ${data.lifecycleState}`);
@@ -766,6 +776,111 @@ async function sessionList(machineId, opts) {
766
776
  }
767
777
  }
768
778
  }
779
+ function formatPeerLine(s) {
780
+ const m = s.metadata || {};
781
+ const title = resolveDisplayName(m, s.directory);
782
+ const agent = m.flavor || "claude";
783
+ const status = s.active ? "\x1B[32mactive\x1B[0m" : "\x1B[90midle\x1B[0m";
784
+ const dir = m.path || s.directory || "-";
785
+ return ` [${s.sessionId.slice(0, 8)}] ${truncate(title, 32)} \u2014 ${status} \xB7 ${agent} \xB7 ${dir}`;
786
+ }
787
+ async function sessionWhoami(opts) {
788
+ const currentSessionId = process.env.SVAMP_SESSION_ID;
789
+ const PEER_CAP = 18;
790
+ const { server, machines } = await connectAndGetAllMachines();
791
+ try {
792
+ const perMachine = await Promise.allSettled(
793
+ machines.map(async (machine) => {
794
+ const [info, sessions] = await Promise.all([
795
+ machine.getMachineInfo(),
796
+ machine.listSessions()
797
+ ]);
798
+ return { info, sessions };
799
+ })
800
+ );
801
+ const gathered = perMachine.filter((r) => r.status === "fulfilled").map((r) => r.value);
802
+ const machineLabel = (info) => info?.metadata?.displayName || info?.metadata?.host || info?.metadata?.hostname || info?.machineId || "unknown";
803
+ let current = null;
804
+ let currentSession = null;
805
+ if (currentSessionId) {
806
+ for (const g of gathered) {
807
+ const match = g.sessions.find((s) => s.sessionId === currentSessionId || s.sessionId.startsWith(currentSessionId));
808
+ if (match) {
809
+ current = g;
810
+ currentSession = match;
811
+ break;
812
+ }
813
+ }
814
+ }
815
+ if (opts?.json) {
816
+ console.log(formatJson({
817
+ currentSessionId: currentSession?.sessionId || currentSessionId || null,
818
+ currentMachine: current ? machineLabel(current.info) : null,
819
+ machines: gathered.map((g) => ({
820
+ machine: machineLabel(g.info),
821
+ isCurrent: g === current,
822
+ sessions: g.sessions.map((s) => ({
823
+ sessionId: s.sessionId,
824
+ title: resolveDisplayName(s.metadata || {}, s.directory),
825
+ agent: s.metadata?.flavor || "claude",
826
+ active: s.active,
827
+ directory: s.metadata?.path || s.directory || null,
828
+ isSelf: s.sessionId === currentSession?.sessionId
829
+ }))
830
+ }))
831
+ }));
832
+ return;
833
+ }
834
+ const lines = ["# Your environment", ""];
835
+ if (currentSession && current) {
836
+ const m = currentSession.metadata || {};
837
+ lines.push("## This session");
838
+ lines.push(`- id: ${currentSession.sessionId}`);
839
+ lines.push(`- title: ${resolveDisplayName(m, currentSession.directory)}`);
840
+ lines.push(`- agent: ${m.flavor || "claude"}`);
841
+ lines.push(`- dir: ${m.path || currentSession.directory || "-"}`);
842
+ lines.push(`- machine: ${machineLabel(current.info)}`);
843
+ } else if (currentSessionId) {
844
+ lines.push("## This session");
845
+ lines.push(`- id: ${currentSessionId} (not yet visible in the machine registry)`);
846
+ } else {
847
+ lines.push("_Not running inside a Svamp session (SVAMP_SESSION_ID unset). Showing all reachable sessions._");
848
+ }
849
+ lines.push("");
850
+ const byActive = (a, b) => (b.active ? 1 : 0) - (a.active ? 1 : 0);
851
+ if (current) {
852
+ const peers = current.sessions.filter((s) => s.sessionId !== currentSession?.sessionId).sort(byActive);
853
+ lines.push(`## Same machine \u2014 ${machineLabel(current.info)} (${peers.length} peer${peers.length === 1 ? "" : "s"})`);
854
+ if (peers.length === 0) lines.push(" (no other sessions here)");
855
+ const shown = opts?.all ? peers : peers.slice(0, PEER_CAP);
856
+ for (const s of shown) lines.push(formatPeerLine(s));
857
+ if (peers.length > shown.length) lines.push(` \u2026 +${peers.length - shown.length} more \u2014 run \`svamp session whoami --all\` to see all`);
858
+ lines.push("");
859
+ }
860
+ const others = gathered.filter((g) => g !== current);
861
+ const otherTotal = others.reduce((n, g) => n + g.sessions.length, 0);
862
+ if (others.length > 0) {
863
+ lines.push(`## Other machines \u2014 same user (${otherTotal} session${otherTotal === 1 ? "" : "s"})`);
864
+ for (const g of others) {
865
+ const ms = [...g.sessions].sort(byActive);
866
+ lines.push(` \u2022 ${machineLabel(g.info)} (${ms.length}):`);
867
+ if (ms.length === 0) lines.push(" (none)");
868
+ const shown = opts?.all ? ms : ms.slice(0, PEER_CAP);
869
+ for (const s of shown) lines.push(formatPeerLine(s));
870
+ if (ms.length > shown.length) lines.push(` \u2026 +${ms.length - shown.length} more (--all)`);
871
+ }
872
+ lines.push("");
873
+ }
874
+ lines.push("## Reach a peer");
875
+ lines.push("- `svamp session info <id>` / `svamp session messages <id>` \u2014 inspect before reaching out");
876
+ lines.push('- `svamp session send <id> "<msg>"` \u2014 drop a message into a peer\'s inbox');
877
+ lines.push('- Reply to an inbox message: `svamp session inbox reply <message-id> "<body>"`');
878
+ lines.push("- Keep it purposeful: only initiate with a concrete reason, avoid ping-pong loops.");
879
+ console.log(lines.join("\n"));
880
+ } finally {
881
+ await server.disconnect();
882
+ }
883
+ }
769
884
  async function listSessionsFromMachines(_server, machines, opts) {
770
885
  const allSessions = [];
771
886
  const machineResults = await Promise.allSettled(
@@ -798,7 +913,7 @@ async function listSessionsFromMachines(_server, machines, opts) {
798
913
  return {
799
914
  ...s,
800
915
  flavor: m.flavor || "claude",
801
- name: m.summary?.text || m.name || "",
916
+ name: resolveDisplayName(m, s.directory),
802
917
  path: m.path || s.directory || "",
803
918
  host: m.host || s.machineHost || ""
804
919
  };
@@ -814,7 +929,7 @@ async function listSessionsFromMachines(_server, machines, opts) {
814
929
  directory: s.directory
815
930
  }))));
816
931
  } else {
817
- const header = `${"ID".padEnd(10)} ${"AGENT".padEnd(10)} ${"STATUS".padEnd(9)} ${"NAME".padEnd(25)} ${"MACHINE".padEnd(18)} ${"DIRECTORY".padEnd(35)}`;
932
+ const header = `${"ID".padEnd(10)} ${"AGENT".padEnd(10)} ${"STATUS".padEnd(9)} ${"TITLE".padEnd(25)} ${"MACHINE".padEnd(18)} ${"DIRECTORY".padEnd(35)}`;
818
933
  console.log(header);
819
934
  console.log("-".repeat(header.length));
820
935
  for (const s of enriched) {
@@ -1095,7 +1210,7 @@ async function sessionInfo(sessionId, machineId, opts) {
1095
1210
  const statusData = {
1096
1211
  sessionId: fullId,
1097
1212
  flavor: metadata.flavor || "claude",
1098
- name: metadata.name || "",
1213
+ name: resolveDisplayName(metadata, metadata.path || void 0),
1099
1214
  path: metadata.path || "",
1100
1215
  host: metadata.host || "",
1101
1216
  lifecycleState: metadata.lifecycleState || "unknown",
@@ -1427,6 +1542,12 @@ async function collectAssistantResponse(machine, fullId, afterSeq) {
1427
1542
  return { text: collected.join("\n").trim(), messageSeqs: seqs };
1428
1543
  }
1429
1544
  function validateSendOptions(opts) {
1545
+ if (opts?.plain) {
1546
+ const bad = [];
1547
+ if (opts.btw) bad.push("--btw");
1548
+ if (opts.model) bad.push("--model");
1549
+ if (bad.length) return bad.map((f) => `${f} (incompatible with --plain)`);
1550
+ }
1430
1551
  if (!opts?.btw) return [];
1431
1552
  const incompatible = [];
1432
1553
  if (opts.subject) incompatible.push("--subject");
@@ -1434,6 +1555,7 @@ function validateSendOptions(opts) {
1434
1555
  if (opts.wait) incompatible.push("--wait");
1435
1556
  if (opts.response) incompatible.push("--response");
1436
1557
  if (opts.model) incompatible.push("--model");
1558
+ if (opts.plain) incompatible.push("--plain");
1437
1559
  return incompatible;
1438
1560
  }
1439
1561
  async function sendCore(machine, fullId, message, opts) {
@@ -1460,6 +1582,35 @@ async function sendCore(machine, fullId, message, opts) {
1460
1582
  }
1461
1583
  const wantResponse = !!opts?.response;
1462
1584
  const shouldWait = !!opts?.wait || wantResponse;
1585
+ if (opts?.plain) {
1586
+ const { randomUUID: ruuid } = await import('node:crypto');
1587
+ if (shouldWait && !opts?.requireApproval) {
1588
+ try {
1589
+ await machine.sessionRPC(fullId, "switchMode", { mode: "bypassPermissions" });
1590
+ } catch {
1591
+ }
1592
+ }
1593
+ const preSeq2 = wantResponse ? await snapshotLatestSeq(machine, fullId) : 0;
1594
+ const meta = { sentFrom: "svamp-cli-plain" };
1595
+ const contentStr = JSON.stringify({ role: "user", content: { type: "text", text: message }, meta });
1596
+ const sendRes = await machine.sessionRPC(fullId, "sendMessage", { content: contentStr, localId: ruuid(), meta });
1597
+ let pWait;
1598
+ if (shouldWait) pWait = await waitForBusyThenIdle(machine, fullId, (opts?.timeout || 300) * 1e3);
1599
+ if (pWait?.pendingPermissions?.length) {
1600
+ return { sessionId: fullId, mode: "send", sent: true, messageId: sendRes?.id, waited: true, status: "permission-pending", pendingPermissions: pWait.pendingPermissions };
1601
+ }
1602
+ let pResp;
1603
+ if (wantResponse) pResp = await collectAssistantResponse(machine, fullId, preSeq2);
1604
+ return {
1605
+ sessionId: fullId,
1606
+ mode: "send",
1607
+ sent: true,
1608
+ messageId: sendRes?.id,
1609
+ waited: !!shouldWait,
1610
+ status: shouldWait ? "idle" : "sent",
1611
+ ...wantResponse && pResp ? { response: pResp.text, responseSeqs: pResp.messageSeqs } : {}
1612
+ };
1613
+ }
1463
1614
  if (opts?.model) {
1464
1615
  const { randomUUID: ruuid } = await import('node:crypto');
1465
1616
  if (shouldWait && !opts?.requireApproval) {
@@ -2280,4 +2431,4 @@ async function sessionInboxClear(sessionIdPartial, machineId, opts) {
2280
2431
  }
2281
2432
  }
2282
2433
 
2283
- export { collectAssistantResponse, connectAndGetMachine, connectAndResolveSession, createWorktree, generateWorktreeName, machineExec, machineInfo, machineLs, machineShare, parseShareArg, queryCore, renderMessage, resolveSessionId, sendCore, sessionApprove, sessionArchive, sessionAttach, sessionDelete, sessionDeny, sessionInboxClear, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxSend, sessionInfo, sessionList, sessionMachines, sessionMessages, sessionQuery, sessionRalphCancel, sessionRalphStart, sessionRalphStatus, sessionResume, sessionSend, sessionShare, sessionSpawn, sessionWait, snapshotLatestSeq, validateSendOptions };
2434
+ export { collectAssistantResponse, connectAndGetMachine, connectAndResolveSession, createWorktree, generateWorktreeName, machineExec, machineInfo, machineLs, machineShare, parseShareArg, queryCore, renderMessage, resolveSessionId, sendCore, sessionApprove, sessionArchive, sessionAttach, sessionDelete, sessionDeny, sessionInboxClear, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxSend, sessionInfo, sessionList, sessionMachines, sessionMessages, sessionQuery, sessionRalphCancel, sessionRalphStart, sessionRalphStatus, sessionResume, sessionSend, sessionShare, sessionSpawn, sessionWait, sessionWhoami, snapshotLatestSeq, validateSendOptions };
@@ -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-rWXfNd7e.mjs';
4
+ import { c as connectToHypha } from './run-C4i9N-F6.mjs';
5
5
  import { PINNED_CLAUDE_CODE_VERSION } from './pinnedClaudeCode-HydRNEt7.mjs';
6
6
  import 'os';
7
7
  import 'fs/promises';
@@ -12,6 +12,7 @@ import 'child_process';
12
12
  import 'crypto';
13
13
  import 'util';
14
14
  import 'node:crypto';
15
+ import 'node:vm';
15
16
  import 'node:child_process';
16
17
  import '@agentclientprotocol/sdk';
17
18
  import '@modelcontextprotocol/sdk/client/index.js';
@@ -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 { e as getFrpsSubdomainHost, f as getFrpsServerPort, h as getFrpsServerAddr } from './run-rWXfNd7e.mjs';
6
+ import { h as getFrpsSubdomainHost, i as getFrpsServerPort, j as getFrpsServerAddr } from './run-C4i9N-F6.mjs';
7
7
  import 'fs/promises';
8
8
  import 'url';
9
9
  import 'node:fs';
@@ -11,6 +11,7 @@ import 'util';
11
11
  import 'node:crypto';
12
12
  import 'node:path';
13
13
  import 'node:os';
14
+ import 'node:vm';
14
15
  import 'node:child_process';
15
16
  import '@agentclientprotocol/sdk';
16
17
  import '@modelcontextprotocol/sdk/client/index.js';
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-rWXfNd7e.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-C4i9N-F6.mjs';
2
2
  import 'os';
3
3
  import 'fs/promises';
4
4
  import 'fs';
@@ -11,6 +11,7 @@ import 'util';
11
11
  import 'node:crypto';
12
12
  import 'node:path';
13
13
  import 'node:os';
14
+ import 'node:vm';
14
15
  import 'node:child_process';
15
16
  import '@agentclientprotocol/sdk';
16
17
  import '@modelcontextprotocol/sdk/client/index.js';
@@ -1,5 +1,5 @@
1
1
  var name = "svamp-cli";
2
- var version = "0.2.86";
2
+ var version = "0.2.89";
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 && 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",
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",
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",