@algosuite/vo-mcp 0.2.0-beta.16 → 0.2.0-beta.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +5 -51
- package/dist/cli.js.map +2 -2
- package/dist/index.js +5 -51
- package/dist/index.js.map +2 -2
- package/dist/runner-cli.js +433 -290
- package/dist/runner-cli.js.map +4 -4
- package/dist/runner-supervisor.js +238 -36
- package/dist/runner-supervisor.js.map +4 -4
- package/package.json +1 -1
|
@@ -66,11 +66,11 @@ function createControlPlaneClient({
|
|
|
66
66
|
throw new Error("VO_CONTROL_PLANE_URL is required for the code-runner daemon");
|
|
67
67
|
}
|
|
68
68
|
const root = resolvedBaseUrl.replace(/\/+$/, "");
|
|
69
|
-
async function req(method,
|
|
69
|
+
async function req(method, path2, body, { timeoutMs } = {}) {
|
|
70
70
|
const bearer = await resolveBearer(env);
|
|
71
71
|
const controller = timeoutMs ? new AbortController() : null;
|
|
72
72
|
let timeoutId;
|
|
73
|
-
const request = Promise.resolve(fetchImpl(`${root}${
|
|
73
|
+
const request = Promise.resolve(fetchImpl(`${root}${path2}`, {
|
|
74
74
|
method,
|
|
75
75
|
headers: {
|
|
76
76
|
"content-type": "application/json",
|
|
@@ -83,7 +83,7 @@ function createControlPlaneClient({
|
|
|
83
83
|
const timeout = new Promise((_, reject) => {
|
|
84
84
|
timeoutId = setTimeout(() => {
|
|
85
85
|
controller.abort();
|
|
86
|
-
reject(new Error(`control-plane ${
|
|
86
|
+
reject(new Error(`control-plane ${path2} timed out after ${timeoutMs}ms`));
|
|
87
87
|
}, timeoutMs);
|
|
88
88
|
});
|
|
89
89
|
try {
|
|
@@ -202,8 +202,8 @@ function createControlPlaneClient({
|
|
|
202
202
|
return json ? json.task : null;
|
|
203
203
|
},
|
|
204
204
|
async downloadTaskAttachment(taskId, attachmentId) {
|
|
205
|
-
const
|
|
206
|
-
const res = await req("GET",
|
|
205
|
+
const path2 = `/api/v1/code-task/${encodeURIComponent(taskId)}/attachment/${encodeURIComponent(attachmentId)}`;
|
|
206
|
+
const res = await req("GET", path2);
|
|
207
207
|
if (res.status === 401) cachedFirebaseToken = null;
|
|
208
208
|
if (!res.ok) throw new Error(`attachment download failed: HTTP ${res.status}`);
|
|
209
209
|
return Buffer.from(await res.arrayBuffer());
|
|
@@ -511,7 +511,7 @@ import {
|
|
|
511
511
|
rmSync as rmSync2,
|
|
512
512
|
writeFileSync as writeFileSync2
|
|
513
513
|
} from "node:fs";
|
|
514
|
-
import { basename, isAbsolute as isAbsolute3, join as join3, resolve as resolve4 } from "node:path";
|
|
514
|
+
import { basename, isAbsolute as isAbsolute3, join as join3, relative as relative3, resolve as resolve4, sep as sep2 } from "node:path";
|
|
515
515
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
516
516
|
|
|
517
517
|
// ../../scripts/virtual-office/runner-bootstrap/runtime-authorization.mjs
|
|
@@ -647,10 +647,10 @@ function validateLock(lock, authorization) {
|
|
|
647
647
|
}
|
|
648
648
|
return { actual, expected };
|
|
649
649
|
}
|
|
650
|
-
function checkPathKind(
|
|
651
|
-
if (!fsOps.exists(
|
|
652
|
-
const stats = fsOps.lstat(
|
|
653
|
-
if (isReparseStat(stats) || fsOps.isReparsePoint(
|
|
650
|
+
function checkPathKind(path2, expectedKind, fsOps, label) {
|
|
651
|
+
if (!fsOps.exists(path2)) throw new Error(`staged runtime ${label} missing`);
|
|
652
|
+
const stats = fsOps.lstat(path2);
|
|
653
|
+
if (isReparseStat(stats) || fsOps.isReparsePoint(path2, stats)) {
|
|
654
654
|
throw new Error(`staged runtime ${label} is a reparse point`);
|
|
655
655
|
}
|
|
656
656
|
if (expectedKind === "directory" && !stats.isDirectory()) {
|
|
@@ -668,30 +668,30 @@ function verifyInstalledPackages(payloadRoot, packageRecords, platform, fsOps) {
|
|
|
668
668
|
const omitted = [];
|
|
669
669
|
let installed = 0;
|
|
670
670
|
for (const [key, entry] of Object.entries(packageRecords)) {
|
|
671
|
-
const
|
|
672
|
-
assertContained(payloadRoot,
|
|
671
|
+
const path2 = resolve(payloadRoot, key);
|
|
672
|
+
assertContained(payloadRoot, path2, "package path");
|
|
673
673
|
const shouldOmit = isOmittedOptionalPackage(entry, platform);
|
|
674
674
|
if (shouldOmit) {
|
|
675
675
|
omitted.push(key);
|
|
676
|
-
if (fsOps.exists(
|
|
676
|
+
if (fsOps.exists(path2)) throw new Error(`staged runtime optional package should be omitted: ${key}`);
|
|
677
677
|
continue;
|
|
678
678
|
}
|
|
679
|
-
checkPathKind(
|
|
679
|
+
checkPathKind(path2, "directory", fsOps, `installed package ${key}`);
|
|
680
680
|
installed += 1;
|
|
681
681
|
}
|
|
682
682
|
return { installed, omitted: omitted.sort() };
|
|
683
683
|
}
|
|
684
|
-
function treeRecord(kind,
|
|
685
|
-
if (kind === "d") return `d ${
|
|
684
|
+
function treeRecord(kind, path2, stats, fileHash = "") {
|
|
685
|
+
if (kind === "d") return `d ${path2}\r
|
|
686
686
|
`;
|
|
687
|
-
return `f ${
|
|
687
|
+
return `f ${path2} ${stats.size} ${fileHash}\r
|
|
688
688
|
`;
|
|
689
689
|
}
|
|
690
690
|
function computeInstalledTree(nodeModulesRoot, fsOps = {}) {
|
|
691
691
|
const ops = {
|
|
692
692
|
exists: existsSync2,
|
|
693
693
|
lstat: lstatSync,
|
|
694
|
-
readdir: (
|
|
694
|
+
readdir: (path2) => readdirSync(path2, { withFileTypes: true }),
|
|
695
695
|
readFile: readFileSync,
|
|
696
696
|
isReparsePoint: () => false,
|
|
697
697
|
listReparsePoints: listWindowsReparsePoints,
|
|
@@ -1328,6 +1328,39 @@ function validateDependencyLock(payloadRoot, expected) {
|
|
|
1328
1328
|
}
|
|
1329
1329
|
if (!foundPackage) throw new Error("installed runner package does not match registry integrity");
|
|
1330
1330
|
}
|
|
1331
|
+
function writeAuthorizedInstallSeed(payloadRoot, tarball, runtimeAuthorization) {
|
|
1332
|
+
const authorization = validateRuntimeAuthorization(runtimeAuthorization);
|
|
1333
|
+
const stagingRoot = resolve4(payloadRoot, "..", "..");
|
|
1334
|
+
const tarballFromStaging = relative3(stagingRoot, resolve4(tarball));
|
|
1335
|
+
if (!tarballFromStaging || tarballFromStaging === ".." || tarballFromStaging.startsWith(`..${sep2}`) || isAbsolute3(tarballFromStaging)) {
|
|
1336
|
+
throw new Error("authorized runtime tarball escaped staging root");
|
|
1337
|
+
}
|
|
1338
|
+
const relativeTarball = relative3(payloadRoot, resolve4(tarball)).replaceAll("\\", "/");
|
|
1339
|
+
if (!relativeTarball || isAbsolute3(relativeTarball) || relativeTarball.includes("\n") || relativeTarball.includes("\r")) {
|
|
1340
|
+
throw new Error("authorized runtime tarball path invalid");
|
|
1341
|
+
}
|
|
1342
|
+
const fileSpec = `file:${relativeTarball}`;
|
|
1343
|
+
const packageRecord = {
|
|
1344
|
+
name: "algohq-runner-runtime",
|
|
1345
|
+
version: "0.0.0",
|
|
1346
|
+
private: true,
|
|
1347
|
+
dependencies: { [PACKAGE_NAME]: fileSpec }
|
|
1348
|
+
};
|
|
1349
|
+
const packages = structuredClone(authorization.dependency_lock.packages);
|
|
1350
|
+
packages[`node_modules/${PACKAGE_NAME}`].resolved = fileSpec;
|
|
1351
|
+
const lock = {
|
|
1352
|
+
name: packageRecord.name,
|
|
1353
|
+
version: packageRecord.version,
|
|
1354
|
+
lockfileVersion: authorization.dependency_lock.source_lockfile_version,
|
|
1355
|
+
requires: true,
|
|
1356
|
+
packages: { "": packageRecord, ...packages }
|
|
1357
|
+
};
|
|
1358
|
+
writeFileSync2(join3(payloadRoot, "package.json"), `${JSON.stringify(packageRecord)}
|
|
1359
|
+
`, { mode: 384 });
|
|
1360
|
+
writeFileSync2(join3(payloadRoot, "package-lock.json"), `${JSON.stringify(lock)}
|
|
1361
|
+
`, { mode: 384 });
|
|
1362
|
+
return { fileSpec, lock };
|
|
1363
|
+
}
|
|
1331
1364
|
function buildActive(slotId, metadata, paths) {
|
|
1332
1365
|
return {
|
|
1333
1366
|
slot_id: slotId,
|
|
@@ -1371,19 +1404,40 @@ function installSlot({
|
|
|
1371
1404
|
let installedSlot = false;
|
|
1372
1405
|
try {
|
|
1373
1406
|
mkdirSync2(payload, { recursive: true });
|
|
1374
|
-
|
|
1407
|
+
let installArgs;
|
|
1408
|
+
if (runtimeAuthorization) {
|
|
1409
|
+
writeAuthorizedInstallSeed(payload, tarball, runtimeAuthorization);
|
|
1410
|
+
installArgs = [
|
|
1411
|
+
"ci",
|
|
1412
|
+
"--ignore-scripts",
|
|
1413
|
+
"--no-bin-links",
|
|
1414
|
+
"--no-audit",
|
|
1415
|
+
"--no-fund",
|
|
1416
|
+
`--registry=${PUBLIC_REGISTRY}`
|
|
1417
|
+
];
|
|
1418
|
+
} else {
|
|
1419
|
+
writeFileSync2(join3(payload, "package.json"), `${JSON.stringify({
|
|
1420
|
+
name: "algohq-runner-runtime",
|
|
1421
|
+
version: "0.0.0",
|
|
1422
|
+
private: true
|
|
1423
|
+
})}
|
|
1375
1424
|
`);
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1425
|
+
installArgs = [
|
|
1426
|
+
"install",
|
|
1427
|
+
"--ignore-scripts",
|
|
1428
|
+
"--no-bin-links",
|
|
1429
|
+
"--no-audit",
|
|
1430
|
+
"--no-fund",
|
|
1431
|
+
"--package-lock=true",
|
|
1432
|
+
"--save-exact",
|
|
1433
|
+
`--registry=${PUBLIC_REGISTRY}`,
|
|
1434
|
+
tarball
|
|
1435
|
+
];
|
|
1436
|
+
}
|
|
1437
|
+
const install = runner.npm(
|
|
1438
|
+
installArgs,
|
|
1439
|
+
{ ...runOptions, cwd: payload, env: npmEnv, timeout: 18e4 }
|
|
1440
|
+
);
|
|
1387
1441
|
if (install.status !== 0) throw new Error(`npm install failed: ${install.stderr || install.error?.message || install.status}`);
|
|
1388
1442
|
assertNoLinks(payload);
|
|
1389
1443
|
validateDependencyLock(payload, metadata);
|
|
@@ -1504,6 +1558,151 @@ function stageAndActivateBundledUpdate(options) {
|
|
|
1504
1558
|
}
|
|
1505
1559
|
}
|
|
1506
1560
|
|
|
1561
|
+
// ../../scripts/virtual-office/code-runner/legacy-orphan-sweep.mjs
|
|
1562
|
+
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
1563
|
+
|
|
1564
|
+
// ../../scripts/virtual-office/code-runner/orphan-agent-reaper.mjs
|
|
1565
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
1566
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readdirSync as readdirSync4, readFileSync as readFileSync5, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
1567
|
+
import os from "node:os";
|
|
1568
|
+
import path from "node:path";
|
|
1569
|
+
function killProcessTree(pid, { platform = process.platform, spawn: spawn2 = spawnSync3 } = {}) {
|
|
1570
|
+
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
1571
|
+
if (platform === "win32") {
|
|
1572
|
+
const r = spawn2("taskkill", ["/PID", String(pid), "/T", "/F"], { windowsHide: true, stdio: "ignore", timeout: 15e3 });
|
|
1573
|
+
return !r.error && r.status === 0;
|
|
1574
|
+
}
|
|
1575
|
+
try {
|
|
1576
|
+
process.kill(-pid, "SIGKILL");
|
|
1577
|
+
return true;
|
|
1578
|
+
} catch {
|
|
1579
|
+
try {
|
|
1580
|
+
process.kill(pid, "SIGKILL");
|
|
1581
|
+
return true;
|
|
1582
|
+
} catch {
|
|
1583
|
+
return false;
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
// ../../scripts/virtual-office/code-runner/legacy-orphan-sweep.mjs
|
|
1589
|
+
var MAX_LEGACY_KILLS = 50;
|
|
1590
|
+
var SWEEP_RECENCY_BUFFER_MS = 5e3;
|
|
1591
|
+
var SIGNATURES = [
|
|
1592
|
+
{
|
|
1593
|
+
signature: "claude-headless",
|
|
1594
|
+
// claude-args.mjs always emits `-p --output-format stream-json --verbose`.
|
|
1595
|
+
test: (cl) => /(?:^|[\\/"\s])claude(?:\.exe|\.cmd|\.ps1)?(?:"|\s)/iu.test(cl) && /--output-format[\s"=]+stream-json/iu.test(cl)
|
|
1596
|
+
},
|
|
1597
|
+
{
|
|
1598
|
+
signature: "codex-headless",
|
|
1599
|
+
// openai-compatible-runner always emits `exec --json`.
|
|
1600
|
+
test: (cl) => /(?:^|[\\/"\s])codex(?:\.exe|\.cmd|\.ps1)?(?:"|\s)/iu.test(cl) && /\bexec\b/u.test(cl) && /--json\b/u.test(cl)
|
|
1601
|
+
}
|
|
1602
|
+
];
|
|
1603
|
+
function matchAgentSignature(commandLine) {
|
|
1604
|
+
if (typeof commandLine !== "string" || !commandLine) return null;
|
|
1605
|
+
for (const { signature, test } of SIGNATURES) {
|
|
1606
|
+
if (test(commandLine)) return signature;
|
|
1607
|
+
}
|
|
1608
|
+
return null;
|
|
1609
|
+
}
|
|
1610
|
+
function selectLegacyOrphans({ processes, cutoffMs, protectedPids = /* @__PURE__ */ new Set() }) {
|
|
1611
|
+
const byPid = /* @__PURE__ */ new Map();
|
|
1612
|
+
for (const proc of processes) {
|
|
1613
|
+
if (Number.isInteger(proc?.pid) && proc.pid > 0) byPid.set(proc.pid, proc);
|
|
1614
|
+
}
|
|
1615
|
+
const kills = [];
|
|
1616
|
+
for (const proc of byPid.values()) {
|
|
1617
|
+
if (protectedPids.has(proc.pid)) continue;
|
|
1618
|
+
if (!(Number.isFinite(proc.creationMs) && proc.creationMs < cutoffMs)) continue;
|
|
1619
|
+
const signature = matchAgentSignature(proc.commandLine);
|
|
1620
|
+
if (!signature) continue;
|
|
1621
|
+
const parent = Number.isInteger(proc.ppid) && proc.ppid > 0 ? byPid.get(proc.ppid) : void 0;
|
|
1622
|
+
const parentDead = !parent || Number.isFinite(parent.creationMs) && parent.creationMs > proc.creationMs;
|
|
1623
|
+
if (!parentDead) continue;
|
|
1624
|
+
kills.push({ pid: proc.pid, creationMs: proc.creationMs, signature, commandLine: proc.commandLine });
|
|
1625
|
+
}
|
|
1626
|
+
kills.sort((a, b) => a.creationMs - b.creationMs);
|
|
1627
|
+
return { kills: kills.slice(0, MAX_LEGACY_KILLS) };
|
|
1628
|
+
}
|
|
1629
|
+
function parsePosixSweepLine(line, nowMs) {
|
|
1630
|
+
const match = /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(.+)$/u.exec(line ?? "");
|
|
1631
|
+
if (!match) return null;
|
|
1632
|
+
const pid = Number(match[1]);
|
|
1633
|
+
if (!Number.isInteger(pid) || pid <= 0) return null;
|
|
1634
|
+
return {
|
|
1635
|
+
pid,
|
|
1636
|
+
ppid: Number(match[2]),
|
|
1637
|
+
creationMs: nowMs - Number(match[3]) * 1e3,
|
|
1638
|
+
commandLine: match[4]
|
|
1639
|
+
};
|
|
1640
|
+
}
|
|
1641
|
+
function listProcessesForSweep({ platform = process.platform, spawn: spawn2 = spawnSync4, nowMs = Date.now() } = {}) {
|
|
1642
|
+
const rows = [];
|
|
1643
|
+
if (platform === "win32") {
|
|
1644
|
+
const ps = "Get-CimInstance Win32_Process | Where-Object { $_.CreationDate } | ForEach-Object { @{ p = $_.ProcessId; pp = $_.ParentProcessId; c = (([DateTimeOffset]$_.CreationDate.ToUniversalTime()).ToUnixTimeMilliseconds()); cl = [string]$_.CommandLine } | ConvertTo-Json -Compress }";
|
|
1645
|
+
const result2 = spawn2("powershell", ["-NoProfile", "-NonInteractive", "-Command", ps], {
|
|
1646
|
+
windowsHide: true,
|
|
1647
|
+
encoding: "utf8",
|
|
1648
|
+
timeout: 3e4,
|
|
1649
|
+
maxBuffer: 64 * 1024 * 1024
|
|
1650
|
+
});
|
|
1651
|
+
if (result2.error || result2.status !== 0) return rows;
|
|
1652
|
+
for (const line of String(result2.stdout ?? "").split(/\r?\n/u)) {
|
|
1653
|
+
if (!line.trim()) continue;
|
|
1654
|
+
try {
|
|
1655
|
+
const parsed = JSON.parse(line);
|
|
1656
|
+
const pid = Number(parsed?.p);
|
|
1657
|
+
if (!Number.isInteger(pid) || pid <= 0) continue;
|
|
1658
|
+
rows.push({
|
|
1659
|
+
pid,
|
|
1660
|
+
ppid: Number(parsed.pp),
|
|
1661
|
+
creationMs: Number(parsed.c),
|
|
1662
|
+
commandLine: typeof parsed.cl === "string" ? parsed.cl : ""
|
|
1663
|
+
});
|
|
1664
|
+
} catch {
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
return rows;
|
|
1668
|
+
}
|
|
1669
|
+
const result = spawn2("ps", ["-eo", "pid=,ppid=,etimes=,args="], { encoding: "utf8", timeout: 3e4, maxBuffer: 64 * 1024 * 1024 });
|
|
1670
|
+
if (result.error || result.status !== 0) return rows;
|
|
1671
|
+
for (const line of String(result.stdout ?? "").split("\n")) {
|
|
1672
|
+
const row = parsePosixSweepLine(line, nowMs);
|
|
1673
|
+
if (row) rows.push(row);
|
|
1674
|
+
}
|
|
1675
|
+
return rows;
|
|
1676
|
+
}
|
|
1677
|
+
function runLegacyOrphanSweep({
|
|
1678
|
+
nowMs = Date.now(),
|
|
1679
|
+
protectedPids = [process.pid],
|
|
1680
|
+
listProcesses = listProcessesForSweep,
|
|
1681
|
+
killTree = killProcessTree,
|
|
1682
|
+
log = () => {
|
|
1683
|
+
}
|
|
1684
|
+
} = {}) {
|
|
1685
|
+
try {
|
|
1686
|
+
const processes = listProcesses({ nowMs });
|
|
1687
|
+
const { kills } = selectLegacyOrphans({
|
|
1688
|
+
processes,
|
|
1689
|
+
cutoffMs: nowMs - SWEEP_RECENCY_BUFFER_MS,
|
|
1690
|
+
protectedPids: new Set(protectedPids)
|
|
1691
|
+
});
|
|
1692
|
+
const killed = [];
|
|
1693
|
+
for (const kill of kills) {
|
|
1694
|
+
const done = killTree(kill.pid);
|
|
1695
|
+
log(`legacy-orphan-sweep ${done ? "killed" : "FAILED to kill"} pid=${kill.pid} sig=${kill.signature} cmd=${String(kill.commandLine).slice(0, 200)}`);
|
|
1696
|
+
if (done) killed.push({ pid: kill.pid, signature: kill.signature });
|
|
1697
|
+
}
|
|
1698
|
+
const failed2 = kills.length - killed.length;
|
|
1699
|
+
const detail = kills.length === 0 ? `no orphaned agent processes matched the sweep criteria (${processes.length} scanned)` : `purged ${killed.length} of ${kills.length} orphaned agent process tree(s)${failed2 > 0 ? ` (${failed2} kill(s) failed)` : ""}: ${killed.map((k) => `${k.pid}:${k.signature}`).join(", ").slice(0, 700)}`;
|
|
1700
|
+
return { ok: true, status: 0, detail, killed };
|
|
1701
|
+
} catch (error) {
|
|
1702
|
+
return { ok: false, status: 1, detail: `legacy sweep error: ${error instanceof Error ? error.message : String(error)}`.slice(0, 500), killed: [] };
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1507
1706
|
// src/runner/supervisor-activation.mjs
|
|
1508
1707
|
var MAX_ACK_ATTEMPTS = 3;
|
|
1509
1708
|
var delay = (ms) => new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
@@ -1859,18 +2058,18 @@ async function prepareSupervisorAuth({
|
|
|
1859
2058
|
}
|
|
1860
2059
|
|
|
1861
2060
|
// src/runner/supervisor-credential-reader.mjs
|
|
1862
|
-
import { spawnSync as
|
|
1863
|
-
import { existsSync as
|
|
2061
|
+
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
2062
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
1864
2063
|
import { dirname as dirname3, join as join4 } from "node:path";
|
|
1865
2064
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
1866
2065
|
function defaultCredentialHelperPath(metaUrl = import.meta.url) {
|
|
1867
2066
|
const moduleDir = dirname3(fileURLToPath2(metaUrl));
|
|
1868
2067
|
const bundled = join4(moduleDir, "supervisor-credential-helper.js");
|
|
1869
2068
|
const source = join4(moduleDir, "..", "supervisor-credential-helper.mjs");
|
|
1870
|
-
return
|
|
2069
|
+
return existsSync6(source) ? source : bundled;
|
|
1871
2070
|
}
|
|
1872
2071
|
function readStoredCredentialIsolated({
|
|
1873
|
-
spawn: spawn2 =
|
|
2072
|
+
spawn: spawn2 = spawnSync5,
|
|
1874
2073
|
execPath = process.execPath,
|
|
1875
2074
|
helperPath = defaultCredentialHelperPath(),
|
|
1876
2075
|
helperArgs = [],
|
|
@@ -1899,7 +2098,7 @@ function readStoredCredentialIsolated({
|
|
|
1899
2098
|
var DEFAULT_CONTROL_PLANE_URL = "https://vo-control-plane-bzjphrajaq-uc.a.run.app";
|
|
1900
2099
|
var POLL_MS = 5e3;
|
|
1901
2100
|
var CHILD_START_MS = 1500;
|
|
1902
|
-
var SUPERVISOR_CAPABILITIES = ["bundled-runtime-slots-v1"];
|
|
2101
|
+
var SUPERVISOR_CAPABILITIES = ["bundled-runtime-slots-v1", "legacy-orphan-purge-v1"];
|
|
1903
2102
|
var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
|
|
1904
2103
|
var selfPath = fileURLToPath3(import.meta.url);
|
|
1905
2104
|
var childEntry = join5(dirname4(selfPath), "runner-cli.js");
|
|
@@ -2062,6 +2261,9 @@ async function main() {
|
|
|
2062
2261
|
},
|
|
2063
2262
|
env: process.env,
|
|
2064
2263
|
force: action.kind === "reinstall"
|
|
2264
|
+
}) : action.kind === "purge-orphans" ? runLegacyOrphanSweep({
|
|
2265
|
+
protectedPids: [process.pid],
|
|
2266
|
+
log: (message) => console.warn(`[vo-runner supervisor] ${message}`)
|
|
2065
2267
|
}) : runHostMaintenance(action.kind, {
|
|
2066
2268
|
env: clientEnv,
|
|
2067
2269
|
log: (message) => console.warn(`[vo-runner supervisor] ${message}`)
|
|
@@ -2078,7 +2280,7 @@ async function main() {
|
|
|
2078
2280
|
...operatorId ? { operatorId } : {},
|
|
2079
2281
|
...supervisorControlIdentity,
|
|
2080
2282
|
status: result.ok ? "succeeded" : "failed",
|
|
2081
|
-
detail: result.ok ? `runner ${packageVersion()} reconnected` : `maintenance exited ${result.status}${result.detail ? `: ${result.detail}` : ""}`
|
|
2283
|
+
detail: result.ok ? result.detail ? `${result.detail}; runner ${packageVersion()} reconnected`.slice(0, 1e3) : `runner ${packageVersion()} reconnected` : `maintenance exited ${result.status}${result.detail ? `: ${result.detail}` : ""}`
|
|
2082
2284
|
});
|
|
2083
2285
|
handling = false;
|
|
2084
2286
|
} catch (error) {
|