svamp-cli 0.2.275 → 0.2.276
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agentCommands-DGT-1wjo.mjs → agentCommands-DYduijxc.mjs} +5 -5
- package/dist/{auth-CT55Rse4.mjs → auth-DF4dUys9.mjs} +1 -1
- package/dist/{cli-DYTmO9JL.mjs → cli-BrZuHfQa.mjs} +65 -65
- package/dist/cli.mjs +2 -2
- package/dist/{commands-C0rRjhMD.mjs → commands-7WZLaYv2.mjs} +2 -2
- package/dist/{commands-BV_9mFkz.mjs → commands-BjkRYbLw.mjs} +2 -2
- package/dist/{commands-CXHZapLH.mjs → commands-Cxn4Cmts.mjs} +1 -1
- package/dist/{commands-D7fIWAgz.mjs → commands-DINv6746.mjs} +1 -1
- package/dist/{commands-CVPcbtWV.mjs → commands-DLlgY23R.mjs} +1 -1
- package/dist/{commands-BvmFXAmu.mjs → commands-DvD1mdMU.mjs} +2 -2
- package/dist/{commands-C8Zc5axO.mjs → commands-clA49kHW.mjs} +7 -7
- package/dist/{fleet-BCel6ZVc.mjs → fleet-xyz1ik_N.mjs} +2 -2
- package/dist/{frpc-D3faR6iR.mjs → frpc-BkGcc69x.mjs} +7 -5
- package/dist/{headlessCli-DVBFm7og.mjs → headlessCli-Je1q_pDw.mjs} +2 -2
- package/dist/index.mjs +1 -1
- package/dist/package-D3rksT8O.mjs +64 -0
- package/dist/{pinnedClaudeCode-CgEtGkX2.mjs → pinnedClaudeCode-D8Tbz32G.mjs} +1 -1
- package/dist/{rpc-xlV-4-BG.mjs → rpc-CBa5WaBD.mjs} +1 -1
- package/dist/{rpc-BQ8zLSUc.mjs → rpc-HiJYPcOU.mjs} +1 -1
- package/dist/{run-DMPVho7i.mjs → run-BRHMebDp.mjs} +4 -3
- package/dist/{run-C3Fcbk-H.mjs → run-DjThStDG.mjs} +192 -46
- package/dist/{scheduler-DaFZY2ob.mjs → scheduler-D1JpZ5m8.mjs} +1 -1
- package/dist/{serveCommands-B9Yhx1fl.mjs → serveCommands-D-3LtTUy.mjs} +5 -5
- package/dist/{sideband-CYqmMG_m.mjs → sideband-DdcXgJHf.mjs} +1 -1
- package/package.json +2 -2
- package/dist/package-DIuZ7Wfp.mjs +0 -64
|
@@ -3,7 +3,7 @@ import fs$1, { mkdir as mkdir$1, readdir as readdir$1, readFile, writeFile as wr
|
|
|
3
3
|
import * as fs from 'fs';
|
|
4
4
|
import fs__default, { existsSync as existsSync$1, rmSync, readFileSync as readFileSync$1, mkdirSync, writeFileSync, renameSync as renameSync$1, realpathSync as realpathSync$1, copyFileSync, unlinkSync as unlinkSync$1, readdirSync as readdirSync$1, watch, rmdirSync } from 'fs';
|
|
5
5
|
import * as path from 'path';
|
|
6
|
-
import path__default, { join, resolve as resolve$1, dirname as dirname$1, basename as basename$1 } from 'path';
|
|
6
|
+
import path__default, { join, delimiter, resolve as resolve$1, dirname as dirname$1, basename as basename$1 } from 'path';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
8
|
import { execFile, spawn, execSync, exec as exec$1 } from 'child_process';
|
|
9
9
|
import * as crypto from 'crypto';
|
|
@@ -1506,6 +1506,9 @@ const COOKIE_NAME = "svamp_serve_token";
|
|
|
1506
1506
|
const SVAMP_SERVE_TOKEN_PARAM = "__svamp_serve_token";
|
|
1507
1507
|
const DEFAULT_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
1508
1508
|
const DEFAULT_CACHE_MAX_SIZE = 1e3;
|
|
1509
|
+
function jsStringLiteral(value) {
|
|
1510
|
+
return JSON.stringify(value).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
1511
|
+
}
|
|
1509
1512
|
class TokenCache {
|
|
1510
1513
|
cache = /* @__PURE__ */ new Map();
|
|
1511
1514
|
ttlMs;
|
|
@@ -1710,10 +1713,10 @@ a:hover{text-decoration:underline}
|
|
|
1710
1713
|
<div class="status" id="status"></div>
|
|
1711
1714
|
</div>
|
|
1712
1715
|
<script>
|
|
1713
|
-
const hyphaServer = ${
|
|
1714
|
-
const redirectUrl = ${
|
|
1715
|
-
const cookieName = ${
|
|
1716
|
-
const tokenParam = ${
|
|
1716
|
+
const hyphaServer = ${jsStringLiteral(this.hyphaServerUrl)};
|
|
1717
|
+
const redirectUrl = ${jsStringLiteral(redirectUrl)};
|
|
1718
|
+
const cookieName = ${jsStringLiteral(COOKIE_NAME)};
|
|
1719
|
+
const tokenParam = ${jsStringLiteral(SVAMP_SERVE_TOKEN_PARAM)};
|
|
1717
1720
|
|
|
1718
1721
|
const btn = document.getElementById('login-btn');
|
|
1719
1722
|
const statusEl = document.getElementById('status');
|
|
@@ -2210,7 +2213,7 @@ class ServeManager {
|
|
|
2210
2213
|
throw new Error(`Path does not exist: ${resolvedDir}`);
|
|
2211
2214
|
}
|
|
2212
2215
|
if (this.mounts.has(spec.name)) {
|
|
2213
|
-
await this.removeMount(spec.name);
|
|
2216
|
+
await this.removeMount(spec.name, { replacing: true });
|
|
2214
2217
|
}
|
|
2215
2218
|
const access = spec.access ?? "link";
|
|
2216
2219
|
if (access === "owner" && !spec.ownerEmail) {
|
|
@@ -2249,7 +2252,7 @@ class ServeManager {
|
|
|
2249
2252
|
/**
|
|
2250
2253
|
* Remove a mount. If no mounts remain, stop Caddy + auth proxy.
|
|
2251
2254
|
*/
|
|
2252
|
-
async removeMount(name) {
|
|
2255
|
+
async removeMount(name, opts) {
|
|
2253
2256
|
if (!this.mounts.has(name)) {
|
|
2254
2257
|
throw new Error(`Mount '${name}' not found`);
|
|
2255
2258
|
}
|
|
@@ -2269,7 +2272,7 @@ class ServeManager {
|
|
|
2269
2272
|
}
|
|
2270
2273
|
this.persist();
|
|
2271
2274
|
this.log(`Mount removed: ${name}`);
|
|
2272
|
-
if (this.mounts.size === 0) {
|
|
2275
|
+
if (this.mounts.size === 0 && !opts?.replacing) {
|
|
2273
2276
|
await this.shutdown();
|
|
2274
2277
|
}
|
|
2275
2278
|
}
|
|
@@ -2708,12 +2711,27 @@ a{color:#0969da;text-decoration:none;font-weight:500}a:hover{text-decoration:und
|
|
|
2708
2711
|
if (req.method === "PUT") {
|
|
2709
2712
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
2710
2713
|
const ws = fs.createWriteStream(filePath);
|
|
2714
|
+
let done = false;
|
|
2715
|
+
const cleanupPartial = () => {
|
|
2716
|
+
if (done) return;
|
|
2717
|
+
done = true;
|
|
2718
|
+
ws.destroy();
|
|
2719
|
+
fs.unlink(filePath, () => {
|
|
2720
|
+
});
|
|
2721
|
+
};
|
|
2722
|
+
req.on("aborted", cleanupPartial);
|
|
2723
|
+
req.on("close", () => {
|
|
2724
|
+
if (!ws.writableFinished) cleanupPartial();
|
|
2725
|
+
});
|
|
2711
2726
|
req.pipe(ws);
|
|
2712
2727
|
ws.on("finish", () => {
|
|
2728
|
+
done = true;
|
|
2713
2729
|
res.writeHead(201);
|
|
2714
2730
|
res.end();
|
|
2715
2731
|
});
|
|
2716
2732
|
ws.on("error", (err) => {
|
|
2733
|
+
if (done) return;
|
|
2734
|
+
done = true;
|
|
2717
2735
|
res.writeHead(500);
|
|
2718
2736
|
res.end(err.message);
|
|
2719
2737
|
});
|
|
@@ -2955,7 +2973,7 @@ Connection: close\r
|
|
|
2955
2973
|
const mount = this.mounts.get(mountName);
|
|
2956
2974
|
const subdomainOverride = mount?.access === "link" && mount.linkToken ? /* @__PURE__ */ new Map([[this.port, buildLinkSubdomain(subdomainSafe, mount.linkToken)]]) : void 0;
|
|
2957
2975
|
try {
|
|
2958
|
-
const { FrpcTunnel } = await import('./frpc-
|
|
2976
|
+
const { FrpcTunnel } = await import('./frpc-BkGcc69x.mjs');
|
|
2959
2977
|
let tunnel;
|
|
2960
2978
|
tunnel = new FrpcTunnel({
|
|
2961
2979
|
name: tunnelName,
|
|
@@ -4350,6 +4368,14 @@ class ChannelOutbox {
|
|
|
4350
4368
|
file;
|
|
4351
4369
|
byChannel = /* @__PURE__ */ new Map();
|
|
4352
4370
|
seqByChannel = /* @__PURE__ */ new Map();
|
|
4371
|
+
// #0500: per-channel MONOTONIC high-water seq that survives TTL eviction/compaction. seqByChannel
|
|
4372
|
+
// is rebuilt from RETAINED records on every reload, so once a channel's replies all age out (>1h
|
|
4373
|
+
// idle) its seq would reset to 1 — a long-poll receiver holding a pre-eviction cursor N would then
|
|
4374
|
+
// silently drop the new seq=1..N replies (since() filters seq > cursor). highWater is never lowered
|
|
4375
|
+
// and is persisted to a small sidecar (_outbox_seq.json) so seq stays monotonic across eviction AND
|
|
4376
|
+
// daemon restarts. Cross-process safe: re-read + max before each bump (via reload()).
|
|
4377
|
+
highWater = /* @__PURE__ */ new Map();
|
|
4378
|
+
seqFile;
|
|
4353
4379
|
emitter = new EventEmitter();
|
|
4354
4380
|
appendsSinceCompact = 0;
|
|
4355
4381
|
// #0362: change-detection for reload() — a long-poll receiver reuses ONE instance and only
|
|
@@ -4360,12 +4386,14 @@ class ChannelOutbox {
|
|
|
4360
4386
|
constructor(projectDir) {
|
|
4361
4387
|
const dir = join$1(projectDir, ".svamp", "channels");
|
|
4362
4388
|
this.file = join$1(dir, "_outbox.jsonl");
|
|
4389
|
+
this.seqFile = join$1(dir, "_outbox_seq.json");
|
|
4363
4390
|
this.emitter.setMaxListeners(0);
|
|
4364
4391
|
try {
|
|
4365
4392
|
mkdirSync$1(dir, { recursive: true });
|
|
4366
4393
|
} catch {
|
|
4367
4394
|
}
|
|
4368
4395
|
this._load();
|
|
4396
|
+
this._loadHighWater();
|
|
4369
4397
|
}
|
|
4370
4398
|
/** Current on-disk (mtimeMs, size), or (0, -1) if the file does not exist. */
|
|
4371
4399
|
_stat() {
|
|
@@ -4388,6 +4416,7 @@ class ChannelOutbox {
|
|
|
4388
4416
|
this.byChannel.clear();
|
|
4389
4417
|
this.seqByChannel.clear();
|
|
4390
4418
|
this._load();
|
|
4419
|
+
this._loadHighWater();
|
|
4391
4420
|
return true;
|
|
4392
4421
|
}
|
|
4393
4422
|
_load() {
|
|
@@ -4410,6 +4439,7 @@ class ChannelOutbox {
|
|
|
4410
4439
|
arr.push(reply);
|
|
4411
4440
|
this.byChannel.set(channelId, arr);
|
|
4412
4441
|
this.seqByChannel.set(channelId, Math.max(this.seqByChannel.get(channelId) || 0, reply.seq));
|
|
4442
|
+
this.highWater.set(channelId, Math.max(this.highWater.get(channelId) || 0, reply.seq));
|
|
4413
4443
|
}
|
|
4414
4444
|
for (const [ch, arr] of this.byChannel) if (arr.length > MAX_PER_CHANNEL) this.byChannel.set(ch, arr.slice(-MAX_PER_CHANNEL));
|
|
4415
4445
|
} catch {
|
|
@@ -4437,6 +4467,30 @@ class ChannelOutbox {
|
|
|
4437
4467
|
} catch {
|
|
4438
4468
|
}
|
|
4439
4469
|
}
|
|
4470
|
+
/** #0500: merge the durable per-channel high-water sidecar into memory (never lowers a value). */
|
|
4471
|
+
_loadHighWater() {
|
|
4472
|
+
try {
|
|
4473
|
+
if (!existsSync(this.seqFile)) return;
|
|
4474
|
+
const obj = JSON.parse(readFileSync(this.seqFile, "utf8"));
|
|
4475
|
+
for (const [ch, seq] of Object.entries(obj)) {
|
|
4476
|
+
if (typeof seq === "number" && Number.isFinite(seq)) {
|
|
4477
|
+
this.highWater.set(ch, Math.max(this.highWater.get(ch) || 0, seq));
|
|
4478
|
+
}
|
|
4479
|
+
}
|
|
4480
|
+
} catch {
|
|
4481
|
+
}
|
|
4482
|
+
}
|
|
4483
|
+
/** #0500: atomically persist the high-water map so seq survives eviction + restart. Best-effort. */
|
|
4484
|
+
_persistHighWater() {
|
|
4485
|
+
try {
|
|
4486
|
+
const obj = {};
|
|
4487
|
+
for (const [ch, seq] of this.highWater) obj[ch] = seq;
|
|
4488
|
+
const tmp = `${this.seqFile}.tmp-${process.pid}-${randomBytes(4).toString("hex")}`;
|
|
4489
|
+
writeFileSync$1(tmp, JSON.stringify(obj));
|
|
4490
|
+
renameSync(tmp, this.seqFile);
|
|
4491
|
+
} catch {
|
|
4492
|
+
}
|
|
4493
|
+
}
|
|
4440
4494
|
_evict(channelId) {
|
|
4441
4495
|
const cutoff = Date.now() - TTL_MS;
|
|
4442
4496
|
let arr = this.byChannel.get(channelId);
|
|
@@ -4448,8 +4502,10 @@ class ChannelOutbox {
|
|
|
4448
4502
|
/** Append a reply addressed to `to`. Assigns seq + ts, persists, and wakes waiters. */
|
|
4449
4503
|
append(channelId, r) {
|
|
4450
4504
|
this.reload();
|
|
4451
|
-
const seq = (this.seqByChannel.get(channelId) || 0) + 1;
|
|
4505
|
+
const seq = Math.max(this.highWater.get(channelId) || 0, this.seqByChannel.get(channelId) || 0) + 1;
|
|
4452
4506
|
this.seqByChannel.set(channelId, seq);
|
|
4507
|
+
this.highWater.set(channelId, seq);
|
|
4508
|
+
this._persistHighWater();
|
|
4453
4509
|
const reply = { seq, ts: Date.now(), to: r.to, body: r.body, ...r.correlationId ? { correlationId: r.correlationId } : {} };
|
|
4454
4510
|
const arr = this.byChannel.get(channelId) || [];
|
|
4455
4511
|
arr.push(reply);
|
|
@@ -5760,7 +5816,7 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
5760
5816
|
const tunnels = handlers.tunnels;
|
|
5761
5817
|
if (!tunnels) throw new Error("Tunnel management not available");
|
|
5762
5818
|
if (tunnels.has(params.name)) throw new Error(`Tunnel '${params.name}' already running`);
|
|
5763
|
-
const { FrpcTunnel } = await import('./frpc-
|
|
5819
|
+
const { FrpcTunnel } = await import('./frpc-BkGcc69x.mjs');
|
|
5764
5820
|
const tunnel = new FrpcTunnel({
|
|
5765
5821
|
name: params.name,
|
|
5766
5822
|
ports: params.ports,
|
|
@@ -5908,7 +5964,9 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
5908
5964
|
authorizeRequest(context, currentMetadata.sharing, "view");
|
|
5909
5965
|
const sm = handlers.serveManager;
|
|
5910
5966
|
if (!sm) throw new Error("Serve manager not available");
|
|
5911
|
-
|
|
5967
|
+
const info = sm.getInfo();
|
|
5968
|
+
const isAdmin = serveCallerTrusted(context);
|
|
5969
|
+
return { ...info, mounts: (info.mounts || []).map((m) => sanitizeMountForRole(m, isAdmin)) };
|
|
5912
5970
|
},
|
|
5913
5971
|
/**
|
|
5914
5972
|
* Aggregate frpc tunnel health for all serve mounts.
|
|
@@ -6234,7 +6292,7 @@ QUESTION: ${params.question || "Summarize this concisely."}` }
|
|
|
6234
6292
|
}
|
|
6235
6293
|
const deps = buildSessionDeps(rpc, { cwd, ownerEmail: owner });
|
|
6236
6294
|
const sender = { name: context?.user?.email || context?.user?.id || "user", kind: "user", verified: true };
|
|
6237
|
-
const { toolsForRole } = await import('./sideband-
|
|
6295
|
+
const { toolsForRole } = await import('./sideband-DdcXgJHf.mjs');
|
|
6238
6296
|
const r2 = await runWiseAgent({ message: params.message, sender, config: { tools: toolsForRole(role2) }, deps, transport, model: resolved.model });
|
|
6239
6297
|
return fmt(r2);
|
|
6240
6298
|
}
|
|
@@ -6333,7 +6391,7 @@ QUESTION: ${params.question || "Summarize this concisely."}` }
|
|
|
6333
6391
|
if (r.error || !r.sender) return { error: r.error || "unauthorized" };
|
|
6334
6392
|
const callId = "call_" + Math.random().toString(16).slice(2, 12);
|
|
6335
6393
|
const rendered = renderMessage(c, { sender: r.sender, body: { message: kwargs.message }, callId });
|
|
6336
|
-
const { queryCore } = await import('./commands-
|
|
6394
|
+
const { queryCore } = await import('./commands-DINv6746.mjs');
|
|
6337
6395
|
const timeout = c.reply?.timeout_sec || 120;
|
|
6338
6396
|
let result;
|
|
6339
6397
|
try {
|
|
@@ -7142,7 +7200,13 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
|
|
|
7142
7200
|
const skillCtxFor = (c) => ({
|
|
7143
7201
|
channelsServiceId,
|
|
7144
7202
|
baseUrl: channelsBaseUrl,
|
|
7145
|
-
|
|
7203
|
+
// #0512: embed ONLY the channel-wide shared_key. The previous `|| callers?.[0]?.key`
|
|
7204
|
+
// fallback leaked one specific caller's PRIVATE per-key credential into the skill body,
|
|
7205
|
+
// which is served by the UNAUTHENTICATED channelDescribe (and view-tier getChannelSkill) —
|
|
7206
|
+
// an anonymous reader could then impersonate that caller (send as them + read their outbox).
|
|
7207
|
+
// For a per-key channel (no shared_key) key is undefined and generateSkillBody renders the
|
|
7208
|
+
// <your-key> placeholder, which is the correct instruction for a per-key caller.
|
|
7209
|
+
key: c.identity?.shared_key,
|
|
7146
7210
|
// The session this skill is being copied FROM — baked into `dynamic` channel
|
|
7147
7211
|
// instructions as the routing target so the copied link lands in THIS session.
|
|
7148
7212
|
session: sessionId
|
|
@@ -7525,7 +7589,9 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
|
|
|
7525
7589
|
name: c.name,
|
|
7526
7590
|
skillUrl,
|
|
7527
7591
|
sendUrl,
|
|
7528
|
-
|
|
7592
|
+
// #0512: only the channel-wide shared_key — never an individual caller's private key
|
|
7593
|
+
// (this getChannelSkill result is reachable at view tier).
|
|
7594
|
+
key: c.identity?.shared_key,
|
|
7529
7595
|
hyphaKeyless: (c.identity?.hypha_allow || []).length > 0,
|
|
7530
7596
|
bind: c.bind,
|
|
7531
7597
|
bindMode: mode,
|
|
@@ -8771,6 +8837,23 @@ function handleClaudeMessage(ctx, msg) {
|
|
|
8771
8837
|
}
|
|
8772
8838
|
}
|
|
8773
8839
|
|
|
8840
|
+
const KNOWN_AGENT_LAUNCHERS = ["claude", "codex", "gemini"];
|
|
8841
|
+
function agentLauncherExists(cmd, env = process.env) {
|
|
8842
|
+
if (!cmd) return false;
|
|
8843
|
+
if (cmd.includes("/") || cmd.includes("\\")) return existsSync$1(cmd);
|
|
8844
|
+
const dirs = (env.PATH || "").split(delimiter).filter(Boolean);
|
|
8845
|
+
const exts = process.platform === "win32" ? ["", ...(env.PATHEXT || ".EXE;.CMD;.BAT;.COM").split(";").filter(Boolean)] : [""];
|
|
8846
|
+
for (const dir of dirs) {
|
|
8847
|
+
for (const ext of exts) {
|
|
8848
|
+
if (existsSync$1(join(dir, cmd + ext))) return true;
|
|
8849
|
+
}
|
|
8850
|
+
}
|
|
8851
|
+
return false;
|
|
8852
|
+
}
|
|
8853
|
+
function detectAvailableAgents(env = process.env) {
|
|
8854
|
+
return KNOWN_AGENT_LAUNCHERS.filter((c) => agentLauncherExists(c, env));
|
|
8855
|
+
}
|
|
8856
|
+
|
|
8774
8857
|
const INLINE_ARTIFACT_MAX_BYTES = 512 * 1024;
|
|
8775
8858
|
const MAX_STORED_MESSAGE_BYTES = 2 * 1024 * 1024;
|
|
8776
8859
|
const MIN_DATA_URI_SCAN_CHARS = INLINE_ARTIFACT_MAX_BYTES;
|
|
@@ -12135,7 +12218,31 @@ async function verifyIsolation(method, binaryPath) {
|
|
|
12135
12218
|
return { passed: false, error: `${method} is not supported for external isolation` };
|
|
12136
12219
|
}
|
|
12137
12220
|
}
|
|
12221
|
+
function isolationDisabledByEnv(env = process.env) {
|
|
12222
|
+
const v = (env.SVAMP_ISOLATION || "").trim().toLowerCase();
|
|
12223
|
+
if (v && ["none", "off", "disabled", "0", "false", "no"].includes(v)) return true;
|
|
12224
|
+
const truthy = (s) => !!s && !["", "0", "false", "no", "off"].includes(s.trim().toLowerCase());
|
|
12225
|
+
return truthy(env.SVAMP_NO_ISOLATION) || truthy(env.SVAMP_SKIP_NONO);
|
|
12226
|
+
}
|
|
12138
12227
|
async function detectIsolationCapabilities() {
|
|
12228
|
+
if (isolationDisabledByEnv()) {
|
|
12229
|
+
console.log(
|
|
12230
|
+
"[isolation] Disabled via env (SVAMP_ISOLATION=none) \u2014 skipping nono auto-install + runtime detection. Sessions run WITHOUT per-session sandboxing; session sharing is allowed (rely on the container/host boundary)."
|
|
12231
|
+
);
|
|
12232
|
+
const notFound = () => ({ found: false });
|
|
12233
|
+
return {
|
|
12234
|
+
available: [],
|
|
12235
|
+
preferred: null,
|
|
12236
|
+
disabled: true,
|
|
12237
|
+
details: {
|
|
12238
|
+
nono: notFound(),
|
|
12239
|
+
docker: notFound(),
|
|
12240
|
+
podman: notFound(),
|
|
12241
|
+
srt: notFound(),
|
|
12242
|
+
bwrap: notFound()
|
|
12243
|
+
}
|
|
12244
|
+
};
|
|
12245
|
+
}
|
|
12139
12246
|
const checks = {
|
|
12140
12247
|
nono: checkCommand("nono", ["--version"]),
|
|
12141
12248
|
docker: checkCommand("docker", ["--version"]),
|
|
@@ -12625,6 +12732,7 @@ class ProcessSupervisor {
|
|
|
12625
12732
|
throw new Error(`Process '${entry.spec.name}' is already running`);
|
|
12626
12733
|
}
|
|
12627
12734
|
entry.stopping = false;
|
|
12735
|
+
this.clearTimers(entry);
|
|
12628
12736
|
if (entry.spec.desiredStopped) {
|
|
12629
12737
|
entry.spec.desiredStopped = false;
|
|
12630
12738
|
await this.persistSpec(entry.spec);
|
|
@@ -12683,6 +12791,8 @@ class ProcessSupervisor {
|
|
|
12683
12791
|
this.clearTimers(entry);
|
|
12684
12792
|
await this.killChild(entry.child);
|
|
12685
12793
|
entry.child = void 0;
|
|
12794
|
+
} else {
|
|
12795
|
+
this.clearTimers(entry);
|
|
12686
12796
|
}
|
|
12687
12797
|
if (entry.deleted) return;
|
|
12688
12798
|
entry.stopping = false;
|
|
@@ -12914,6 +13024,7 @@ class ProcessSupervisor {
|
|
|
12914
13024
|
spawnProcess(entry) {
|
|
12915
13025
|
const { spec, state } = entry;
|
|
12916
13026
|
if (entry.deleted) return;
|
|
13027
|
+
state.consecutiveProbeFailures = 0;
|
|
12917
13028
|
try {
|
|
12918
13029
|
const env = { ...process.env, ...spec.env ?? {} };
|
|
12919
13030
|
const child = spawn(spec.command, spec.args, {
|
|
@@ -13018,6 +13129,7 @@ class ProcessSupervisor {
|
|
|
13018
13129
|
);
|
|
13019
13130
|
entry.restartTimer = setTimeout(() => {
|
|
13020
13131
|
if (entry.deleted || entry.stopping) return;
|
|
13132
|
+
if (entry.child) return;
|
|
13021
13133
|
state.restartCount++;
|
|
13022
13134
|
state.status = "starting";
|
|
13023
13135
|
this.spawnProcess(entry);
|
|
@@ -13046,6 +13158,8 @@ class ProcessSupervisor {
|
|
|
13046
13158
|
const timeoutMs = (probe.timeout ?? DEFAULT_PROBE_TIMEOUT_S) * 1e3;
|
|
13047
13159
|
const threshold = probe.failureThreshold ?? DEFAULT_PROBE_FAILURE_THRESHOLD;
|
|
13048
13160
|
const url = `http://localhost:${probe.port}${urlPath}`;
|
|
13161
|
+
const probedChild = entry.child;
|
|
13162
|
+
const stillSameChild = () => !entry.deleted && !entry.stopping && entry.child === probedChild && entry.state.status === "running";
|
|
13049
13163
|
try {
|
|
13050
13164
|
const controller = new AbortController();
|
|
13051
13165
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -13055,6 +13169,7 @@ class ProcessSupervisor {
|
|
|
13055
13169
|
} finally {
|
|
13056
13170
|
clearTimeout(timer);
|
|
13057
13171
|
}
|
|
13172
|
+
if (!stillSameChild()) return;
|
|
13058
13173
|
const ok = resp.ok;
|
|
13059
13174
|
entry.state.lastProbe = { ok, timestamp: Date.now(), statusCode: resp.status };
|
|
13060
13175
|
if (ok) {
|
|
@@ -13069,6 +13184,7 @@ class ProcessSupervisor {
|
|
|
13069
13184
|
}
|
|
13070
13185
|
}
|
|
13071
13186
|
} catch (err) {
|
|
13187
|
+
if (!stillSameChild()) return;
|
|
13072
13188
|
entry.state.lastProbe = { ok: false, timestamp: Date.now(), error: err.message };
|
|
13073
13189
|
entry.state.consecutiveProbeFailures++;
|
|
13074
13190
|
console.warn(
|
|
@@ -13099,7 +13215,12 @@ class ProcessSupervisor {
|
|
|
13099
13215
|
return;
|
|
13100
13216
|
}
|
|
13101
13217
|
console.log(`[SUPERVISOR] Process '${entry.spec.name}' TTL: expires in ${remainingS.toFixed(0)}s`);
|
|
13102
|
-
|
|
13218
|
+
const MAX_DELAY = 2147483647;
|
|
13219
|
+
const delayMs = remainingS * 1e3;
|
|
13220
|
+
entry.ttlTimer = setTimeout(
|
|
13221
|
+
() => delayMs > MAX_DELAY ? this.setupTTL(entry) : this.expireProcess(entry),
|
|
13222
|
+
Math.min(delayMs, MAX_DELAY)
|
|
13223
|
+
);
|
|
13103
13224
|
}
|
|
13104
13225
|
expireProcess(entry) {
|
|
13105
13226
|
if (entry.deleted) return;
|
|
@@ -14031,7 +14152,7 @@ function summarizeExtensions(extensions, maxExtensions = DEFAULT_LOOP_MAX_EXTENS
|
|
|
14031
14152
|
const n = grantedExtensionCount(extensions, maxExtensions);
|
|
14032
14153
|
if (n === 0) return "";
|
|
14033
14154
|
const turns = extensionTurns(extensions, maxExtensions);
|
|
14034
|
-
const reasons = extensions.slice(0, maxExtensions).map((e) => (e
|
|
14155
|
+
const reasons = extensions.slice(0, maxExtensions).map((e) => (e?.reason || "").trim()).filter(Boolean).join("; ").slice(0, 300);
|
|
14035
14156
|
return `${n} extension${n === 1 ? "" : "s"} granted (+${turns} turns)${reasons ? `: ${reasons}` : ""}`;
|
|
14036
14157
|
}
|
|
14037
14158
|
const DEFAULT_LOOP_STUCK_CHECKPOINTS = 3;
|
|
@@ -14039,7 +14160,7 @@ const DEFAULT_LOOP_MAX_AUTORESUMES = Number.POSITIVE_INFINITY;
|
|
|
14039
14160
|
const PROGRESS_HISTORY_CAP = 12;
|
|
14040
14161
|
function resolveStuckLimit(envValue) {
|
|
14041
14162
|
const n = Number(envValue);
|
|
14042
|
-
if (Number.isFinite(n) && n >= 1) return Math.floor(n);
|
|
14163
|
+
if (Number.isFinite(n) && n >= 1) return Math.min(Math.floor(n), PROGRESS_HISTORY_CAP - 1);
|
|
14043
14164
|
return DEFAULT_LOOP_STUCK_CHECKPOINTS;
|
|
14044
14165
|
}
|
|
14045
14166
|
function resolveMaxAutoResumes(envValue) {
|
|
@@ -14097,7 +14218,8 @@ function resolveEvaluatorModel(envValue) {
|
|
|
14097
14218
|
function parseEvaluatorVerdict(text) {
|
|
14098
14219
|
if (!text) return null;
|
|
14099
14220
|
const candidates = [];
|
|
14100
|
-
|
|
14221
|
+
const openStack = [];
|
|
14222
|
+
let inStr = false, esc = false;
|
|
14101
14223
|
for (let i = 0; i < text.length; i++) {
|
|
14102
14224
|
const c = text[i];
|
|
14103
14225
|
if (inStr) {
|
|
@@ -14113,15 +14235,11 @@ function parseEvaluatorVerdict(text) {
|
|
|
14113
14235
|
if (c === '"') {
|
|
14114
14236
|
inStr = true;
|
|
14115
14237
|
} else if (c === "{") {
|
|
14116
|
-
|
|
14117
|
-
depth++;
|
|
14238
|
+
openStack.push(i);
|
|
14118
14239
|
} else if (c === "}") {
|
|
14119
|
-
|
|
14120
|
-
|
|
14121
|
-
|
|
14122
|
-
candidates.push(text.slice(start, i + 1));
|
|
14123
|
-
start = -1;
|
|
14124
|
-
}
|
|
14240
|
+
const open = openStack.pop();
|
|
14241
|
+
if (open !== void 0) {
|
|
14242
|
+
candidates.push(text.slice(open, i + 1));
|
|
14125
14243
|
}
|
|
14126
14244
|
}
|
|
14127
14245
|
}
|
|
@@ -15387,7 +15505,7 @@ function createSvampConfigChecker(directory, sessionId, getMetadata, setMetadata
|
|
|
15387
15505
|
const key = s.started_at ?? "\u2205";
|
|
15388
15506
|
if (key === announcedLoopStart) return;
|
|
15389
15507
|
announcedLoopStart = key;
|
|
15390
|
-
const iter = typeof s.iteration === "number" ? s.iteration : 0;
|
|
15508
|
+
const iter = s.ledger && typeof s.ledger.turns === "number" && s.ledger.turns > 0 ? s.ledger.turns : typeof s.iteration === "number" ? s.iteration : 0;
|
|
15391
15509
|
const plural = iter === 1 ? "" : "s";
|
|
15392
15510
|
const gaveUpCfg = readLoopJson(directory, sessionId, "loop.config.json") || {};
|
|
15393
15511
|
const curMax = typeof gaveUpCfg.max_iterations === "number" ? gaveUpCfg.max_iterations : iter;
|
|
@@ -16015,7 +16133,7 @@ async function startDaemon(options) {
|
|
|
16015
16133
|
try {
|
|
16016
16134
|
const dir = loadSessionIndex()[sessionId]?.directory;
|
|
16017
16135
|
if (!dir) return;
|
|
16018
|
-
const { reconcileServiceLinks } = await import('./agentCommands-
|
|
16136
|
+
const { reconcileServiceLinks } = await import('./agentCommands-DYduijxc.mjs');
|
|
16019
16137
|
const configPath = getSvampConfigPath(dir, sessionId);
|
|
16020
16138
|
const config = readSvampConfig(configPath);
|
|
16021
16139
|
const entries = Array.from(urls.entries());
|
|
@@ -16033,7 +16151,7 @@ async function startDaemon(options) {
|
|
|
16033
16151
|
}
|
|
16034
16152
|
}
|
|
16035
16153
|
async function createExposedTunnel(spec) {
|
|
16036
|
-
const { FrpcTunnel } = await import('./frpc-
|
|
16154
|
+
const { FrpcTunnel } = await import('./frpc-BkGcc69x.mjs');
|
|
16037
16155
|
const tunnel = new FrpcTunnel({
|
|
16038
16156
|
name: spec.name,
|
|
16039
16157
|
ports: spec.ports,
|
|
@@ -16061,7 +16179,7 @@ async function startDaemon(options) {
|
|
|
16061
16179
|
ensureAutoInstalledCommands(logger);
|
|
16062
16180
|
(async () => {
|
|
16063
16181
|
try {
|
|
16064
|
-
const { beginClaudeVersionReconcile } = await import('./pinnedClaudeCode-
|
|
16182
|
+
const { beginClaudeVersionReconcile } = await import('./pinnedClaudeCode-D8Tbz32G.mjs');
|
|
16065
16183
|
beginClaudeVersionReconcile((msg) => logger.log(msg));
|
|
16066
16184
|
} catch (e) {
|
|
16067
16185
|
logger.log(`[claude-version] check failed: ${e?.message || e}`);
|
|
@@ -16743,10 +16861,11 @@ ${parts.join("\n")}`);
|
|
|
16743
16861
|
logger.log(`[Session ${sessionId}] loop was cancelled during verification \u2014 not re-kicking (#0308)`);
|
|
16744
16862
|
return;
|
|
16745
16863
|
}
|
|
16746
|
-
const
|
|
16864
|
+
const curLs = readLoopState(directory, sessionId) || ls;
|
|
16865
|
+
const ledger = curLs.ledger ?? ls.ledger;
|
|
16747
16866
|
const budget = ls.budget;
|
|
16748
|
-
const progress_history = ls.progress_history;
|
|
16749
|
-
const extensions = ls.extensions;
|
|
16867
|
+
const progress_history = curLs.progress_history ?? ls.progress_history;
|
|
16868
|
+
const extensions = curLs.extensions ?? ls.extensions;
|
|
16750
16869
|
if (result.action === "rekick") {
|
|
16751
16870
|
const cond = ls.task || "";
|
|
16752
16871
|
writeGoalLoopState(directory, sessionId, {
|
|
@@ -16875,6 +16994,7 @@ ${parts.join("\n")}`);
|
|
|
16875
16994
|
let consecutiveOverloadRetries = 0;
|
|
16876
16995
|
let overloadBailedThisTurn = false;
|
|
16877
16996
|
let pendingCompactTurn = false;
|
|
16997
|
+
let noIsolationWarned = false;
|
|
16878
16998
|
const RATELIMIT_CFG = getRateLimitRetryConfig();
|
|
16879
16999
|
let currentTurnMessage;
|
|
16880
17000
|
let rateLimitRetryCount = 0;
|
|
@@ -16982,6 +17102,14 @@ ${parts.join("\n")}`);
|
|
|
16982
17102
|
} else if (shouldIsolateSession()) {
|
|
16983
17103
|
logger.log(`[Session ${sessionId}] WARNING: No isolation runtime (nono/docker/podman) available. Session is NOT sandboxed.`);
|
|
16984
17104
|
sessionMetadata = { ...sessionMetadata, isolationMethod: void 0 };
|
|
17105
|
+
if (!isolationCapabilities.disabled && !noIsolationWarned) {
|
|
17106
|
+
noIsolationWarned = true;
|
|
17107
|
+
sessionService.pushMessage({
|
|
17108
|
+
type: "message",
|
|
17109
|
+
level: "warning",
|
|
17110
|
+
message: "This session requested sandboxing (a security context / --isolate) but no isolation runtime (nono, docker, or podman) is available on this machine \u2014 it is running WITHOUT a sandbox. Install a runtime, or set SVAMP_ISOLATION=none to run unsandboxed intentionally (e.g. when the machine is already a container)."
|
|
17111
|
+
}, "event");
|
|
17112
|
+
}
|
|
16985
17113
|
} else {
|
|
16986
17114
|
sessionMetadata = { ...sessionMetadata, isolationMethod: void 0 };
|
|
16987
17115
|
}
|
|
@@ -17030,6 +17158,22 @@ ${parts.join("\n")}`);
|
|
|
17030
17158
|
spawnEnv.SVAMP_SANDBOXED = "1";
|
|
17031
17159
|
logger.log(`[Session ${sessionId}] Credential staging: HOME=${stagedCredentials.homePath}, SVAMP_SANDBOXED=1`);
|
|
17032
17160
|
}
|
|
17161
|
+
if (!agentLauncherExists("claude")) {
|
|
17162
|
+
const others = detectAvailableAgents().filter((a) => a !== "claude");
|
|
17163
|
+
const hint = others.length ? ` This machine has: ${others.join(", ")} \u2014 start a ${others[0]} session instead.` : " No agent launchers were found on this machine.";
|
|
17164
|
+
logger.log(`[Session ${sessionId}] Claude launcher ('claude') not found on PATH \u2014 aborting spawn (available: ${detectAvailableAgents().join(", ") || "none"})`);
|
|
17165
|
+
sessionService.pushMessage({
|
|
17166
|
+
type: "message",
|
|
17167
|
+
level: "error",
|
|
17168
|
+
message: `Claude Code (\`claude\`) isn't installed on this machine (${os$1.hostname()}), so this Claude session can't run.${hint}`
|
|
17169
|
+
}, "event");
|
|
17170
|
+
sessionMetadata = { ...sessionMetadata, lifecycleState: "idle" };
|
|
17171
|
+
sessionService.updateMetadata(sessionMetadata);
|
|
17172
|
+
sessionWasProcessing = false;
|
|
17173
|
+
signalProcessing(false);
|
|
17174
|
+
sessionService.sendSessionEnd();
|
|
17175
|
+
return void 0;
|
|
17176
|
+
}
|
|
17033
17177
|
const child = spawn(spawnCommand, spawnArgs, {
|
|
17034
17178
|
cwd: directory,
|
|
17035
17179
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -17046,7 +17190,7 @@ ${parts.join("\n")}`);
|
|
|
17046
17190
|
child.on("error", (err) => {
|
|
17047
17191
|
logger.log(`[Session ${sessionId}] Claude process error: ${err.message}`);
|
|
17048
17192
|
sessionService.pushMessage(
|
|
17049
|
-
{ type: "message", message: `Agent process
|
|
17193
|
+
{ type: "message", level: "error", message: `Agent process failed to start: ${err.message}. Please ensure the Claude Code CLI is installed on this machine.` },
|
|
17050
17194
|
"event"
|
|
17051
17195
|
);
|
|
17052
17196
|
sessionWasProcessing = false;
|
|
@@ -18223,18 +18367,19 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
18223
18367
|
});
|
|
18224
18368
|
},
|
|
18225
18369
|
onIssue: async (params) => {
|
|
18226
|
-
const { issueRpc } = await import('./rpc-
|
|
18370
|
+
const { issueRpc } = await import('./rpc-HiJYPcOU.mjs');
|
|
18227
18371
|
return issueRpc(params?.cwd || directory, params || {}, { notifySession: notifyIssueOwner, rekickLoopOwner });
|
|
18228
18372
|
},
|
|
18229
18373
|
onWorkflow: async (params) => {
|
|
18230
|
-
const { workflowRpc } = await import('./rpc-
|
|
18374
|
+
const { workflowRpc } = await import('./rpc-CBa5WaBD.mjs');
|
|
18231
18375
|
return workflowRpc(params?.cwd || directory, params || {});
|
|
18232
18376
|
},
|
|
18233
18377
|
onRipgrep: async (args, cwd) => {
|
|
18234
|
-
const {
|
|
18378
|
+
const { execFile } = await import('child_process');
|
|
18235
18379
|
const rgCwd = cwd || directory;
|
|
18380
|
+
const argv = Array.isArray(args) ? args : String(args).split(/\s+/).filter(Boolean);
|
|
18236
18381
|
return new Promise((resolve2, reject) => {
|
|
18237
|
-
|
|
18382
|
+
execFile("rg", argv, { cwd: rgCwd, timeout: 3e4, maxBuffer: 5 * 1024 * 1024 }, (err, stdout) => {
|
|
18238
18383
|
if (err && !stdout) {
|
|
18239
18384
|
reject(new Error(err.message));
|
|
18240
18385
|
} else {
|
|
@@ -18838,18 +18983,19 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
18838
18983
|
});
|
|
18839
18984
|
},
|
|
18840
18985
|
onIssue: async (params) => {
|
|
18841
|
-
const { issueRpc } = await import('./rpc-
|
|
18986
|
+
const { issueRpc } = await import('./rpc-HiJYPcOU.mjs');
|
|
18842
18987
|
return issueRpc(params?.cwd || directory, params || {}, { notifySession: notifyIssueOwner, rekickLoopOwner });
|
|
18843
18988
|
},
|
|
18844
18989
|
onWorkflow: async (params) => {
|
|
18845
|
-
const { workflowRpc } = await import('./rpc-
|
|
18990
|
+
const { workflowRpc } = await import('./rpc-CBa5WaBD.mjs');
|
|
18846
18991
|
return workflowRpc(params?.cwd || directory, params || {});
|
|
18847
18992
|
},
|
|
18848
18993
|
onRipgrep: async (args, cwd) => {
|
|
18849
|
-
const {
|
|
18994
|
+
const { execFile } = await import('child_process');
|
|
18850
18995
|
const rgCwd = cwd || directory;
|
|
18996
|
+
const argv = Array.isArray(args) ? args : String(args).split(/\s+/).filter(Boolean);
|
|
18851
18997
|
return new Promise((resolve2, reject) => {
|
|
18852
|
-
|
|
18998
|
+
execFile("rg", argv, { cwd: rgCwd, timeout: 3e4, maxBuffer: 5 * 1024 * 1024 }, (err, stdout) => {
|
|
18853
18999
|
if (err && !stdout) {
|
|
18854
19000
|
reject(new Error(err.message));
|
|
18855
19001
|
} else {
|
|
@@ -19734,7 +19880,7 @@ ${oracle.output.trim().slice(0, 500)}`, "\u{1F501} Continuing loop");
|
|
|
19734
19880
|
}
|
|
19735
19881
|
if (persistedSessions.length > 0) {
|
|
19736
19882
|
try {
|
|
19737
|
-
const { awaitClaudeVersionReady } = await import('./pinnedClaudeCode-
|
|
19883
|
+
const { awaitClaudeVersionReady } = await import('./pinnedClaudeCode-D8Tbz32G.mjs');
|
|
19738
19884
|
await awaitClaudeVersionReady();
|
|
19739
19885
|
} catch {
|
|
19740
19886
|
}
|
|
@@ -19931,7 +20077,7 @@ ${oracle.output.trim().slice(0, 500)}`, "\u{1F501} Continuing loop");
|
|
|
19931
20077
|
const PING_TIMEOUT_MS = 15e3;
|
|
19932
20078
|
const POST_RECONNECT_GRACE_MS = 2e4;
|
|
19933
20079
|
const RECONNECT_JITTER_MS = 2500;
|
|
19934
|
-
const { WorkflowScheduler } = await import('./scheduler-
|
|
20080
|
+
const { WorkflowScheduler } = await import('./scheduler-D1JpZ5m8.mjs');
|
|
19935
20081
|
const workflowScheduler = new WorkflowScheduler({
|
|
19936
20082
|
projectRoots: () => {
|
|
19937
20083
|
const dirs = /* @__PURE__ */ new Set();
|
|
@@ -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-DjThStDG.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-DINv6746.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-DINv6746.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-DINv6746.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-DINv6746.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-DINv6746.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, J as loadMachineContext, K as buildMachineInstructions, L as machineToolsForRole, M as buildMachineTools } from './run-
|
|
1
|
+
import { R as READ_ONLY_TOOLS, J as loadMachineContext, K as buildMachineInstructions, L as machineToolsForRole, M as buildMachineTools } from './run-DjThStDG.mjs';
|
|
2
2
|
import 'node:child_process';
|
|
3
3
|
import 'os';
|
|
4
4
|
import 'fs/promises';
|