svamp-cli 0.1.94 → 0.1.96
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.
- package/dist/{agentCommands-Cz70sSe9.mjs → agentCommands-CJNxmnV5.mjs} +9 -2
- package/dist/cli.mjs +56 -27
- package/dist/{commands-Be7nMudu.mjs → commands-CFQRfeSs.mjs} +1 -1
- package/dist/{commands-DUkN2-4K.mjs → commands-D1hYL4Vi.mjs} +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{package-6Vk_An57.mjs → package-YOLex1RV.mjs} +2 -2
- package/dist/{run-B1p0kGdr.mjs → run-DxZEyfKG.mjs} +110 -11
- package/dist/{run-HWBNSz_5.mjs → run-jvUqdZAp.mjs} +1 -1
- package/dist/sandboxDetect-BWA3zQlA.mjs +27 -0
- package/package.json +2 -2
|
@@ -1,6 +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
5
|
|
|
5
6
|
const SVAMP_HOME = process.env.SVAMP_HOME || join(os.homedir(), ".svamp");
|
|
6
7
|
function getConfigPath(sessionId) {
|
|
@@ -94,6 +95,7 @@ async function sessionSetLink(url, label) {
|
|
|
94
95
|
console.log(`Session link set: "${resolvedLabel}" \u2192 ${url.trim()}`);
|
|
95
96
|
}
|
|
96
97
|
async function sessionNotify(message, level = "info") {
|
|
98
|
+
requireNotSandboxed("session notify");
|
|
97
99
|
const sessionId = process.env.SVAMP_SESSION_ID;
|
|
98
100
|
if (!sessionId) {
|
|
99
101
|
console.error("SVAMP_SESSION_ID not set. This command must be run inside a Svamp session.");
|
|
@@ -106,6 +108,7 @@ async function sessionNotify(message, level = "info") {
|
|
|
106
108
|
console.log(`Notification sent [${level}]: ${message}`);
|
|
107
109
|
}
|
|
108
110
|
async function sessionBroadcast(action, args) {
|
|
111
|
+
requireNotSandboxed("session broadcast");
|
|
109
112
|
const sessionId = process.env.SVAMP_SESSION_ID;
|
|
110
113
|
if (!sessionId) {
|
|
111
114
|
console.error("SVAMP_SESSION_ID not set. This command must be run inside a Svamp session.");
|
|
@@ -145,10 +148,11 @@ async function sessionBroadcast(action, args) {
|
|
|
145
148
|
console.log(`Broadcast sent: ${action}`);
|
|
146
149
|
}
|
|
147
150
|
async function connectToMachineService() {
|
|
148
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
151
|
+
const { connectAndGetMachine } = await import('./commands-CFQRfeSs.mjs');
|
|
149
152
|
return connectAndGetMachine();
|
|
150
153
|
}
|
|
151
154
|
async function inboxSend(targetSessionId, opts) {
|
|
155
|
+
requireNotSandboxed("inbox send");
|
|
152
156
|
const sessionId = process.env.SVAMP_SESSION_ID;
|
|
153
157
|
if (!sessionId) {
|
|
154
158
|
console.error("SVAMP_SESSION_ID not set. This command must be run inside a Svamp session.");
|
|
@@ -161,7 +165,7 @@ async function inboxSend(targetSessionId, opts) {
|
|
|
161
165
|
}
|
|
162
166
|
const { server, machine } = await connectToMachineService();
|
|
163
167
|
try {
|
|
164
|
-
const { resolveSessionId } = await import('./commands-
|
|
168
|
+
const { resolveSessionId } = await import('./commands-CFQRfeSs.mjs');
|
|
165
169
|
const sessions = await machine.listSessions();
|
|
166
170
|
const match = resolveSessionId(sessions, targetSessionId);
|
|
167
171
|
const fullTargetId = match.sessionId;
|
|
@@ -184,6 +188,7 @@ async function inboxSend(targetSessionId, opts) {
|
|
|
184
188
|
}
|
|
185
189
|
}
|
|
186
190
|
async function inboxList(opts) {
|
|
191
|
+
requireNotSandboxed("inbox list");
|
|
187
192
|
const sessionId = process.env.SVAMP_SESSION_ID;
|
|
188
193
|
if (!sessionId) {
|
|
189
194
|
console.error("SVAMP_SESSION_ID not set. This command must be run inside a Svamp session.");
|
|
@@ -214,6 +219,7 @@ async function inboxList(opts) {
|
|
|
214
219
|
}
|
|
215
220
|
}
|
|
216
221
|
async function inboxReply(messageId, body) {
|
|
222
|
+
requireNotSandboxed("inbox reply");
|
|
217
223
|
const sessionId = process.env.SVAMP_SESSION_ID;
|
|
218
224
|
if (!sessionId) {
|
|
219
225
|
console.error("SVAMP_SESSION_ID not set. This command must be run inside a Svamp session.");
|
|
@@ -252,6 +258,7 @@ async function inboxReply(messageId, body) {
|
|
|
252
258
|
}
|
|
253
259
|
}
|
|
254
260
|
async function machineNotify(message, level = "info") {
|
|
261
|
+
requireNotSandboxed("machine notify");
|
|
255
262
|
const machineId = process.env.SVAMP_MACHINE_ID;
|
|
256
263
|
await connectAndEmit({
|
|
257
264
|
type: "svamp:machine-notify",
|
package/dist/cli.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as stopDaemon, s as startDaemon, d as daemonStatus } from './run-
|
|
1
|
+
import { b as stopDaemon, s as startDaemon, d as daemonStatus } from './run-DxZEyfKG.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|
|
@@ -204,14 +204,34 @@ async function main() {
|
|
|
204
204
|
} else if (subcommand === "session") {
|
|
205
205
|
await handleSessionCommand();
|
|
206
206
|
} else if (subcommand === "machine") {
|
|
207
|
+
const { isSandboxed } = await import('./sandboxDetect-BWA3zQlA.mjs');
|
|
208
|
+
if (isSandboxed()) {
|
|
209
|
+
console.error("svamp machine: Machine commands are not available in sandboxed sessions.");
|
|
210
|
+
process.exit(1);
|
|
211
|
+
}
|
|
207
212
|
await handleMachineCommand();
|
|
208
213
|
} else if (subcommand === "skills") {
|
|
214
|
+
const { isSandboxed } = await import('./sandboxDetect-BWA3zQlA.mjs');
|
|
215
|
+
if (isSandboxed()) {
|
|
216
|
+
console.error("svamp skills: Skills commands are not available in sandboxed sessions.");
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
209
219
|
await handleSkillsCommand();
|
|
210
220
|
} else if (subcommand === "service" || subcommand === "svc") {
|
|
221
|
+
const { isSandboxed } = await import('./sandboxDetect-BWA3zQlA.mjs');
|
|
222
|
+
if (isSandboxed()) {
|
|
223
|
+
console.error("svamp service: Service commands are not available in sandboxed sessions.");
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
211
226
|
const { handleServiceCommand } = await import('./commands-BYbuedOK.mjs');
|
|
212
227
|
await handleServiceCommand();
|
|
213
228
|
} else if (subcommand === "process" || subcommand === "proc") {
|
|
214
|
-
const {
|
|
229
|
+
const { isSandboxed: isSandboxedProc } = await import('./sandboxDetect-BWA3zQlA.mjs');
|
|
230
|
+
if (isSandboxedProc()) {
|
|
231
|
+
console.error("svamp process: Process commands are not available in sandboxed sessions.");
|
|
232
|
+
process.exit(1);
|
|
233
|
+
}
|
|
234
|
+
const { processCommand } = await import('./commands-D1hYL4Vi.mjs');
|
|
215
235
|
let machineId;
|
|
216
236
|
const processArgs = args.slice(1);
|
|
217
237
|
const mIdx = processArgs.findIndex((a) => a === "--machine" || a === "-m");
|
|
@@ -229,7 +249,7 @@ async function main() {
|
|
|
229
249
|
} else if (!subcommand || subcommand === "start") {
|
|
230
250
|
await handleInteractiveCommand();
|
|
231
251
|
} else if (subcommand === "--version" || subcommand === "-v") {
|
|
232
|
-
const pkg = await import('./package-
|
|
252
|
+
const pkg = await import('./package-YOLex1RV.mjs').catch(() => ({ default: { version: "unknown" } }));
|
|
233
253
|
console.log(`svamp version: ${pkg.default.version}`);
|
|
234
254
|
} else {
|
|
235
255
|
console.error(`Unknown command: ${subcommand}`);
|
|
@@ -238,7 +258,7 @@ async function main() {
|
|
|
238
258
|
}
|
|
239
259
|
}
|
|
240
260
|
async function handleInteractiveCommand() {
|
|
241
|
-
const { runInteractive } = await import('./run-
|
|
261
|
+
const { runInteractive } = await import('./run-jvUqdZAp.mjs');
|
|
242
262
|
const interactiveArgs = subcommand === "start" ? args.slice(1) : args;
|
|
243
263
|
let directory = process.cwd();
|
|
244
264
|
let resumeSessionId;
|
|
@@ -283,7 +303,7 @@ async function handleAgentCommand() {
|
|
|
283
303
|
return;
|
|
284
304
|
}
|
|
285
305
|
if (agentArgs[0] === "list") {
|
|
286
|
-
const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-
|
|
306
|
+
const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-DxZEyfKG.mjs').then(function (n) { return n.i; });
|
|
287
307
|
console.log("Known agents:");
|
|
288
308
|
for (const [name, config2] of Object.entries(KNOWN_ACP_AGENTS)) {
|
|
289
309
|
console.log(` ${name.padEnd(12)} ${config2.command} ${config2.args.join(" ")} (ACP)`);
|
|
@@ -295,7 +315,7 @@ async function handleAgentCommand() {
|
|
|
295
315
|
console.log('Use "svamp agent -- <command> [args]" for a custom ACP agent.');
|
|
296
316
|
return;
|
|
297
317
|
}
|
|
298
|
-
const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-
|
|
318
|
+
const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-DxZEyfKG.mjs').then(function (n) { return n.i; });
|
|
299
319
|
let cwd = process.cwd();
|
|
300
320
|
const filteredArgs = [];
|
|
301
321
|
for (let i = 0; i < agentArgs.length; i++) {
|
|
@@ -319,12 +339,12 @@ async function handleAgentCommand() {
|
|
|
319
339
|
console.log(`Starting ${config.agentName} agent in ${cwd}...`);
|
|
320
340
|
let backend;
|
|
321
341
|
if (KNOWN_MCP_AGENTS[config.agentName]) {
|
|
322
|
-
const { CodexMcpBackend } = await import('./run-
|
|
342
|
+
const { CodexMcpBackend } = await import('./run-DxZEyfKG.mjs').then(function (n) { return n.j; });
|
|
323
343
|
backend = new CodexMcpBackend({ cwd, log: logFn });
|
|
324
344
|
} else {
|
|
325
|
-
const { AcpBackend } = await import('./run-
|
|
326
|
-
const { GeminiTransport } = await import('./run-
|
|
327
|
-
const { DefaultTransport } = await import('./run-
|
|
345
|
+
const { AcpBackend } = await import('./run-DxZEyfKG.mjs').then(function (n) { return n.h; });
|
|
346
|
+
const { GeminiTransport } = await import('./run-DxZEyfKG.mjs').then(function (n) { return n.G; });
|
|
347
|
+
const { DefaultTransport } = await import('./run-DxZEyfKG.mjs').then(function (n) { return n.D; });
|
|
328
348
|
const transportHandler = config.agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(config.agentName);
|
|
329
349
|
backend = new AcpBackend({
|
|
330
350
|
agentName: config.agentName,
|
|
@@ -442,7 +462,16 @@ async function handleSessionCommand() {
|
|
|
442
462
|
printSessionHelp();
|
|
443
463
|
return;
|
|
444
464
|
}
|
|
445
|
-
const
|
|
465
|
+
const SANDBOX_SAFE_SESSION_CMDS = /* @__PURE__ */ new Set(["set-title", "set-link"]);
|
|
466
|
+
if (!SANDBOX_SAFE_SESSION_CMDS.has(sessionSubcommand)) {
|
|
467
|
+
const { isSandboxed } = await import('./sandboxDetect-BWA3zQlA.mjs');
|
|
468
|
+
if (isSandboxed()) {
|
|
469
|
+
console.error(`svamp session ${sessionSubcommand}: This command is not available in sandboxed sessions.`);
|
|
470
|
+
console.error("Available commands: set-title, set-link");
|
|
471
|
+
process.exit(1);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-CFQRfeSs.mjs');
|
|
446
475
|
const parseFlagStr = (flag, shortFlag) => {
|
|
447
476
|
for (let i = 1; i < sessionArgs.length; i++) {
|
|
448
477
|
if ((sessionArgs[i] === flag || shortFlag) && i + 1 < sessionArgs.length) {
|
|
@@ -502,7 +531,7 @@ async function handleSessionCommand() {
|
|
|
502
531
|
allowDomain.push(sessionArgs[++i]);
|
|
503
532
|
}
|
|
504
533
|
}
|
|
505
|
-
const { parseShareArg } = await import('./commands-
|
|
534
|
+
const { parseShareArg } = await import('./commands-CFQRfeSs.mjs');
|
|
506
535
|
const shareEntries = share.map((s) => parseShareArg(s));
|
|
507
536
|
await sessionSpawn(agent, dir, targetMachineId, {
|
|
508
537
|
message,
|
|
@@ -588,7 +617,7 @@ async function handleSessionCommand() {
|
|
|
588
617
|
console.error("Usage: svamp session approve <session-id> [request-id] [--json]");
|
|
589
618
|
process.exit(1);
|
|
590
619
|
}
|
|
591
|
-
const { sessionApprove } = await import('./commands-
|
|
620
|
+
const { sessionApprove } = await import('./commands-CFQRfeSs.mjs');
|
|
592
621
|
const approveReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
593
622
|
await sessionApprove(sessionArgs[1], approveReqId, targetMachineId, {
|
|
594
623
|
json: hasFlag("--json")
|
|
@@ -598,7 +627,7 @@ async function handleSessionCommand() {
|
|
|
598
627
|
console.error("Usage: svamp session deny <session-id> [request-id] [--json]");
|
|
599
628
|
process.exit(1);
|
|
600
629
|
}
|
|
601
|
-
const { sessionDeny } = await import('./commands-
|
|
630
|
+
const { sessionDeny } = await import('./commands-CFQRfeSs.mjs');
|
|
602
631
|
const denyReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
603
632
|
await sessionDeny(sessionArgs[1], denyReqId, targetMachineId, {
|
|
604
633
|
json: hasFlag("--json")
|
|
@@ -634,7 +663,7 @@ async function handleSessionCommand() {
|
|
|
634
663
|
console.error("Usage: svamp session set-title <title>");
|
|
635
664
|
process.exit(1);
|
|
636
665
|
}
|
|
637
|
-
const { sessionSetTitle } = await import('./agentCommands-
|
|
666
|
+
const { sessionSetTitle } = await import('./agentCommands-CJNxmnV5.mjs');
|
|
638
667
|
await sessionSetTitle(title);
|
|
639
668
|
} else if (sessionSubcommand === "set-link") {
|
|
640
669
|
const url = sessionArgs[1];
|
|
@@ -643,7 +672,7 @@ async function handleSessionCommand() {
|
|
|
643
672
|
process.exit(1);
|
|
644
673
|
}
|
|
645
674
|
const label = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
646
|
-
const { sessionSetLink } = await import('./agentCommands-
|
|
675
|
+
const { sessionSetLink } = await import('./agentCommands-CJNxmnV5.mjs');
|
|
647
676
|
await sessionSetLink(url, label);
|
|
648
677
|
} else if (sessionSubcommand === "notify") {
|
|
649
678
|
const message = sessionArgs[1];
|
|
@@ -652,7 +681,7 @@ async function handleSessionCommand() {
|
|
|
652
681
|
process.exit(1);
|
|
653
682
|
}
|
|
654
683
|
const level = parseFlagStr("--level") || "info";
|
|
655
|
-
const { sessionNotify } = await import('./agentCommands-
|
|
684
|
+
const { sessionNotify } = await import('./agentCommands-CJNxmnV5.mjs');
|
|
656
685
|
await sessionNotify(message, level);
|
|
657
686
|
} else if (sessionSubcommand === "broadcast") {
|
|
658
687
|
const action = sessionArgs[1];
|
|
@@ -660,7 +689,7 @@ async function handleSessionCommand() {
|
|
|
660
689
|
console.error("Usage: svamp session broadcast <action> [args...]\nActions: open-canvas <url> [label], close-canvas, toast <message>");
|
|
661
690
|
process.exit(1);
|
|
662
691
|
}
|
|
663
|
-
const { sessionBroadcast } = await import('./agentCommands-
|
|
692
|
+
const { sessionBroadcast } = await import('./agentCommands-CJNxmnV5.mjs');
|
|
664
693
|
await sessionBroadcast(action, sessionArgs.slice(2).filter((a) => !a.startsWith("--")));
|
|
665
694
|
} else if (sessionSubcommand === "inbox") {
|
|
666
695
|
const inboxSubcmd = sessionArgs[1];
|
|
@@ -671,7 +700,7 @@ async function handleSessionCommand() {
|
|
|
671
700
|
process.exit(1);
|
|
672
701
|
}
|
|
673
702
|
if (agentSessionId) {
|
|
674
|
-
const { inboxSend } = await import('./agentCommands-
|
|
703
|
+
const { inboxSend } = await import('./agentCommands-CJNxmnV5.mjs');
|
|
675
704
|
await inboxSend(sessionArgs[2], {
|
|
676
705
|
body: sessionArgs[3],
|
|
677
706
|
subject: parseFlagStr("--subject"),
|
|
@@ -686,7 +715,7 @@ async function handleSessionCommand() {
|
|
|
686
715
|
}
|
|
687
716
|
} else if (inboxSubcmd === "list" || inboxSubcmd === "ls") {
|
|
688
717
|
if (agentSessionId && !sessionArgs[2]) {
|
|
689
|
-
const { inboxList } = await import('./agentCommands-
|
|
718
|
+
const { inboxList } = await import('./agentCommands-CJNxmnV5.mjs');
|
|
690
719
|
await inboxList({
|
|
691
720
|
unread: hasFlag("--unread"),
|
|
692
721
|
limit: parseFlagInt("--limit"),
|
|
@@ -708,7 +737,7 @@ async function handleSessionCommand() {
|
|
|
708
737
|
process.exit(1);
|
|
709
738
|
}
|
|
710
739
|
if (agentSessionId && !sessionArgs[3]) {
|
|
711
|
-
const { inboxList } = await import('./agentCommands-
|
|
740
|
+
const { inboxList } = await import('./agentCommands-CJNxmnV5.mjs');
|
|
712
741
|
await sessionInboxRead(agentSessionId, sessionArgs[2], targetMachineId);
|
|
713
742
|
} else if (sessionArgs[3]) {
|
|
714
743
|
await sessionInboxRead(sessionArgs[2], sessionArgs[3], targetMachineId);
|
|
@@ -718,7 +747,7 @@ async function handleSessionCommand() {
|
|
|
718
747
|
}
|
|
719
748
|
} else if (inboxSubcmd === "reply") {
|
|
720
749
|
if (agentSessionId && sessionArgs[2] && sessionArgs[3] && !sessionArgs[4]) {
|
|
721
|
-
const { inboxReply } = await import('./agentCommands-
|
|
750
|
+
const { inboxReply } = await import('./agentCommands-CJNxmnV5.mjs');
|
|
722
751
|
await inboxReply(sessionArgs[2], sessionArgs[3]);
|
|
723
752
|
} else if (sessionArgs[2] && sessionArgs[3] && sessionArgs[4]) {
|
|
724
753
|
await sessionInboxReply(sessionArgs[2], sessionArgs[3], sessionArgs[4], targetMachineId);
|
|
@@ -754,7 +783,7 @@ async function handleMachineCommand() {
|
|
|
754
783
|
return;
|
|
755
784
|
}
|
|
756
785
|
if (machineSubcommand === "share") {
|
|
757
|
-
const { machineShare } = await import('./commands-
|
|
786
|
+
const { machineShare } = await import('./commands-CFQRfeSs.mjs');
|
|
758
787
|
let machineId;
|
|
759
788
|
const shareArgs = [];
|
|
760
789
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
@@ -784,7 +813,7 @@ async function handleMachineCommand() {
|
|
|
784
813
|
}
|
|
785
814
|
await machineShare(machineId, { add, remove, list, configPath, showConfig });
|
|
786
815
|
} else if (machineSubcommand === "exec") {
|
|
787
|
-
const { machineExec } = await import('./commands-
|
|
816
|
+
const { machineExec } = await import('./commands-CFQRfeSs.mjs');
|
|
788
817
|
let machineId;
|
|
789
818
|
let cwd;
|
|
790
819
|
const cmdParts = [];
|
|
@@ -804,7 +833,7 @@ async function handleMachineCommand() {
|
|
|
804
833
|
}
|
|
805
834
|
await machineExec(machineId, command, cwd);
|
|
806
835
|
} else if (machineSubcommand === "info") {
|
|
807
|
-
const { machineInfo } = await import('./commands-
|
|
836
|
+
const { machineInfo } = await import('./commands-CFQRfeSs.mjs');
|
|
808
837
|
let machineId;
|
|
809
838
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
810
839
|
if ((machineArgs[i] === "--machine" || machineArgs[i] === "-m") && i + 1 < machineArgs.length) {
|
|
@@ -824,10 +853,10 @@ async function handleMachineCommand() {
|
|
|
824
853
|
level = machineArgs[++i];
|
|
825
854
|
}
|
|
826
855
|
}
|
|
827
|
-
const { machineNotify } = await import('./agentCommands-
|
|
856
|
+
const { machineNotify } = await import('./agentCommands-CJNxmnV5.mjs');
|
|
828
857
|
await machineNotify(message, level);
|
|
829
858
|
} else if (machineSubcommand === "ls") {
|
|
830
|
-
const { machineLs } = await import('./commands-
|
|
859
|
+
const { machineLs } = await import('./commands-CFQRfeSs.mjs');
|
|
831
860
|
let machineId;
|
|
832
861
|
let showHidden = false;
|
|
833
862
|
let path;
|
|
@@ -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-
|
|
5
|
+
import { l as loadSecurityContextConfig, e as resolveSecurityContext, f as buildSecurityContextFromFlags, m as mergeSecurityContexts, c as connectToHypha } from './run-DxZEyfKG.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-
|
|
3
|
+
import { connectAndGetMachine } from './commands-CFQRfeSs.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-
|
|
8
|
+
import './run-DxZEyfKG.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-
|
|
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-DxZEyfKG.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.1.
|
|
2
|
+
var version = "0.1.96";
|
|
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 && tsc --noEmit && pkgroll",
|
|
21
21
|
typecheck: "tsc --noEmit",
|
|
22
|
-
test: "npx tsx test/test-authorize.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-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-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-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-clear-detection.mjs && npx tsx test/test-session-consolidation.mjs && npx tsx test/test-inbox.mjs && npx tsx test/test-session-rpc-dispatch.mjs",
|
|
22
|
+
test: "npx tsx test/test-authorize.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-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-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-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-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",
|
|
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",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import os__default from 'os';
|
|
2
|
-
import fs, { mkdir as mkdir$1, readdir, readFile, writeFile as writeFile$1, rename, unlink } from 'fs/promises';
|
|
2
|
+
import fs, { mkdir as mkdir$1, readdir as readdir$1, readFile, writeFile as writeFile$1, rename, unlink } from 'fs/promises';
|
|
3
3
|
import { readFileSync as readFileSync$1, mkdirSync, writeFileSync, renameSync, existsSync as existsSync$1, copyFileSync, unlinkSync, watch, rmdirSync } from 'fs';
|
|
4
4
|
import path__default, { join, dirname, resolve, basename } from 'path';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
@@ -15,7 +15,7 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
|
15
15
|
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
16
16
|
import { ElicitRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
17
17
|
import { z } from 'zod';
|
|
18
|
-
import { mkdir, rm, chmod, access, mkdtemp, copyFile, writeFile } from 'node:fs/promises';
|
|
18
|
+
import { mkdir, rm, chmod, access, mkdtemp, copyFile, writeFile, stat, readdir } from 'node:fs/promises';
|
|
19
19
|
import { promisify } from 'node:util';
|
|
20
20
|
|
|
21
21
|
let connectToServerFn = null;
|
|
@@ -381,12 +381,42 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
381
381
|
config: { visibility: "unlisted", require_context: true },
|
|
382
382
|
// Machine info
|
|
383
383
|
getMachineInfo: async (context) => {
|
|
384
|
-
|
|
384
|
+
let hasMachineAccess = false;
|
|
385
|
+
try {
|
|
386
|
+
authorizeRequest(context, currentMetadata.sharing, "view");
|
|
387
|
+
hasMachineAccess = true;
|
|
388
|
+
} catch {
|
|
389
|
+
}
|
|
390
|
+
if (hasMachineAccess) {
|
|
391
|
+
return {
|
|
392
|
+
machineId,
|
|
393
|
+
metadata: currentMetadata,
|
|
394
|
+
metadataVersion,
|
|
395
|
+
daemonState: currentDaemonState,
|
|
396
|
+
daemonStateVersion
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
const sessionIds = handlers.getSessionIds?.() || [];
|
|
400
|
+
let hasSessionAccess = false;
|
|
401
|
+
for (const sid of sessionIds) {
|
|
402
|
+
const rpc = handlers.getSessionRPCHandlers?.(sid);
|
|
403
|
+
if (!rpc) continue;
|
|
404
|
+
try {
|
|
405
|
+
await rpc.getMetadata(context);
|
|
406
|
+
hasSessionAccess = true;
|
|
407
|
+
break;
|
|
408
|
+
} catch {
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
if (!hasSessionAccess) {
|
|
412
|
+
throw new Error("Access denied: no machine or session-level access");
|
|
413
|
+
}
|
|
414
|
+
const { sharing: _s, securityContextConfig: _sc, ...safeMetadata } = currentMetadata;
|
|
385
415
|
return {
|
|
386
416
|
machineId,
|
|
387
|
-
metadata:
|
|
417
|
+
metadata: safeMetadata,
|
|
388
418
|
metadataVersion,
|
|
389
|
-
daemonState: currentDaemonState,
|
|
419
|
+
daemonState: { status: currentDaemonState.status },
|
|
390
420
|
daemonStateVersion
|
|
391
421
|
};
|
|
392
422
|
},
|
|
@@ -400,16 +430,42 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
400
430
|
};
|
|
401
431
|
},
|
|
402
432
|
// List active sessions on this machine
|
|
433
|
+
// If machine sharing grants access, return all. Otherwise return only
|
|
434
|
+
// sessions whose own sharing config grants access to this user.
|
|
403
435
|
listSessions: async (context) => {
|
|
404
|
-
|
|
405
|
-
|
|
436
|
+
let hasMachineAccess = false;
|
|
437
|
+
try {
|
|
438
|
+
authorizeRequest(context, currentMetadata.sharing, "view");
|
|
439
|
+
hasMachineAccess = true;
|
|
440
|
+
} catch {
|
|
441
|
+
}
|
|
442
|
+
const tracked = handlers.getTrackedSessions();
|
|
443
|
+
if (hasMachineAccess) return tracked;
|
|
444
|
+
const result = [];
|
|
445
|
+
for (const t of tracked) {
|
|
446
|
+
const rpc = handlers.getSessionRPCHandlers?.(t.sessionId);
|
|
447
|
+
if (!rpc) continue;
|
|
448
|
+
try {
|
|
449
|
+
const meta = await rpc.getMetadata(context);
|
|
450
|
+
result.push(t);
|
|
451
|
+
} catch {
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
return result;
|
|
406
455
|
},
|
|
407
456
|
/**
|
|
408
457
|
* Get summary info for all sessions (metadata, agent state, activity).
|
|
409
458
|
* Replaces the need to discover and query N individual session services.
|
|
459
|
+
* For session-shared users (no machine-level access), only returns
|
|
460
|
+
* sessions whose sharing config grants them access.
|
|
410
461
|
*/
|
|
411
462
|
getSessions: async (context) => {
|
|
412
|
-
|
|
463
|
+
let hasMachineAccess = false;
|
|
464
|
+
try {
|
|
465
|
+
authorizeRequest(context, currentMetadata.sharing, "view");
|
|
466
|
+
hasMachineAccess = true;
|
|
467
|
+
} catch {
|
|
468
|
+
}
|
|
413
469
|
const sessionIds = handlers.getSessionIds?.() || [];
|
|
414
470
|
const sessions = [];
|
|
415
471
|
for (const sid of sessionIds) {
|
|
@@ -446,11 +502,21 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
446
502
|
* eliminating the need for per-session Hypha service registration.
|
|
447
503
|
*/
|
|
448
504
|
sessionRPC: async (sessionId, method, kwargs, context) => {
|
|
449
|
-
authorizeRequest(context, currentMetadata.sharing, "view");
|
|
450
505
|
const rpc = handlers.getSessionRPCHandlers?.(sessionId);
|
|
451
506
|
if (!rpc) {
|
|
452
507
|
throw new Error(`Session ${sessionId} not found on this machine`);
|
|
453
508
|
}
|
|
509
|
+
try {
|
|
510
|
+
authorizeRequest(context, currentMetadata.sharing, "view");
|
|
511
|
+
} catch (machineErr) {
|
|
512
|
+
try {
|
|
513
|
+
const meta = await rpc.getMetadata(context);
|
|
514
|
+
const sessionSharing = meta?.metadata?.sharing;
|
|
515
|
+
authorizeRequest(context, sessionSharing, "view");
|
|
516
|
+
} catch {
|
|
517
|
+
throw machineErr;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
454
520
|
const handler = rpc[method];
|
|
455
521
|
if (typeof handler !== "function") {
|
|
456
522
|
throw new Error(`Unknown session method: ${method}`);
|
|
@@ -466,11 +532,21 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
466
532
|
* Delegates to the session store's registerListener.
|
|
467
533
|
*/
|
|
468
534
|
registerSessionListener: async (sessionId, callback, context) => {
|
|
469
|
-
authorizeRequest(context, currentMetadata.sharing, "view");
|
|
470
535
|
const rpc = handlers.getSessionRPCHandlers?.(sessionId);
|
|
471
536
|
if (!rpc) {
|
|
472
537
|
throw new Error(`Session ${sessionId} not found on this machine`);
|
|
473
538
|
}
|
|
539
|
+
try {
|
|
540
|
+
authorizeRequest(context, currentMetadata.sharing, "view");
|
|
541
|
+
} catch (machineErr) {
|
|
542
|
+
try {
|
|
543
|
+
const meta = await rpc.getMetadata(context);
|
|
544
|
+
const sessionSharing = meta?.metadata?.sharing;
|
|
545
|
+
authorizeRequest(context, sessionSharing, "view");
|
|
546
|
+
} catch {
|
|
547
|
+
throw machineErr;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
474
550
|
return await rpc.registerListener(callback, context);
|
|
475
551
|
},
|
|
476
552
|
// Spawn a new session
|
|
@@ -4343,6 +4419,12 @@ async function stageCredentialsForSharing(sessionId) {
|
|
|
4343
4419
|
} catch {
|
|
4344
4420
|
}
|
|
4345
4421
|
}
|
|
4422
|
+
const realSkillsDir = join$1(realClaudeDir, "skills");
|
|
4423
|
+
const stagedSkillsDir = join$1(stagedClaudeDir, "skills");
|
|
4424
|
+
try {
|
|
4425
|
+
await copyDirRecursive(realSkillsDir, stagedSkillsDir);
|
|
4426
|
+
} catch {
|
|
4427
|
+
}
|
|
4346
4428
|
return {
|
|
4347
4429
|
homePath: tmpHome,
|
|
4348
4430
|
env: { HOME: tmpHome },
|
|
@@ -4359,6 +4441,21 @@ function sanitizeEnvForSharing(env) {
|
|
|
4359
4441
|
}
|
|
4360
4442
|
return sanitized;
|
|
4361
4443
|
}
|
|
4444
|
+
async function copyDirRecursive(src, dest) {
|
|
4445
|
+
const srcStat = await stat(src);
|
|
4446
|
+
if (!srcStat.isDirectory()) return;
|
|
4447
|
+
await mkdir(dest, { recursive: true });
|
|
4448
|
+
const entries = await readdir(src, { withFileTypes: true });
|
|
4449
|
+
for (const entry of entries) {
|
|
4450
|
+
const srcPath = join$1(src, entry.name);
|
|
4451
|
+
const destPath = join$1(dest, entry.name);
|
|
4452
|
+
if (entry.isDirectory()) {
|
|
4453
|
+
await copyDirRecursive(srcPath, destPath);
|
|
4454
|
+
} else if (entry.isFile()) {
|
|
4455
|
+
await copyFile(srcPath, destPath);
|
|
4456
|
+
}
|
|
4457
|
+
}
|
|
4458
|
+
}
|
|
4362
4459
|
|
|
4363
4460
|
const DEFAULT_PROBE_INTERVAL_S = 10;
|
|
4364
4461
|
const DEFAULT_PROBE_TIMEOUT_S = 5;
|
|
@@ -4554,7 +4651,7 @@ class ProcessSupervisor {
|
|
|
4554
4651
|
async loadAll() {
|
|
4555
4652
|
let files;
|
|
4556
4653
|
try {
|
|
4557
|
-
files = await readdir(this.persistDir);
|
|
4654
|
+
files = await readdir$1(this.persistDir);
|
|
4558
4655
|
} catch {
|
|
4559
4656
|
return;
|
|
4560
4657
|
}
|
|
@@ -6837,6 +6934,7 @@ The automated loop has finished. Review the progress above and let me know if yo
|
|
|
6837
6934
|
logger.log(`[Session ${sessionId}] Inbox message received (urgency: ${message.urgency || "normal"}, from: ${message.from || "unknown"})`);
|
|
6838
6935
|
const formatted = formatInboxMessageXml(message);
|
|
6839
6936
|
sessionService.pushMessage(formatted, "user");
|
|
6937
|
+
sessionService.markInboxRead(message.messageId);
|
|
6840
6938
|
if (message.urgency === "urgent") {
|
|
6841
6939
|
logger.log(`[Session ${sessionId}] Delivering urgent inbox message to agent`);
|
|
6842
6940
|
if (!claudeProcess || claudeProcess.exitCode !== null) {
|
|
@@ -7262,6 +7360,7 @@ The automated loop has finished. Review the progress above and let me know if yo
|
|
|
7262
7360
|
logger.log(`[${agentName} Session ${sessionId}] Inbox message received (urgency: ${message.urgency || "normal"}, from: ${message.from || "unknown"})`);
|
|
7263
7361
|
const formatted = formatInboxMessageXml(message);
|
|
7264
7362
|
sessionService.pushMessage(formatted, "user");
|
|
7363
|
+
sessionService.markInboxRead(message.messageId);
|
|
7265
7364
|
if (message.urgency === "urgent" && acpBackendReady) {
|
|
7266
7365
|
logger.log(`[${agentName} Session ${sessionId}] Delivering urgent inbox message to agent`);
|
|
7267
7366
|
sessionMetadata = { ...sessionMetadata, lifecycleState: "running" };
|
|
@@ -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-
|
|
5
|
+
import { c as connectToHypha, a as registerSessionService } from './run-DxZEyfKG.mjs';
|
|
6
6
|
import { createServer } from 'node:http';
|
|
7
7
|
import { spawn } from 'node:child_process';
|
|
8
8
|
import { createInterface } from 'node:readline';
|
|
@@ -0,0 +1,27 @@
|
|
|
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 };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svamp-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.96",
|
|
4
4
|
"description": "Svamp CLI — AI workspace daemon on Hypha Cloud",
|
|
5
5
|
"author": "Amun AI AB",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"scripts": {
|
|
21
21
|
"build": "rm -rf dist && tsc --noEmit && pkgroll",
|
|
22
22
|
"typecheck": "tsc --noEmit",
|
|
23
|
-
"test": "npx tsx test/test-authorize.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-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-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-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-clear-detection.mjs && npx tsx test/test-session-consolidation.mjs && npx tsx test/test-inbox.mjs && npx tsx test/test-session-rpc-dispatch.mjs",
|
|
23
|
+
"test": "npx tsx test/test-authorize.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-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-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-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-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",
|
|
24
24
|
"test:hypha": "node --no-warnings test/test-hypha-service.mjs",
|
|
25
25
|
"dev": "tsx src/cli.ts",
|
|
26
26
|
"dev:daemon": "tsx src/cli.ts daemon start-sync",
|