@algosuite/vo-mcp 0.2.0-beta.72 → 0.2.0-beta.73
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/agent-auth-probe-cli.mjs +18 -0
- package/dist/cli.js +110 -8
- package/dist/cli.js.map +2 -2
- package/dist/index.js +110 -8
- package/dist/index.js.map +2 -2
- package/dist/runner-cli.js +1677 -1058
- package/dist/runner-cli.js.map +3 -3
- package/dist/runner-supervisor.js +116 -57
- package/dist/runner-supervisor.js.map +3 -3
- package/package.json +1 -1
|
@@ -32,7 +32,7 @@ var init_control_plane_auth_stub = __esm({
|
|
|
32
32
|
// src/runner-supervisor.mjs
|
|
33
33
|
import { spawn } from "node:child_process";
|
|
34
34
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
35
|
-
import { createRequire } from "node:module";
|
|
35
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
36
36
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
37
37
|
import { dirname as dirname4, join as join5 } from "node:path";
|
|
38
38
|
|
|
@@ -61,6 +61,60 @@ async function fetchInstallationToken({ req, required = false, readOnly = false,
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
// ../../scripts/virtual-office/code-runner/claude-credential-choice.mjs
|
|
65
|
+
var CLAUDE_CREDENTIAL_SOURCE = Object.freeze({
|
|
66
|
+
/** PREFER_LOGIN set (and not overridden): any API key is ignored. */
|
|
67
|
+
PREFER_LOGIN: "prefer_login",
|
|
68
|
+
/** An explicit ANTHROPIC_API_KEY in the environment — the manual override. */
|
|
69
|
+
ENV_KEY: "env_key",
|
|
70
|
+
/** No key anywhere; the spawn falls through to the login session. */
|
|
71
|
+
NO_KEY: "no_key",
|
|
72
|
+
/** A stored key, used because the operator explicitly opted out of tier 1. */
|
|
73
|
+
KEYCHAIN_PREFER_KEY: "keychain_prefer_key",
|
|
74
|
+
/** A stored key exists but a proven live subscription outranks it. */
|
|
75
|
+
SUBSCRIPTION_WINS: "subscription_wins",
|
|
76
|
+
/** A stored key, used because no live subscription was proven. */
|
|
77
|
+
KEYCHAIN: "keychain"
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// ../../scripts/virtual-office/code-runner/anthropic-key-store.mjs
|
|
81
|
+
import { createRequire } from "node:module";
|
|
82
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
83
|
+
|
|
84
|
+
// ../../scripts/virtual-office/code-runner/windows-claude-launch.mjs
|
|
85
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
86
|
+
import { win32 as path } from "node:path";
|
|
87
|
+
import { spawnSync } from "node:child_process";
|
|
88
|
+
|
|
89
|
+
// ../../scripts/virtual-office/code-runner/anthropic-key-store.mjs
|
|
90
|
+
var require2 = createRequire(import.meta.url);
|
|
91
|
+
var AUTH_SOURCE_DESCRIPTION = Object.freeze({
|
|
92
|
+
[CLAUDE_CREDENTIAL_SOURCE.PREFER_LOGIN]: "claude auth login (VO_RUNNER_PREFER_LOGIN set \u2014 any API key ignored)",
|
|
93
|
+
[CLAUDE_CREDENTIAL_SOURCE.ENV_KEY]: "ANTHROPIC_API_KEY from environment",
|
|
94
|
+
[CLAUDE_CREDENTIAL_SOURCE.NO_KEY]: "claude auth login session (no API key set)",
|
|
95
|
+
[CLAUDE_CREDENTIAL_SOURCE.KEYCHAIN_PREFER_KEY]: "ANTHROPIC_API_KEY from OS keychain (VO_RUNNER_PREFER_KEY set \u2014 subscription ignored)",
|
|
96
|
+
[CLAUDE_CREDENTIAL_SOURCE.SUBSCRIPTION_WINS]: "claude auth login session (subscription beats the stored keychain key)",
|
|
97
|
+
[CLAUDE_CREDENTIAL_SOURCE.KEYCHAIN]: "ANTHROPIC_API_KEY from OS keychain"
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// ../../scripts/virtual-office/code-runner/agent-auth-attestation.mjs
|
|
101
|
+
var AGENT_AUTH_SOURCE = Object.freeze({
|
|
102
|
+
/** A flat-cost linked account (`claude auth login`). No per-token vendor bill. */
|
|
103
|
+
LOGIN: "login",
|
|
104
|
+
/** A metered per-token credential the vendor bills. */
|
|
105
|
+
API_KEY: "api_key"
|
|
106
|
+
});
|
|
107
|
+
var AGENT_AUTH_SOURCES = Object.freeze([
|
|
108
|
+
AGENT_AUTH_SOURCE.LOGIN,
|
|
109
|
+
AGENT_AUTH_SOURCE.API_KEY
|
|
110
|
+
]);
|
|
111
|
+
var API_BILLING_ENV_NAMES = Object.freeze([
|
|
112
|
+
"ANTHROPIC_API_KEY",
|
|
113
|
+
"ANTHROPIC_AUTH_TOKEN",
|
|
114
|
+
"CLAUDE_API_KEY"
|
|
115
|
+
]);
|
|
116
|
+
var API_BILLING_ENV_NAME_SET = new Set(API_BILLING_ENV_NAMES);
|
|
117
|
+
|
|
64
118
|
// ../../scripts/virtual-office/code-runner/control-plane-heartbeat-body.mjs
|
|
65
119
|
function buildRunnerHeartbeatBody({
|
|
66
120
|
runnerId: runnerId2,
|
|
@@ -86,6 +140,8 @@ function buildRunnerHeartbeatBody({
|
|
|
86
140
|
accountUsage,
|
|
87
141
|
availableLocalModels,
|
|
88
142
|
supportedTaskKinds,
|
|
143
|
+
hostHealth,
|
|
144
|
+
agentAuthSource,
|
|
89
145
|
prepared_job_shadow: preparedJobShadow
|
|
90
146
|
} = {}) {
|
|
91
147
|
const body = { runner_id: runnerId2, ...preparedJobShadow ? { prepared_job_shadow: preparedJobShadow } : {} };
|
|
@@ -123,6 +179,8 @@ function buildRunnerHeartbeatBody({
|
|
|
123
179
|
if (Array.isArray(supportedTaskKinds) && supportedTaskKinds.length > 0) {
|
|
124
180
|
body.supported_task_kinds = supportedTaskKinds;
|
|
125
181
|
}
|
|
182
|
+
if (hostHealth && typeof hostHealth === "object") body.host_health = hostHealth;
|
|
183
|
+
if (AGENT_AUTH_SOURCES.includes(agentAuthSource)) body.agent_auth_source = agentAuthSource;
|
|
126
184
|
return body;
|
|
127
185
|
}
|
|
128
186
|
|
|
@@ -381,13 +439,13 @@ async function getTaskKnowledgeContextRequest(req, taskId, { query, knowledgeReq
|
|
|
381
439
|
const canonicalQuery = canonicalizeKnowledgeContextQuery(query);
|
|
382
440
|
if (canonicalQuery.trim()) body.query = canonicalQuery;
|
|
383
441
|
if (typeof knowledgeRequestId === "string" && knowledgeRequestId) body.knowledge_request_id = knowledgeRequestId;
|
|
384
|
-
const
|
|
442
|
+
const path3 = `/api/v1/code-task/${encodeURIComponent(taskId)}/knowledge-context`;
|
|
385
443
|
const timeoutMs = Math.max(Number(taskRequestTimeoutMs) || 0, MIN_KNOWLEDGE_CONTEXT_TIMEOUT_MS);
|
|
386
444
|
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt += 1) {
|
|
387
445
|
let res;
|
|
388
446
|
let cause;
|
|
389
447
|
try {
|
|
390
|
-
res = await req("POST",
|
|
448
|
+
res = await req("POST", path3, body, { timeoutMs });
|
|
391
449
|
} catch (err) {
|
|
392
450
|
cause = err;
|
|
393
451
|
}
|
|
@@ -456,10 +514,10 @@ async function getPreparedJobRequest(req, taskId, options = {}, invalidateToken
|
|
|
456
514
|
if (typeof taskId !== "string" || taskId.length === 0) {
|
|
457
515
|
return { ok: false, reason: "missing_task_id", status: 0, ...envMeta };
|
|
458
516
|
}
|
|
459
|
-
const
|
|
517
|
+
const path3 = `/api/v1/code-task/${encodeURIComponent(taskId)}/prepared-job?${query}`;
|
|
460
518
|
let res;
|
|
461
519
|
try {
|
|
462
|
-
res = await req("GET",
|
|
520
|
+
res = await req("GET", path3, void 0, { timeoutMs });
|
|
463
521
|
} catch (err) {
|
|
464
522
|
return { ok: false, reason: `transport: ${err?.message || String(err)}`, status: 0, ...envMeta };
|
|
465
523
|
}
|
|
@@ -535,11 +593,11 @@ function createControlPlaneClient({
|
|
|
535
593
|
if (!resolvedBaseUrl) throw new Error("VO_CONTROL_PLANE_URL is required for the code-runner daemon");
|
|
536
594
|
const root = resolvedBaseUrl.replace(/\/+$/, "");
|
|
537
595
|
const claimOccurrences = /* @__PURE__ */ new Map();
|
|
538
|
-
async function req(method,
|
|
596
|
+
async function req(method, path3, body, { timeoutMs } = {}) {
|
|
539
597
|
const bearer = await resolveBearer(env);
|
|
540
598
|
const controller = timeoutMs ? new AbortController() : null;
|
|
541
599
|
let timeoutId;
|
|
542
|
-
const request = Promise.resolve(fetchImpl(`${root}${
|
|
600
|
+
const request = Promise.resolve(fetchImpl(`${root}${path3}`, {
|
|
543
601
|
method,
|
|
544
602
|
headers: {
|
|
545
603
|
"content-type": "application/json",
|
|
@@ -552,7 +610,7 @@ function createControlPlaneClient({
|
|
|
552
610
|
const timeout = new Promise((_, reject) => {
|
|
553
611
|
timeoutId = setTimeout(() => {
|
|
554
612
|
controller.abort();
|
|
555
|
-
reject(new Error(`control-plane ${
|
|
613
|
+
reject(new Error(`control-plane ${path3} timed out after ${timeoutMs}ms`));
|
|
556
614
|
}, timeoutMs);
|
|
557
615
|
});
|
|
558
616
|
try {
|
|
@@ -561,7 +619,7 @@ function createControlPlaneClient({
|
|
|
561
619
|
clearTimeout(timeoutId);
|
|
562
620
|
}
|
|
563
621
|
}
|
|
564
|
-
const taskReq = (method,
|
|
622
|
+
const taskReq = (method, path3, body, options = {}) => req(method, path3, body, { timeoutMs: taskRequestTimeoutMs, ...options });
|
|
565
623
|
const claimGate = makeClaimGateNotice({ log: (m) => console.warn(`[code-runner ${(/* @__PURE__ */ new Date()).toISOString()}] ${m}`) });
|
|
566
624
|
return {
|
|
567
625
|
getClaimGate: () => claimGate.current(),
|
|
@@ -590,6 +648,7 @@ function createControlPlaneClient({
|
|
|
590
648
|
}
|
|
591
649
|
if (session.runnerInstanceId && session.reconcileStale) body.reconcile_stale = true;
|
|
592
650
|
if (session.defaultAgent) body.default_agent = session.defaultAgent;
|
|
651
|
+
if (AGENT_AUTH_SOURCES.includes(session.agentAuthSource)) body.agent_auth_source = session.agentAuthSource;
|
|
593
652
|
if (Array.isArray(session.availableAgents)) {
|
|
594
653
|
body.available_agents = session.availableAgents.filter((entry) => entry?.installed === true && entry?.authenticated === true).map((entry) => entry.agent);
|
|
595
654
|
}
|
|
@@ -732,8 +791,8 @@ function createControlPlaneClient({
|
|
|
732
791
|
return listAllPrOpenedTasks(taskReq);
|
|
733
792
|
},
|
|
734
793
|
async downloadTaskAttachment(taskId, attachmentId) {
|
|
735
|
-
const
|
|
736
|
-
const res = await taskReq("GET",
|
|
794
|
+
const path3 = `/api/v1/code-task/${encodeURIComponent(taskId)}/attachment/${encodeURIComponent(attachmentId)}`;
|
|
795
|
+
const res = await taskReq("GET", path3);
|
|
737
796
|
if (res.status === 401) cachedFirebaseToken = null;
|
|
738
797
|
if (!res.ok) throw new Error(`attachment download failed: HTTP ${res.status}`);
|
|
739
798
|
return Buffer.from(await res.arrayBuffer());
|
|
@@ -864,8 +923,8 @@ function createControlPlaneClient({
|
|
|
864
923
|
}
|
|
865
924
|
|
|
866
925
|
// ../../scripts/virtual-office/code-runner/runner-host-maintenance.mjs
|
|
867
|
-
import { spawnSync } from "node:child_process";
|
|
868
|
-
import { existsSync } from "node:fs";
|
|
926
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
927
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
869
928
|
import { win32 } from "node:path";
|
|
870
929
|
var DEFAULT_RUNNER_PACKAGE = "@algosuite/vo-mcp@beta";
|
|
871
930
|
var PACKAGE_SPEC_RE = /^@algosuite\/vo-mcp@(beta|latest|\d+(?:\.\d+){0,2}(?:-[\w.-]+)?)$/u;
|
|
@@ -892,7 +951,7 @@ function isNpmCliPath(value) {
|
|
|
892
951
|
function resolveNpmCli({
|
|
893
952
|
env = process.env,
|
|
894
953
|
execPath = process.execPath,
|
|
895
|
-
fileExists =
|
|
954
|
+
fileExists = existsSync2
|
|
896
955
|
} = {}) {
|
|
897
956
|
const candidates = [];
|
|
898
957
|
if (isNpmCliPath(env.npm_execpath)) candidates.push(env.npm_execpath);
|
|
@@ -918,7 +977,7 @@ function buildMaintenanceCommand(kind, {
|
|
|
918
977
|
packageSpec = DEFAULT_RUNNER_PACKAGE,
|
|
919
978
|
env = process.env,
|
|
920
979
|
execPath = process.execPath,
|
|
921
|
-
fileExists =
|
|
980
|
+
fileExists = existsSync2
|
|
922
981
|
} = {}) {
|
|
923
982
|
if (!["update", "reinstall"].includes(kind)) return null;
|
|
924
983
|
if (!PACKAGE_SPEC_RE.test(packageSpec)) throw new Error("unsafe runner package spec");
|
|
@@ -934,8 +993,8 @@ function runHostMaintenance(kind, {
|
|
|
934
993
|
packageSpec = DEFAULT_RUNNER_PACKAGE,
|
|
935
994
|
env = process.env,
|
|
936
995
|
execPath = process.execPath,
|
|
937
|
-
fileExists =
|
|
938
|
-
spawn: spawn2 =
|
|
996
|
+
fileExists = existsSync2,
|
|
997
|
+
spawn: spawn2 = spawnSync3,
|
|
939
998
|
log = () => {
|
|
940
999
|
}
|
|
941
1000
|
} = {}) {
|
|
@@ -973,7 +1032,7 @@ function runHostMaintenance(kind, {
|
|
|
973
1032
|
// src/runner/bundled-runtime-updater.mjs
|
|
974
1033
|
import { createHash as createHash4, randomUUID as randomUUID2 } from "node:crypto";
|
|
975
1034
|
import {
|
|
976
|
-
existsSync as
|
|
1035
|
+
existsSync as existsSync5,
|
|
977
1036
|
lstatSync as lstatSync3,
|
|
978
1037
|
mkdirSync as mkdirSync2,
|
|
979
1038
|
readFileSync as readFileSync4,
|
|
@@ -983,7 +1042,7 @@ import {
|
|
|
983
1042
|
writeFileSync as writeFileSync2
|
|
984
1043
|
} from "node:fs";
|
|
985
1044
|
import { basename, isAbsolute as isAbsolute3, join as join3, relative as relative3, resolve as resolve4, sep as sep2 } from "node:path";
|
|
986
|
-
import { spawnSync as
|
|
1045
|
+
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
987
1046
|
|
|
988
1047
|
// ../../scripts/virtual-office/runner-bootstrap/runtime-authorization.mjs
|
|
989
1048
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -995,7 +1054,7 @@ import { fileURLToPath } from "node:url";
|
|
|
995
1054
|
import { execFileSync } from "node:child_process";
|
|
996
1055
|
import { createHash } from "node:crypto";
|
|
997
1056
|
import {
|
|
998
|
-
existsSync as
|
|
1057
|
+
existsSync as existsSync3,
|
|
999
1058
|
lstatSync,
|
|
1000
1059
|
readFileSync,
|
|
1001
1060
|
readdirSync
|
|
@@ -1118,10 +1177,10 @@ function validateLock(lock, authorization) {
|
|
|
1118
1177
|
}
|
|
1119
1178
|
return { actual, expected };
|
|
1120
1179
|
}
|
|
1121
|
-
function checkPathKind(
|
|
1122
|
-
if (!fsOps.exists(
|
|
1123
|
-
const stats = fsOps.lstat(
|
|
1124
|
-
if (isReparseStat(stats) || fsOps.isReparsePoint(
|
|
1180
|
+
function checkPathKind(path3, expectedKind, fsOps, label) {
|
|
1181
|
+
if (!fsOps.exists(path3)) throw new Error(`staged runtime ${label} missing`);
|
|
1182
|
+
const stats = fsOps.lstat(path3);
|
|
1183
|
+
if (isReparseStat(stats) || fsOps.isReparsePoint(path3, stats)) {
|
|
1125
1184
|
throw new Error(`staged runtime ${label} is a reparse point`);
|
|
1126
1185
|
}
|
|
1127
1186
|
if (expectedKind === "directory" && !stats.isDirectory()) {
|
|
@@ -1139,30 +1198,30 @@ function verifyInstalledPackages(payloadRoot, packageRecords, platform, fsOps) {
|
|
|
1139
1198
|
const omitted = [];
|
|
1140
1199
|
let installed = 0;
|
|
1141
1200
|
for (const [key, entry] of Object.entries(packageRecords)) {
|
|
1142
|
-
const
|
|
1143
|
-
assertContained(payloadRoot,
|
|
1201
|
+
const path3 = resolve(payloadRoot, key);
|
|
1202
|
+
assertContained(payloadRoot, path3, "package path");
|
|
1144
1203
|
const shouldOmit = isOmittedOptionalPackage(entry, platform);
|
|
1145
1204
|
if (shouldOmit) {
|
|
1146
1205
|
omitted.push(key);
|
|
1147
|
-
if (fsOps.exists(
|
|
1206
|
+
if (fsOps.exists(path3)) throw new Error(`staged runtime optional package should be omitted: ${key}`);
|
|
1148
1207
|
continue;
|
|
1149
1208
|
}
|
|
1150
|
-
checkPathKind(
|
|
1209
|
+
checkPathKind(path3, "directory", fsOps, `installed package ${key}`);
|
|
1151
1210
|
installed += 1;
|
|
1152
1211
|
}
|
|
1153
1212
|
return { installed, omitted: omitted.sort() };
|
|
1154
1213
|
}
|
|
1155
|
-
function treeRecord(kind,
|
|
1156
|
-
if (kind === "d") return `d ${
|
|
1214
|
+
function treeRecord(kind, path3, stats, fileHash = "") {
|
|
1215
|
+
if (kind === "d") return `d ${path3}\r
|
|
1157
1216
|
`;
|
|
1158
|
-
return `f ${
|
|
1217
|
+
return `f ${path3} ${stats.size} ${fileHash}\r
|
|
1159
1218
|
`;
|
|
1160
1219
|
}
|
|
1161
1220
|
function computeInstalledTree(nodeModulesRoot, fsOps = {}) {
|
|
1162
1221
|
const ops = {
|
|
1163
|
-
exists:
|
|
1222
|
+
exists: existsSync3,
|
|
1164
1223
|
lstat: lstatSync,
|
|
1165
|
-
readdir: (
|
|
1224
|
+
readdir: (path3) => readdirSync(path3, { withFileTypes: true }),
|
|
1166
1225
|
readFile: readFileSync,
|
|
1167
1226
|
isReparsePoint: () => false,
|
|
1168
1227
|
listReparsePoints: listWindowsReparsePoints,
|
|
@@ -1232,7 +1291,7 @@ function compareStagedRuntime({
|
|
|
1232
1291
|
throw new Error("staged runtime paths do not identify one canonical payload");
|
|
1233
1292
|
}
|
|
1234
1293
|
const ops = {
|
|
1235
|
-
exists:
|
|
1294
|
+
exists: existsSync3,
|
|
1236
1295
|
lstat: lstatSync,
|
|
1237
1296
|
readFile: readFileSync,
|
|
1238
1297
|
isReparsePoint: () => false,
|
|
@@ -1406,14 +1465,14 @@ if (process.argv[1] && resolve2(process.argv[1]) === fileURLToPath(import.meta.u
|
|
|
1406
1465
|
import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
1407
1466
|
import {
|
|
1408
1467
|
closeSync,
|
|
1409
|
-
existsSync as
|
|
1468
|
+
existsSync as existsSync4,
|
|
1410
1469
|
fsyncSync,
|
|
1411
1470
|
lstatSync as lstatSync2,
|
|
1412
1471
|
mkdirSync,
|
|
1413
1472
|
openSync,
|
|
1414
1473
|
readFileSync as readFileSync3,
|
|
1415
1474
|
readdirSync as readdirSync2,
|
|
1416
|
-
realpathSync,
|
|
1475
|
+
realpathSync as realpathSync2,
|
|
1417
1476
|
renameSync,
|
|
1418
1477
|
rmSync,
|
|
1419
1478
|
writeFileSync
|
|
@@ -1517,7 +1576,7 @@ function atomicWriteJson(file, value) {
|
|
|
1517
1576
|
}
|
|
1518
1577
|
function readActivation(runtimeRoot) {
|
|
1519
1578
|
const file = join2(runtimeRoot, "current.json");
|
|
1520
|
-
if (!
|
|
1579
|
+
if (!existsSync4(file)) return null;
|
|
1521
1580
|
try {
|
|
1522
1581
|
const value = JSON.parse(readFileSync3(file, "utf8"));
|
|
1523
1582
|
return value?.schema_version === 1 ? value : null;
|
|
@@ -1563,7 +1622,7 @@ function validateSlot(runtimeRoot, active) {
|
|
|
1563
1622
|
if (lstatSync2(paths.entry).isSymbolicLink() || lstatSync2(paths.supervisor).isSymbolicLink() || lstatSync2(paths.credentialHelper).isSymbolicLink()) {
|
|
1564
1623
|
return { ok: false, detail: "runtime entry cannot be a link" };
|
|
1565
1624
|
}
|
|
1566
|
-
if (!within(paths.slotRoot,
|
|
1625
|
+
if (!within(paths.slotRoot, realpathSync2(paths.entry)) || !within(paths.slotRoot, realpathSync2(paths.supervisor)) || !within(paths.slotRoot, realpathSync2(paths.credentialHelper))) {
|
|
1567
1626
|
return { ok: false, detail: "runtime entry escaped its slot" };
|
|
1568
1627
|
}
|
|
1569
1628
|
if (hashFileSha512(paths.entry) !== active.entry_sha512) return { ok: false, detail: "entry hash mismatch" };
|
|
@@ -1636,7 +1695,7 @@ function attestCurrentSupervisor({ runtimeRoot, selfPath: selfPath2, version })
|
|
|
1636
1695
|
const validated = validateSlot(runtimeRoot, pointer.active);
|
|
1637
1696
|
if (!validated.ok) return validated;
|
|
1638
1697
|
try {
|
|
1639
|
-
if (
|
|
1698
|
+
if (realpathSync2(selfPath2) !== realpathSync2(validated.paths.supervisor)) {
|
|
1640
1699
|
return { ok: false, detail: "running supervisor is not the activated supervisor" };
|
|
1641
1700
|
}
|
|
1642
1701
|
} catch {
|
|
@@ -1749,7 +1808,7 @@ function buildMinimalMaintenanceEnv(env = process.env, runtimeRoot = "") {
|
|
|
1749
1808
|
};
|
|
1750
1809
|
}
|
|
1751
1810
|
function defaultRun(command, args, options) {
|
|
1752
|
-
return
|
|
1811
|
+
return spawnSync4(command, args, {
|
|
1753
1812
|
cwd: options.cwd,
|
|
1754
1813
|
encoding: "utf8",
|
|
1755
1814
|
env: options.env,
|
|
@@ -1874,7 +1933,7 @@ function installSlot({
|
|
|
1874
1933
|
const suffix = force ? `${digest}-${randomUUID2().slice(0, 8)}` : digest;
|
|
1875
1934
|
const slotId = `vo-mcp-${metadata.version}-${suffix}`;
|
|
1876
1935
|
const finalPaths = slotPaths(runtimeRoot, slotId);
|
|
1877
|
-
if (!force &&
|
|
1936
|
+
if (!force && existsSync5(finalPaths.slotRoot)) {
|
|
1878
1937
|
const manifest = JSON.parse(readFileSync4(finalPaths.manifest, "utf8"));
|
|
1879
1938
|
const active = buildActive(slotId, metadata, finalPaths);
|
|
1880
1939
|
const validated = validateSlot(runtimeRoot, active);
|
|
@@ -1950,7 +2009,7 @@ function installSlot({
|
|
|
1950
2009
|
const active = buildActive(slotId, metadata, stagedPaths);
|
|
1951
2010
|
atomicWriteJson(join3(payload, "runtime-manifest.json"), { schema_version: 1, ...active });
|
|
1952
2011
|
mkdirSync2(join3(runtimeRoot, "slots"), { recursive: true });
|
|
1953
|
-
if (
|
|
2012
|
+
if (existsSync5(finalPaths.slotRoot)) throw new Error("immutable runtime slot already exists");
|
|
1954
2013
|
renameSync2(payload, finalPaths.slotRoot);
|
|
1955
2014
|
installedSlot = true;
|
|
1956
2015
|
const validated = validateSlot(runtimeRoot, active);
|
|
@@ -1972,7 +2031,7 @@ function stageBundledRuntimeSlot(options) {
|
|
|
1972
2031
|
platform = process.platform,
|
|
1973
2032
|
execPath = process.execPath,
|
|
1974
2033
|
env = process.env,
|
|
1975
|
-
fileExists =
|
|
2034
|
+
fileExists = existsSync5,
|
|
1976
2035
|
run = defaultRun,
|
|
1977
2036
|
force = false,
|
|
1978
2037
|
runtimeAuthorization = null
|
|
@@ -2010,7 +2069,7 @@ function stageBundledRuntimeSlot(options) {
|
|
|
2010
2069
|
], runOptions), "npm pack");
|
|
2011
2070
|
const record = Array.isArray(packed) ? packed[0] : packed;
|
|
2012
2071
|
const tarball = join3(tarDir, basename(String(record?.filename || "")));
|
|
2013
|
-
if (!
|
|
2072
|
+
if (!existsSync5(tarball) || !basename(tarball).endsWith(".tgz")) throw new Error("npm pack returned no tarball");
|
|
2014
2073
|
if (lstatSync3(tarball).size > MAX_TARBALL_BYTES) throw new Error("runner package tarball exceeds size limit");
|
|
2015
2074
|
if (record.integrity !== metadata.integrity || tarballIntegrity(tarball) !== metadata.integrity) {
|
|
2016
2075
|
throw new Error("runner package sha512 integrity mismatch");
|
|
@@ -2048,23 +2107,23 @@ function stageAndActivateBundledUpdate(options) {
|
|
|
2048
2107
|
}
|
|
2049
2108
|
|
|
2050
2109
|
// ../../scripts/virtual-office/code-runner/legacy-orphan-sweep.mjs
|
|
2051
|
-
import { spawnSync as
|
|
2110
|
+
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
2052
2111
|
|
|
2053
2112
|
// ../../scripts/virtual-office/code-runner/orphan-agent-reaper.mjs
|
|
2054
|
-
import { spawnSync as
|
|
2055
|
-
import { existsSync as
|
|
2113
|
+
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
2114
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3, readdirSync as readdirSync4, readFileSync as readFileSync5, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
2056
2115
|
import os from "node:os";
|
|
2057
|
-
import
|
|
2116
|
+
import path2 from "node:path";
|
|
2058
2117
|
function windowsSystemRoot(env = process.env) {
|
|
2059
2118
|
return env.SystemRoot || env.WINDIR || "C:\\Windows";
|
|
2060
2119
|
}
|
|
2061
2120
|
function windowsPowershellExe(env = process.env) {
|
|
2062
|
-
return
|
|
2121
|
+
return path2.join(windowsSystemRoot(env), "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
|
|
2063
2122
|
}
|
|
2064
|
-
function killProcessTree(pid, { platform = process.platform, spawn: spawn2 =
|
|
2123
|
+
function killProcessTree(pid, { platform = process.platform, spawn: spawn2 = spawnSync5, env = process.env } = {}) {
|
|
2065
2124
|
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
2066
2125
|
if (platform === "win32") {
|
|
2067
|
-
const taskkill =
|
|
2126
|
+
const taskkill = path2.join(windowsSystemRoot(env), "System32", "taskkill.exe");
|
|
2068
2127
|
const r = spawn2(taskkill, ["/PID", String(pid), "/T", "/F"], { windowsHide: true, stdio: "ignore", timeout: 15e3 });
|
|
2069
2128
|
return !r.error && r.status === 0;
|
|
2070
2129
|
}
|
|
@@ -2134,7 +2193,7 @@ function parsePosixSweepLine(line, nowMs) {
|
|
|
2134
2193
|
commandLine: match[4]
|
|
2135
2194
|
};
|
|
2136
2195
|
}
|
|
2137
|
-
function listProcessesForSweep({ platform = process.platform, spawn: spawn2 =
|
|
2196
|
+
function listProcessesForSweep({ platform = process.platform, spawn: spawn2 = spawnSync6, nowMs = Date.now(), env = process.env, warn = console.warn } = {}) {
|
|
2138
2197
|
const rows = [];
|
|
2139
2198
|
if (platform === "win32") {
|
|
2140
2199
|
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 }";
|
|
@@ -2941,18 +3000,18 @@ async function prepareSupervisorAuth({
|
|
|
2941
3000
|
}
|
|
2942
3001
|
|
|
2943
3002
|
// src/runner/supervisor-credential-reader.mjs
|
|
2944
|
-
import { spawnSync as
|
|
2945
|
-
import { existsSync as
|
|
3003
|
+
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
3004
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
2946
3005
|
import { dirname as dirname3, join as join4 } from "node:path";
|
|
2947
3006
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
2948
3007
|
function defaultCredentialHelperPath(metaUrl = import.meta.url) {
|
|
2949
3008
|
const moduleDir = dirname3(fileURLToPath2(metaUrl));
|
|
2950
3009
|
const bundled = join4(moduleDir, "supervisor-credential-helper.js");
|
|
2951
3010
|
const source = join4(moduleDir, "..", "supervisor-credential-helper.mjs");
|
|
2952
|
-
return
|
|
3011
|
+
return existsSync7(source) ? source : bundled;
|
|
2953
3012
|
}
|
|
2954
3013
|
function readStoredCredentialIsolated({
|
|
2955
|
-
spawn: spawn2 =
|
|
3014
|
+
spawn: spawn2 = spawnSync7,
|
|
2956
3015
|
execPath = process.execPath,
|
|
2957
3016
|
helperPath = defaultCredentialHelperPath(),
|
|
2958
3017
|
helperArgs = [],
|
|
@@ -3302,7 +3361,7 @@ var sleep = (ms) => new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
|
3302
3361
|
var runnerId = resolveSupervisorRunnerId(process.env);
|
|
3303
3362
|
function packageVersion() {
|
|
3304
3363
|
try {
|
|
3305
|
-
return
|
|
3364
|
+
return createRequire2(import.meta.url)("../package.json").version || "unknown";
|
|
3306
3365
|
} catch {
|
|
3307
3366
|
return "unknown";
|
|
3308
3367
|
}
|