@algosuite/vo-mcp 0.2.0-beta.13 → 0.2.0-beta.15

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.
@@ -33,8 +33,8 @@ var init_control_plane_auth_stub = __esm({
33
33
  import { spawn } from "node:child_process";
34
34
  import { randomUUID as randomUUID3 } from "node:crypto";
35
35
  import { createRequire } from "node:module";
36
- import { fileURLToPath as fileURLToPath2 } from "node:url";
37
- import { dirname as dirname3, join as join4 } from "node:path";
36
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
37
+ import { dirname as dirname4, join as join5 } from "node:path";
38
38
 
39
39
  // ../../scripts/virtual-office/code-runner/control-plane-client.mjs
40
40
  var cachedFirebaseToken = null;
@@ -53,7 +53,7 @@ async function resolveBearer(env) {
53
53
  return cachedFirebaseToken;
54
54
  }
55
55
  function createControlPlaneClient({
56
- baseUrl = process.env.VO_CONTROL_PLANE_URL || "",
56
+ baseUrl,
57
57
  env = process.env,
58
58
  fetchImpl = fetch,
59
59
  heartbeatTimeoutMs = Math.min(
@@ -61,10 +61,11 @@ function createControlPlaneClient({
61
61
  6e4
62
62
  )
63
63
  } = {}) {
64
- if (!baseUrl) {
64
+ const resolvedBaseUrl = baseUrl ?? env.VO_CONTROL_PLANE_URL ?? "";
65
+ if (!resolvedBaseUrl) {
65
66
  throw new Error("VO_CONTROL_PLANE_URL is required for the code-runner daemon");
66
67
  }
67
- const root = baseUrl.replace(/\/+$/, "");
68
+ const root = resolvedBaseUrl.replace(/\/+$/, "");
68
69
  async function req(method, path, body, { timeoutMs } = {}) {
69
70
  const bearer = await resolveBearer(env);
70
71
  const controller = timeoutMs ? new AbortController() : null;
@@ -193,7 +194,6 @@ function createControlPlaneClient({
193
194
  const json = await res.json();
194
195
  return { task: json && json.task };
195
196
  },
196
- /** Read the current task (cancel detection). Null on 404. */
197
197
  async getTask(taskId) {
198
198
  const res = await req("GET", `/api/v1/code-task/${taskId}`);
199
199
  if (res.status === 404) return null;
@@ -201,7 +201,13 @@ function createControlPlaneClient({
201
201
  const json = await res.json();
202
202
  return json ? json.task : null;
203
203
  },
204
- /** Fetch bounded, prompt-ready AlgoHQ knowledge snippets for this task. */
204
+ async downloadTaskAttachment(taskId, attachmentId) {
205
+ const path = `/api/v1/code-task/${encodeURIComponent(taskId)}/attachment/${encodeURIComponent(attachmentId)}`;
206
+ const res = await req("GET", path);
207
+ if (res.status === 401) cachedFirebaseToken = null;
208
+ if (!res.ok) throw new Error(`attachment download failed: HTTP ${res.status}`);
209
+ return Buffer.from(await res.arrayBuffer());
210
+ },
205
211
  async getTaskKnowledgeContext(taskId, { query } = {}) {
206
212
  const body = {};
207
213
  if (typeof query === "string" && query.trim()) body.query = query;
@@ -252,12 +258,17 @@ function createControlPlaneClient({
252
258
  * authenticated operator so the web shows a TRUE "runner online" signal.
253
259
  * Best-effort caller; throws on 401/non-ok so the daemon can log + retry.
254
260
  */
255
- async postHeartbeat({ runnerId: runnerId2, runnerInstanceId, operatorId, uptimeSec, activeTasks, version, daemonVersion, defaultAgent, supervisorInstanceId: supervisorInstanceId2, supervisorVersion: supervisorVersion2, supervisorCapabilities, servedRepos, servedOperators, availableAgents, accountUsage }) {
261
+ async postHeartbeat({ runnerId: runnerId2, runnerInstanceId, operatorId, uptimeSec, activeTasks, maxConcurrency, effectiveConcurrency, measuredTaskSlots, measuredCpuSlots, measuredMemorySlots, version, daemonVersion, defaultAgent, supervisorInstanceId: supervisorInstanceId2, supervisorVersion: supervisorVersion2, supervisorCapabilities, servedRepos, servedOperators, availableAgents, accountUsage }) {
256
262
  const body = { runner_id: runnerId2 };
257
263
  if (runnerInstanceId) body.runner_instance_id = runnerInstanceId;
258
264
  if (operatorId) body.operator_id = operatorId;
259
265
  if (typeof uptimeSec === "number") body.uptime_sec = uptimeSec;
260
266
  if (typeof activeTasks === "number") body.active_tasks = activeTasks;
267
+ if (typeof maxConcurrency === "number") body.max_concurrency = maxConcurrency;
268
+ if (typeof effectiveConcurrency === "number") body.effective_concurrency = effectiveConcurrency;
269
+ if (typeof measuredTaskSlots === "number") body.measured_task_slots = measuredTaskSlots;
270
+ if (typeof measuredCpuSlots === "number") body.measured_cpu_slots = measuredCpuSlots;
271
+ if (typeof measuredMemorySlots === "number") body.measured_memory_slots = measuredMemorySlots;
261
272
  if (version) body.version = version;
262
273
  if (daemonVersion) body.daemon_version = daemonVersion;
263
274
  if (defaultAgent) body.default_agent = defaultAgent;
@@ -284,9 +295,8 @@ function createControlPlaneClient({
284
295
  throw new Error("heartbeat unauthorized (401)");
285
296
  }
286
297
  if (!res.ok) throw new Error(`heartbeat failed: HTTP ${res.status}`);
287
- return true;
298
+ return res.json();
288
299
  },
289
- /** Read the server-authoritative heartbeat ledger without mutating it. */
290
300
  async getRunnerStatus({ operatorId } = {}) {
291
301
  const query = operatorId ? `?operator_id=${encodeURIComponent(operatorId)}` : "";
292
302
  const res = await req("GET", `/api/v1/runner/status${query}`, void 0, {
@@ -300,7 +310,6 @@ function createControlPlaneClient({
300
310
  const body = await res.json();
301
311
  return Array.isArray(body?.runners) ? body.runners : [];
302
312
  },
303
- /** Poll one authenticated runner's durable Mission Control action queue. */
304
313
  async pollRunnerControl({ runnerId: runnerId2, operatorId, supervisorInstanceId: supervisorInstanceId2, supervisorVersion: supervisorVersion2, capabilities }) {
305
314
  const body = { runner_id: runnerId2 };
306
315
  if (operatorId) body.operator_id = operatorId;
@@ -317,7 +326,6 @@ function createControlPlaneClient({
317
326
  const action = json?.action;
318
327
  return action && typeof action.action_id === "string" && action.action_id ? { ...action, actionId: action.action_id } : null;
319
328
  },
320
- /** Acknowledge a maintenance action after the host has restarted the child. */
321
329
  async completeRunnerControl(actionId, { runnerId: runnerId2, operatorId, supervisorInstanceId: supervisorInstanceId2, supervisorVersion: supervisorVersion2, capabilities, status, detail }) {
322
330
  const body = { runner_id: runnerId2, status };
323
331
  if (operatorId) body.operator_id = operatorId;
@@ -492,69 +500,486 @@ function runHostMaintenance(kind, {
492
500
  }
493
501
 
494
502
  // src/runner/bundled-runtime-updater.mjs
495
- import { createHash as createHash2, randomUUID as randomUUID2 } from "node:crypto";
503
+ import { createHash as createHash4, randomUUID as randomUUID2 } from "node:crypto";
496
504
  import {
497
- existsSync as existsSync3,
498
- lstatSync as lstatSync2,
505
+ existsSync as existsSync4,
506
+ lstatSync as lstatSync3,
499
507
  mkdirSync as mkdirSync2,
500
- readFileSync as readFileSync2,
501
- readdirSync as readdirSync2,
508
+ readFileSync as readFileSync4,
509
+ readdirSync as readdirSync3,
502
510
  renameSync as renameSync2,
503
511
  rmSync as rmSync2,
504
512
  writeFileSync as writeFileSync2
505
513
  } from "node:fs";
506
- import { basename, isAbsolute as isAbsolute2, join as join2, resolve as resolve2 } from "node:path";
514
+ import { basename, isAbsolute as isAbsolute3, join as join3, resolve as resolve4 } from "node:path";
507
515
  import { spawnSync as spawnSync2 } from "node:child_process";
508
516
 
517
+ // ../../scripts/virtual-office/runner-bootstrap/runtime-authorization.mjs
518
+ import { createHash as createHash2 } from "node:crypto";
519
+ import { readFileSync as readFileSync2 } from "node:fs";
520
+ import { dirname, posix, resolve as resolve2 } from "node:path";
521
+ import { fileURLToPath } from "node:url";
522
+
523
+ // ../../scripts/virtual-office/runner-bootstrap/runtime-staged-tree.mjs
524
+ import { execFileSync } from "node:child_process";
525
+ import { createHash } from "node:crypto";
526
+ import {
527
+ existsSync as existsSync2,
528
+ lstatSync,
529
+ readFileSync,
530
+ readdirSync
531
+ } from "node:fs";
532
+ import { isAbsolute, join, relative, resolve, sep, win32 as win322 } from "node:path";
533
+ var WINDOWS_REPARSE_ATTRIBUTE = 1024;
534
+ var RUNNER_LOCK_KEY = "node_modules/@algosuite/vo-mcp";
535
+ var INSTALLED_TREE_ALGORITHM = "algohq-node-modules-manifest-sha256-v1";
536
+ function canonical(value) {
537
+ if (Array.isArray(value)) return value.map(canonical);
538
+ if (value && typeof value === "object") {
539
+ return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonical(value[key])]));
540
+ }
541
+ return value;
542
+ }
543
+ function canonicalJson(value) {
544
+ return JSON.stringify(canonical(value));
545
+ }
546
+ function hasFileAttribute(value, bit) {
547
+ if (typeof value === "bigint") return (value & BigInt(bit)) !== 0n;
548
+ return Number.isSafeInteger(value) && (value & bit) !== 0;
549
+ }
550
+ function isReparseStat(stats) {
551
+ if (!stats || typeof stats !== "object") return false;
552
+ if (typeof stats.isSymbolicLink === "function" && stats.isSymbolicLink()) return true;
553
+ if (stats.reparseTag !== void 0 && stats.reparseTag !== null && stats.reparseTag !== 0) return true;
554
+ return ["fileAttributes", "fileAttribute", "attributes"].some((key) => hasFileAttribute(stats[key], WINDOWS_REPARSE_ATTRIBUTE));
555
+ }
556
+ function platformConstraintAllows(values, target) {
557
+ if (!Array.isArray(values) || values.length === 0) return true;
558
+ if (values.some((value) => value === `!${target}`)) return false;
559
+ const positive = values.filter((value) => typeof value === "string" && !value.startsWith("!"));
560
+ return positive.length === 0 || positive.includes(target);
561
+ }
562
+ function isOmittedOptionalPackage(entry, platform = { os: "win32", arch: "x64" }) {
563
+ return entry?.optional === true && (!platformConstraintAllows(entry.os, platform.os) || !platformConstraintAllows(entry.cpu, platform.arch));
564
+ }
565
+ function assertContained(root, candidate, label) {
566
+ const rel = relative(root, candidate);
567
+ if (rel === "" || !rel.startsWith(`..${sep}`) && rel !== ".." && !isAbsolute(rel)) return;
568
+ throw new Error(`staged runtime ${label} escapes the payload root`);
569
+ }
570
+ function normalizeReportedPath(root, candidate) {
571
+ const absolute = resolve(String(candidate || ""));
572
+ assertContained(root, absolute, "reparse point");
573
+ return absolute;
574
+ }
575
+ function listWindowsReparsePoints(root, {
576
+ execFile = execFileSync,
577
+ env = process.env,
578
+ platform = process.platform
579
+ } = {}) {
580
+ if (platform !== "win32") return [];
581
+ const systemRoot = String(env.SystemRoot || env.SYSTEMROOT || "");
582
+ if (!win322.isAbsolute(systemRoot) || win322.normalize(systemRoot) !== systemRoot) {
583
+ throw new Error("staged runtime trusted PowerShell root unavailable");
584
+ }
585
+ const system32 = win322.join(systemRoot, "System32");
586
+ const powershell = win322.join(system32, "WindowsPowerShell", "v1.0", "powershell.exe");
587
+ const script = [
588
+ '$ErrorActionPreference = "Stop"',
589
+ "$root = [IO.Path]::GetFullPath($env:ALGOHQ_REPARSE_ROOT)",
590
+ "$items = @((Get-Item -LiteralPath $root -Force)) + @(Get-ChildItem -LiteralPath $root -Force -Recurse)",
591
+ "foreach ($item in $items) {",
592
+ " if (($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0) {",
593
+ " [Console]::Out.WriteLine($item.FullName)",
594
+ " }",
595
+ "}"
596
+ ].join("; ");
597
+ const output = execFile(powershell, [
598
+ "-NoLogo",
599
+ "-NoProfile",
600
+ "-NonInteractive",
601
+ "-Command",
602
+ script
603
+ ], {
604
+ cwd: system32,
605
+ encoding: "utf8",
606
+ env: { SystemRoot: systemRoot, ALGOHQ_REPARSE_ROOT: win322.resolve(root) },
607
+ windowsHide: true
608
+ });
609
+ return String(output || "").split(/\r?\n/u).filter(Boolean).map((item) => normalizeReportedPath(root, item));
610
+ }
611
+ function normalizedRunnerRecord(actual, expected) {
612
+ const normalized = structuredClone(actual);
613
+ if (normalized?.resolved === expected?.resolved) return normalized;
614
+ if (typeof normalized?.resolved !== "string" || !normalized.resolved.startsWith("file:")) {
615
+ return normalized;
616
+ }
617
+ const fileName = normalized.resolved.slice("file:".length).replaceAll("\\", "/").split("/").at(-1);
618
+ const expectedFileNames = /* @__PURE__ */ new Set([
619
+ String(expected.resolved || "").split("/").at(-1),
620
+ `algosuite-vo-mcp-${expected.version}.tgz`
621
+ ]);
622
+ if (expectedFileNames.has(fileName)) normalized.resolved = expected.resolved;
623
+ return normalized;
624
+ }
625
+ function validateLock(lock, authorization) {
626
+ if (!lock || typeof lock !== "object" || Array.isArray(lock)) {
627
+ throw new Error("staged runtime package-lock must be an object");
628
+ }
629
+ if (lock.lockfileVersion !== authorization.dependency_lock.source_lockfile_version) {
630
+ throw new Error("staged runtime package-lock version mismatch");
631
+ }
632
+ if (!lock.packages || typeof lock.packages !== "object" || Array.isArray(lock.packages)) {
633
+ throw new Error("staged runtime package-lock package map missing");
634
+ }
635
+ const expected = authorization.dependency_lock.packages;
636
+ const actual = Object.fromEntries(Object.entries(lock.packages).filter(([key]) => key !== ""));
637
+ const expectedKeys = Object.keys(expected).sort();
638
+ const actualKeys = Object.keys(actual).sort();
639
+ if (canonicalJson(actualKeys) !== canonicalJson(expectedKeys)) {
640
+ throw new Error("staged runtime package-lock package set mismatch");
641
+ }
642
+ for (const key of expectedKeys) {
643
+ const record = key === RUNNER_LOCK_KEY ? normalizedRunnerRecord(actual[key], expected[key]) : actual[key];
644
+ if (canonicalJson(record) !== canonicalJson(expected[key])) {
645
+ throw new Error(`staged runtime package-lock record mismatch: ${key}`);
646
+ }
647
+ }
648
+ return { actual, expected };
649
+ }
650
+ function checkPathKind(path, expectedKind, fsOps, label) {
651
+ if (!fsOps.exists(path)) throw new Error(`staged runtime ${label} missing`);
652
+ const stats = fsOps.lstat(path);
653
+ if (isReparseStat(stats) || fsOps.isReparsePoint(path, stats)) {
654
+ throw new Error(`staged runtime ${label} is a reparse point`);
655
+ }
656
+ if (expectedKind === "directory" && !stats.isDirectory()) {
657
+ throw new Error(`staged runtime ${label} is not a directory`);
658
+ }
659
+ if (expectedKind === "file" && !stats.isFile()) {
660
+ throw new Error(`staged runtime ${label} is not a regular file`);
661
+ }
662
+ if (expectedKind === "file" && Number(stats.nlink) > 1) {
663
+ throw new Error(`staged runtime ${label} is hardlinked`);
664
+ }
665
+ return stats;
666
+ }
667
+ function verifyInstalledPackages(payloadRoot, packageRecords, platform, fsOps) {
668
+ const omitted = [];
669
+ let installed = 0;
670
+ for (const [key, entry] of Object.entries(packageRecords)) {
671
+ const path = resolve(payloadRoot, key);
672
+ assertContained(payloadRoot, path, "package path");
673
+ const shouldOmit = isOmittedOptionalPackage(entry, platform);
674
+ if (shouldOmit) {
675
+ omitted.push(key);
676
+ if (fsOps.exists(path)) throw new Error(`staged runtime optional package should be omitted: ${key}`);
677
+ continue;
678
+ }
679
+ checkPathKind(path, "directory", fsOps, `installed package ${key}`);
680
+ installed += 1;
681
+ }
682
+ return { installed, omitted: omitted.sort() };
683
+ }
684
+ function treeRecord(kind, path, stats, fileHash = "") {
685
+ if (kind === "d") return `d ${path}\r
686
+ `;
687
+ return `f ${path} ${stats.size} ${fileHash}\r
688
+ `;
689
+ }
690
+ function computeInstalledTree(nodeModulesRoot, fsOps = {}) {
691
+ const ops = {
692
+ exists: existsSync2,
693
+ lstat: lstatSync,
694
+ readdir: (path) => readdirSync(path, { withFileTypes: true }),
695
+ readFile: readFileSync,
696
+ isReparsePoint: () => false,
697
+ listReparsePoints: listWindowsReparsePoints,
698
+ ...fsOps
699
+ };
700
+ const root = resolve(nodeModulesRoot);
701
+ checkPathKind(root, "directory", ops, "node_modules root");
702
+ const reported = ops.listReparsePoints(root);
703
+ if (!Array.isArray(reported)) throw new Error("staged runtime reparse probe returned an invalid result");
704
+ if (reported.length > 0) throw new Error("staged runtime tree contains a Windows reparse point");
705
+ let fileCount = 0;
706
+ let directoryCount = 1;
707
+ let byteCount = 0;
708
+ const entries = [];
709
+ function walk(absolute, relativePath) {
710
+ for (const entry of ops.readdir(absolute)) {
711
+ const childRelative = relativePath ? `${relativePath}/${entry.name}` : entry.name;
712
+ if (childRelative === ".package-lock.json") continue;
713
+ const child = resolve(absolute, entry.name);
714
+ assertContained(root, child, "tree entry");
715
+ const stats = ops.lstat(child);
716
+ if (isReparseStat(stats) || ops.isReparsePoint(child, stats)) {
717
+ throw new Error(`staged runtime tree contains a reparse point: ${childRelative}`);
718
+ }
719
+ if (stats.isDirectory()) {
720
+ directoryCount += 1;
721
+ entries.push({ kind: "d", path: childRelative, stats });
722
+ walk(child, childRelative);
723
+ } else if (stats.isFile()) {
724
+ if (Number(stats.nlink) > 1) {
725
+ throw new Error(`staged runtime tree contains a hardlinked file: ${childRelative}`);
726
+ }
727
+ fileCount += 1;
728
+ byteCount += Number(stats.size);
729
+ const digest = createHash("sha256").update(ops.readFile(child)).digest("hex");
730
+ entries.push({ kind: "f", path: childRelative, stats, digest });
731
+ } else {
732
+ throw new Error(`staged runtime tree contains a non-file entry: ${childRelative}`);
733
+ }
734
+ }
735
+ }
736
+ walk(root, "");
737
+ entries.sort((left, right) => Buffer.compare(Buffer.from(left.path), Buffer.from(right.path)));
738
+ const manifest = treeRecord("d", "", { size: 0 }) + entries.map((entry) => treeRecord(entry.kind, entry.path, entry.stats, entry.digest)).join("");
739
+ return {
740
+ algorithm: INSTALLED_TREE_ALGORITHM,
741
+ sha256: createHash("sha256").update(manifest, "utf8").digest("hex"),
742
+ file_count: fileCount,
743
+ directory_count: directoryCount,
744
+ byte_count: byteCount,
745
+ canonical_manifest_byte_count: Buffer.byteLength(manifest),
746
+ reparse_point_count: 0,
747
+ hardlinked_file_count: 0
748
+ };
749
+ }
750
+ function compareStagedRuntime({
751
+ payloadRoot,
752
+ nodeModulesRoot = join(payloadRoot, "node_modules"),
753
+ packageLockFile = join(payloadRoot, "package-lock.json"),
754
+ authorization,
755
+ fsOps = {}
756
+ }) {
757
+ const payload = resolve(payloadRoot);
758
+ const modules = resolve(nodeModulesRoot);
759
+ const lockFile = resolve(packageLockFile);
760
+ if (modules !== resolve(payload, "node_modules") || lockFile !== resolve(payload, "package-lock.json")) {
761
+ throw new Error("staged runtime paths do not identify one canonical payload");
762
+ }
763
+ const ops = {
764
+ exists: existsSync2,
765
+ lstat: lstatSync,
766
+ readFile: readFileSync,
767
+ isReparsePoint: () => false,
768
+ ...fsOps
769
+ };
770
+ checkPathKind(lockFile, "file", ops, "package-lock");
771
+ const lock = JSON.parse(ops.readFile(lockFile, "utf8"));
772
+ const { expected } = validateLock(lock, authorization);
773
+ const platform = { os: authorization.platform.os, arch: authorization.platform.arch };
774
+ const packages = verifyInstalledPackages(payload, expected, platform, ops);
775
+ const declaredOmitted = [...authorization.dependency_lock.windows_x64_omitted_optional_entries].sort();
776
+ if (canonicalJson(packages.omitted) !== canonicalJson(declaredOmitted)) {
777
+ throw new Error("staged runtime optional omission list mismatch");
778
+ }
779
+ if (packages.installed !== Object.keys(expected).length - packages.omitted.length) {
780
+ throw new Error("staged runtime installed package count mismatch");
781
+ }
782
+ const tree = computeInstalledTree(modules, fsOps);
783
+ if (canonicalJson(tree) !== canonicalJson(authorization.installed_tree)) {
784
+ throw new Error("staged runtime installed tree mismatch");
785
+ }
786
+ return { ok: true, packageCount: Object.keys(expected).length, ...packages, tree };
787
+ }
788
+
789
+ // ../../scripts/virtual-office/runner-bootstrap/runtime-authorization.mjs
790
+ var HERE = dirname(fileURLToPath(import.meta.url));
791
+ var BETA13_WINDOWS_X64_AUTHORIZATION = resolve2(
792
+ HERE,
793
+ "authorizations",
794
+ "vo-mcp-0.2.0-beta.13-win32-x64.json"
795
+ );
796
+ var EXPECTED = Object.freeze({
797
+ authorizationId: "vo-mcp-0.2.0-beta.13-win32-x64-v1",
798
+ packageName: "@algosuite/vo-mcp",
799
+ version: "0.2.0-beta.13",
800
+ registry: "https://registry.npmjs.org/",
801
+ tarballUrl: "https://registry.npmjs.org/@algosuite/vo-mcp/-/vo-mcp-0.2.0-beta.13.tgz",
802
+ integrity: "sha512-TQa5VaEFsaleHbAZZp+zS4u5U/0zQBIGOiPDGn9IqfZfdMltH2dY81nTftvu5EUABthE1xTCrdSzJjO9mzkNag==",
803
+ tarballSha256: "c1e39e8bb2df7f53f48e46e77ffb617452a01849469ff4757b4384a478c1cbff",
804
+ npmShasumSha1: "f076649b31294aa38deb7852f38a889e0d0fbe44",
805
+ gitHead: "ba00db90720416fa7474581eb823c6255221880f",
806
+ sourceLockSha256: "f8bbb5e81a0057ee2d60145580ec07f7e7055d999bdd038515c6c4e88af6cc92",
807
+ canonicalEntriesSha256: "7f6b2f93ccb93ad625ed244dc59ac556792e478178fc690ad2ca2c6f3a2325d2",
808
+ entryCount: 107,
809
+ optionalEntryCount: 13,
810
+ installedEntryCount: 96,
811
+ treeAlgorithm: "algohq-node-modules-manifest-sha256-v1",
812
+ treeSha256: "9c8b0749d7ae1e2c132ef08c5b5655673ae88432859c561806276c9eb18f4874",
813
+ treeFileCount: 3538,
814
+ treeDirectoryCount: 553,
815
+ treeByteCount: 20566445,
816
+ treeManifestByteCount: 412062
817
+ });
818
+ var SRI_RE = /^sha512-[A-Za-z0-9+/]{86}==$/u;
819
+ var SHA256_RE = /^[a-f0-9]{64}$/u;
820
+ function canonical2(value) {
821
+ if (Array.isArray(value)) return value.map(canonical2);
822
+ if (value && typeof value === "object") {
823
+ return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonical2(value[key])]));
824
+ }
825
+ return value;
826
+ }
827
+ function sha256Canonical(value) {
828
+ return createHash2("sha256").update(`${JSON.stringify(canonical2(value))}
829
+ `, "utf8").digest("hex");
830
+ }
831
+ function assertEqual(actual, expected, label) {
832
+ if (actual !== expected) throw new Error(`runtime authorization ${label} mismatch`);
833
+ }
834
+ function isOmittedOnWindowsX64(entry) {
835
+ return isOmittedOptionalPackage(entry, { os: "win32", arch: "x64" });
836
+ }
837
+ function validateRuntimeAuthorization(value) {
838
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
839
+ throw new Error("runtime authorization must be an object");
840
+ }
841
+ assertEqual(value.schema_version, 1, "schema version");
842
+ assertEqual(value.authorization_id, EXPECTED.authorizationId, "id");
843
+ assertEqual(value.package?.name, EXPECTED.packageName, "package name");
844
+ assertEqual(value.package?.version, EXPECTED.version, "package version");
845
+ assertEqual(value.package?.registry, EXPECTED.registry, "registry");
846
+ assertEqual(value.package?.tarball_url, EXPECTED.tarballUrl, "tarball URL");
847
+ assertEqual(value.package?.sri_sha512, EXPECTED.integrity, "package integrity");
848
+ assertEqual(value.package?.tarball_sha256, EXPECTED.tarballSha256, "tarball sha256");
849
+ assertEqual(value.package?.npm_shasum_sha1, EXPECTED.npmShasumSha1, "npm shasum");
850
+ assertEqual(value.package?.git_head, EXPECTED.gitHead, "git head");
851
+ assertEqual(value.package?.packed_file_count, 25, "packed file count");
852
+ assertEqual(value.package?.packed_bytes, 846151, "packed byte count");
853
+ assertEqual(value.package?.unpacked_bytes, 3350387, "unpacked byte count");
854
+ assertEqual(value.platform?.os, "win32", "operating system");
855
+ assertEqual(value.platform?.arch, "x64", "architecture");
856
+ assertEqual(value.platform?.package_node_engine, ">=22.5.0", "package node engine");
857
+ if (!/^24\.15\.0$/u.test(String(value.platform?.authorization_builder_node || "")) || value.platform?.authorization_builder_npm !== "11.12.1") {
858
+ throw new Error("runtime authorization builder toolchain mismatch");
859
+ }
860
+ for (const [key, expected] of Object.entries({
861
+ ignore_scripts: true,
862
+ bin_links: false,
863
+ include_optional: true,
864
+ omit_dev: true,
865
+ audit: false,
866
+ fund: false,
867
+ reject_links_reparse_points: true,
868
+ reject_hardlinks: true,
869
+ remove_generated_node_modules_package_lock_before_tree_validation: true
870
+ })) assertEqual(value.install_contract?.[key], expected, `install contract ${key}`);
871
+ assertEqual(value.install_contract?.allowed_registry_prefix, EXPECTED.registry, "registry prefix");
872
+ const lock = value.dependency_lock;
873
+ if (!lock?.packages || typeof lock.packages !== "object" || Array.isArray(lock.packages)) {
874
+ throw new Error("runtime authorization dependency set missing");
875
+ }
876
+ assertEqual(lock.source_lockfile_version, 3, "lockfile version");
877
+ assertEqual(lock.source_lock_sha256, EXPECTED.sourceLockSha256, "source lock sha256");
878
+ assertEqual(lock.canonical_entries_sha256, EXPECTED.canonicalEntriesSha256, "entry-set sha256");
879
+ assertEqual(lock.entry_count, EXPECTED.entryCount, "entry count");
880
+ assertEqual(lock.integrity_entry_count, EXPECTED.entryCount, "integrity count");
881
+ assertEqual(lock.optional_entry_count, EXPECTED.optionalEntryCount, "optional count");
882
+ assertEqual(lock.windows_x64_installed_entry_count, EXPECTED.installedEntryCount, "installed count");
883
+ const entries = Object.entries(lock.packages);
884
+ assertEqual(entries.length, EXPECTED.entryCount, "package map count");
885
+ for (const [key, entry] of entries) {
886
+ if (!key.startsWith("node_modules/") || key.includes("\\") || posix.normalize(key) !== key || key.split("/").includes("..")) {
887
+ throw new Error(`runtime authorization has unsafe package path: ${key}`);
888
+ }
889
+ if (!entry || typeof entry !== "object" || entry.link === true) {
890
+ throw new Error(`runtime authorization contains a linked package: ${key}`);
891
+ }
892
+ if (!SRI_RE.test(String(entry.integrity || ""))) {
893
+ throw new Error(`runtime authorization package lacks sha512 integrity: ${key}`);
894
+ }
895
+ if (!String(entry.resolved || "").startsWith(EXPECTED.registry)) {
896
+ throw new Error(`runtime authorization package is outside the public registry: ${key}`);
897
+ }
898
+ if (entry.hasInstallScript === true) {
899
+ throw new Error(`runtime authorization package declares an install script: ${key}`);
900
+ }
901
+ }
902
+ const runner = lock.packages["node_modules/@algosuite/vo-mcp"];
903
+ assertEqual(runner?.version, EXPECTED.version, "runner dependency version");
904
+ assertEqual(runner?.integrity, EXPECTED.integrity, "runner dependency integrity");
905
+ assertEqual(sha256Canonical(lock.packages), EXPECTED.canonicalEntriesSha256, "computed entry-set sha256");
906
+ const omitted = entries.filter(([, entry]) => isOmittedOnWindowsX64(entry)).map(([key]) => key).sort();
907
+ const declaredOmitted = [...lock.windows_x64_omitted_optional_entries || []].sort();
908
+ assertEqual(JSON.stringify(declaredOmitted), JSON.stringify(omitted), "omitted optional entries");
909
+ assertEqual(entries.length - omitted.length, EXPECTED.installedEntryCount, "derived installed count");
910
+ const tree = value.installed_tree;
911
+ assertEqual(tree?.algorithm, EXPECTED.treeAlgorithm, "tree algorithm");
912
+ if (!SHA256_RE.test(String(tree?.sha256 || ""))) throw new Error("runtime authorization tree hash invalid");
913
+ assertEqual(tree.sha256, EXPECTED.treeSha256, "tree sha256");
914
+ assertEqual(tree.file_count, EXPECTED.treeFileCount, "tree file count");
915
+ assertEqual(tree.directory_count, EXPECTED.treeDirectoryCount, "tree directory count");
916
+ assertEqual(tree.byte_count, EXPECTED.treeByteCount, "tree byte count");
917
+ assertEqual(tree.canonical_manifest_byte_count, EXPECTED.treeManifestByteCount, "tree manifest byte count");
918
+ assertEqual(tree.reparse_point_count, 0, "tree reparse count");
919
+ assertEqual(tree.hardlinked_file_count, 0, "tree hardlink count");
920
+ return value;
921
+ }
922
+ function readRuntimeAuthorization(file = BETA13_WINDOWS_X64_AUTHORIZATION) {
923
+ return validateRuntimeAuthorization(JSON.parse(readFileSync2(file, "utf8")));
924
+ }
925
+ function validateStagedRuntimeAuthorization(options) {
926
+ const authorization = validateRuntimeAuthorization(options?.authorization || readRuntimeAuthorization());
927
+ return compareStagedRuntime({ ...options, authorization });
928
+ }
929
+ if (process.argv[1] && resolve2(process.argv[1]) === fileURLToPath(import.meta.url)) {
930
+ readRuntimeAuthorization(process.argv[2] ? resolve2(process.argv[2]) : void 0);
931
+ process.stdout.write("AlgoHQ runtime authorization valid\n");
932
+ }
933
+
509
934
  // src/runner/bundled-runtime-store.mjs
510
- import { createHash, randomUUID } from "node:crypto";
935
+ import { createHash as createHash3, randomUUID } from "node:crypto";
511
936
  import {
512
937
  closeSync,
513
- existsSync as existsSync2,
938
+ existsSync as existsSync3,
514
939
  fsyncSync,
515
- lstatSync,
940
+ lstatSync as lstatSync2,
516
941
  mkdirSync,
517
942
  openSync,
518
- readFileSync,
519
- readdirSync,
943
+ readFileSync as readFileSync3,
944
+ readdirSync as readdirSync2,
520
945
  realpathSync,
521
946
  renameSync,
522
947
  rmSync,
523
948
  writeFileSync
524
949
  } from "node:fs";
525
- import { dirname, isAbsolute, join, relative, resolve } from "node:path";
950
+ import { dirname as dirname2, isAbsolute as isAbsolute2, join as join2, relative as relative2, resolve as resolve3 } from "node:path";
526
951
  var SLOT_ID_RE = /^vo-mcp-[0-9A-Za-z._-]{1,96}$/u;
527
952
  var ACTION_ID_RE = /^[0-9A-Za-z._-]{1,128}$/u;
528
953
  var INTEGRITY_RE = /^sha512-[A-Za-z0-9+/]{86}==$/u;
529
954
  var VERSION_RE = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u;
530
955
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
531
- var ENTRY_REL = join("node_modules", "@algosuite", "vo-mcp", "bin", "vo-mcp");
532
- var SUPERVISOR_REL = join("node_modules", "@algosuite", "vo-mcp", "dist", "runner-supervisor.js");
533
- var PACKAGE_REL = join("node_modules", "@algosuite", "vo-mcp", "package.json");
534
- var CREDENTIAL_HELPER_REL = join("node_modules", "@algosuite", "vo-mcp", "dist", "supervisor-credential-helper.js");
956
+ var ENTRY_REL = join2("node_modules", "@algosuite", "vo-mcp", "bin", "vo-mcp");
957
+ var SUPERVISOR_REL = join2("node_modules", "@algosuite", "vo-mcp", "dist", "runner-supervisor.js");
958
+ var PACKAGE_REL = join2("node_modules", "@algosuite", "vo-mcp", "package.json");
959
+ var CREDENTIAL_HELPER_REL = join2("node_modules", "@algosuite", "vo-mcp", "dist", "supervisor-credential-helper.js");
535
960
  var MANIFEST_FILE = "runtime-manifest.json";
536
961
  function within(parent, candidate) {
537
- const rel = relative(resolve(parent), resolve(candidate));
538
- return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
962
+ const rel = relative2(resolve3(parent), resolve3(candidate));
963
+ return rel === "" || !rel.startsWith("..") && !isAbsolute2(rel);
539
964
  }
540
965
  function runtimeRootFromEnv(env = process.env) {
541
966
  const value = String(env.VO_RUNNER_RUNTIME_ROOT || "").trim();
542
- return value && isAbsolute(value) ? resolve(value) : null;
967
+ return value && isAbsolute2(value) ? resolve3(value) : null;
543
968
  }
544
969
  function hashFileSha512(file) {
545
- return `sha512-${createHash("sha512").update(readFileSync(file)).digest("base64")}`;
970
+ return `sha512-${createHash3("sha512").update(readFileSync3(file)).digest("base64")}`;
546
971
  }
547
972
  function hashRuntimeTree(root) {
548
- const hasher = createHash("sha512");
973
+ const hasher = createHash3("sha512");
549
974
  const files = [];
550
975
  const visit = (directory, prefix = "") => {
551
- const rootStat = lstatSync(directory);
976
+ const rootStat = lstatSync2(directory);
552
977
  if (rootStat.isSymbolicLink()) throw new Error("runtime tree contains a link/reparse point");
553
978
  if (!rootStat.isDirectory()) throw new Error("runtime tree root is not a directory");
554
- for (const name of readdirSync(directory).sort((a, b) => Buffer.compare(Buffer.from(a), Buffer.from(b)))) {
555
- const absolute = join(directory, name);
979
+ for (const name of readdirSync2(directory).sort((a, b) => Buffer.compare(Buffer.from(a), Buffer.from(b)))) {
980
+ const absolute = join2(directory, name);
556
981
  const relativePath = prefix ? `${prefix}/${name}` : name;
557
- const stat = lstatSync(absolute);
982
+ const stat = lstatSync2(absolute);
558
983
  if (stat.isSymbolicLink()) throw new Error("runtime tree contains a link/reparse point");
559
984
  if (stat.isDirectory()) visit(absolute, relativePath);
560
985
  else if (stat.isFile() && relativePath !== MANIFEST_FILE) files.push({ absolute, relativePath, size: stat.size });
@@ -568,14 +993,14 @@ function hashRuntimeTree(root) {
568
993
  hasher.update(`${pathBytes.length}:`);
569
994
  hasher.update(pathBytes);
570
995
  hasher.update(`:${file.size}:`);
571
- hasher.update(readFileSync(file.absolute));
996
+ hasher.update(readFileSync3(file.absolute));
572
997
  hasher.update("\n");
573
998
  }
574
999
  return `sha512-${hasher.digest("base64")}`;
575
1000
  }
576
1001
  function atomicWriteJson(file, value) {
577
- mkdirSync(dirname(file), { recursive: true });
578
- const temp = join(dirname(file), `.${randomUUID()}.tmp`);
1002
+ mkdirSync(dirname2(file), { recursive: true });
1003
+ const temp = join2(dirname2(file), `.${randomUUID()}.tmp`);
579
1004
  const fd = openSync(temp, "wx", 384);
580
1005
  try {
581
1006
  writeFileSync(fd, `${JSON.stringify(value, null, 2)}
@@ -588,7 +1013,7 @@ function atomicWriteJson(file, value) {
588
1013
  renameSync(temp, file);
589
1014
  if (process.platform !== "win32") {
590
1015
  try {
591
- const parentFd = openSync(dirname(file), "r");
1016
+ const parentFd = openSync(dirname2(file), "r");
592
1017
  try {
593
1018
  fsyncSync(parentFd);
594
1019
  } finally {
@@ -602,10 +1027,10 @@ function atomicWriteJson(file, value) {
602
1027
  }
603
1028
  }
604
1029
  function readActivation(runtimeRoot) {
605
- const file = join(runtimeRoot, "current.json");
606
- if (!existsSync2(file)) return null;
1030
+ const file = join2(runtimeRoot, "current.json");
1031
+ if (!existsSync3(file)) return null;
607
1032
  try {
608
- const value = JSON.parse(readFileSync(file, "utf8"));
1033
+ const value = JSON.parse(readFileSync3(file, "utf8"));
609
1034
  return value?.schema_version === 1 ? value : null;
610
1035
  } catch {
611
1036
  return null;
@@ -613,14 +1038,14 @@ function readActivation(runtimeRoot) {
613
1038
  }
614
1039
  function slotPaths(runtimeRoot, slotId) {
615
1040
  if (!SLOT_ID_RE.test(slotId)) throw new Error("invalid runtime slot id");
616
- const slotRoot = join(runtimeRoot, "slots", slotId);
1041
+ const slotRoot = join2(runtimeRoot, "slots", slotId);
617
1042
  return {
618
1043
  slotRoot,
619
- entry: join(slotRoot, ENTRY_REL),
620
- supervisor: join(slotRoot, SUPERVISOR_REL),
621
- packageJson: join(slotRoot, PACKAGE_REL),
622
- credentialHelper: join(slotRoot, CREDENTIAL_HELPER_REL),
623
- manifest: join(slotRoot, MANIFEST_FILE)
1044
+ entry: join2(slotRoot, ENTRY_REL),
1045
+ supervisor: join2(slotRoot, SUPERVISOR_REL),
1046
+ packageJson: join2(slotRoot, PACKAGE_REL),
1047
+ credentialHelper: join2(slotRoot, CREDENTIAL_HELPER_REL),
1048
+ manifest: join2(slotRoot, MANIFEST_FILE)
624
1049
  };
625
1050
  }
626
1051
  function validActive(active) {
@@ -630,8 +1055,8 @@ function validateSlot(runtimeRoot, active) {
630
1055
  if (!validActive(active)) return { ok: false, detail: "invalid activation metadata" };
631
1056
  const paths = slotPaths(runtimeRoot, active.slot_id);
632
1057
  try {
633
- const manifest = JSON.parse(readFileSync(paths.manifest, "utf8"));
634
- const pkg = JSON.parse(readFileSync(paths.packageJson, "utf8"));
1058
+ const manifest = JSON.parse(readFileSync3(paths.manifest, "utf8"));
1059
+ const pkg = JSON.parse(readFileSync3(paths.packageJson, "utf8"));
635
1060
  const expected = {
636
1061
  slot_id: active.slot_id,
637
1062
  version: active.version,
@@ -646,7 +1071,7 @@ function validateSlot(runtimeRoot, active) {
646
1071
  if (manifest?.schema_version !== 1 || pkg?.name !== "@algosuite/vo-mcp" || pkg?.version !== active.version) {
647
1072
  return { ok: false, detail: "package identity mismatch" };
648
1073
  }
649
- if (lstatSync(paths.entry).isSymbolicLink() || lstatSync(paths.supervisor).isSymbolicLink() || lstatSync(paths.credentialHelper).isSymbolicLink()) {
1074
+ if (lstatSync2(paths.entry).isSymbolicLink() || lstatSync2(paths.supervisor).isSymbolicLink() || lstatSync2(paths.credentialHelper).isSymbolicLink()) {
650
1075
  return { ok: false, detail: "runtime entry cannot be a link" };
651
1076
  }
652
1077
  if (!within(paths.slotRoot, realpathSync(paths.entry)) || !within(paths.slotRoot, realpathSync(paths.supervisor)) || !within(paths.slotRoot, realpathSync(paths.credentialHelper))) {
@@ -662,7 +1087,7 @@ function validateSlot(runtimeRoot, active) {
662
1087
  }
663
1088
  function journalActivation(runtimeRoot, actionId, state, detail = "") {
664
1089
  if (!ACTION_ID_RE.test(actionId)) throw new Error("invalid runner action id");
665
- atomicWriteJson(join(runtimeRoot, "transactions", `${actionId}.json`), {
1090
+ atomicWriteJson(join2(runtimeRoot, "transactions", `${actionId}.json`), {
666
1091
  schema_version: 1,
667
1092
  action_id: actionId,
668
1093
  state,
@@ -693,7 +1118,7 @@ function activateSlot(runtimeRoot, active, action) {
693
1118
  }
694
1119
  };
695
1120
  journalActivation(runtimeRoot, action.actionId, "prepared", `${active.version} ${active.integrity}`);
696
- atomicWriteJson(join(runtimeRoot, "current.json"), pointer);
1121
+ atomicWriteJson(join2(runtimeRoot, "current.json"), pointer);
697
1122
  return pointer;
698
1123
  }
699
1124
  function activationSupervisorInstanceId(runtimeRoot, fallback) {
@@ -712,7 +1137,7 @@ function recordActivationRetry(runtimeRoot, pointer, detail) {
712
1137
  ...current,
713
1138
  pending: { ...current.pending, ack_attempts: attempts, last_error: String(detail).slice(0, 240) }
714
1139
  };
715
- atomicWriteJson(join(runtimeRoot, "current.json"), updated);
1140
+ atomicWriteJson(join2(runtimeRoot, "current.json"), updated);
716
1141
  journalActivation(runtimeRoot, current.pending.action_id, "ack-retry", `attempt ${attempts}: ${detail}`);
717
1142
  return updated;
718
1143
  }
@@ -737,7 +1162,7 @@ function finalizeActivation(runtimeRoot, pointer) {
737
1162
  throw new Error("runtime activation generation changed before finalization");
738
1163
  }
739
1164
  journalActivation(runtimeRoot, pointer.pending.action_id, "attesting", `${pointer.active.version} verified`);
740
- atomicWriteJson(join(runtimeRoot, "current.json"), {
1165
+ atomicWriteJson(join2(runtimeRoot, "current.json"), {
741
1166
  schema_version: 1,
742
1167
  generation: pointer.generation,
743
1168
  active: pointer.active,
@@ -767,7 +1192,7 @@ function rollbackActivation(runtimeRoot, pointer, detail) {
767
1192
  rolled_back_at: (/* @__PURE__ */ new Date()).toISOString()
768
1193
  }
769
1194
  };
770
- atomicWriteJson(join(runtimeRoot, "current.json"), rolledBack);
1195
+ atomicWriteJson(join2(runtimeRoot, "current.json"), rolledBack);
771
1196
  try {
772
1197
  journalActivation(runtimeRoot, pointer.pending.action_id, "rolled-back", detail);
773
1198
  } catch {
@@ -779,7 +1204,7 @@ function acknowledgeActivationFailure(runtimeRoot, pointer) {
779
1204
  if (current?.generation !== pointer?.generation || current?.pending?.action_id !== pointer?.pending?.action_id || current?.pending?.terminal_status !== "failed") {
780
1205
  throw new Error("runtime rollback acknowledgement obligation changed");
781
1206
  }
782
- atomicWriteJson(join(runtimeRoot, "current.json"), { ...current, pending: null });
1207
+ atomicWriteJson(join2(runtimeRoot, "current.json"), { ...current, pending: null });
783
1208
  try {
784
1209
  journalActivation(runtimeRoot, pointer.pending.action_id, "failure-acknowledged", pointer.pending.terminal_detail);
785
1210
  } catch {
@@ -828,9 +1253,9 @@ function buildMinimalMaintenanceEnv(env = process.env, runtimeRoot = "") {
828
1253
  npm_config_update_notifier: "false",
829
1254
  npm_config_registry: PUBLIC_REGISTRY,
830
1255
  ...runtimeRoot ? {
831
- npm_config_userconfig: join2(runtimeRoot, "maintenance", "user.npmrc"),
832
- npm_config_globalconfig: join2(runtimeRoot, "maintenance", "global.npmrc"),
833
- npm_config_cache: join2(runtimeRoot, "maintenance", "npm-cache")
1256
+ npm_config_userconfig: join3(runtimeRoot, "maintenance", "user.npmrc"),
1257
+ npm_config_globalconfig: join3(runtimeRoot, "maintenance", "global.npmrc"),
1258
+ npm_config_cache: join3(runtimeRoot, "maintenance", "npm-cache")
834
1259
  } : {}
835
1260
  };
836
1261
  }
@@ -870,20 +1295,20 @@ function parseJsonOutput(result, operation) {
870
1295
  }
871
1296
  }
872
1297
  function tarballIntegrity(file) {
873
- return `sha512-${createHash2("sha512").update(readFileSync2(file)).digest("base64")}`;
1298
+ return `sha512-${createHash4("sha512").update(readFileSync4(file)).digest("base64")}`;
874
1299
  }
875
1300
  function assertNoLinks(root) {
876
1301
  const pending = [root];
877
1302
  while (pending.length) {
878
1303
  const current = pending.pop();
879
- const stat = lstatSync2(current);
1304
+ const stat = lstatSync3(current);
880
1305
  if (stat.isSymbolicLink()) throw new Error("installed runtime contains a link/reparse point");
881
1306
  if (!stat.isDirectory()) continue;
882
- for (const entry of readdirSync2(current)) pending.push(join2(current, entry));
1307
+ for (const entry of readdirSync3(current)) pending.push(join3(current, entry));
883
1308
  }
884
1309
  }
885
1310
  function validateDependencyLock(payloadRoot, expected) {
886
- const lock = JSON.parse(readFileSync2(join2(payloadRoot, "package-lock.json"), "utf8"));
1311
+ const lock = JSON.parse(readFileSync4(join3(payloadRoot, "package-lock.json"), "utf8"));
887
1312
  if (Number(lock.lockfileVersion) < 3 || !lock.packages || typeof lock.packages !== "object") {
888
1313
  throw new Error("runtime dependency lock is missing or unsupported");
889
1314
  }
@@ -913,23 +1338,40 @@ function buildActive(slotId, metadata, paths) {
913
1338
  tree_sha512: hashRuntimeTree(paths.slotRoot ?? paths.payloadRoot)
914
1339
  };
915
1340
  }
916
- function installSlot({ runtimeRoot, metadata, tarball, runner, npmEnv, runOptions, force }) {
917
- const digest = createHash2("sha256").update(metadata.integrity).digest("hex").slice(0, 16);
1341
+ function installSlot({
1342
+ runtimeRoot,
1343
+ metadata,
1344
+ tarball,
1345
+ runner,
1346
+ npmEnv,
1347
+ runOptions,
1348
+ force,
1349
+ runtimeAuthorization
1350
+ }) {
1351
+ const digest = createHash4("sha256").update(metadata.integrity).digest("hex").slice(0, 16);
918
1352
  const suffix = force ? `${digest}-${randomUUID2().slice(0, 8)}` : digest;
919
1353
  const slotId = `vo-mcp-${metadata.version}-${suffix}`;
920
1354
  const finalPaths = slotPaths(runtimeRoot, slotId);
921
- if (!force && existsSync3(finalPaths.slotRoot)) {
922
- const manifest = JSON.parse(readFileSync2(finalPaths.manifest, "utf8"));
1355
+ if (!force && existsSync4(finalPaths.slotRoot)) {
1356
+ const manifest = JSON.parse(readFileSync4(finalPaths.manifest, "utf8"));
923
1357
  const active = buildActive(slotId, metadata, finalPaths);
924
1358
  const validated = validateSlot(runtimeRoot, active);
925
- if (validated.ok && manifest.integrity === metadata.integrity) return { active, created: false };
1359
+ if (validated.ok && manifest.integrity === metadata.integrity) {
1360
+ if (runtimeAuthorization) {
1361
+ validateStagedRuntimeAuthorization({
1362
+ payloadRoot: finalPaths.slotRoot,
1363
+ authorization: runtimeAuthorization
1364
+ });
1365
+ }
1366
+ return { active, created: false };
1367
+ }
926
1368
  }
927
- const staging = join2(runtimeRoot, "staging", randomUUID2());
928
- const payload = join2(staging, "payload");
1369
+ const staging = join3(runtimeRoot, "staging", randomUUID2());
1370
+ const payload = join3(staging, "payload");
929
1371
  let installedSlot = false;
930
1372
  try {
931
1373
  mkdirSync2(payload, { recursive: true });
932
- writeFileSync2(join2(payload, "package.json"), `${JSON.stringify({ name: "algohq-runner-runtime", version: "0.0.0", private: true })}
1374
+ writeFileSync2(join3(payload, "package.json"), `${JSON.stringify({ name: "algohq-runner-runtime", version: "0.0.0", private: true })}
933
1375
  `);
934
1376
  const install = runner.npm([
935
1377
  "install",
@@ -945,24 +1387,27 @@ function installSlot({ runtimeRoot, metadata, tarball, runner, npmEnv, runOption
945
1387
  if (install.status !== 0) throw new Error(`npm install failed: ${install.stderr || install.error?.message || install.status}`);
946
1388
  assertNoLinks(payload);
947
1389
  validateDependencyLock(payload, metadata);
1390
+ if (runtimeAuthorization) {
1391
+ validateStagedRuntimeAuthorization({ payloadRoot: payload, authorization: runtimeAuthorization });
1392
+ }
948
1393
  const stagedPaths = {
949
- entry: join2(payload, "node_modules", "@algosuite", "vo-mcp", "bin", "vo-mcp"),
950
- supervisor: join2(payload, "node_modules", "@algosuite", "vo-mcp", "dist", "runner-supervisor.js"),
951
- packageJson: join2(payload, "node_modules", "@algosuite", "vo-mcp", "package.json"),
952
- credentialHelper: join2(payload, "node_modules", "@algosuite", "vo-mcp", "dist", "supervisor-credential-helper.js"),
1394
+ entry: join3(payload, "node_modules", "@algosuite", "vo-mcp", "bin", "vo-mcp"),
1395
+ supervisor: join3(payload, "node_modules", "@algosuite", "vo-mcp", "dist", "runner-supervisor.js"),
1396
+ packageJson: join3(payload, "node_modules", "@algosuite", "vo-mcp", "package.json"),
1397
+ credentialHelper: join3(payload, "node_modules", "@algosuite", "vo-mcp", "dist", "supervisor-credential-helper.js"),
953
1398
  slotRoot: payload
954
1399
  };
955
- const pkg = JSON.parse(readFileSync2(stagedPaths.packageJson, "utf8"));
1400
+ const pkg = JSON.parse(readFileSync4(stagedPaths.packageJson, "utf8"));
956
1401
  if (pkg.name !== PACKAGE_NAME || pkg.version !== metadata.version) throw new Error("installed package identity mismatch");
957
- if (!lstatSync2(stagedPaths.credentialHelper).isFile()) throw new Error("installed credential helper is missing");
1402
+ if (!lstatSync3(stagedPaths.credentialHelper).isFile()) throw new Error("installed credential helper is missing");
958
1403
  const smoke = runner.node([stagedPaths.entry, "runner", "--version"], { ...runOptions, cwd: payload, env: npmEnv, timeout: 3e4 });
959
1404
  if (smoke.status !== 0 || String(smoke.stdout || "").trim() !== `vo-mcp runner ${metadata.version}`) {
960
1405
  throw new Error("bundled runtime smoke check failed");
961
1406
  }
962
1407
  const active = buildActive(slotId, metadata, stagedPaths);
963
- atomicWriteJson(join2(payload, "runtime-manifest.json"), { schema_version: 1, ...active });
964
- mkdirSync2(join2(runtimeRoot, "slots"), { recursive: true });
965
- if (existsSync3(finalPaths.slotRoot)) throw new Error("immutable runtime slot already exists");
1408
+ atomicWriteJson(join3(payload, "runtime-manifest.json"), { schema_version: 1, ...active });
1409
+ mkdirSync2(join3(runtimeRoot, "slots"), { recursive: true });
1410
+ if (existsSync4(finalPaths.slotRoot)) throw new Error("immutable runtime slot already exists");
966
1411
  renameSync2(payload, finalPaths.slotRoot);
967
1412
  installedSlot = true;
968
1413
  const validated = validateSlot(runtimeRoot, active);
@@ -984,11 +1429,12 @@ function stageBundledRuntimeSlot(options) {
984
1429
  platform = process.platform,
985
1430
  execPath = process.execPath,
986
1431
  env = process.env,
987
- fileExists = existsSync3,
1432
+ fileExists = existsSync4,
988
1433
  run = defaultRun,
989
- force = false
1434
+ force = false,
1435
+ runtimeAuthorization = null
990
1436
  } = options;
991
- if (!runtimeRoot || !isAbsolute2(runtimeRoot)) return { ok: false, status: 2, detail: "bundled runtime root unavailable" };
1437
+ if (!runtimeRoot || !isAbsolute3(runtimeRoot)) return { ok: false, status: 2, detail: "bundled runtime root unavailable" };
992
1438
  if (!expectedVersion || !PACKAGE_SPEC_RE2.test(`${PACKAGE_NAME}@${expectedVersion}`)) {
993
1439
  return { ok: false, status: 2, detail: "invalid expected runner version" };
994
1440
  }
@@ -997,18 +1443,18 @@ function stageBundledRuntimeSlot(options) {
997
1443
  }
998
1444
  const exactSpec = `${PACKAGE_NAME}@${expectedVersion}`;
999
1445
  if (packageSpec !== exactSpec) return { ok: false, status: 2, detail: "runner package spec does not match authorized version" };
1000
- const resolvedRoot = resolve2(runtimeRoot);
1446
+ const resolvedRoot = resolve4(runtimeRoot);
1001
1447
  const npmEnv = buildMinimalMaintenanceEnv(env, resolvedRoot);
1002
1448
  const runOptions = { env: npmEnv, cwd: resolvedRoot };
1003
1449
  let tarDir = null;
1004
1450
  try {
1005
1451
  mkdirSync2(resolvedRoot, { recursive: true });
1006
- mkdirSync2(join2(resolvedRoot, "maintenance"), { recursive: true });
1452
+ mkdirSync2(join3(resolvedRoot, "maintenance"), { recursive: true });
1007
1453
  writeFileSync2(npmEnv.npm_config_userconfig, "", { mode: 384 });
1008
1454
  writeFileSync2(npmEnv.npm_config_globalconfig, "", { mode: 384 });
1009
1455
  const runner = commandRunner({ platform, execPath, env: npmEnv, fileExists, run });
1010
1456
  const metadata = { version: expectedVersion, integrity: expectedIntegrity };
1011
- tarDir = join2(resolvedRoot, "staging", randomUUID2());
1457
+ tarDir = join3(resolvedRoot, "staging", randomUUID2());
1012
1458
  mkdirSync2(tarDir, { recursive: true });
1013
1459
  const packed = parseJsonOutput(runner.npm([
1014
1460
  "pack",
@@ -1020,13 +1466,22 @@ function stageBundledRuntimeSlot(options) {
1020
1466
  `--registry=${PUBLIC_REGISTRY}`
1021
1467
  ], runOptions), "npm pack");
1022
1468
  const record = Array.isArray(packed) ? packed[0] : packed;
1023
- const tarball = join2(tarDir, basename(String(record?.filename || "")));
1024
- if (!existsSync3(tarball) || !basename(tarball).endsWith(".tgz")) throw new Error("npm pack returned no tarball");
1025
- if (lstatSync2(tarball).size > MAX_TARBALL_BYTES) throw new Error("runner package tarball exceeds size limit");
1469
+ const tarball = join3(tarDir, basename(String(record?.filename || "")));
1470
+ if (!existsSync4(tarball) || !basename(tarball).endsWith(".tgz")) throw new Error("npm pack returned no tarball");
1471
+ if (lstatSync3(tarball).size > MAX_TARBALL_BYTES) throw new Error("runner package tarball exceeds size limit");
1026
1472
  if (record.integrity !== metadata.integrity || tarballIntegrity(tarball) !== metadata.integrity) {
1027
1473
  throw new Error("runner package sha512 integrity mismatch");
1028
1474
  }
1029
- const installed = installSlot({ runtimeRoot: resolvedRoot, metadata, tarball, runner, npmEnv, runOptions, force });
1475
+ const installed = installSlot({
1476
+ runtimeRoot: resolvedRoot,
1477
+ metadata,
1478
+ tarball,
1479
+ runner,
1480
+ npmEnv,
1481
+ runOptions,
1482
+ force,
1483
+ runtimeAuthorization
1484
+ });
1030
1485
  return { ok: true, status: 0, ...installed };
1031
1486
  } catch (error) {
1032
1487
  return { ok: false, status: 1, detail: sanitizeMaintenanceDiagnostic(error instanceof Error ? error.message : String(error), env) };
@@ -1038,7 +1493,7 @@ function stageAndActivateBundledUpdate(options) {
1038
1493
  const staged = stageBundledRuntimeSlot(options);
1039
1494
  if (!staged.ok) return staged;
1040
1495
  try {
1041
- activateSlot(resolve2(options.runtimeRoot), staged.active, options.action);
1496
+ activateSlot(resolve4(options.runtimeRoot), staged.active, options.action);
1042
1497
  return { ...staged, handoff: true };
1043
1498
  } catch (error) {
1044
1499
  return {
@@ -1051,7 +1506,7 @@ function stageAndActivateBundledUpdate(options) {
1051
1506
 
1052
1507
  // src/runner/supervisor-activation.mjs
1053
1508
  var MAX_ACK_ATTEMPTS = 3;
1054
- var delay = (ms) => new Promise((resolve3) => setTimeout(resolve3, ms));
1509
+ var delay = (ms) => new Promise((resolve5) => setTimeout(resolve5, ms));
1055
1510
  async function waitForAuthoritativeRunnerHeartbeat({
1056
1511
  client,
1057
1512
  runnerId: runnerId2,
@@ -1405,14 +1860,14 @@ async function prepareSupervisorAuth({
1405
1860
 
1406
1861
  // src/runner/supervisor-credential-reader.mjs
1407
1862
  import { spawnSync as spawnSync3 } from "node:child_process";
1408
- import { existsSync as existsSync4 } from "node:fs";
1409
- import { dirname as dirname2, join as join3 } from "node:path";
1410
- import { fileURLToPath } from "node:url";
1863
+ import { existsSync as existsSync5 } from "node:fs";
1864
+ import { dirname as dirname3, join as join4 } from "node:path";
1865
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
1411
1866
  function defaultCredentialHelperPath(metaUrl = import.meta.url) {
1412
- const moduleDir = dirname2(fileURLToPath(metaUrl));
1413
- const bundled = join3(moduleDir, "supervisor-credential-helper.js");
1414
- const source = join3(moduleDir, "..", "supervisor-credential-helper.mjs");
1415
- return existsSync4(source) ? source : bundled;
1867
+ const moduleDir = dirname3(fileURLToPath2(metaUrl));
1868
+ const bundled = join4(moduleDir, "supervisor-credential-helper.js");
1869
+ const source = join4(moduleDir, "..", "supervisor-credential-helper.mjs");
1870
+ return existsSync5(source) ? source : bundled;
1416
1871
  }
1417
1872
  function readStoredCredentialIsolated({
1418
1873
  spawn: spawn2 = spawnSync3,
@@ -1446,9 +1901,9 @@ var POLL_MS = 5e3;
1446
1901
  var CHILD_START_MS = 1500;
1447
1902
  var SUPERVISOR_CAPABILITIES = ["bundled-runtime-slots-v1"];
1448
1903
  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;
1449
- var selfPath = fileURLToPath2(import.meta.url);
1450
- var childEntry = join4(dirname3(selfPath), "runner-cli.js");
1451
- var sleep = (ms) => new Promise((resolve3) => setTimeout(resolve3, ms));
1904
+ var selfPath = fileURLToPath3(import.meta.url);
1905
+ var childEntry = join5(dirname4(selfPath), "runner-cli.js");
1906
+ var sleep = (ms) => new Promise((resolve5) => setTimeout(resolve5, ms));
1452
1907
  var runnerId = resolveSupervisorRunnerId(process.env);
1453
1908
  function packageVersion() {
1454
1909
  try {
@@ -1507,7 +1962,7 @@ async function stopChild(child) {
1507
1962
  if (!child || child.exitCode !== null) return;
1508
1963
  child.kill(process.platform === "win32" ? void 0 : "SIGTERM");
1509
1964
  await Promise.race([
1510
- new Promise((resolve3) => child.once("exit", resolve3)),
1965
+ new Promise((resolve5) => child.once("exit", resolve5)),
1511
1966
  sleep(15e3)
1512
1967
  ]);
1513
1968
  if (child.exitCode === null) child.kill("SIGKILL");