svamp-cli 0.1.61 → 0.1.63
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/cli.mjs +19 -19
- package/dist/{commands-DTNg_sCX.mjs → commands-3Zu9sCxa.mjs} +2 -2
- package/dist/{commands-CBTCiCjK.mjs → commands-BRow9cGp.mjs} +1 -1
- package/dist/{commands-T_SLBdOH.mjs → commands-dm3PSNsk.mjs} +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{package-D8bLCX8i.mjs → package-7U32bRBY.mjs} +2 -2
- package/dist/{run-Bds_JVXp.mjs → run-BaMf-bAo.mjs} +28 -4
- package/dist/{run-Dg1i7D_o.mjs → run-COqTRwXb.mjs} +1 -1
- package/dist/{tunnel-DTyspats.mjs → tunnel-dl6vFKgd.mjs} +60 -44
- package/package.json +2 -2
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-BaMf-bAo.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|
|
@@ -106,10 +106,10 @@ async function main() {
|
|
|
106
106
|
} else if (subcommand === "skills") {
|
|
107
107
|
await handleSkillsCommand();
|
|
108
108
|
} else if (subcommand === "service" || subcommand === "svc") {
|
|
109
|
-
const { handleServiceCommand } = await import('./commands-
|
|
109
|
+
const { handleServiceCommand } = await import('./commands-dm3PSNsk.mjs');
|
|
110
110
|
await handleServiceCommand();
|
|
111
111
|
} else if (subcommand === "process" || subcommand === "proc") {
|
|
112
|
-
const { processCommand } = await import('./commands-
|
|
112
|
+
const { processCommand } = await import('./commands-3Zu9sCxa.mjs');
|
|
113
113
|
let machineId;
|
|
114
114
|
const processArgs = args.slice(1);
|
|
115
115
|
const mIdx = processArgs.findIndex((a) => a === "--machine" || a === "-m");
|
|
@@ -127,7 +127,7 @@ async function main() {
|
|
|
127
127
|
} else if (!subcommand || subcommand === "start") {
|
|
128
128
|
await handleInteractiveCommand();
|
|
129
129
|
} else if (subcommand === "--version" || subcommand === "-v") {
|
|
130
|
-
const pkg = await import('./package-
|
|
130
|
+
const pkg = await import('./package-7U32bRBY.mjs').catch(() => ({ default: { version: "unknown" } }));
|
|
131
131
|
console.log(`svamp version: ${pkg.default.version}`);
|
|
132
132
|
} else {
|
|
133
133
|
console.error(`Unknown command: ${subcommand}`);
|
|
@@ -136,7 +136,7 @@ async function main() {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
async function handleInteractiveCommand() {
|
|
139
|
-
const { runInteractive } = await import('./run-
|
|
139
|
+
const { runInteractive } = await import('./run-COqTRwXb.mjs');
|
|
140
140
|
const interactiveArgs = subcommand === "start" ? args.slice(1) : args;
|
|
141
141
|
let directory = process.cwd();
|
|
142
142
|
let resumeSessionId;
|
|
@@ -181,7 +181,7 @@ async function handleAgentCommand() {
|
|
|
181
181
|
return;
|
|
182
182
|
}
|
|
183
183
|
if (agentArgs[0] === "list") {
|
|
184
|
-
const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-
|
|
184
|
+
const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-BaMf-bAo.mjs').then(function (n) { return n.i; });
|
|
185
185
|
console.log("Known agents:");
|
|
186
186
|
for (const [name, config2] of Object.entries(KNOWN_ACP_AGENTS)) {
|
|
187
187
|
console.log(` ${name.padEnd(12)} ${config2.command} ${config2.args.join(" ")} (ACP)`);
|
|
@@ -193,7 +193,7 @@ async function handleAgentCommand() {
|
|
|
193
193
|
console.log('Use "svamp agent -- <command> [args]" for a custom ACP agent.');
|
|
194
194
|
return;
|
|
195
195
|
}
|
|
196
|
-
const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-
|
|
196
|
+
const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-BaMf-bAo.mjs').then(function (n) { return n.i; });
|
|
197
197
|
let cwd = process.cwd();
|
|
198
198
|
const filteredArgs = [];
|
|
199
199
|
for (let i = 0; i < agentArgs.length; i++) {
|
|
@@ -217,12 +217,12 @@ async function handleAgentCommand() {
|
|
|
217
217
|
console.log(`Starting ${config.agentName} agent in ${cwd}...`);
|
|
218
218
|
let backend;
|
|
219
219
|
if (KNOWN_MCP_AGENTS[config.agentName]) {
|
|
220
|
-
const { CodexMcpBackend } = await import('./run-
|
|
220
|
+
const { CodexMcpBackend } = await import('./run-BaMf-bAo.mjs').then(function (n) { return n.j; });
|
|
221
221
|
backend = new CodexMcpBackend({ cwd, log: logFn });
|
|
222
222
|
} else {
|
|
223
|
-
const { AcpBackend } = await import('./run-
|
|
224
|
-
const { GeminiTransport } = await import('./run-
|
|
225
|
-
const { DefaultTransport } = await import('./run-
|
|
223
|
+
const { AcpBackend } = await import('./run-BaMf-bAo.mjs').then(function (n) { return n.h; });
|
|
224
|
+
const { GeminiTransport } = await import('./run-BaMf-bAo.mjs').then(function (n) { return n.G; });
|
|
225
|
+
const { DefaultTransport } = await import('./run-BaMf-bAo.mjs').then(function (n) { return n.D; });
|
|
226
226
|
const transportHandler = config.agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(config.agentName);
|
|
227
227
|
backend = new AcpBackend({
|
|
228
228
|
agentName: config.agentName,
|
|
@@ -340,7 +340,7 @@ async function handleSessionCommand() {
|
|
|
340
340
|
printSessionHelp();
|
|
341
341
|
return;
|
|
342
342
|
}
|
|
343
|
-
const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionQueueAdd, sessionQueueList, sessionQueueClear } = await import('./commands-
|
|
343
|
+
const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionQueueAdd, sessionQueueList, sessionQueueClear } = await import('./commands-BRow9cGp.mjs');
|
|
344
344
|
const parseFlagStr = (flag, shortFlag) => {
|
|
345
345
|
for (let i = 1; i < sessionArgs.length; i++) {
|
|
346
346
|
if ((sessionArgs[i] === flag || shortFlag) && i + 1 < sessionArgs.length) {
|
|
@@ -400,7 +400,7 @@ async function handleSessionCommand() {
|
|
|
400
400
|
allowDomain.push(sessionArgs[++i]);
|
|
401
401
|
}
|
|
402
402
|
}
|
|
403
|
-
const { parseShareArg } = await import('./commands-
|
|
403
|
+
const { parseShareArg } = await import('./commands-BRow9cGp.mjs');
|
|
404
404
|
const shareEntries = share.map((s) => parseShareArg(s));
|
|
405
405
|
await sessionSpawn(agent, dir, targetMachineId, {
|
|
406
406
|
message,
|
|
@@ -484,7 +484,7 @@ async function handleSessionCommand() {
|
|
|
484
484
|
console.error("Usage: svamp session approve <session-id> [request-id] [--json]");
|
|
485
485
|
process.exit(1);
|
|
486
486
|
}
|
|
487
|
-
const { sessionApprove } = await import('./commands-
|
|
487
|
+
const { sessionApprove } = await import('./commands-BRow9cGp.mjs');
|
|
488
488
|
const approveReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
489
489
|
await sessionApprove(sessionArgs[1], approveReqId, targetMachineId, {
|
|
490
490
|
json: hasFlag("--json")
|
|
@@ -494,7 +494,7 @@ async function handleSessionCommand() {
|
|
|
494
494
|
console.error("Usage: svamp session deny <session-id> [request-id] [--json]");
|
|
495
495
|
process.exit(1);
|
|
496
496
|
}
|
|
497
|
-
const { sessionDeny } = await import('./commands-
|
|
497
|
+
const { sessionDeny } = await import('./commands-BRow9cGp.mjs');
|
|
498
498
|
const denyReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
499
499
|
await sessionDeny(sessionArgs[1], denyReqId, targetMachineId, {
|
|
500
500
|
json: hasFlag("--json")
|
|
@@ -563,7 +563,7 @@ async function handleMachineCommand() {
|
|
|
563
563
|
return;
|
|
564
564
|
}
|
|
565
565
|
if (machineSubcommand === "share") {
|
|
566
|
-
const { machineShare } = await import('./commands-
|
|
566
|
+
const { machineShare } = await import('./commands-BRow9cGp.mjs');
|
|
567
567
|
let machineId;
|
|
568
568
|
const shareArgs = [];
|
|
569
569
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
@@ -593,7 +593,7 @@ async function handleMachineCommand() {
|
|
|
593
593
|
}
|
|
594
594
|
await machineShare(machineId, { add, remove, list, configPath, showConfig });
|
|
595
595
|
} else if (machineSubcommand === "exec") {
|
|
596
|
-
const { machineExec } = await import('./commands-
|
|
596
|
+
const { machineExec } = await import('./commands-BRow9cGp.mjs');
|
|
597
597
|
let machineId;
|
|
598
598
|
let cwd;
|
|
599
599
|
const cmdParts = [];
|
|
@@ -613,7 +613,7 @@ async function handleMachineCommand() {
|
|
|
613
613
|
}
|
|
614
614
|
await machineExec(machineId, command, cwd);
|
|
615
615
|
} else if (machineSubcommand === "info") {
|
|
616
|
-
const { machineInfo } = await import('./commands-
|
|
616
|
+
const { machineInfo } = await import('./commands-BRow9cGp.mjs');
|
|
617
617
|
let machineId;
|
|
618
618
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
619
619
|
if ((machineArgs[i] === "--machine" || machineArgs[i] === "-m") && i + 1 < machineArgs.length) {
|
|
@@ -622,7 +622,7 @@ async function handleMachineCommand() {
|
|
|
622
622
|
}
|
|
623
623
|
await machineInfo(machineId);
|
|
624
624
|
} else if (machineSubcommand === "ls") {
|
|
625
|
-
const { machineLs } = await import('./commands-
|
|
625
|
+
const { machineLs } = await import('./commands-BRow9cGp.mjs');
|
|
626
626
|
let machineId;
|
|
627
627
|
let showHidden = false;
|
|
628
628
|
let path;
|
|
@@ -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-BRow9cGp.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-BaMf-bAo.mjs';
|
|
9
9
|
import 'os';
|
|
10
10
|
import 'fs/promises';
|
|
11
11
|
import 'url';
|
|
@@ -2,7 +2,7 @@ import { existsSync, readFileSync } from 'node:fs';
|
|
|
2
2
|
import { execSync } from 'node:child_process';
|
|
3
3
|
import { 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-BaMf-bAo.mjs';
|
|
6
6
|
import 'os';
|
|
7
7
|
import 'fs/promises';
|
|
8
8
|
import 'fs';
|
|
@@ -296,7 +296,7 @@ Service is live:`);
|
|
|
296
296
|
}
|
|
297
297
|
} else {
|
|
298
298
|
console.log(`No SANDBOX_ID detected \u2014 starting reverse tunnel.`);
|
|
299
|
-
const { runTunnel } = await import('./tunnel-
|
|
299
|
+
const { runTunnel } = await import('./tunnel-dl6vFKgd.mjs');
|
|
300
300
|
await runTunnel(name, ports);
|
|
301
301
|
}
|
|
302
302
|
} catch (err) {
|
|
@@ -312,7 +312,7 @@ async function serviceTunnel(args) {
|
|
|
312
312
|
console.error("Usage: svamp service tunnel <name> --port <port> [--port <port2>]");
|
|
313
313
|
process.exit(1);
|
|
314
314
|
}
|
|
315
|
-
const { runTunnel } = await import('./tunnel-
|
|
315
|
+
const { runTunnel } = await import('./tunnel-dl6vFKgd.mjs');
|
|
316
316
|
await runTunnel(name, ports);
|
|
317
317
|
}
|
|
318
318
|
async function handleServiceCommand() {
|
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-BaMf-bAo.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.63";
|
|
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",
|
|
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-tunnel-proxy.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",
|
|
@@ -549,10 +549,21 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
549
549
|
authorizeRequest(context, currentMetadata.sharing, "view");
|
|
550
550
|
const pending = [];
|
|
551
551
|
let wake = null;
|
|
552
|
+
let callerDisconnected = false;
|
|
553
|
+
const callerClientId = context?.from;
|
|
552
554
|
const push = (update) => {
|
|
553
555
|
pending.push(update);
|
|
554
556
|
wake?.();
|
|
555
557
|
};
|
|
558
|
+
const onDisconnect = (event) => {
|
|
559
|
+
if (callerClientId && event.client_id === callerClientId) {
|
|
560
|
+
callerDisconnected = true;
|
|
561
|
+
const w = wake;
|
|
562
|
+
wake = null;
|
|
563
|
+
w?.();
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
server.on("remote_client_disconnected", onDisconnect);
|
|
556
567
|
subscribers.add(push);
|
|
557
568
|
console.log(`[HYPHA MACHINE] subscribe() started (total: ${subscribers.size})`);
|
|
558
569
|
try {
|
|
@@ -562,8 +573,8 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
562
573
|
metadata: { value: currentMetadata, version: metadataVersion },
|
|
563
574
|
daemonState: { value: currentDaemonState, version: daemonStateVersion }
|
|
564
575
|
};
|
|
565
|
-
while (
|
|
566
|
-
while (pending.length === 0) {
|
|
576
|
+
while (!callerDisconnected) {
|
|
577
|
+
while (pending.length === 0 && !callerDisconnected) {
|
|
567
578
|
await new Promise((r) => {
|
|
568
579
|
wake = r;
|
|
569
580
|
});
|
|
@@ -574,6 +585,7 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
574
585
|
}
|
|
575
586
|
}
|
|
576
587
|
} finally {
|
|
588
|
+
server.off("remote_client_disconnected", onDisconnect);
|
|
577
589
|
subscribers.delete(push);
|
|
578
590
|
wake?.();
|
|
579
591
|
console.log(`[HYPHA MACHINE] subscribe() ended (remaining: ${subscribers.size})`);
|
|
@@ -1153,10 +1165,21 @@ async function registerSessionService(server, sessionId, initialMetadata, initia
|
|
|
1153
1165
|
authorizeRequest(context, metadata.sharing, "view");
|
|
1154
1166
|
const pending = [];
|
|
1155
1167
|
let wake = null;
|
|
1168
|
+
let callerDisconnected = false;
|
|
1169
|
+
const callerClientId = context?.from;
|
|
1156
1170
|
const push = (update) => {
|
|
1157
1171
|
pending.push(update);
|
|
1158
1172
|
wake?.();
|
|
1159
1173
|
};
|
|
1174
|
+
const onDisconnect = (event) => {
|
|
1175
|
+
if (callerClientId && event.client_id === callerClientId) {
|
|
1176
|
+
callerDisconnected = true;
|
|
1177
|
+
const w = wake;
|
|
1178
|
+
wake = null;
|
|
1179
|
+
w?.();
|
|
1180
|
+
}
|
|
1181
|
+
};
|
|
1182
|
+
server.on("remote_client_disconnected", onDisconnect);
|
|
1160
1183
|
subscribers.add(push);
|
|
1161
1184
|
console.log(`[HYPHA SESSION ${sessionId}] subscribe() started (total: ${subscribers.size})`);
|
|
1162
1185
|
try {
|
|
@@ -1171,8 +1194,8 @@ async function registerSessionService(server, sessionId, initialMetadata, initia
|
|
|
1171
1194
|
yield { type: "new-message", sessionId, message: msg };
|
|
1172
1195
|
}
|
|
1173
1196
|
yield { type: "activity", sessionId, ...lastActivity };
|
|
1174
|
-
while (
|
|
1175
|
-
while (pending.length === 0) {
|
|
1197
|
+
while (!callerDisconnected) {
|
|
1198
|
+
while (pending.length === 0 && !callerDisconnected) {
|
|
1176
1199
|
await new Promise((r) => {
|
|
1177
1200
|
wake = r;
|
|
1178
1201
|
});
|
|
@@ -1183,6 +1206,7 @@ async function registerSessionService(server, sessionId, initialMetadata, initia
|
|
|
1183
1206
|
}
|
|
1184
1207
|
}
|
|
1185
1208
|
} finally {
|
|
1209
|
+
server.off("remote_client_disconnected", onDisconnect);
|
|
1186
1210
|
subscribers.delete(push);
|
|
1187
1211
|
wake?.();
|
|
1188
1212
|
console.log(`[HYPHA SESSION ${sessionId}] subscribe() ended (remaining: ${subscribers.size})`);
|
|
@@ -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-BaMf-bAo.mjs';
|
|
6
6
|
import { createServer } from 'node:http';
|
|
7
7
|
import { spawn } from 'node:child_process';
|
|
8
8
|
import { createInterface } from 'node:readline';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as os from 'os';
|
|
2
|
+
import * as http from 'http';
|
|
2
3
|
import { requireSandboxApiEnv } from './api-Cegey1dh.mjs';
|
|
3
4
|
import { WebSocket } from 'ws';
|
|
4
5
|
|
|
@@ -123,57 +124,72 @@ class TunnelClient {
|
|
|
123
124
|
async proxyRequest(req) {
|
|
124
125
|
this.requestCount++;
|
|
125
126
|
const port = req.port || this.options.ports[0];
|
|
126
|
-
const url = `http://${this.options.localHost}:${port}${req.path}`;
|
|
127
|
-
const controller = new AbortController();
|
|
128
|
-
const timeout = setTimeout(() => controller.abort(), this.options.requestTimeout);
|
|
129
127
|
const forwardHeaders = { ...req.headers };
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
128
|
+
forwardHeaders["accept-encoding"] = "identity";
|
|
129
|
+
const chunks = [];
|
|
130
|
+
const status_holder = { status: 502, headers: {} };
|
|
131
|
+
await new Promise((resolve, reject) => {
|
|
132
|
+
const timeout = setTimeout(() => reject(new Error("timeout")), this.options.requestTimeout);
|
|
133
|
+
const options = {
|
|
134
|
+
hostname: this.options.localHost,
|
|
135
|
+
port,
|
|
136
|
+
path: req.path,
|
|
137
|
+
method: req.method,
|
|
138
|
+
headers: forwardHeaders
|
|
139
|
+
};
|
|
140
|
+
const httpReq = http.request(options, (res) => {
|
|
141
|
+
status_holder.status = res.statusCode ?? 502;
|
|
142
|
+
const rawHeaders = res.headers;
|
|
143
|
+
for (const [key, value] of Object.entries(rawHeaders)) {
|
|
144
|
+
if (Array.isArray(value)) {
|
|
145
|
+
status_holder.headers[key] = value.join(", ");
|
|
146
|
+
} else if (value !== void 0) {
|
|
147
|
+
status_holder.headers[key] = value;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
res.on("data", (chunk) => chunks.push(chunk));
|
|
151
|
+
res.on("end", () => {
|
|
152
|
+
clearTimeout(timeout);
|
|
153
|
+
resolve();
|
|
154
|
+
});
|
|
155
|
+
res.on("error", (e) => {
|
|
156
|
+
clearTimeout(timeout);
|
|
157
|
+
reject(e);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
httpReq.on("error", (e) => {
|
|
161
|
+
clearTimeout(timeout);
|
|
162
|
+
reject(e);
|
|
149
163
|
});
|
|
164
|
+
if (req.body && !["GET", "HEAD"].includes(req.method.toUpperCase())) {
|
|
165
|
+
httpReq.write(Buffer.from(req.body, "base64"));
|
|
166
|
+
}
|
|
167
|
+
httpReq.end();
|
|
168
|
+
}).then(() => {
|
|
169
|
+
const bodyBuffer = Buffer.concat(chunks);
|
|
170
|
+
const bodyBase64 = bodyBuffer.length > 0 ? bodyBuffer.toString("base64") : void 0;
|
|
171
|
+
for (const h of ["connection", "keep-alive", "transfer-encoding"]) {
|
|
172
|
+
delete status_holder.headers[h];
|
|
173
|
+
}
|
|
150
174
|
this.send({
|
|
151
175
|
type: "response",
|
|
152
176
|
id: req.id,
|
|
153
|
-
status:
|
|
154
|
-
headers,
|
|
177
|
+
status: status_holder.status,
|
|
178
|
+
headers: status_holder.headers,
|
|
155
179
|
body: bodyBase64
|
|
156
180
|
});
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
type: "response",
|
|
170
|
-
id: req.id,
|
|
171
|
-
status: 502,
|
|
172
|
-
headers: { "content-type": "text/plain" },
|
|
173
|
-
body: Buffer.from(`Tunnel: local service error: ${err.message}`).toString("base64")
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
}
|
|
181
|
+
}).catch((err) => {
|
|
182
|
+
const isTimeout = err.message === "timeout";
|
|
183
|
+
this.send({
|
|
184
|
+
type: "response",
|
|
185
|
+
id: req.id,
|
|
186
|
+
status: isTimeout ? 504 : 502,
|
|
187
|
+
headers: { "content-type": "text/plain" },
|
|
188
|
+
body: Buffer.from(
|
|
189
|
+
isTimeout ? "Tunnel: request timeout" : `Tunnel: local service error: ${err.message}`
|
|
190
|
+
).toString("base64")
|
|
191
|
+
});
|
|
192
|
+
});
|
|
177
193
|
}
|
|
178
194
|
// ── WebSocket proxying ───────────────────────────────────────────────
|
|
179
195
|
async handleWsOpen(msg) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svamp-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.63",
|
|
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",
|
|
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-tunnel-proxy.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",
|