@algosuite/vo-mcp 0.2.0-beta.21 → 0.2.0-beta.22

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.
@@ -36,6 +36,31 @@ import { createRequire } 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
 
39
+ // ../../scripts/virtual-office/code-runner/installation-token.mjs
40
+ var READ_TOKEN_TIMEOUT_MS = 15e3;
41
+ async function fetchInstallationToken({ req, required = false, readOnly = false, repo = null }) {
42
+ const fail = (reason) => {
43
+ if (required) throw new Error(`installation-token required: ${reason}`);
44
+ return null;
45
+ };
46
+ try {
47
+ const res = await req(
48
+ "POST",
49
+ "/api/v1/github/installation-token",
50
+ readOnly ? { scope: "read", ...repo ? { repo } : {} } : {},
51
+ readOnly ? { timeoutMs: READ_TOKEN_TIMEOUT_MS } : {}
52
+ );
53
+ if (!res.ok) return fail(`HTTP ${res.status}`);
54
+ const json = await res.json();
55
+ if (!json || !json.token) return fail("missing token");
56
+ if (readOnly && json.scope !== "read") return fail("control plane did not confirm a read-only grant");
57
+ return { token: json.token, expiresAt: json.expires_at || null };
58
+ } catch (err) {
59
+ if (required) throw err;
60
+ return null;
61
+ }
62
+ }
63
+
39
64
  // ../../scripts/virtual-office/code-runner/control-plane-client.mjs
40
65
  var cachedFirebaseToken = null;
41
66
  async function resolveBearer(env) {
@@ -345,37 +370,9 @@ function createControlPlaneClient({
345
370
  const json = await res.json();
346
371
  return json?.action || null;
347
372
  },
348
- /**
349
- * Mint a short-lived (~1h), repo-scoped GitHub App installation token for
350
- * THIS runner's operator (M3). The control-plane keys the mint on the
351
- * authenticated operator (ctx.operator_id), so the token covers only that
352
- * operator's installation.
353
- *
354
- * Returns { token, expiresAt } on success. In legacy/admin mode it returns
355
- * null on a miss so the caller may use ambient `gh`. In scoped-operator mode
356
- * callers pass `{ required: true }`, which fails closed instead of letting a
357
- * missing/mis-scoped installation fall through to the runner machine's `gh`.
358
- *
359
- * The minted token is only usable for push + PR if the GitHub App grants
360
- * BOTH `Contents: write` (git push) AND `Pull requests: write` (gh pr
361
- * create) — see docs/vo/github-app-setup-2026-06-18.md. A token missing
362
- * either scope fails at push (→ ambient fallback) or at `gh pr create`.
363
- */
364
- async getInstallationToken({ required = false } = {}) {
365
- const fail = (reason) => {
366
- if (required) throw new Error(`installation-token required: ${reason}`);
367
- return null;
368
- };
369
- try {
370
- const res = await req("POST", "/api/v1/github/installation-token", {});
371
- if (!res.ok) return fail(`HTTP ${res.status}`);
372
- const json = await res.json();
373
- if (!json || !json.token) return fail("missing token");
374
- return { token: json.token, expiresAt: json.expires_at || null };
375
- } catch (err) {
376
- if (required) throw err;
377
- return null;
378
- }
373
+ /** Mint a GitHub App installation token — see installation-token.mjs. */
374
+ async getInstallationToken({ required = false, readOnly = false, repo = null } = {}) {
375
+ return fetchInstallationToken({ req, required, readOnly, repo });
379
376
  },
380
377
  /**
381
378
  * Read the operator's dispatch-mode config (Fast→Ultracode effort setting).