svamp-cli 0.2.300 → 0.2.302
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-DS0S7m5p.mjs} +1 -1
- package/dist/{agentCommands-C56-TSwf.mjs → agentCommands-DVqrplvE.mjs} +5 -5
- package/dist/{auth-y5EinW_c.mjs → auth-BfG-xU5r.mjs} +1 -1
- package/dist/{cli-BbbzgMWX.mjs → cli-LhsJPCvo.mjs} +69 -69
- package/dist/cli.mjs +2 -2
- package/dist/{commands-Db1SMhcL.mjs → commands-42n-Wsc9.mjs} +2 -2
- package/dist/{commands-Bjbq2pJg.mjs → commands-BKtoVB7x.mjs} +2 -2
- package/dist/{commands-BLFj8bE8.mjs → commands-BTz8U0zj.mjs} +1 -1
- package/dist/{commands-Qz7oTXdj.mjs → commands-CPX3zxJe.mjs} +1 -1
- package/dist/{commands-Cb00JySn.mjs → commands-CZ_Cyoz7.mjs} +1 -1
- package/dist/{commands-BlVHxX-n.mjs → commands-D8ZNPhRo.mjs} +7 -7
- package/dist/{commands-VtqFEtFc.mjs → commands-DVGzSbt1.mjs} +2 -2
- package/dist/commands-DfbZae0h.mjs +161 -0
- package/dist/{fleet-DKAN08u-.mjs → fleet-CiHBV4mW.mjs} +1 -1
- package/dist/{frpc-Bx0J5hIR.mjs → frpc-4f18mvfV.mjs} +1 -1
- package/dist/{headlessCli-DaqkPy9x.mjs → headlessCli-Dl3YG5R3.mjs} +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{notifyCommands-DaAd67p4.mjs → notifyCommands-BqYtOHL3.mjs} +1 -1
- package/dist/package-DPWB-cK9.mjs +64 -0
- package/dist/{rpc-C2l4b6gk.mjs → rpc-BRt7OvrH.mjs} +1 -1
- package/dist/{rpc-D1Vg26a1.mjs → rpc-DaeHWgwG.mjs} +1 -1
- package/dist/{run-DrG6nwGm.mjs → run-BCS8Ckf7.mjs} +379 -61
- package/dist/{run-CVRu9pzU.mjs → run-BijIGfNu.mjs} +1 -1
- package/dist/{scheduler-CGmlf3VQ.mjs → scheduler-DobkEDw0.mjs} +1 -1
- package/dist/{serveCommands-CiYytaPO.mjs → serveCommands-0F39YIXd.mjs} +5 -5
- package/dist/{sideband-BQz9FNc9.mjs → sideband-C9Y7_Sni.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-4f18mvfV.mjs');
|
|
2977
2977
|
let tunnel;
|
|
2978
2978
|
tunnel = new FrpcTunnel({
|
|
2979
2979
|
name: tunnelName,
|
|
@@ -3274,12 +3274,28 @@ function codexForcedModel(env = process.env) {
|
|
|
3274
3274
|
if (!f || f === "0" || f === "false" || f === "no" || f === "off") return void 0;
|
|
3275
3275
|
return env.SVAMP_CODEX_MODEL || env.LLM_MODEL || void 0;
|
|
3276
3276
|
}
|
|
3277
|
+
function codexModelMenu(env = process.env) {
|
|
3278
|
+
return (env.SVAMP_CODEX_MODELS || "").split(",").map((s) => s.trim()).filter(Boolean).filter((m, i, a) => a.indexOf(m) === i);
|
|
3279
|
+
}
|
|
3280
|
+
function codexDefaultModel(env = process.env) {
|
|
3281
|
+
const menu = codexModelMenu(env);
|
|
3282
|
+
return env.SVAMP_CODEX_MODEL || env.LLM_MODEL || menu[0] || void 0;
|
|
3283
|
+
}
|
|
3284
|
+
function codexClampModel(requested, env = process.env) {
|
|
3285
|
+
const menu = codexModelMenu(env);
|
|
3286
|
+
if (!menu.length) return requested;
|
|
3287
|
+
if (requested && menu.includes(requested)) return requested;
|
|
3288
|
+
return codexDefaultModel(env);
|
|
3289
|
+
}
|
|
3277
3290
|
|
|
3278
3291
|
var codexProvider = /*#__PURE__*/Object.freeze({
|
|
3279
3292
|
__proto__: null,
|
|
3280
3293
|
CODEX_PROVIDER_KEY_ENV: CODEX_PROVIDER_KEY_ENV,
|
|
3281
3294
|
buildCodexProviderArgs: buildCodexProviderArgs,
|
|
3295
|
+
codexClampModel: codexClampModel,
|
|
3296
|
+
codexDefaultModel: codexDefaultModel,
|
|
3282
3297
|
codexForcedModel: codexForcedModel,
|
|
3298
|
+
codexModelMenu: codexModelMenu,
|
|
3283
3299
|
codexPermissionSettings: codexPermissionSettings,
|
|
3284
3300
|
hasCustomProvider: hasCustomProvider,
|
|
3285
3301
|
resolveCodexProvider: resolveCodexProvider
|
|
@@ -4639,11 +4655,6 @@ class ChannelOutbox {
|
|
|
4639
4655
|
}
|
|
4640
4656
|
}
|
|
4641
4657
|
|
|
4642
|
-
var outbox = /*#__PURE__*/Object.freeze({
|
|
4643
|
-
__proto__: null,
|
|
4644
|
-
ChannelOutbox: ChannelOutbox
|
|
4645
|
-
});
|
|
4646
|
-
|
|
4647
4658
|
function getParamNames(fn) {
|
|
4648
4659
|
const src = fn.toString();
|
|
4649
4660
|
const match = src.match(/^(?:async\s+)?(?:function\s*\w*)?\s*\(([^)]*)\)/);
|
|
@@ -5872,7 +5883,7 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
5872
5883
|
const tunnels = handlers.tunnels;
|
|
5873
5884
|
if (!tunnels) throw new Error("Tunnel management not available");
|
|
5874
5885
|
if (tunnels.has(params.name)) throw new Error(`Tunnel '${params.name}' already running`);
|
|
5875
|
-
const { FrpcTunnel } = await import('./frpc-
|
|
5886
|
+
const { FrpcTunnel } = await import('./frpc-4f18mvfV.mjs');
|
|
5876
5887
|
const tunnel = new FrpcTunnel({
|
|
5877
5888
|
name: params.name,
|
|
5878
5889
|
ports: params.ports,
|
|
@@ -6348,7 +6359,7 @@ QUESTION: ${params.question || "Summarize this concisely."}` }
|
|
|
6348
6359
|
}
|
|
6349
6360
|
const deps = buildSessionDeps(rpc, { cwd, ownerEmail: owner });
|
|
6350
6361
|
const sender = { name: context?.user?.email || context?.user?.id || "user", kind: "user", verified: true };
|
|
6351
|
-
const { toolsForRole } = await import('./sideband-
|
|
6362
|
+
const { toolsForRole } = await import('./sideband-C9Y7_Sni.mjs');
|
|
6352
6363
|
const r2 = await runWiseAgent({ message: params.message, sender, config: { tools: toolsForRole(role2) }, deps, transport, model: resolved.model });
|
|
6353
6364
|
return fmt(r2);
|
|
6354
6365
|
}
|
|
@@ -6453,7 +6464,7 @@ QUESTION: ${params.question || "Summarize this concisely."}` }
|
|
|
6453
6464
|
return { ok: false, call_id: callId, status: "busy", error: "channel is busy (too many concurrent requests) \u2014 retry shortly" };
|
|
6454
6465
|
}
|
|
6455
6466
|
const rendered = renderMessage(c, { sender: r.sender, body: { message: kwargs.message }, callId });
|
|
6456
|
-
const { queryCore } = await import('./commands-
|
|
6467
|
+
const { queryCore } = await import('./commands-CZ_Cyoz7.mjs');
|
|
6457
6468
|
const timeout = c.reply?.timeout_sec || 120;
|
|
6458
6469
|
let result;
|
|
6459
6470
|
try {
|
|
@@ -6605,6 +6616,44 @@ ${d?.error || "not found"}`;
|
|
|
6605
6616
|
{ overwrite: true }
|
|
6606
6617
|
);
|
|
6607
6618
|
console.log(`[HYPHA MACHINE] Channels service registered: ${channelsServiceInfo.id} (type svamp-channels)`);
|
|
6619
|
+
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>"}}.';
|
|
6620
|
+
const routeOutpost = (session) => {
|
|
6621
|
+
const sid = String(session || "").trim();
|
|
6622
|
+
if (!sid) return { error: OUTPOST_MISSING_SESSION };
|
|
6623
|
+
const rpc = handlers.getSessionRPCHandlers?.(sid);
|
|
6624
|
+
if (!rpc?.outpostHello) return { error: `session ${sid.slice(0, 12)} is not connected on this machine` };
|
|
6625
|
+
return { rpc };
|
|
6626
|
+
};
|
|
6627
|
+
const outpostServiceInfo = await server.registerService(
|
|
6628
|
+
{
|
|
6629
|
+
id: "outpost",
|
|
6630
|
+
name: `Svamp Outpost (${currentMetadata.displayName || machineId})`,
|
|
6631
|
+
type: "svamp-outpost",
|
|
6632
|
+
// Public so a remote machine (possibly anonymous) can dial in; token-authed per call,
|
|
6633
|
+
// so no Hypha identity/context is needed (the handlers ignore context entirely).
|
|
6634
|
+
config: { visibility: "public", require_context: false },
|
|
6635
|
+
hello: async (kwargs = {}) => {
|
|
6636
|
+
trackInbound();
|
|
6637
|
+
const r = routeOutpost(kwargs?.session);
|
|
6638
|
+
if ("error" in r) return { error: r.error };
|
|
6639
|
+
return r.rpc.outpostHello(kwargs);
|
|
6640
|
+
},
|
|
6641
|
+
poll: async (kwargs = {}) => {
|
|
6642
|
+
trackInbound();
|
|
6643
|
+
const r = routeOutpost(kwargs?.session);
|
|
6644
|
+
if ("error" in r) return { error: r.error };
|
|
6645
|
+
return r.rpc.outpostPoll(kwargs);
|
|
6646
|
+
},
|
|
6647
|
+
result: async (kwargs = {}) => {
|
|
6648
|
+
trackInbound();
|
|
6649
|
+
const r = routeOutpost(kwargs?.session);
|
|
6650
|
+
if ("error" in r) return { error: r.error };
|
|
6651
|
+
return r.rpc.outpostResult(kwargs);
|
|
6652
|
+
}
|
|
6653
|
+
},
|
|
6654
|
+
{ overwrite: true }
|
|
6655
|
+
);
|
|
6656
|
+
console.log(`[HYPHA MACHINE] Outpost service registered: ${outpostServiceInfo.id} (type svamp-outpost)`);
|
|
6608
6657
|
return {
|
|
6609
6658
|
serviceInfo,
|
|
6610
6659
|
notifySessionEvent: notifyListeners,
|
|
@@ -6639,6 +6688,8 @@ ${d?.error || "not found"}`;
|
|
|
6639
6688
|
await server.unregisterService(serviceInfo.id);
|
|
6640
6689
|
await server.unregisterService(channelsServiceInfo.id).catch(() => {
|
|
6641
6690
|
});
|
|
6691
|
+
await server.unregisterService(outpostServiceInfo.id).catch(() => {
|
|
6692
|
+
});
|
|
6642
6693
|
}
|
|
6643
6694
|
};
|
|
6644
6695
|
}
|
|
@@ -6930,6 +6981,43 @@ function retryDelayMs(now, backoffUntil) {
|
|
|
6930
6981
|
return Math.max(0, backoffUntil - now);
|
|
6931
6982
|
}
|
|
6932
6983
|
|
|
6984
|
+
function tokenPath(projectDir, session) {
|
|
6985
|
+
return join$1(projectDir, ".svamp", session, "outpost.json");
|
|
6986
|
+
}
|
|
6987
|
+
function genToken() {
|
|
6988
|
+
return randomBytes(24).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
6989
|
+
}
|
|
6990
|
+
function loadOutpostToken(projectDir, session) {
|
|
6991
|
+
const file = tokenPath(projectDir, session);
|
|
6992
|
+
if (!existsSync(file)) return null;
|
|
6993
|
+
try {
|
|
6994
|
+
const parsed = JSON.parse(readFileSync(file, "utf-8"));
|
|
6995
|
+
if (!parsed || typeof parsed.token !== "string" || !parsed.token) return null;
|
|
6996
|
+
return parsed;
|
|
6997
|
+
} catch {
|
|
6998
|
+
return null;
|
|
6999
|
+
}
|
|
7000
|
+
}
|
|
7001
|
+
function ensureOutpostToken(projectDir, session) {
|
|
7002
|
+
const existing = loadOutpostToken(projectDir, session);
|
|
7003
|
+
if (existing) return existing;
|
|
7004
|
+
const rec = { version: 1, session, token: genToken(), createdAt: Date.now() };
|
|
7005
|
+
const file = tokenPath(projectDir, session);
|
|
7006
|
+
mkdirSync$1(dirname(file), { recursive: true });
|
|
7007
|
+
writeFileSync$1(file, JSON.stringify(rec, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
7008
|
+
try {
|
|
7009
|
+
chmodSync(file, 384);
|
|
7010
|
+
} catch {
|
|
7011
|
+
}
|
|
7012
|
+
return rec;
|
|
7013
|
+
}
|
|
7014
|
+
function outpostTokenMatches(rec, presented) {
|
|
7015
|
+
if (!rec || typeof presented !== "string" || presented.length !== rec.token.length) return false;
|
|
7016
|
+
let diff = 0;
|
|
7017
|
+
for (let i = 0; i < rec.token.length; i++) diff |= rec.token.charCodeAt(i) ^ presented.charCodeAt(i);
|
|
7018
|
+
return diff === 0;
|
|
7019
|
+
}
|
|
7020
|
+
|
|
6933
7021
|
const DEFAULT_DOWNLOAD_BASE = "https://github.com/amun-ai/hypha-cloud/releases/latest/download";
|
|
6934
7022
|
function shq(v) {
|
|
6935
7023
|
return `'${String(v).replace(/'/g, `'\\''`)}'`;
|
|
@@ -6940,10 +7028,10 @@ function psq(v) {
|
|
|
6940
7028
|
function buildOutpostInstall(params) {
|
|
6941
7029
|
const base = params.serverBase.replace(/\/$/, "");
|
|
6942
7030
|
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)} --
|
|
7031
|
+
const session = params.session;
|
|
7032
|
+
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`;
|
|
7033
|
+
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`;
|
|
7034
|
+
const direct = `svamp-outpost --server ${shq(base)} --token ${shq(params.token)} --session ${shq(session)}`;
|
|
6947
7035
|
return { unix, windows, direct };
|
|
6948
7036
|
}
|
|
6949
7037
|
|
|
@@ -6955,37 +7043,19 @@ const OUTPOST_BINARIES = [
|
|
|
6955
7043
|
{ label: "Linux (arm64)", file: "svamp-outpost-linux-arm64" },
|
|
6956
7044
|
{ label: "Windows (x86-64)", file: "svamp-outpost-windows-amd64.exe" }
|
|
6957
7045
|
];
|
|
6958
|
-
function
|
|
7046
|
+
function setupOutpost(params) {
|
|
6959
7047
|
const serverUrl = params.serverUrl || "https://hypha.aicell.io";
|
|
6960
7048
|
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;
|
|
7049
|
+
const serverBase = gatewayBase(params.outpostServiceId, serverUrl);
|
|
7050
|
+
const { token } = ensureOutpostToken(params.projectDir, params.session);
|
|
7051
|
+
const install = buildOutpostInstall({ serverBase, session: params.session, token, downloadBase });
|
|
6981
7052
|
return {
|
|
6982
|
-
channelId,
|
|
6983
7053
|
token,
|
|
6984
7054
|
serverBase,
|
|
6985
7055
|
downloadBase,
|
|
6986
7056
|
install,
|
|
6987
7057
|
binaries: OUTPOST_BINARIES.map((b) => ({ label: b.label, url: `${downloadBase}/${b.file}` })),
|
|
6988
|
-
connectedCount
|
|
7058
|
+
connectedCount: params.connectedCount || 0
|
|
6989
7059
|
};
|
|
6990
7060
|
}
|
|
6991
7061
|
|
|
@@ -7070,7 +7140,6 @@ async function mintPairingCode(opts) {
|
|
|
7070
7140
|
const expiresAt = now + ttlMs;
|
|
7071
7141
|
const pairJson = JSON.stringify({
|
|
7072
7142
|
server: payload.server,
|
|
7073
|
-
channel: payload.channel,
|
|
7074
7143
|
token: payload.token,
|
|
7075
7144
|
session: payload.session,
|
|
7076
7145
|
expiresAt
|
|
@@ -7107,6 +7176,157 @@ async function mintPairingCode(opts) {
|
|
|
7107
7176
|
return { code, resolver, expiresAt };
|
|
7108
7177
|
}
|
|
7109
7178
|
|
|
7179
|
+
const OUTPOST_STALE_MS = 9e4;
|
|
7180
|
+
const OUTPOST_EXEC_TIMEOUT_MS = 10 * 6e4;
|
|
7181
|
+
class OutpostCoordinator {
|
|
7182
|
+
conns = /* @__PURE__ */ new Map();
|
|
7183
|
+
queue = /* @__PURE__ */ new Map();
|
|
7184
|
+
pending = /* @__PURE__ */ new Map();
|
|
7185
|
+
seq = 0;
|
|
7186
|
+
now;
|
|
7187
|
+
setTimer;
|
|
7188
|
+
clearTimer;
|
|
7189
|
+
execTimeoutMs;
|
|
7190
|
+
staleMs;
|
|
7191
|
+
constructor(opts = {}) {
|
|
7192
|
+
this.now = opts.now || (() => Date.now());
|
|
7193
|
+
this.setTimer = opts.setTimer || ((fn, ms) => setTimeout(fn, ms));
|
|
7194
|
+
this.clearTimer = opts.clearTimer || ((t) => clearTimeout(t));
|
|
7195
|
+
this.execTimeoutMs = opts.execTimeoutMs ?? OUTPOST_EXEC_TIMEOUT_MS;
|
|
7196
|
+
this.staleMs = opts.staleMs ?? OUTPOST_STALE_MS;
|
|
7197
|
+
}
|
|
7198
|
+
isStale(c, at) {
|
|
7199
|
+
return at - c.lastSeen > this.staleMs;
|
|
7200
|
+
}
|
|
7201
|
+
/** Drop dead connections; fail any in-flight execs bound to them so callers never hang. */
|
|
7202
|
+
prune(at = this.now()) {
|
|
7203
|
+
for (const [machine, c] of [...this.conns]) {
|
|
7204
|
+
if (this.isStale(c, at)) {
|
|
7205
|
+
this.conns.delete(machine);
|
|
7206
|
+
this.queue.delete(machine);
|
|
7207
|
+
this.failMachine(machine, "the remote outpost disconnected");
|
|
7208
|
+
}
|
|
7209
|
+
}
|
|
7210
|
+
}
|
|
7211
|
+
/** Reject every pending exec on a machine with a synthetic disconnect result (exitCode -1). */
|
|
7212
|
+
failMachine(machine, reason) {
|
|
7213
|
+
for (const [id, p] of [...this.pending]) {
|
|
7214
|
+
if (p.machine !== machine) continue;
|
|
7215
|
+
this.clearTimer(p.timer);
|
|
7216
|
+
this.pending.delete(id);
|
|
7217
|
+
p.resolve({ id, stdout: "", stderr: reason, exitCode: -1, synthetic: true, ts: this.now() });
|
|
7218
|
+
}
|
|
7219
|
+
}
|
|
7220
|
+
/**
|
|
7221
|
+
* A remote said hello (first connect OR reconnect after an outage). Upserts the connection and
|
|
7222
|
+
* returns `isNew` = true when it should trigger the ONE-TIME inbox announce — true on the first
|
|
7223
|
+
* appearance and on a reconnect after the connection had gone stale/pruned.
|
|
7224
|
+
*/
|
|
7225
|
+
registerConnection(machine, meta = {}) {
|
|
7226
|
+
const at = this.now();
|
|
7227
|
+
this.prune(at);
|
|
7228
|
+
const existing = this.conns.get(machine);
|
|
7229
|
+
const isNew = !existing;
|
|
7230
|
+
const connection = {
|
|
7231
|
+
machine,
|
|
7232
|
+
label: meta.label ?? existing?.label,
|
|
7233
|
+
os: meta.os ?? existing?.os,
|
|
7234
|
+
arch: meta.arch ?? existing?.arch,
|
|
7235
|
+
version: meta.version ?? existing?.version,
|
|
7236
|
+
connectedAt: existing?.connectedAt ?? at,
|
|
7237
|
+
lastSeen: at
|
|
7238
|
+
};
|
|
7239
|
+
this.conns.set(machine, connection);
|
|
7240
|
+
return { isNew, connection };
|
|
7241
|
+
}
|
|
7242
|
+
/** Refresh liveness for an active poll (keeps the connection "always on"). */
|
|
7243
|
+
touch(machine) {
|
|
7244
|
+
const c = this.conns.get(machine);
|
|
7245
|
+
if (!c) return false;
|
|
7246
|
+
c.lastSeen = this.now();
|
|
7247
|
+
return true;
|
|
7248
|
+
}
|
|
7249
|
+
/** Live connections only (prunes first). */
|
|
7250
|
+
listConnections() {
|
|
7251
|
+
this.prune();
|
|
7252
|
+
return [...this.conns.values()].sort((a, b) => a.connectedAt - b.connectedAt);
|
|
7253
|
+
}
|
|
7254
|
+
isConnected(machine) {
|
|
7255
|
+
this.prune();
|
|
7256
|
+
return this.conns.has(machine);
|
|
7257
|
+
}
|
|
7258
|
+
/**
|
|
7259
|
+
* Pick the machine an exec should target: an explicit live target, or the sole live outpost.
|
|
7260
|
+
* Ambiguity (0 or >1 without a target) is a clear error, never a silent guess.
|
|
7261
|
+
*/
|
|
7262
|
+
resolveTarget(target) {
|
|
7263
|
+
const live = this.listConnections();
|
|
7264
|
+
if (target) {
|
|
7265
|
+
const hit = live.find((c) => c.machine === target || c.label === target);
|
|
7266
|
+
if (!hit) return { error: `no connected outpost named "${target}" (connected: ${live.map((c) => c.machine).join(", ") || "none"})` };
|
|
7267
|
+
return { machine: hit.machine };
|
|
7268
|
+
}
|
|
7269
|
+
if (live.length === 0) return { error: "no remote outpost is connected \u2014 run the install one-liner on the remote machine first" };
|
|
7270
|
+
if (live.length > 1) return { error: `multiple outposts connected (${live.map((c) => c.machine).join(", ")}) \u2014 pass a target` };
|
|
7271
|
+
return { machine: live[0].machine };
|
|
7272
|
+
}
|
|
7273
|
+
/**
|
|
7274
|
+
* Enqueue a command for a machine and return a promise that resolves with the REAL result once
|
|
7275
|
+
* the outpost posts it back (or a synthetic exitCode -1 on disconnect/timeout). Fails fast if the
|
|
7276
|
+
* machine is not connected.
|
|
7277
|
+
*/
|
|
7278
|
+
enqueueExec(machine, cmd, cwd) {
|
|
7279
|
+
const id = `x${(++this.seq).toString(36)}_${this.now().toString(36)}`;
|
|
7280
|
+
if (!this.isConnected(machine)) {
|
|
7281
|
+
return {
|
|
7282
|
+
id,
|
|
7283
|
+
promise: Promise.resolve({ id, stdout: "", stderr: `outpost "${machine}" is not connected`, exitCode: -1, synthetic: true, ts: this.now() })
|
|
7284
|
+
};
|
|
7285
|
+
}
|
|
7286
|
+
const command = { id, cmd, cwd, ts: this.now() };
|
|
7287
|
+
const q = this.queue.get(machine) || [];
|
|
7288
|
+
q.push(command);
|
|
7289
|
+
this.queue.set(machine, q);
|
|
7290
|
+
const promise = new Promise((resolve) => {
|
|
7291
|
+
const timer = this.setTimer(() => {
|
|
7292
|
+
if (!this.pending.has(id)) return;
|
|
7293
|
+
this.pending.delete(id);
|
|
7294
|
+
resolve({ id, stdout: "", stderr: `command timed out after ${Math.round(this.execTimeoutMs / 1e3)}s`, exitCode: -1, synthetic: true, ts: this.now() });
|
|
7295
|
+
}, this.execTimeoutMs);
|
|
7296
|
+
this.pending.set(id, { machine, resolve, timer, enqueuedAt: this.now() });
|
|
7297
|
+
});
|
|
7298
|
+
return { id, promise };
|
|
7299
|
+
}
|
|
7300
|
+
/** Long-poll drain: return (and clear) the commands queued for a machine; refreshes liveness. */
|
|
7301
|
+
pollCommands(machine) {
|
|
7302
|
+
this.touch(machine);
|
|
7303
|
+
const q = this.queue.get(machine);
|
|
7304
|
+
if (!q || q.length === 0) return [];
|
|
7305
|
+
this.queue.set(machine, []);
|
|
7306
|
+
return q;
|
|
7307
|
+
}
|
|
7308
|
+
/** Deliver a result from the outpost to the waiting exec. Returns false if unknown/expired. */
|
|
7309
|
+
resolveResult(result) {
|
|
7310
|
+
const p = this.pending.get(result.id);
|
|
7311
|
+
if (!p) return false;
|
|
7312
|
+
this.clearTimer(p.timer);
|
|
7313
|
+
this.pending.delete(result.id);
|
|
7314
|
+
this.touch(p.machine);
|
|
7315
|
+
p.resolve({
|
|
7316
|
+
id: result.id,
|
|
7317
|
+
stdout: result.stdout ?? "",
|
|
7318
|
+
stderr: result.stderr ?? "",
|
|
7319
|
+
exitCode: typeof result.exitCode === "number" ? result.exitCode : 0,
|
|
7320
|
+
ts: this.now()
|
|
7321
|
+
});
|
|
7322
|
+
return true;
|
|
7323
|
+
}
|
|
7324
|
+
/** Test/introspection: how many execs are awaiting a result. */
|
|
7325
|
+
pendingCount() {
|
|
7326
|
+
return this.pending.size;
|
|
7327
|
+
}
|
|
7328
|
+
}
|
|
7329
|
+
|
|
7110
7330
|
const PARTICIPANTS_CHANNEL_ID = "sys-participants";
|
|
7111
7331
|
function channelPublicView(c) {
|
|
7112
7332
|
const u = c.upload;
|
|
@@ -7513,8 +7733,28 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
|
|
|
7513
7733
|
const channelStore = new ChannelStore(initialMetadata.path);
|
|
7514
7734
|
const meetingActivity = [];
|
|
7515
7735
|
const channelOutbox = new ChannelOutbox(initialMetadata.path);
|
|
7736
|
+
const outpostCoordinator = new OutpostCoordinator();
|
|
7737
|
+
const outpostProjectDir = () => metadata.path || process.cwd();
|
|
7738
|
+
const announceOutpost = (conn) => {
|
|
7739
|
+
const who = conn.label || conn.machine;
|
|
7740
|
+
const plat = [conn.os, conn.arch].filter(Boolean).join("/") || "unknown platform";
|
|
7741
|
+
const msg = {
|
|
7742
|
+
messageId: "op_" + Math.random().toString(16).slice(2, 10),
|
|
7743
|
+
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"`,
|
|
7744
|
+
timestamp: Date.now(),
|
|
7745
|
+
read: false,
|
|
7746
|
+
from: "outpost",
|
|
7747
|
+
subject: `Remote outpost connected: ${who}`
|
|
7748
|
+
};
|
|
7749
|
+
inbox.push(msg);
|
|
7750
|
+
while (inbox.length > INBOX_MAX) inbox.shift();
|
|
7751
|
+
syncInboxToMetadata();
|
|
7752
|
+
callbacks.onInboxMessage?.(msg);
|
|
7753
|
+
notifyListeners({ type: "inbox-update", sessionId, message: msg });
|
|
7754
|
+
};
|
|
7516
7755
|
const cfg = server?.config || {};
|
|
7517
7756
|
const channelsServiceId = cfg.workspace && cfg.client_id ? `${cfg.workspace}/${cfg.client_id}:channels` : void 0;
|
|
7757
|
+
const outpostServiceId = cfg.workspace && cfg.client_id ? `${cfg.workspace}/${cfg.client_id}:outpost` : void 0;
|
|
7518
7758
|
const channelsBaseUrl = cfg.public_base_url || process.env.HYPHA_SERVER_URL || "https://hypha.aicell.io";
|
|
7519
7759
|
const skillCtxFor = (c) => ({
|
|
7520
7760
|
channelsServiceId,
|
|
@@ -7898,34 +8138,36 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
|
|
|
7898
8138
|
syncChannelsToMetadata();
|
|
7899
8139
|
return { success: !!caller, caller };
|
|
7900
8140
|
},
|
|
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
|
-
//
|
|
8141
|
+
// FDE outpost (#0565 redesign): provision (idempotently) this session's durable outpost TOKEN
|
|
8142
|
+
// and return the install one-liners + direct binary download links + a LIVE connected count.
|
|
8143
|
+
// The app's "Connect a remote machine" panel calls this; it reuses the SAME setupOutpost core as
|
|
8144
|
+
// `svamp outpost up`, so the install command never drifts. NO channel is created — the remote
|
|
8145
|
+
// dials the machine's public `:outpost` gateway and this session's token authenticates it.
|
|
8146
|
+
// Admin-gated: the returned token is a capability to run commands on whatever machine connects.
|
|
7906
8147
|
outpostConnectInfo: async (params, context) => {
|
|
7907
8148
|
authorizeRequest(context, metadata.sharing, "admin");
|
|
7908
|
-
if (!
|
|
8149
|
+
if (!outpostServiceId) return { error: "the outpost service is not available on this machine" };
|
|
7909
8150
|
try {
|
|
7910
|
-
const
|
|
8151
|
+
const connectedCount = outpostCoordinator.listConnections().length;
|
|
8152
|
+
const info = setupOutpost({
|
|
7911
8153
|
session: sessionId,
|
|
7912
|
-
projectDir:
|
|
7913
|
-
|
|
8154
|
+
projectDir: outpostProjectDir(),
|
|
8155
|
+
outpostServiceId,
|
|
7914
8156
|
serverUrl: channelsBaseUrl,
|
|
7915
|
-
downloadBase: params?.downloadBase || process.env.SVAMP_OUTPOST_DL
|
|
8157
|
+
downloadBase: params?.downloadBase || process.env.SVAMP_OUTPOST_DL,
|
|
8158
|
+
connectedCount
|
|
7916
8159
|
});
|
|
7917
|
-
syncChannelsToMetadata();
|
|
7918
8160
|
let pairing = {};
|
|
7919
8161
|
try {
|
|
7920
8162
|
const am = await server.getService("public/artifact-manager");
|
|
7921
8163
|
if (am) {
|
|
7922
|
-
if (
|
|
8164
|
+
if (connectedCount > 0) {
|
|
7923
8165
|
await burnSessionPairings(am, sessionId, void 0, (m) => console.log(m));
|
|
7924
8166
|
} else {
|
|
7925
8167
|
const r = await mintPairingCode({
|
|
7926
8168
|
am,
|
|
7927
8169
|
session: sessionId,
|
|
7928
|
-
payload: { server: info.serverBase,
|
|
8170
|
+
payload: { server: info.serverBase, token: info.token, session: sessionId },
|
|
7929
8171
|
resolverBase: channelsBaseUrl,
|
|
7930
8172
|
log: (m) => console.log(m)
|
|
7931
8173
|
});
|
|
@@ -7940,6 +8182,69 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
|
|
|
7940
8182
|
return { error: e?.message || String(e) };
|
|
7941
8183
|
}
|
|
7942
8184
|
},
|
|
8185
|
+
// ── FDE outpost transport (#0565): token-authed remote endpoints + owner-facing exec/list ──
|
|
8186
|
+
// hello/poll/result carry NO session-sharing auth (the remote is anonymous); the per-session
|
|
8187
|
+
// capability token IS the auth (checked against the durable on-disk token). Routed here by the
|
|
8188
|
+
// machine's public `:outpost` gateway, which passes the remote-supplied `session` as the key.
|
|
8189
|
+
outpostHello: async (params) => {
|
|
8190
|
+
const rec = loadOutpostToken(outpostProjectDir(), sessionId);
|
|
8191
|
+
if (!outpostTokenMatches(rec, params?.token)) return { error: "unauthorized" };
|
|
8192
|
+
const machine = (String(params?.machine || "").trim() || "outpost").slice(0, 128);
|
|
8193
|
+
const { isNew, connection } = outpostCoordinator.registerConnection(machine, {
|
|
8194
|
+
label: params?.label ? String(params.label).slice(0, 128) : void 0,
|
|
8195
|
+
os: params?.os ? String(params.os).slice(0, 64) : void 0,
|
|
8196
|
+
arch: params?.arch ? String(params.arch).slice(0, 64) : void 0,
|
|
8197
|
+
version: params?.version ? String(params.version).slice(0, 64) : void 0
|
|
8198
|
+
});
|
|
8199
|
+
if (isNew) {
|
|
8200
|
+
announceOutpost(connection);
|
|
8201
|
+
try {
|
|
8202
|
+
const am = await server.getService("public/artifact-manager");
|
|
8203
|
+
if (am) await burnSessionPairings(am, sessionId, void 0, (m) => console.log(m));
|
|
8204
|
+
} catch {
|
|
8205
|
+
}
|
|
8206
|
+
}
|
|
8207
|
+
return { ok: true, machine: connection.machine };
|
|
8208
|
+
},
|
|
8209
|
+
outpostPoll: async (params) => {
|
|
8210
|
+
const rec = loadOutpostToken(outpostProjectDir(), sessionId);
|
|
8211
|
+
if (!outpostTokenMatches(rec, params?.token)) return { error: "unauthorized" };
|
|
8212
|
+
const machine = (String(params?.machine || "").trim() || "outpost").slice(0, 128);
|
|
8213
|
+
if (!outpostCoordinator.isConnected(machine)) {
|
|
8214
|
+
const { isNew, connection } = outpostCoordinator.registerConnection(machine, {});
|
|
8215
|
+
if (isNew) announceOutpost(connection);
|
|
8216
|
+
}
|
|
8217
|
+
const waitRaw = Number(params?.wait ?? 25);
|
|
8218
|
+
const waitSec = Number.isFinite(waitRaw) ? waitRaw : 25;
|
|
8219
|
+
const waitMs = Math.min(Math.max(0, waitSec * 1e3), 6e4);
|
|
8220
|
+
const deadline = Date.now() + waitMs;
|
|
8221
|
+
for (; ; ) {
|
|
8222
|
+
const commands = outpostCoordinator.pollCommands(machine);
|
|
8223
|
+
if (commands.length || Date.now() >= deadline) return { ok: true, commands };
|
|
8224
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
8225
|
+
}
|
|
8226
|
+
},
|
|
8227
|
+
outpostResult: async (params) => {
|
|
8228
|
+
const rec = loadOutpostToken(outpostProjectDir(), sessionId);
|
|
8229
|
+
if (!outpostTokenMatches(rec, params?.token)) return { error: "unauthorized" };
|
|
8230
|
+
if (!params?.id) return { error: "missing result id" };
|
|
8231
|
+
const ok = outpostCoordinator.resolveResult({ id: params.id, stdout: params.stdout, stderr: params.stderr, exitCode: params.exitCode });
|
|
8232
|
+
return { ok };
|
|
8233
|
+
},
|
|
8234
|
+
outpostExec: async (params, context) => {
|
|
8235
|
+
authorizeRequest(context, metadata.sharing, "admin");
|
|
8236
|
+
const cmd = String(params?.cmd || "").trim();
|
|
8237
|
+
if (!cmd) return { error: "cmd is required" };
|
|
8238
|
+
const t = outpostCoordinator.resolveTarget(params?.target ? String(params.target) : void 0);
|
|
8239
|
+
if ("error" in t) return { error: t.error };
|
|
8240
|
+
const { promise } = outpostCoordinator.enqueueExec(t.machine, cmd, params?.cwd ? String(params.cwd) : void 0);
|
|
8241
|
+
const r = await promise;
|
|
8242
|
+
return { ok: r.exitCode === 0, stdout: r.stdout, stderr: r.stderr, exitCode: r.exitCode, machine: t.machine };
|
|
8243
|
+
},
|
|
8244
|
+
outpostList: async (context) => {
|
|
8245
|
+
authorizeRequest(context, metadata.sharing, "view");
|
|
8246
|
+
return { ok: true, outposts: outpostCoordinator.listConnections() };
|
|
8247
|
+
},
|
|
7943
8248
|
getChannelSkill: async (id, context) => {
|
|
7944
8249
|
authorizeRequest(context, metadata.sharing, "view");
|
|
7945
8250
|
const c = channelStore.get(id);
|
|
@@ -16693,7 +16998,7 @@ async function startDaemon(options) {
|
|
|
16693
16998
|
try {
|
|
16694
16999
|
const dir = loadSessionIndex()[sessionId]?.directory;
|
|
16695
17000
|
if (!dir) return;
|
|
16696
|
-
const { reconcileServiceLinks } = await import('./agentCommands-
|
|
17001
|
+
const { reconcileServiceLinks } = await import('./agentCommands-DVqrplvE.mjs');
|
|
16697
17002
|
const configPath = getSvampConfigPath(dir, sessionId);
|
|
16698
17003
|
const config = readSvampConfig(configPath);
|
|
16699
17004
|
const entries = Array.from(urls.entries());
|
|
@@ -16711,7 +17016,7 @@ async function startDaemon(options) {
|
|
|
16711
17016
|
}
|
|
16712
17017
|
}
|
|
16713
17018
|
async function createExposedTunnel(spec) {
|
|
16714
|
-
const { FrpcTunnel } = await import('./frpc-
|
|
17019
|
+
const { FrpcTunnel } = await import('./frpc-4f18mvfV.mjs');
|
|
16715
17020
|
const tunnel = new FrpcTunnel({
|
|
16716
17021
|
name: spec.name,
|
|
16717
17022
|
ports: spec.ports,
|
|
@@ -18927,11 +19232,11 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
18927
19232
|
});
|
|
18928
19233
|
},
|
|
18929
19234
|
onIssue: async (params) => {
|
|
18930
|
-
const { issueRpc } = await import('./rpc-
|
|
19235
|
+
const { issueRpc } = await import('./rpc-BRt7OvrH.mjs');
|
|
18931
19236
|
return issueRpc(params?.cwd || directory, params || {}, { notifySession: notifyIssueOwner, rekickLoopOwner });
|
|
18932
19237
|
},
|
|
18933
19238
|
onWorkflow: async (params) => {
|
|
18934
|
-
const { workflowRpc } = await import('./rpc-
|
|
19239
|
+
const { workflowRpc } = await import('./rpc-DaeHWgwG.mjs');
|
|
18935
19240
|
return workflowRpc(params?.cwd || directory, params || {});
|
|
18936
19241
|
},
|
|
18937
19242
|
onRipgrep: async (args, cwd) => {
|
|
@@ -19304,7 +19609,8 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
19304
19609
|
}
|
|
19305
19610
|
{
|
|
19306
19611
|
const forcedModel = agentName === "codex" ? codexForcedModel() : void 0;
|
|
19307
|
-
const
|
|
19612
|
+
const composerModel = typeof msgMeta?.model === "string" && msgMeta.model ? msgMeta.model : void 0;
|
|
19613
|
+
const rawModel = forcedModel || (agentName === "codex" && codexModelMenu().length ? codexClampModel(composerModel) : composerModel);
|
|
19308
19614
|
const desiredModel = rawModel || agentConfig?.default_model || void 0;
|
|
19309
19615
|
if (desiredModel !== appliedAgentModel) {
|
|
19310
19616
|
agentBackend?.setModel?.(desiredModel);
|
|
@@ -19544,11 +19850,11 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
19544
19850
|
});
|
|
19545
19851
|
},
|
|
19546
19852
|
onIssue: async (params) => {
|
|
19547
|
-
const { issueRpc } = await import('./rpc-
|
|
19853
|
+
const { issueRpc } = await import('./rpc-BRt7OvrH.mjs');
|
|
19548
19854
|
return issueRpc(params?.cwd || directory, params || {}, { notifySession: notifyIssueOwner, rekickLoopOwner });
|
|
19549
19855
|
},
|
|
19550
19856
|
onWorkflow: async (params) => {
|
|
19551
|
-
const { workflowRpc } = await import('./rpc-
|
|
19857
|
+
const { workflowRpc } = await import('./rpc-DaeHWgwG.mjs');
|
|
19552
19858
|
return workflowRpc(params?.cwd || directory, params || {});
|
|
19553
19859
|
},
|
|
19554
19860
|
onRipgrep: async (args, cwd) => {
|
|
@@ -19729,8 +20035,20 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
19729
20035
|
}
|
|
19730
20036
|
}
|
|
19731
20037
|
}
|
|
19732
|
-
const
|
|
19733
|
-
|
|
20038
|
+
const codexMenu = codexModelMenu();
|
|
20039
|
+
const codexModel = codexForcedModel() || (codexMenu.length ? codexClampModel(options2.model ?? void 0) || codexDefaultModel() : void 0) || options2.model || agentConfig?.default_model || provider.model || void 0;
|
|
20040
|
+
if (codexMenu.length) {
|
|
20041
|
+
sessionMetadata.models = codexMenu.map((m) => ({
|
|
20042
|
+
code: m,
|
|
20043
|
+
value: m,
|
|
20044
|
+
description: m === codexModel ? "Default on this machine" : "Available on this machine"
|
|
20045
|
+
}));
|
|
20046
|
+
try {
|
|
20047
|
+
sessionService.updateMetadata(sessionMetadata);
|
|
20048
|
+
} catch {
|
|
20049
|
+
}
|
|
20050
|
+
logger.log(`[Agent Session ${sessionId}] Codex model menu advertised (SVAMP_CODEX_MODELS): [${codexMenu.join(", ")}] default=${codexModel}`);
|
|
20051
|
+
} else if (codexModel && (provider.apiBase || codexForcedModel())) {
|
|
19734
20052
|
sessionMetadata.models = [{ code: codexModel, value: codexModel, description: "Configured on this machine" }];
|
|
19735
20053
|
try {
|
|
19736
20054
|
sessionService.updateMetadata(sessionMetadata);
|
|
@@ -20683,7 +21001,7 @@ ${oracle.output.trim().slice(0, 500)}`, "\u{1F501} Continuing loop");
|
|
|
20683
21001
|
const PING_TIMEOUT_MS = 15e3;
|
|
20684
21002
|
const POST_RECONNECT_GRACE_MS = 2e4;
|
|
20685
21003
|
const RECONNECT_JITTER_MS = 2500;
|
|
20686
|
-
const { WorkflowScheduler } = await import('./scheduler-
|
|
21004
|
+
const { WorkflowScheduler } = await import('./scheduler-DobkEDw0.mjs');
|
|
20687
21005
|
const workflowScheduler = new WorkflowScheduler({
|
|
20688
21006
|
projectRoots: () => {
|
|
20689
21007
|
const dirs = /* @__PURE__ */ new Set();
|
|
@@ -21307,4 +21625,4 @@ var run = /*#__PURE__*/Object.freeze({
|
|
|
21307
21625
|
writeStopMarker: writeStopMarker
|
|
21308
21626
|
});
|
|
21309
21627
|
|
|
21310
|
-
export {
|
|
21628
|
+
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-BCS8Ckf7.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-BCS8Ckf7.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|