svamp-cli 0.2.300 → 0.2.301
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/{adminCommands-lOuwAyXW.mjs → adminCommands-DMiliv55.mjs} +1 -1
- package/dist/{agentCommands-C56-TSwf.mjs → agentCommands-BCkWdFFW.mjs} +5 -5
- package/dist/{auth-y5EinW_c.mjs → auth-Ba1_zl1h.mjs} +1 -1
- package/dist/{cli-BbbzgMWX.mjs → cli-Bv0Zhf3M.mjs} +69 -69
- package/dist/cli.mjs +2 -2
- package/dist/{commands-Db1SMhcL.mjs → commands-B2mRza8S.mjs} +2 -2
- package/dist/{commands-Qz7oTXdj.mjs → commands-BA3eBROn.mjs} +1 -1
- package/dist/{commands-Cb00JySn.mjs → commands-BAlaK67Y.mjs} +1 -1
- package/dist/{commands-VtqFEtFc.mjs → commands-BC3RuhRx.mjs} +2 -2
- package/dist/commands-BnirT9RR.mjs +161 -0
- package/dist/{commands-BlVHxX-n.mjs → commands-DhB2iz0_.mjs} +7 -7
- package/dist/{commands-Bjbq2pJg.mjs → commands-bIioWHWe.mjs} +2 -2
- package/dist/{commands-BLFj8bE8.mjs → commands-hHZu5qJh.mjs} +1 -1
- package/dist/{fleet-DKAN08u-.mjs → fleet-BFurNsSA.mjs} +1 -1
- package/dist/{frpc-Bx0J5hIR.mjs → frpc-Cb6jUvED.mjs} +1 -1
- package/dist/{headlessCli-DaqkPy9x.mjs → headlessCli-DP9gpAxv.mjs} +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{notifyCommands-DaAd67p4.mjs → notifyCommands-C0i6P1yC.mjs} +1 -1
- package/dist/package-D8lHDQja.mjs +64 -0
- package/dist/{rpc-C2l4b6gk.mjs → rpc-B-bxS-Pv.mjs} +1 -1
- package/dist/{rpc-D1Vg26a1.mjs → rpc-CNkfUlz1.mjs} +1 -1
- package/dist/{run-DrG6nwGm.mjs → run-C0GhrtVf.mjs} +347 -58
- package/dist/{run-CVRu9pzU.mjs → run-CvT_37Ov.mjs} +1 -1
- package/dist/{scheduler-CGmlf3VQ.mjs → scheduler-DT1_BBdZ.mjs} +1 -1
- package/dist/{serveCommands-CiYytaPO.mjs → serveCommands-CUabu97u.mjs} +5 -5
- package/dist/{sideband-BQz9FNc9.mjs → sideband-BlZBmbji.mjs} +1 -1
- package/package.json +2 -2
- package/dist/commands-Beysszfu.mjs +0 -293
- package/dist/package-B5_N_B9C.mjs +0 -64
|
@@ -2973,7 +2973,7 @@ Connection: close\r
|
|
|
2973
2973
|
const mount = this.mounts.get(mountName);
|
|
2974
2974
|
const subdomainOverride = mount?.access === "link" && mount.linkToken ? /* @__PURE__ */ new Map([[this.port, buildLinkSubdomain(subdomainSafe, mount.linkToken)]]) : void 0;
|
|
2975
2975
|
try {
|
|
2976
|
-
const { FrpcTunnel } = await import('./frpc-
|
|
2976
|
+
const { FrpcTunnel } = await import('./frpc-Cb6jUvED.mjs');
|
|
2977
2977
|
let tunnel;
|
|
2978
2978
|
tunnel = new FrpcTunnel({
|
|
2979
2979
|
name: tunnelName,
|
|
@@ -4639,11 +4639,6 @@ class ChannelOutbox {
|
|
|
4639
4639
|
}
|
|
4640
4640
|
}
|
|
4641
4641
|
|
|
4642
|
-
var outbox = /*#__PURE__*/Object.freeze({
|
|
4643
|
-
__proto__: null,
|
|
4644
|
-
ChannelOutbox: ChannelOutbox
|
|
4645
|
-
});
|
|
4646
|
-
|
|
4647
4642
|
function getParamNames(fn) {
|
|
4648
4643
|
const src = fn.toString();
|
|
4649
4644
|
const match = src.match(/^(?:async\s+)?(?:function\s*\w*)?\s*\(([^)]*)\)/);
|
|
@@ -5872,7 +5867,7 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
5872
5867
|
const tunnels = handlers.tunnels;
|
|
5873
5868
|
if (!tunnels) throw new Error("Tunnel management not available");
|
|
5874
5869
|
if (tunnels.has(params.name)) throw new Error(`Tunnel '${params.name}' already running`);
|
|
5875
|
-
const { FrpcTunnel } = await import('./frpc-
|
|
5870
|
+
const { FrpcTunnel } = await import('./frpc-Cb6jUvED.mjs');
|
|
5876
5871
|
const tunnel = new FrpcTunnel({
|
|
5877
5872
|
name: params.name,
|
|
5878
5873
|
ports: params.ports,
|
|
@@ -6348,7 +6343,7 @@ QUESTION: ${params.question || "Summarize this concisely."}` }
|
|
|
6348
6343
|
}
|
|
6349
6344
|
const deps = buildSessionDeps(rpc, { cwd, ownerEmail: owner });
|
|
6350
6345
|
const sender = { name: context?.user?.email || context?.user?.id || "user", kind: "user", verified: true };
|
|
6351
|
-
const { toolsForRole } = await import('./sideband-
|
|
6346
|
+
const { toolsForRole } = await import('./sideband-BlZBmbji.mjs');
|
|
6352
6347
|
const r2 = await runWiseAgent({ message: params.message, sender, config: { tools: toolsForRole(role2) }, deps, transport, model: resolved.model });
|
|
6353
6348
|
return fmt(r2);
|
|
6354
6349
|
}
|
|
@@ -6453,7 +6448,7 @@ QUESTION: ${params.question || "Summarize this concisely."}` }
|
|
|
6453
6448
|
return { ok: false, call_id: callId, status: "busy", error: "channel is busy (too many concurrent requests) \u2014 retry shortly" };
|
|
6454
6449
|
}
|
|
6455
6450
|
const rendered = renderMessage(c, { sender: r.sender, body: { message: kwargs.message }, callId });
|
|
6456
|
-
const { queryCore } = await import('./commands-
|
|
6451
|
+
const { queryCore } = await import('./commands-BAlaK67Y.mjs');
|
|
6457
6452
|
const timeout = c.reply?.timeout_sec || 120;
|
|
6458
6453
|
let result;
|
|
6459
6454
|
try {
|
|
@@ -6605,6 +6600,44 @@ ${d?.error || "not found"}`;
|
|
|
6605
6600
|
{ overwrite: true }
|
|
6606
6601
|
);
|
|
6607
6602
|
console.log(`[HYPHA MACHINE] Channels service registered: ${channelsServiceInfo.id} (type svamp-channels)`);
|
|
6603
|
+
const OUTPOST_MISSING_SESSION = 'missing "session" \u2014 the outpost gateway routes by session id. Over HTTP wrap args: POST {"kwargs": {"session": "<id>", "token": "<token>", "machine": "<name>"}}.';
|
|
6604
|
+
const routeOutpost = (session) => {
|
|
6605
|
+
const sid = String(session || "").trim();
|
|
6606
|
+
if (!sid) return { error: OUTPOST_MISSING_SESSION };
|
|
6607
|
+
const rpc = handlers.getSessionRPCHandlers?.(sid);
|
|
6608
|
+
if (!rpc?.outpostHello) return { error: `session ${sid.slice(0, 12)} is not connected on this machine` };
|
|
6609
|
+
return { rpc };
|
|
6610
|
+
};
|
|
6611
|
+
const outpostServiceInfo = await server.registerService(
|
|
6612
|
+
{
|
|
6613
|
+
id: "outpost",
|
|
6614
|
+
name: `Svamp Outpost (${currentMetadata.displayName || machineId})`,
|
|
6615
|
+
type: "svamp-outpost",
|
|
6616
|
+
// Public so a remote machine (possibly anonymous) can dial in; token-authed per call,
|
|
6617
|
+
// so no Hypha identity/context is needed (the handlers ignore context entirely).
|
|
6618
|
+
config: { visibility: "public", require_context: false },
|
|
6619
|
+
hello: async (kwargs = {}) => {
|
|
6620
|
+
trackInbound();
|
|
6621
|
+
const r = routeOutpost(kwargs?.session);
|
|
6622
|
+
if ("error" in r) return { error: r.error };
|
|
6623
|
+
return r.rpc.outpostHello(kwargs);
|
|
6624
|
+
},
|
|
6625
|
+
poll: async (kwargs = {}) => {
|
|
6626
|
+
trackInbound();
|
|
6627
|
+
const r = routeOutpost(kwargs?.session);
|
|
6628
|
+
if ("error" in r) return { error: r.error };
|
|
6629
|
+
return r.rpc.outpostPoll(kwargs);
|
|
6630
|
+
},
|
|
6631
|
+
result: async (kwargs = {}) => {
|
|
6632
|
+
trackInbound();
|
|
6633
|
+
const r = routeOutpost(kwargs?.session);
|
|
6634
|
+
if ("error" in r) return { error: r.error };
|
|
6635
|
+
return r.rpc.outpostResult(kwargs);
|
|
6636
|
+
}
|
|
6637
|
+
},
|
|
6638
|
+
{ overwrite: true }
|
|
6639
|
+
);
|
|
6640
|
+
console.log(`[HYPHA MACHINE] Outpost service registered: ${outpostServiceInfo.id} (type svamp-outpost)`);
|
|
6608
6641
|
return {
|
|
6609
6642
|
serviceInfo,
|
|
6610
6643
|
notifySessionEvent: notifyListeners,
|
|
@@ -6639,6 +6672,8 @@ ${d?.error || "not found"}`;
|
|
|
6639
6672
|
await server.unregisterService(serviceInfo.id);
|
|
6640
6673
|
await server.unregisterService(channelsServiceInfo.id).catch(() => {
|
|
6641
6674
|
});
|
|
6675
|
+
await server.unregisterService(outpostServiceInfo.id).catch(() => {
|
|
6676
|
+
});
|
|
6642
6677
|
}
|
|
6643
6678
|
};
|
|
6644
6679
|
}
|
|
@@ -6930,6 +6965,43 @@ function retryDelayMs(now, backoffUntil) {
|
|
|
6930
6965
|
return Math.max(0, backoffUntil - now);
|
|
6931
6966
|
}
|
|
6932
6967
|
|
|
6968
|
+
function tokenPath(projectDir, session) {
|
|
6969
|
+
return join$1(projectDir, ".svamp", session, "outpost.json");
|
|
6970
|
+
}
|
|
6971
|
+
function genToken() {
|
|
6972
|
+
return randomBytes(24).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
6973
|
+
}
|
|
6974
|
+
function loadOutpostToken(projectDir, session) {
|
|
6975
|
+
const file = tokenPath(projectDir, session);
|
|
6976
|
+
if (!existsSync(file)) return null;
|
|
6977
|
+
try {
|
|
6978
|
+
const parsed = JSON.parse(readFileSync(file, "utf-8"));
|
|
6979
|
+
if (!parsed || typeof parsed.token !== "string" || !parsed.token) return null;
|
|
6980
|
+
return parsed;
|
|
6981
|
+
} catch {
|
|
6982
|
+
return null;
|
|
6983
|
+
}
|
|
6984
|
+
}
|
|
6985
|
+
function ensureOutpostToken(projectDir, session) {
|
|
6986
|
+
const existing = loadOutpostToken(projectDir, session);
|
|
6987
|
+
if (existing) return existing;
|
|
6988
|
+
const rec = { version: 1, session, token: genToken(), createdAt: Date.now() };
|
|
6989
|
+
const file = tokenPath(projectDir, session);
|
|
6990
|
+
mkdirSync$1(dirname(file), { recursive: true });
|
|
6991
|
+
writeFileSync$1(file, JSON.stringify(rec, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
6992
|
+
try {
|
|
6993
|
+
chmodSync(file, 384);
|
|
6994
|
+
} catch {
|
|
6995
|
+
}
|
|
6996
|
+
return rec;
|
|
6997
|
+
}
|
|
6998
|
+
function outpostTokenMatches(rec, presented) {
|
|
6999
|
+
if (!rec || typeof presented !== "string" || presented.length !== rec.token.length) return false;
|
|
7000
|
+
let diff = 0;
|
|
7001
|
+
for (let i = 0; i < rec.token.length; i++) diff |= rec.token.charCodeAt(i) ^ presented.charCodeAt(i);
|
|
7002
|
+
return diff === 0;
|
|
7003
|
+
}
|
|
7004
|
+
|
|
6933
7005
|
const DEFAULT_DOWNLOAD_BASE = "https://github.com/amun-ai/hypha-cloud/releases/latest/download";
|
|
6934
7006
|
function shq(v) {
|
|
6935
7007
|
return `'${String(v).replace(/'/g, `'\\''`)}'`;
|
|
@@ -6940,10 +7012,10 @@ function psq(v) {
|
|
|
6940
7012
|
function buildOutpostInstall(params) {
|
|
6941
7013
|
const base = params.serverBase.replace(/\/$/, "");
|
|
6942
7014
|
const dl = (params.downloadBase || DEFAULT_DOWNLOAD_BASE).replace(/\/$/, "");
|
|
6943
|
-
const session = params.session
|
|
6944
|
-
const unix = `curl -fsSL ${shq(`${dl}/install.sh`)} | SVAMP_OUTPOST_SERVER=${shq(base)}
|
|
6945
|
-
const windows = `$env:SVAMP_OUTPOST_SERVER=${psq(base)}; $env:
|
|
6946
|
-
const direct = `svamp-outpost --server ${shq(base)} --
|
|
7015
|
+
const session = params.session;
|
|
7016
|
+
const unix = `curl -fsSL ${shq(`${dl}/install.sh`)} | SVAMP_OUTPOST_SERVER=${shq(base)} SVAMP_OUTPOST_TOKEN=${shq(params.token)} SVAMP_OUTPOST_SESSION=${shq(session)} SVAMP_OUTPOST_DL=${shq(dl)} sh`;
|
|
7017
|
+
const windows = `$env:SVAMP_OUTPOST_SERVER=${psq(base)}; $env:SVAMP_OUTPOST_TOKEN=${psq(params.token)}; $env:SVAMP_OUTPOST_SESSION=${psq(session)}; $env:SVAMP_OUTPOST_DL=${psq(dl)}; irm ${psq(`${dl}/install.ps1`)} | iex`;
|
|
7018
|
+
const direct = `svamp-outpost --server ${shq(base)} --token ${shq(params.token)} --session ${shq(session)}`;
|
|
6947
7019
|
return { unix, windows, direct };
|
|
6948
7020
|
}
|
|
6949
7021
|
|
|
@@ -6955,37 +7027,19 @@ const OUTPOST_BINARIES = [
|
|
|
6955
7027
|
{ label: "Linux (arm64)", file: "svamp-outpost-linux-arm64" },
|
|
6956
7028
|
{ label: "Windows (x86-64)", file: "svamp-outpost-windows-amd64.exe" }
|
|
6957
7029
|
];
|
|
6958
|
-
function
|
|
7030
|
+
function setupOutpost(params) {
|
|
6959
7031
|
const serverUrl = params.serverUrl || "https://hypha.aicell.io";
|
|
6960
7032
|
const downloadBase = (params.downloadBase || DEFAULT_OUTPOST_DOWNLOAD_BASE).replace(/\/$/, "");
|
|
6961
|
-
const serverBase = gatewayBase(params.
|
|
6962
|
-
const
|
|
6963
|
-
const
|
|
6964
|
-
const existing = store.get(channelId);
|
|
6965
|
-
let token = existing?.identity?.callers?.find((c) => c.name === "outpost")?.key;
|
|
6966
|
-
if (!token) token = genKey();
|
|
6967
|
-
const channel = {
|
|
6968
|
-
id: channelId,
|
|
6969
|
-
name: `Remote outpost \u2014 ${params.session}`,
|
|
6970
|
-
description: "FDE remote machine: a svamp-outpost binary connects here and the agent runs commands on it.",
|
|
6971
|
-
enabled: true,
|
|
6972
|
-
bind: { session: params.session },
|
|
6973
|
-
identity: { mode: "per-key", callers: [{ name: "outpost", kind: "agent", key: token }] },
|
|
6974
|
-
action: { kind: "message" },
|
|
6975
|
-
reply: { mode: "queue" },
|
|
6976
|
-
skill: { name: "remote-outpost", description: "Run commands on the connected remote machine." }
|
|
6977
|
-
};
|
|
6978
|
-
store.save(channel);
|
|
6979
|
-
const install = buildOutpostInstall({ serverBase, channel: channelId, token, session: params.session, downloadBase });
|
|
6980
|
-
const connectedCount = (store.get(channelId)?.last_calls || []).filter((c) => c.sender === "outpost").length;
|
|
7033
|
+
const serverBase = gatewayBase(params.outpostServiceId, serverUrl);
|
|
7034
|
+
const { token } = ensureOutpostToken(params.projectDir, params.session);
|
|
7035
|
+
const install = buildOutpostInstall({ serverBase, session: params.session, token, downloadBase });
|
|
6981
7036
|
return {
|
|
6982
|
-
channelId,
|
|
6983
7037
|
token,
|
|
6984
7038
|
serverBase,
|
|
6985
7039
|
downloadBase,
|
|
6986
7040
|
install,
|
|
6987
7041
|
binaries: OUTPOST_BINARIES.map((b) => ({ label: b.label, url: `${downloadBase}/${b.file}` })),
|
|
6988
|
-
connectedCount
|
|
7042
|
+
connectedCount: params.connectedCount || 0
|
|
6989
7043
|
};
|
|
6990
7044
|
}
|
|
6991
7045
|
|
|
@@ -7070,7 +7124,6 @@ async function mintPairingCode(opts) {
|
|
|
7070
7124
|
const expiresAt = now + ttlMs;
|
|
7071
7125
|
const pairJson = JSON.stringify({
|
|
7072
7126
|
server: payload.server,
|
|
7073
|
-
channel: payload.channel,
|
|
7074
7127
|
token: payload.token,
|
|
7075
7128
|
session: payload.session,
|
|
7076
7129
|
expiresAt
|
|
@@ -7107,6 +7160,157 @@ async function mintPairingCode(opts) {
|
|
|
7107
7160
|
return { code, resolver, expiresAt };
|
|
7108
7161
|
}
|
|
7109
7162
|
|
|
7163
|
+
const OUTPOST_STALE_MS = 9e4;
|
|
7164
|
+
const OUTPOST_EXEC_TIMEOUT_MS = 10 * 6e4;
|
|
7165
|
+
class OutpostCoordinator {
|
|
7166
|
+
conns = /* @__PURE__ */ new Map();
|
|
7167
|
+
queue = /* @__PURE__ */ new Map();
|
|
7168
|
+
pending = /* @__PURE__ */ new Map();
|
|
7169
|
+
seq = 0;
|
|
7170
|
+
now;
|
|
7171
|
+
setTimer;
|
|
7172
|
+
clearTimer;
|
|
7173
|
+
execTimeoutMs;
|
|
7174
|
+
staleMs;
|
|
7175
|
+
constructor(opts = {}) {
|
|
7176
|
+
this.now = opts.now || (() => Date.now());
|
|
7177
|
+
this.setTimer = opts.setTimer || ((fn, ms) => setTimeout(fn, ms));
|
|
7178
|
+
this.clearTimer = opts.clearTimer || ((t) => clearTimeout(t));
|
|
7179
|
+
this.execTimeoutMs = opts.execTimeoutMs ?? OUTPOST_EXEC_TIMEOUT_MS;
|
|
7180
|
+
this.staleMs = opts.staleMs ?? OUTPOST_STALE_MS;
|
|
7181
|
+
}
|
|
7182
|
+
isStale(c, at) {
|
|
7183
|
+
return at - c.lastSeen > this.staleMs;
|
|
7184
|
+
}
|
|
7185
|
+
/** Drop dead connections; fail any in-flight execs bound to them so callers never hang. */
|
|
7186
|
+
prune(at = this.now()) {
|
|
7187
|
+
for (const [machine, c] of [...this.conns]) {
|
|
7188
|
+
if (this.isStale(c, at)) {
|
|
7189
|
+
this.conns.delete(machine);
|
|
7190
|
+
this.queue.delete(machine);
|
|
7191
|
+
this.failMachine(machine, "the remote outpost disconnected");
|
|
7192
|
+
}
|
|
7193
|
+
}
|
|
7194
|
+
}
|
|
7195
|
+
/** Reject every pending exec on a machine with a synthetic disconnect result (exitCode -1). */
|
|
7196
|
+
failMachine(machine, reason) {
|
|
7197
|
+
for (const [id, p] of [...this.pending]) {
|
|
7198
|
+
if (p.machine !== machine) continue;
|
|
7199
|
+
this.clearTimer(p.timer);
|
|
7200
|
+
this.pending.delete(id);
|
|
7201
|
+
p.resolve({ id, stdout: "", stderr: reason, exitCode: -1, synthetic: true, ts: this.now() });
|
|
7202
|
+
}
|
|
7203
|
+
}
|
|
7204
|
+
/**
|
|
7205
|
+
* A remote said hello (first connect OR reconnect after an outage). Upserts the connection and
|
|
7206
|
+
* returns `isNew` = true when it should trigger the ONE-TIME inbox announce — true on the first
|
|
7207
|
+
* appearance and on a reconnect after the connection had gone stale/pruned.
|
|
7208
|
+
*/
|
|
7209
|
+
registerConnection(machine, meta = {}) {
|
|
7210
|
+
const at = this.now();
|
|
7211
|
+
this.prune(at);
|
|
7212
|
+
const existing = this.conns.get(machine);
|
|
7213
|
+
const isNew = !existing;
|
|
7214
|
+
const connection = {
|
|
7215
|
+
machine,
|
|
7216
|
+
label: meta.label ?? existing?.label,
|
|
7217
|
+
os: meta.os ?? existing?.os,
|
|
7218
|
+
arch: meta.arch ?? existing?.arch,
|
|
7219
|
+
version: meta.version ?? existing?.version,
|
|
7220
|
+
connectedAt: existing?.connectedAt ?? at,
|
|
7221
|
+
lastSeen: at
|
|
7222
|
+
};
|
|
7223
|
+
this.conns.set(machine, connection);
|
|
7224
|
+
return { isNew, connection };
|
|
7225
|
+
}
|
|
7226
|
+
/** Refresh liveness for an active poll (keeps the connection "always on"). */
|
|
7227
|
+
touch(machine) {
|
|
7228
|
+
const c = this.conns.get(machine);
|
|
7229
|
+
if (!c) return false;
|
|
7230
|
+
c.lastSeen = this.now();
|
|
7231
|
+
return true;
|
|
7232
|
+
}
|
|
7233
|
+
/** Live connections only (prunes first). */
|
|
7234
|
+
listConnections() {
|
|
7235
|
+
this.prune();
|
|
7236
|
+
return [...this.conns.values()].sort((a, b) => a.connectedAt - b.connectedAt);
|
|
7237
|
+
}
|
|
7238
|
+
isConnected(machine) {
|
|
7239
|
+
this.prune();
|
|
7240
|
+
return this.conns.has(machine);
|
|
7241
|
+
}
|
|
7242
|
+
/**
|
|
7243
|
+
* Pick the machine an exec should target: an explicit live target, or the sole live outpost.
|
|
7244
|
+
* Ambiguity (0 or >1 without a target) is a clear error, never a silent guess.
|
|
7245
|
+
*/
|
|
7246
|
+
resolveTarget(target) {
|
|
7247
|
+
const live = this.listConnections();
|
|
7248
|
+
if (target) {
|
|
7249
|
+
const hit = live.find((c) => c.machine === target || c.label === target);
|
|
7250
|
+
if (!hit) return { error: `no connected outpost named "${target}" (connected: ${live.map((c) => c.machine).join(", ") || "none"})` };
|
|
7251
|
+
return { machine: hit.machine };
|
|
7252
|
+
}
|
|
7253
|
+
if (live.length === 0) return { error: "no remote outpost is connected \u2014 run the install one-liner on the remote machine first" };
|
|
7254
|
+
if (live.length > 1) return { error: `multiple outposts connected (${live.map((c) => c.machine).join(", ")}) \u2014 pass a target` };
|
|
7255
|
+
return { machine: live[0].machine };
|
|
7256
|
+
}
|
|
7257
|
+
/**
|
|
7258
|
+
* Enqueue a command for a machine and return a promise that resolves with the REAL result once
|
|
7259
|
+
* the outpost posts it back (or a synthetic exitCode -1 on disconnect/timeout). Fails fast if the
|
|
7260
|
+
* machine is not connected.
|
|
7261
|
+
*/
|
|
7262
|
+
enqueueExec(machine, cmd, cwd) {
|
|
7263
|
+
const id = `x${(++this.seq).toString(36)}_${this.now().toString(36)}`;
|
|
7264
|
+
if (!this.isConnected(machine)) {
|
|
7265
|
+
return {
|
|
7266
|
+
id,
|
|
7267
|
+
promise: Promise.resolve({ id, stdout: "", stderr: `outpost "${machine}" is not connected`, exitCode: -1, synthetic: true, ts: this.now() })
|
|
7268
|
+
};
|
|
7269
|
+
}
|
|
7270
|
+
const command = { id, cmd, cwd, ts: this.now() };
|
|
7271
|
+
const q = this.queue.get(machine) || [];
|
|
7272
|
+
q.push(command);
|
|
7273
|
+
this.queue.set(machine, q);
|
|
7274
|
+
const promise = new Promise((resolve) => {
|
|
7275
|
+
const timer = this.setTimer(() => {
|
|
7276
|
+
if (!this.pending.has(id)) return;
|
|
7277
|
+
this.pending.delete(id);
|
|
7278
|
+
resolve({ id, stdout: "", stderr: `command timed out after ${Math.round(this.execTimeoutMs / 1e3)}s`, exitCode: -1, synthetic: true, ts: this.now() });
|
|
7279
|
+
}, this.execTimeoutMs);
|
|
7280
|
+
this.pending.set(id, { machine, resolve, timer, enqueuedAt: this.now() });
|
|
7281
|
+
});
|
|
7282
|
+
return { id, promise };
|
|
7283
|
+
}
|
|
7284
|
+
/** Long-poll drain: return (and clear) the commands queued for a machine; refreshes liveness. */
|
|
7285
|
+
pollCommands(machine) {
|
|
7286
|
+
this.touch(machine);
|
|
7287
|
+
const q = this.queue.get(machine);
|
|
7288
|
+
if (!q || q.length === 0) return [];
|
|
7289
|
+
this.queue.set(machine, []);
|
|
7290
|
+
return q;
|
|
7291
|
+
}
|
|
7292
|
+
/** Deliver a result from the outpost to the waiting exec. Returns false if unknown/expired. */
|
|
7293
|
+
resolveResult(result) {
|
|
7294
|
+
const p = this.pending.get(result.id);
|
|
7295
|
+
if (!p) return false;
|
|
7296
|
+
this.clearTimer(p.timer);
|
|
7297
|
+
this.pending.delete(result.id);
|
|
7298
|
+
this.touch(p.machine);
|
|
7299
|
+
p.resolve({
|
|
7300
|
+
id: result.id,
|
|
7301
|
+
stdout: result.stdout ?? "",
|
|
7302
|
+
stderr: result.stderr ?? "",
|
|
7303
|
+
exitCode: typeof result.exitCode === "number" ? result.exitCode : 0,
|
|
7304
|
+
ts: this.now()
|
|
7305
|
+
});
|
|
7306
|
+
return true;
|
|
7307
|
+
}
|
|
7308
|
+
/** Test/introspection: how many execs are awaiting a result. */
|
|
7309
|
+
pendingCount() {
|
|
7310
|
+
return this.pending.size;
|
|
7311
|
+
}
|
|
7312
|
+
}
|
|
7313
|
+
|
|
7110
7314
|
const PARTICIPANTS_CHANNEL_ID = "sys-participants";
|
|
7111
7315
|
function channelPublicView(c) {
|
|
7112
7316
|
const u = c.upload;
|
|
@@ -7513,8 +7717,28 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
|
|
|
7513
7717
|
const channelStore = new ChannelStore(initialMetadata.path);
|
|
7514
7718
|
const meetingActivity = [];
|
|
7515
7719
|
const channelOutbox = new ChannelOutbox(initialMetadata.path);
|
|
7720
|
+
const outpostCoordinator = new OutpostCoordinator();
|
|
7721
|
+
const outpostProjectDir = () => metadata.path || process.cwd();
|
|
7722
|
+
const announceOutpost = (conn) => {
|
|
7723
|
+
const who = conn.label || conn.machine;
|
|
7724
|
+
const plat = [conn.os, conn.arch].filter(Boolean).join("/") || "unknown platform";
|
|
7725
|
+
const msg = {
|
|
7726
|
+
messageId: "op_" + Math.random().toString(16).slice(2, 10),
|
|
7727
|
+
body: `A remote machine connected as an outpost: ${xmlEscape(who)} (${xmlEscape(plat)}). You can now run shell commands on it \u2014 its output returns synchronously, like a local command. Run one with: svamp outpost exec "uname -a"`,
|
|
7728
|
+
timestamp: Date.now(),
|
|
7729
|
+
read: false,
|
|
7730
|
+
from: "outpost",
|
|
7731
|
+
subject: `Remote outpost connected: ${who}`
|
|
7732
|
+
};
|
|
7733
|
+
inbox.push(msg);
|
|
7734
|
+
while (inbox.length > INBOX_MAX) inbox.shift();
|
|
7735
|
+
syncInboxToMetadata();
|
|
7736
|
+
callbacks.onInboxMessage?.(msg);
|
|
7737
|
+
notifyListeners({ type: "inbox-update", sessionId, message: msg });
|
|
7738
|
+
};
|
|
7516
7739
|
const cfg = server?.config || {};
|
|
7517
7740
|
const channelsServiceId = cfg.workspace && cfg.client_id ? `${cfg.workspace}/${cfg.client_id}:channels` : void 0;
|
|
7741
|
+
const outpostServiceId = cfg.workspace && cfg.client_id ? `${cfg.workspace}/${cfg.client_id}:outpost` : void 0;
|
|
7518
7742
|
const channelsBaseUrl = cfg.public_base_url || process.env.HYPHA_SERVER_URL || "https://hypha.aicell.io";
|
|
7519
7743
|
const skillCtxFor = (c) => ({
|
|
7520
7744
|
channelsServiceId,
|
|
@@ -7898,34 +8122,36 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
|
|
|
7898
8122
|
syncChannelsToMetadata();
|
|
7899
8123
|
return { success: !!caller, caller };
|
|
7900
8124
|
},
|
|
7901
|
-
// FDE outpost (#
|
|
7902
|
-
// install one-liners + direct binary download links + a
|
|
7903
|
-
// "Connect a remote machine" panel calls this; it reuses the SAME
|
|
7904
|
-
// `svamp outpost up`, so the
|
|
7905
|
-
//
|
|
8125
|
+
// FDE outpost (#0565 redesign): provision (idempotently) this session's durable outpost TOKEN
|
|
8126
|
+
// and return the install one-liners + direct binary download links + a LIVE connected count.
|
|
8127
|
+
// The app's "Connect a remote machine" panel calls this; it reuses the SAME setupOutpost core as
|
|
8128
|
+
// `svamp outpost up`, so the install command never drifts. NO channel is created — the remote
|
|
8129
|
+
// dials the machine's public `:outpost` gateway and this session's token authenticates it.
|
|
8130
|
+
// Admin-gated: the returned token is a capability to run commands on whatever machine connects.
|
|
7906
8131
|
outpostConnectInfo: async (params, context) => {
|
|
7907
8132
|
authorizeRequest(context, metadata.sharing, "admin");
|
|
7908
|
-
if (!
|
|
8133
|
+
if (!outpostServiceId) return { error: "the outpost service is not available on this machine" };
|
|
7909
8134
|
try {
|
|
7910
|
-
const
|
|
8135
|
+
const connectedCount = outpostCoordinator.listConnections().length;
|
|
8136
|
+
const info = setupOutpost({
|
|
7911
8137
|
session: sessionId,
|
|
7912
|
-
projectDir:
|
|
7913
|
-
|
|
8138
|
+
projectDir: outpostProjectDir(),
|
|
8139
|
+
outpostServiceId,
|
|
7914
8140
|
serverUrl: channelsBaseUrl,
|
|
7915
|
-
downloadBase: params?.downloadBase || process.env.SVAMP_OUTPOST_DL
|
|
8141
|
+
downloadBase: params?.downloadBase || process.env.SVAMP_OUTPOST_DL,
|
|
8142
|
+
connectedCount
|
|
7916
8143
|
});
|
|
7917
|
-
syncChannelsToMetadata();
|
|
7918
8144
|
let pairing = {};
|
|
7919
8145
|
try {
|
|
7920
8146
|
const am = await server.getService("public/artifact-manager");
|
|
7921
8147
|
if (am) {
|
|
7922
|
-
if (
|
|
8148
|
+
if (connectedCount > 0) {
|
|
7923
8149
|
await burnSessionPairings(am, sessionId, void 0, (m) => console.log(m));
|
|
7924
8150
|
} else {
|
|
7925
8151
|
const r = await mintPairingCode({
|
|
7926
8152
|
am,
|
|
7927
8153
|
session: sessionId,
|
|
7928
|
-
payload: { server: info.serverBase,
|
|
8154
|
+
payload: { server: info.serverBase, token: info.token, session: sessionId },
|
|
7929
8155
|
resolverBase: channelsBaseUrl,
|
|
7930
8156
|
log: (m) => console.log(m)
|
|
7931
8157
|
});
|
|
@@ -7940,6 +8166,69 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
|
|
|
7940
8166
|
return { error: e?.message || String(e) };
|
|
7941
8167
|
}
|
|
7942
8168
|
},
|
|
8169
|
+
// ── FDE outpost transport (#0565): token-authed remote endpoints + owner-facing exec/list ──
|
|
8170
|
+
// hello/poll/result carry NO session-sharing auth (the remote is anonymous); the per-session
|
|
8171
|
+
// capability token IS the auth (checked against the durable on-disk token). Routed here by the
|
|
8172
|
+
// machine's public `:outpost` gateway, which passes the remote-supplied `session` as the key.
|
|
8173
|
+
outpostHello: async (params) => {
|
|
8174
|
+
const rec = loadOutpostToken(outpostProjectDir(), sessionId);
|
|
8175
|
+
if (!outpostTokenMatches(rec, params?.token)) return { error: "unauthorized" };
|
|
8176
|
+
const machine = (String(params?.machine || "").trim() || "outpost").slice(0, 128);
|
|
8177
|
+
const { isNew, connection } = outpostCoordinator.registerConnection(machine, {
|
|
8178
|
+
label: params?.label ? String(params.label).slice(0, 128) : void 0,
|
|
8179
|
+
os: params?.os ? String(params.os).slice(0, 64) : void 0,
|
|
8180
|
+
arch: params?.arch ? String(params.arch).slice(0, 64) : void 0,
|
|
8181
|
+
version: params?.version ? String(params.version).slice(0, 64) : void 0
|
|
8182
|
+
});
|
|
8183
|
+
if (isNew) {
|
|
8184
|
+
announceOutpost(connection);
|
|
8185
|
+
try {
|
|
8186
|
+
const am = await server.getService("public/artifact-manager");
|
|
8187
|
+
if (am) await burnSessionPairings(am, sessionId, void 0, (m) => console.log(m));
|
|
8188
|
+
} catch {
|
|
8189
|
+
}
|
|
8190
|
+
}
|
|
8191
|
+
return { ok: true, machine: connection.machine };
|
|
8192
|
+
},
|
|
8193
|
+
outpostPoll: async (params) => {
|
|
8194
|
+
const rec = loadOutpostToken(outpostProjectDir(), sessionId);
|
|
8195
|
+
if (!outpostTokenMatches(rec, params?.token)) return { error: "unauthorized" };
|
|
8196
|
+
const machine = (String(params?.machine || "").trim() || "outpost").slice(0, 128);
|
|
8197
|
+
if (!outpostCoordinator.isConnected(machine)) {
|
|
8198
|
+
const { isNew, connection } = outpostCoordinator.registerConnection(machine, {});
|
|
8199
|
+
if (isNew) announceOutpost(connection);
|
|
8200
|
+
}
|
|
8201
|
+
const waitRaw = Number(params?.wait ?? 25);
|
|
8202
|
+
const waitSec = Number.isFinite(waitRaw) ? waitRaw : 25;
|
|
8203
|
+
const waitMs = Math.min(Math.max(0, waitSec * 1e3), 6e4);
|
|
8204
|
+
const deadline = Date.now() + waitMs;
|
|
8205
|
+
for (; ; ) {
|
|
8206
|
+
const commands = outpostCoordinator.pollCommands(machine);
|
|
8207
|
+
if (commands.length || Date.now() >= deadline) return { ok: true, commands };
|
|
8208
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
8209
|
+
}
|
|
8210
|
+
},
|
|
8211
|
+
outpostResult: async (params) => {
|
|
8212
|
+
const rec = loadOutpostToken(outpostProjectDir(), sessionId);
|
|
8213
|
+
if (!outpostTokenMatches(rec, params?.token)) return { error: "unauthorized" };
|
|
8214
|
+
if (!params?.id) return { error: "missing result id" };
|
|
8215
|
+
const ok = outpostCoordinator.resolveResult({ id: params.id, stdout: params.stdout, stderr: params.stderr, exitCode: params.exitCode });
|
|
8216
|
+
return { ok };
|
|
8217
|
+
},
|
|
8218
|
+
outpostExec: async (params, context) => {
|
|
8219
|
+
authorizeRequest(context, metadata.sharing, "admin");
|
|
8220
|
+
const cmd = String(params?.cmd || "").trim();
|
|
8221
|
+
if (!cmd) return { error: "cmd is required" };
|
|
8222
|
+
const t = outpostCoordinator.resolveTarget(params?.target ? String(params.target) : void 0);
|
|
8223
|
+
if ("error" in t) return { error: t.error };
|
|
8224
|
+
const { promise } = outpostCoordinator.enqueueExec(t.machine, cmd, params?.cwd ? String(params.cwd) : void 0);
|
|
8225
|
+
const r = await promise;
|
|
8226
|
+
return { ok: r.exitCode === 0, stdout: r.stdout, stderr: r.stderr, exitCode: r.exitCode, machine: t.machine };
|
|
8227
|
+
},
|
|
8228
|
+
outpostList: async (context) => {
|
|
8229
|
+
authorizeRequest(context, metadata.sharing, "view");
|
|
8230
|
+
return { ok: true, outposts: outpostCoordinator.listConnections() };
|
|
8231
|
+
},
|
|
7943
8232
|
getChannelSkill: async (id, context) => {
|
|
7944
8233
|
authorizeRequest(context, metadata.sharing, "view");
|
|
7945
8234
|
const c = channelStore.get(id);
|
|
@@ -16693,7 +16982,7 @@ async function startDaemon(options) {
|
|
|
16693
16982
|
try {
|
|
16694
16983
|
const dir = loadSessionIndex()[sessionId]?.directory;
|
|
16695
16984
|
if (!dir) return;
|
|
16696
|
-
const { reconcileServiceLinks } = await import('./agentCommands-
|
|
16985
|
+
const { reconcileServiceLinks } = await import('./agentCommands-BCkWdFFW.mjs');
|
|
16697
16986
|
const configPath = getSvampConfigPath(dir, sessionId);
|
|
16698
16987
|
const config = readSvampConfig(configPath);
|
|
16699
16988
|
const entries = Array.from(urls.entries());
|
|
@@ -16711,7 +17000,7 @@ async function startDaemon(options) {
|
|
|
16711
17000
|
}
|
|
16712
17001
|
}
|
|
16713
17002
|
async function createExposedTunnel(spec) {
|
|
16714
|
-
const { FrpcTunnel } = await import('./frpc-
|
|
17003
|
+
const { FrpcTunnel } = await import('./frpc-Cb6jUvED.mjs');
|
|
16715
17004
|
const tunnel = new FrpcTunnel({
|
|
16716
17005
|
name: spec.name,
|
|
16717
17006
|
ports: spec.ports,
|
|
@@ -18927,11 +19216,11 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
18927
19216
|
});
|
|
18928
19217
|
},
|
|
18929
19218
|
onIssue: async (params) => {
|
|
18930
|
-
const { issueRpc } = await import('./rpc-
|
|
19219
|
+
const { issueRpc } = await import('./rpc-B-bxS-Pv.mjs');
|
|
18931
19220
|
return issueRpc(params?.cwd || directory, params || {}, { notifySession: notifyIssueOwner, rekickLoopOwner });
|
|
18932
19221
|
},
|
|
18933
19222
|
onWorkflow: async (params) => {
|
|
18934
|
-
const { workflowRpc } = await import('./rpc-
|
|
19223
|
+
const { workflowRpc } = await import('./rpc-CNkfUlz1.mjs');
|
|
18935
19224
|
return workflowRpc(params?.cwd || directory, params || {});
|
|
18936
19225
|
},
|
|
18937
19226
|
onRipgrep: async (args, cwd) => {
|
|
@@ -19544,11 +19833,11 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
19544
19833
|
});
|
|
19545
19834
|
},
|
|
19546
19835
|
onIssue: async (params) => {
|
|
19547
|
-
const { issueRpc } = await import('./rpc-
|
|
19836
|
+
const { issueRpc } = await import('./rpc-B-bxS-Pv.mjs');
|
|
19548
19837
|
return issueRpc(params?.cwd || directory, params || {}, { notifySession: notifyIssueOwner, rekickLoopOwner });
|
|
19549
19838
|
},
|
|
19550
19839
|
onWorkflow: async (params) => {
|
|
19551
|
-
const { workflowRpc } = await import('./rpc-
|
|
19840
|
+
const { workflowRpc } = await import('./rpc-CNkfUlz1.mjs');
|
|
19552
19841
|
return workflowRpc(params?.cwd || directory, params || {});
|
|
19553
19842
|
},
|
|
19554
19843
|
onRipgrep: async (args, cwd) => {
|
|
@@ -20683,7 +20972,7 @@ ${oracle.output.trim().slice(0, 500)}`, "\u{1F501} Continuing loop");
|
|
|
20683
20972
|
const PING_TIMEOUT_MS = 15e3;
|
|
20684
20973
|
const POST_RECONNECT_GRACE_MS = 2e4;
|
|
20685
20974
|
const RECONNECT_JITTER_MS = 2500;
|
|
20686
|
-
const { WorkflowScheduler } = await import('./scheduler-
|
|
20975
|
+
const { WorkflowScheduler } = await import('./scheduler-DT1_BBdZ.mjs');
|
|
20687
20976
|
const workflowScheduler = new WorkflowScheduler({
|
|
20688
20977
|
projectRoots: () => {
|
|
20689
20978
|
const dirs = /* @__PURE__ */ new Set();
|
|
@@ -21307,4 +21596,4 @@ var run = /*#__PURE__*/Object.freeze({
|
|
|
21307
21596
|
writeStopMarker: writeStopMarker
|
|
21308
21597
|
});
|
|
21309
21598
|
|
|
21310
|
-
export {
|
|
21599
|
+
export { listSkillFiles as $, removeWorkflow as A, saveWorkflow as B, rawWorkflow as C, listWorkflows as D, isWorkflowEnabled as E, workflowCrons as F, cronMatches as G, summarize as H, workflowSteps as I, parseJwtEmail as J, computeCollectionConfigUpdate as K, SYSTEM_COLLECTION_CONFIG as L, loadMachineContext as M, buildMachineInstructions as N, machineToolsForRole as O, buildMachineTools as P, parseFrontmatter as Q, READ_ONLY_TOOLS as R, SharingNotificationSync as S, getSkillsServer as T, getSkillsWorkspaceName as U, getSkillsCollectionName as V, fetchWithTimeout as W, searchSkills as X, SKILLS_DIR as Y, getSkillInfo as Z, downloadSkillFile as _, createSessionStore as a, resolveModel as a0, clearStopMarker as a1, stopMarkerExists as a2, formatHandle as a3, normalizeAllowedUser as a4, loadSecurityContextConfig as a5, resolveSecurityContext as a6, buildSecurityContextFromFlags as a7, mergeSecurityContexts as a8, buildSessionShareUrl as a9, computeOutboundHop as aa, registerAwaitingReply as ab, buildMachineShareUrl as ac, parseHandle as ad, handleMatchesMetadata as ae, describeMisconfiguration as af, buildMachineDeps as ag, applyClaudeProxyEnv as ah, composeSessionId as ai, generateFriendlyName as aj, generateHookSettings as ak, staticFileServer as al, instanceConfig as am, claudeAuth as an, codexProvider as ao, projectInfo as ap, DefaultTransport$1 as aq, acpBackend as ar, acpAgentConfig as as, codexAppServerBackend as at, GeminiTransport$1 as au, api as av, run as aw, stopDaemon as b, connectToHypha as c, daemonStatus as d, getFrpsSubdomainHost as e, getFrpsServerPort as f, getHyphaServerUrl$1 as g, getFrpsServerAddr as h, shortId as i, resolveProjectRoot as j, getIssue as k, resumeIssue as l, addComment as m, addIssue as n, listIssues as o, pauseIssue as p, searchIssues as q, registerMachineService as r, startDaemon as s, isVisibleTo as t, updateIssue as u, getRun as v, listRuns as w, getWorkflow as x, runWorkflow as y, setWorkflowEnabled as z };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import {
|
|
1
|
+
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import { ah as applyClaudeProxyEnv, ai as composeSessionId, aj as generateFriendlyName, c as connectToHypha, a as createSessionStore, r as registerMachineService, ak as generateHookSettings } from './run-C0GhrtVf.mjs';
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import { resolve, join } from 'node:path';
|
|
4
4
|
import { existsSync, readFileSync, watch } from 'node:fs';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { j as resolveProjectRoot, D as listWorkflows, E as isWorkflowEnabled, F as workflowCrons, y as runWorkflow, G as cronMatches } from './run-
|
|
1
|
+
import { j as resolveProjectRoot, D as listWorkflows, E as isWorkflowEnabled, F as workflowCrons, y as runWorkflow, G as cronMatches } from './run-C0GhrtVf.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|
|
@@ -54,7 +54,7 @@ async function handleServeCommand() {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
async function serveAdd(args, machineId) {
|
|
57
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
57
|
+
const { connectAndGetMachine } = await import('./commands-BAlaK67Y.mjs');
|
|
58
58
|
const pos = positionalArgs(args);
|
|
59
59
|
const name = pos[0];
|
|
60
60
|
if (!name) {
|
|
@@ -93,7 +93,7 @@ async function serveAdd(args, machineId) {
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
async function serveApply(args, machineId) {
|
|
96
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
96
|
+
const { connectAndGetMachine } = await import('./commands-BAlaK67Y.mjs');
|
|
97
97
|
const fs = await import('fs');
|
|
98
98
|
const yaml = await import('yaml');
|
|
99
99
|
const file = positionalArgs(args)[0];
|
|
@@ -182,7 +182,7 @@ async function serveApply(args, machineId) {
|
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
async function serveRemove(args, machineId) {
|
|
185
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
185
|
+
const { connectAndGetMachine } = await import('./commands-BAlaK67Y.mjs');
|
|
186
186
|
const pos = positionalArgs(args);
|
|
187
187
|
const name = pos[0];
|
|
188
188
|
if (!name) {
|
|
@@ -202,7 +202,7 @@ async function serveRemove(args, machineId) {
|
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
204
|
async function serveList(args, machineId) {
|
|
205
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
205
|
+
const { connectAndGetMachine } = await import('./commands-BAlaK67Y.mjs');
|
|
206
206
|
const all = hasFlag(args, "--all", "-a");
|
|
207
207
|
const json = hasFlag(args, "--json");
|
|
208
208
|
const sessionId = getFlag(args, "--session");
|
|
@@ -235,7 +235,7 @@ async function serveList(args, machineId) {
|
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
237
|
async function serveInfo(machineId) {
|
|
238
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
238
|
+
const { connectAndGetMachine } = await import('./commands-BAlaK67Y.mjs');
|
|
239
239
|
const { machine, server } = await connectAndGetMachine(machineId);
|
|
240
240
|
try {
|
|
241
241
|
const info = await machine.serveInfo();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { R as READ_ONLY_TOOLS,
|
|
1
|
+
import { R as READ_ONLY_TOOLS, M as loadMachineContext, N as buildMachineInstructions, O as machineToolsForRole, P as buildMachineTools } from './run-C0GhrtVf.mjs';
|
|
2
2
|
import 'node:child_process';
|
|
3
3
|
import 'os';
|
|
4
4
|
import 'fs/promises';
|