@algosuite/vo-mcp 0.2.0-beta.34 → 0.2.0-beta.36
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/runner-cli.js +129 -246
- package/dist/runner-cli.js.map +4 -4
- package/package.json +1 -1
package/dist/runner-cli.js
CHANGED
|
@@ -2582,11 +2582,6 @@ var init_control_plane_auth_stub = __esm({
|
|
|
2582
2582
|
});
|
|
2583
2583
|
|
|
2584
2584
|
// ../../scripts/virtual-office/code-runner/control-plane-client.mjs
|
|
2585
|
-
var control_plane_client_exports = {};
|
|
2586
|
-
__export(control_plane_client_exports, {
|
|
2587
|
-
ClaimAuthorityChangedError: () => ClaimAuthorityChangedError,
|
|
2588
|
-
createControlPlaneClient: () => createControlPlaneClient
|
|
2589
|
-
});
|
|
2590
2585
|
async function resolveBearer(env2) {
|
|
2591
2586
|
const adminToken = env2.VO_CONTROL_PLANE_ADMIN_TOKEN;
|
|
2592
2587
|
if (adminToken) return adminToken;
|
|
@@ -2619,11 +2614,11 @@ function createControlPlaneClient({
|
|
|
2619
2614
|
const resolvedBaseUrl = baseUrl ?? env2.VO_CONTROL_PLANE_URL ?? "";
|
|
2620
2615
|
if (!resolvedBaseUrl) throw new Error("VO_CONTROL_PLANE_URL is required for the code-runner daemon");
|
|
2621
2616
|
const root = resolvedBaseUrl.replace(/\/+$/, "");
|
|
2622
|
-
async function req(method,
|
|
2617
|
+
async function req(method, path22, body, { timeoutMs } = {}) {
|
|
2623
2618
|
const bearer = await resolveBearer(env2);
|
|
2624
2619
|
const controller = timeoutMs ? new AbortController() : null;
|
|
2625
2620
|
let timeoutId;
|
|
2626
|
-
const request = Promise.resolve(fetchImpl(`${root}${
|
|
2621
|
+
const request = Promise.resolve(fetchImpl(`${root}${path22}`, {
|
|
2627
2622
|
method,
|
|
2628
2623
|
headers: {
|
|
2629
2624
|
"content-type": "application/json",
|
|
@@ -2636,7 +2631,7 @@ function createControlPlaneClient({
|
|
|
2636
2631
|
const timeout = new Promise((_, reject) => {
|
|
2637
2632
|
timeoutId = setTimeout(() => {
|
|
2638
2633
|
controller.abort();
|
|
2639
|
-
reject(new Error(`control-plane ${
|
|
2634
|
+
reject(new Error(`control-plane ${path22} timed out after ${timeoutMs}ms`));
|
|
2640
2635
|
}, timeoutMs);
|
|
2641
2636
|
});
|
|
2642
2637
|
try {
|
|
@@ -2645,7 +2640,7 @@ function createControlPlaneClient({
|
|
|
2645
2640
|
clearTimeout(timeoutId);
|
|
2646
2641
|
}
|
|
2647
2642
|
}
|
|
2648
|
-
const taskReq = (method,
|
|
2643
|
+
const taskReq = (method, path22, body, options = {}) => req(method, path22, body, { timeoutMs: taskRequestTimeoutMs, ...options });
|
|
2649
2644
|
return {
|
|
2650
2645
|
...makeAutonomousDispatchAdmissionClient(
|
|
2651
2646
|
req,
|
|
@@ -2768,8 +2763,8 @@ function createControlPlaneClient({
|
|
|
2768
2763
|
return listAllPrOpenedTasks(taskReq);
|
|
2769
2764
|
},
|
|
2770
2765
|
async downloadTaskAttachment(taskId, attachmentId) {
|
|
2771
|
-
const
|
|
2772
|
-
const res = await taskReq("GET",
|
|
2766
|
+
const path22 = `/api/v1/code-task/${encodeURIComponent(taskId)}/attachment/${encodeURIComponent(attachmentId)}`;
|
|
2767
|
+
const res = await taskReq("GET", path22);
|
|
2773
2768
|
if (res.status === 401) cachedFirebaseToken = null;
|
|
2774
2769
|
if (!res.ok) throw new Error(`attachment download failed: HTTP ${res.status}`);
|
|
2775
2770
|
return Buffer.from(await res.arrayBuffer());
|
|
@@ -5981,14 +5976,14 @@ function parsePorcelainZ(out) {
|
|
|
5981
5976
|
for (let i = 0; i < tokens.length; i += 1) {
|
|
5982
5977
|
const token2 = tokens[i];
|
|
5983
5978
|
if (!token2) continue;
|
|
5984
|
-
const
|
|
5985
|
-
if (
|
|
5979
|
+
const path22 = token2.slice(3);
|
|
5980
|
+
if (path22) files.push(path22);
|
|
5986
5981
|
if (token2[0] === "R" || token2[0] === "C") i += 1;
|
|
5987
5982
|
}
|
|
5988
5983
|
return files;
|
|
5989
5984
|
}
|
|
5990
|
-
function isAgentScratch(
|
|
5991
|
-
const normalized = String(
|
|
5985
|
+
function isAgentScratch(path22) {
|
|
5986
|
+
const normalized = String(path22 || "");
|
|
5992
5987
|
return SCRATCH_PATTERNS.some((pattern) => pattern.test(normalized));
|
|
5993
5988
|
}
|
|
5994
5989
|
var SCRATCH_PATTERNS;
|
|
@@ -6055,6 +6050,15 @@ var init_publish = __esm({
|
|
|
6055
6050
|
}
|
|
6056
6051
|
});
|
|
6057
6052
|
|
|
6053
|
+
// ../../scripts/virtual-office/test-gen/marker.mjs
|
|
6054
|
+
var TEST_GEN_MARKER;
|
|
6055
|
+
var init_marker = __esm({
|
|
6056
|
+
"../../scripts/virtual-office/test-gen/marker.mjs"() {
|
|
6057
|
+
"use strict";
|
|
6058
|
+
TEST_GEN_MARKER = "[VO-TEST-GEN]";
|
|
6059
|
+
}
|
|
6060
|
+
});
|
|
6061
|
+
|
|
6058
6062
|
// ../../scripts/virtual-office/test-gen/auto-tier.mjs
|
|
6059
6063
|
function lower(s) {
|
|
6060
6064
|
return typeof s === "string" ? s.toLowerCase() : "";
|
|
@@ -6128,146 +6132,6 @@ var init_auto_tier = __esm({
|
|
|
6128
6132
|
}
|
|
6129
6133
|
});
|
|
6130
6134
|
|
|
6131
|
-
// ../../scripts/virtual-office/test-gen/dispatch.mjs
|
|
6132
|
-
import { spawnSync as spawnSync10 } from "node:child_process";
|
|
6133
|
-
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
6134
|
-
import path14 from "node:path";
|
|
6135
|
-
function buildGenerationPrompt({ contract = {}, tier }) {
|
|
6136
|
-
const label = tierLabel(tier);
|
|
6137
|
-
const target = contract.callable ? `the \`${contract.callable}\` callable` : contract.route ? `the \`${contract.route}\` route` : contract.feature_name || "the feature";
|
|
6138
|
-
return [
|
|
6139
|
-
`Write a ${label} test for ${target} in product "${contract.product || "unknown"}".`,
|
|
6140
|
-
contract.source_file ? `Source: ${contract.source_file}.` : "",
|
|
6141
|
-
contract.expected_behavior ? `Expected behavior: ${contract.expected_behavior}.` : "",
|
|
6142
|
-
"",
|
|
6143
|
-
`TIER REQUIREMENT \u2014 ${TIER_GUIDANCE[tier] || TIER_GUIDANCE[2]}`,
|
|
6144
|
-
"",
|
|
6145
|
-
"Follow the AlgoSuite test-honesty standard: NO fake-green (no bare toBeTruthy, no broad",
|
|
6146
|
-
"try/catch that swallows failures, no treating INVALID_ARGUMENT / empty / null / SKIP as a",
|
|
6147
|
-
"pass). Use a real fixture (smoke@algosuite.ai) and real data shapes.",
|
|
6148
|
-
"",
|
|
6149
|
-
"After writing the test, it will be GATED server-side: deterministic ratchets, then",
|
|
6150
|
-
"multi-model consensus that it proves the behavior with VERIFIED-CORRECT expected values.",
|
|
6151
|
-
"A test that does not pass BOTH gates will NOT ship \u2014 so make the assertions real and the",
|
|
6152
|
-
"expected values known-correct. Leave the test file UNCOMMITTED; the runner opens the PR."
|
|
6153
|
-
].filter((l) => l !== "").join("\n");
|
|
6154
|
-
}
|
|
6155
|
-
function planTestGenDispatch({ contract = {} }) {
|
|
6156
|
-
const { tier, rationale } = classifyTier(contract);
|
|
6157
|
-
return {
|
|
6158
|
-
contract,
|
|
6159
|
-
tier,
|
|
6160
|
-
tier_label: tierLabel(tier),
|
|
6161
|
-
tier_rationale: rationale,
|
|
6162
|
-
generation_prompt: buildGenerationPrompt({ contract, tier })
|
|
6163
|
-
};
|
|
6164
|
-
}
|
|
6165
|
-
function buildTestGenTaskPrompt(dispatch = {}) {
|
|
6166
|
-
const contractJson = JSON.stringify(dispatch.contract ?? {});
|
|
6167
|
-
return `${TEST_GEN_MARKER} ${contractJson}
|
|
6168
|
-
|
|
6169
|
-
${dispatch.generation_prompt ?? ""}`;
|
|
6170
|
-
}
|
|
6171
|
-
function pickNextTarget({ gaps = [] }) {
|
|
6172
|
-
if (!Array.isArray(gaps) || gaps.length === 0) return null;
|
|
6173
|
-
const ranked = [...gaps].sort((a, b) => {
|
|
6174
|
-
const al = LEGAL.has(String(a.product)) ? 0 : 1;
|
|
6175
|
-
const bl = LEGAL.has(String(b.product)) ? 0 : 1;
|
|
6176
|
-
return al - bl;
|
|
6177
|
-
});
|
|
6178
|
-
return ranked[0];
|
|
6179
|
-
}
|
|
6180
|
-
function resolveRepo(argv, env2) {
|
|
6181
|
-
const repoArg = argv.indexOf("--repo");
|
|
6182
|
-
if (repoArg >= 0 && argv[repoArg + 1]) return argv[repoArg + 1];
|
|
6183
|
-
if (env2.VO_TEST_GEN_REPO) return env2.VO_TEST_GEN_REPO;
|
|
6184
|
-
const remote = spawnSync10("git", ["remote", "get-url", "origin"], { encoding: "utf8" });
|
|
6185
|
-
if (remote.status === 0) {
|
|
6186
|
-
const m = String(remote.stdout).trim().match(/[:/]([^/]+\/[^/]+?)(?:\.git)?$/);
|
|
6187
|
-
if (m) return m[1];
|
|
6188
|
-
}
|
|
6189
|
-
return null;
|
|
6190
|
-
}
|
|
6191
|
-
async function main(argv = process.argv.slice(2)) {
|
|
6192
|
-
const countArg = argv.indexOf("--count");
|
|
6193
|
-
const count3 = countArg >= 0 ? Math.max(1, Number(argv[countArg + 1]) || 1) : 1;
|
|
6194
|
-
const enqueue = argv.includes("--enqueue");
|
|
6195
|
-
const here = path14.dirname(fileURLToPath3(import.meta.url));
|
|
6196
|
-
const scan = spawnSync10("node", [path14.join(here, "coverage-scan.mjs"), "--limit", String(count3 * 8)], {
|
|
6197
|
-
encoding: "utf8",
|
|
6198
|
-
maxBuffer: 64 * 1024 * 1024
|
|
6199
|
-
});
|
|
6200
|
-
if (scan.status !== 0) {
|
|
6201
|
-
console.error(`[dispatch] coverage-scan failed: ${scan.stderr || scan.stdout}`);
|
|
6202
|
-
process.exit(1);
|
|
6203
|
-
}
|
|
6204
|
-
let gaps = [];
|
|
6205
|
-
try {
|
|
6206
|
-
gaps = JSON.parse(scan.stdout).gaps || [];
|
|
6207
|
-
} catch (err) {
|
|
6208
|
-
console.error(`[dispatch] could not parse scan output: ${err.message}`);
|
|
6209
|
-
process.exit(1);
|
|
6210
|
-
}
|
|
6211
|
-
const dispatches = [];
|
|
6212
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6213
|
-
let pool = gaps;
|
|
6214
|
-
while (dispatches.length < count3 && pool.length > 0) {
|
|
6215
|
-
const target = pickNextTarget({ gaps: pool });
|
|
6216
|
-
if (!target) break;
|
|
6217
|
-
const key = `${target.product}:${target.callable}`;
|
|
6218
|
-
if (!seen.has(key)) {
|
|
6219
|
-
seen.add(key);
|
|
6220
|
-
dispatches.push(planTestGenDispatch({ contract: target }));
|
|
6221
|
-
}
|
|
6222
|
-
pool = pool.filter((g) => `${g.product}:${g.callable}` !== key);
|
|
6223
|
-
}
|
|
6224
|
-
if (!enqueue) {
|
|
6225
|
-
console.log(JSON.stringify({ requested: count3, emitted: dispatches.length, dispatches }, null, 2));
|
|
6226
|
-
return;
|
|
6227
|
-
}
|
|
6228
|
-
const repo = resolveRepo(argv, process.env);
|
|
6229
|
-
if (!repo) {
|
|
6230
|
-
console.error("[dispatch] --enqueue needs a repo: pass --repo owner/name or set VO_TEST_GEN_REPO (could not derive from git origin)");
|
|
6231
|
-
process.exit(1);
|
|
6232
|
-
}
|
|
6233
|
-
const { createControlPlaneClient: createControlPlaneClient2 } = await Promise.resolve().then(() => (init_control_plane_client(), control_plane_client_exports));
|
|
6234
|
-
const client = createControlPlaneClient2({ env: process.env });
|
|
6235
|
-
const enqueued = [];
|
|
6236
|
-
for (const d of dispatches) {
|
|
6237
|
-
const task = await client.enqueueCodeTask({
|
|
6238
|
-
repo,
|
|
6239
|
-
prompt: buildTestGenTaskPrompt(d),
|
|
6240
|
-
max_turns: 40
|
|
6241
|
-
});
|
|
6242
|
-
const taskId = task && task.code_task_id ? task.code_task_id : "(unknown)";
|
|
6243
|
-
enqueued.push({ task_id: taskId, product: d.contract.product, callable: d.contract.callable, tier: d.tier_label });
|
|
6244
|
-
console.error(`[dispatch] enqueued ${d.tier_label} test-gen for ${d.contract.product}:${d.contract.callable} \u2192 task ${taskId}`);
|
|
6245
|
-
}
|
|
6246
|
-
console.log(JSON.stringify({ requested: count3, enqueued: enqueued.length, repo, tasks: enqueued }, null, 2));
|
|
6247
|
-
}
|
|
6248
|
-
var TEST_GEN_MARKER, TIER_GUIDANCE, LEGAL, invokedDirectly;
|
|
6249
|
-
var init_dispatch = __esm({
|
|
6250
|
-
"../../scripts/virtual-office/test-gen/dispatch.mjs"() {
|
|
6251
|
-
"use strict";
|
|
6252
|
-
init_auto_tier();
|
|
6253
|
-
TEST_GEN_MARKER = "[VO-TEST-GEN]";
|
|
6254
|
-
TIER_GUIDANCE = {
|
|
6255
|
-
1: "Surface/navigation smoke: assert the surface renders and the key controls are present. No backend effect needed.",
|
|
6256
|
-
2: "E2E with VERIFIED RESULTS: drive the real user/callable workflow, then READ BACK the produced artifact and assert KNOWN-CORRECT expected values (not just a 200 / truthiness).",
|
|
6257
|
-
3: "Real-time monitor / sentinel: drive the workflow AND verify the state transitions + safety rails (no money moved / graded / admin action without the guard). Assert the post-conditions, not just the response.",
|
|
6258
|
-
4: "Source-grounded governed-fact: assert expected values that are GROUNDED in the cited authoritative source (the contract's authoritative_source_url). The fixture and the expected number/string must trace to that source."
|
|
6259
|
-
};
|
|
6260
|
-
LEGAL = /* @__PURE__ */ new Set(["algotax", "algolaw", "algoteach", "algolegal"]);
|
|
6261
|
-
invokedDirectly = process.argv[1] && fileURLToPath3(import.meta.url) === path14.resolve(process.argv[1]);
|
|
6262
|
-
if (invokedDirectly) {
|
|
6263
|
-
main().catch((err) => {
|
|
6264
|
-
console.error(`[dispatch] ${err.message}`);
|
|
6265
|
-
process.exit(1);
|
|
6266
|
-
});
|
|
6267
|
-
}
|
|
6268
|
-
}
|
|
6269
|
-
});
|
|
6270
|
-
|
|
6271
6135
|
// ../../scripts/virtual-office/test-gen/executor.mjs
|
|
6272
6136
|
function consensusQuestion(tier) {
|
|
6273
6137
|
const tierAsk = tier >= 4 ? " For this governed-fact (Tier 4) test, the expected values MUST be grounded in the cited authoritative source." : tier >= 3 ? " For this safety-critical (Tier 3) test, it must verify state transitions and the safety rails, not just a 200." : "";
|
|
@@ -6374,7 +6238,7 @@ var init_executor = __esm({
|
|
|
6374
6238
|
|
|
6375
6239
|
// ../../scripts/virtual-office/code-runner/test-gen-gate.mjs
|
|
6376
6240
|
import fs7 from "node:fs";
|
|
6377
|
-
import
|
|
6241
|
+
import path14 from "node:path";
|
|
6378
6242
|
async function postFailed(client, id, message, result) {
|
|
6379
6243
|
try {
|
|
6380
6244
|
await client.postProgress(id, {
|
|
@@ -6410,7 +6274,7 @@ async function gateTestGenTaskOrFail({ client, id, task, files, worktreeDir, env
|
|
|
6410
6274
|
}
|
|
6411
6275
|
let testSource = "";
|
|
6412
6276
|
try {
|
|
6413
|
-
testSource = fs7.readFileSync(
|
|
6277
|
+
testSource = fs7.readFileSync(path14.join(worktreeDir, testFile), "utf8");
|
|
6414
6278
|
} catch (err) {
|
|
6415
6279
|
await postFailed(client, id, `could not read generated test ${testFile}: ${err.message}`, "gate_test_unreadable");
|
|
6416
6280
|
return true;
|
|
@@ -6451,7 +6315,7 @@ var TEST_FILE_RE;
|
|
|
6451
6315
|
var init_test_gen_gate = __esm({
|
|
6452
6316
|
"../../scripts/virtual-office/code-runner/test-gen-gate.mjs"() {
|
|
6453
6317
|
"use strict";
|
|
6454
|
-
|
|
6318
|
+
init_marker();
|
|
6455
6319
|
init_executor();
|
|
6456
6320
|
TEST_FILE_RE = /\.(test|spec)\.(ts|tsx|mjs|js)$/;
|
|
6457
6321
|
}
|
|
@@ -6460,7 +6324,7 @@ var init_test_gen_gate = __esm({
|
|
|
6460
6324
|
// ../../scripts/virtual-office/code-runner/completion-gate.mjs
|
|
6461
6325
|
import { execFile } from "node:child_process";
|
|
6462
6326
|
import fs8 from "node:fs";
|
|
6463
|
-
import
|
|
6327
|
+
import path15 from "node:path";
|
|
6464
6328
|
function resolveCompletionGate(task) {
|
|
6465
6329
|
const raw = task?.completion_gate;
|
|
6466
6330
|
if (raw === void 0 || raw === null) return null;
|
|
@@ -6498,14 +6362,14 @@ function workspaceFingerprint(worktreeDir, execFileImpl = execFile) {
|
|
|
6498
6362
|
}
|
|
6499
6363
|
function readState(worktreeDir) {
|
|
6500
6364
|
try {
|
|
6501
|
-
return JSON.parse(fs8.readFileSync(
|
|
6365
|
+
return JSON.parse(fs8.readFileSync(path15.join(worktreeDir, COMPLETION_GATE_STATE_FILE), "utf8"));
|
|
6502
6366
|
} catch {
|
|
6503
6367
|
return null;
|
|
6504
6368
|
}
|
|
6505
6369
|
}
|
|
6506
6370
|
function writeState(worktreeDir, state) {
|
|
6507
6371
|
try {
|
|
6508
|
-
fs8.writeFileSync(
|
|
6372
|
+
fs8.writeFileSync(path15.join(worktreeDir, COMPLETION_GATE_STATE_FILE), `${JSON.stringify(state)}
|
|
6509
6373
|
`, "utf8");
|
|
6510
6374
|
} catch {
|
|
6511
6375
|
}
|
|
@@ -7083,7 +6947,7 @@ var init_publish_async = __esm({
|
|
|
7083
6947
|
// ../../scripts/virtual-office/code-runner/skill-catalog.mjs
|
|
7084
6948
|
import { readdirSync as readdirSync2, readFileSync as readFileSync3, statSync } from "node:fs";
|
|
7085
6949
|
import { dirname as dirname3, join as join4 } from "node:path";
|
|
7086
|
-
import { fileURLToPath as
|
|
6950
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
7087
6951
|
function parseFrontmatterNameDescription(raw) {
|
|
7088
6952
|
const text = String(raw).replace(/\r\n/g, "\n");
|
|
7089
6953
|
if (!text.startsWith("---\n")) return null;
|
|
@@ -7102,7 +6966,7 @@ function parseFrontmatterNameDescription(raw) {
|
|
|
7102
6966
|
return name && description ? { name, description } : null;
|
|
7103
6967
|
}
|
|
7104
6968
|
function resolveDefaultRepoRoot() {
|
|
7105
|
-
const starts = [dirname3(
|
|
6969
|
+
const starts = [dirname3(fileURLToPath3(import.meta.url)), process.cwd()];
|
|
7106
6970
|
for (const start of starts) {
|
|
7107
6971
|
let dir = start;
|
|
7108
6972
|
for (let i = 0; i < 8; i += 1) {
|
|
@@ -7358,7 +7222,7 @@ var init_task_prompt = __esm({
|
|
|
7358
7222
|
import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
|
|
7359
7223
|
import { chmod, mkdir, mkdtemp, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
7360
7224
|
import os2 from "node:os";
|
|
7361
|
-
import
|
|
7225
|
+
import path16 from "node:path";
|
|
7362
7226
|
function safeTaskToken(taskId) {
|
|
7363
7227
|
return String(taskId || "task").replace(/[^0-9A-Za-z_-]/gu, "_").slice(0, 48) || "task";
|
|
7364
7228
|
}
|
|
@@ -7368,25 +7232,25 @@ function sanitizeTaskAttachmentName(name, index = 0) {
|
|
|
7368
7232
|
return `${String(index + 1).padStart(2, "0")}-${normalized}`;
|
|
7369
7233
|
}
|
|
7370
7234
|
function assertGeneratedDirectory(directory, tempRoot) {
|
|
7371
|
-
const resolvedDirectory =
|
|
7372
|
-
const resolvedRoot =
|
|
7373
|
-
if (
|
|
7235
|
+
const resolvedDirectory = path16.resolve(directory);
|
|
7236
|
+
const resolvedRoot = path16.resolve(tempRoot);
|
|
7237
|
+
if (path16.dirname(resolvedDirectory) !== resolvedRoot || !path16.basename(resolvedDirectory).startsWith(DIRECTORY_PREFIX)) {
|
|
7374
7238
|
throw new Error("refusing to clean an unverified task-attachment directory");
|
|
7375
7239
|
}
|
|
7376
7240
|
return resolvedDirectory;
|
|
7377
7241
|
}
|
|
7378
7242
|
async function createAttachmentDirectory(taskId, tempRoot) {
|
|
7379
|
-
const root =
|
|
7243
|
+
const root = path16.resolve(tempRoot);
|
|
7380
7244
|
await mkdir(root, { recursive: true });
|
|
7381
|
-
const directory = await mkdtemp(
|
|
7382
|
-
const marker = JSON.stringify({ owner: MARKER_OWNER, token: randomUUID2(), directory:
|
|
7383
|
-
await writeFile(
|
|
7245
|
+
const directory = await mkdtemp(path16.join(root, `${DIRECTORY_PREFIX}${safeTaskToken(taskId)}-`));
|
|
7246
|
+
const marker = JSON.stringify({ owner: MARKER_OWNER, token: randomUUID2(), directory: path16.basename(directory), created_at: (/* @__PURE__ */ new Date()).toISOString() });
|
|
7247
|
+
await writeFile(path16.join(directory, MARKER_FILE), marker, { encoding: "utf8", mode: 384 });
|
|
7384
7248
|
return { directory, marker, tempRoot: root };
|
|
7385
7249
|
}
|
|
7386
7250
|
async function cleanupGeneratedDirectory(state) {
|
|
7387
7251
|
if (!state || state.cleaned) return;
|
|
7388
7252
|
const directory = assertGeneratedDirectory(state.directory, state.tempRoot);
|
|
7389
|
-
const marker = await readFile(
|
|
7253
|
+
const marker = await readFile(path16.join(directory, MARKER_FILE), "utf8").catch(() => "");
|
|
7390
7254
|
if (marker !== state.marker) throw new Error("refusing to clean a task-attachment directory without its exact marker");
|
|
7391
7255
|
await rm(directory, { recursive: true, force: true });
|
|
7392
7256
|
state.cleaned = true;
|
|
@@ -7405,7 +7269,7 @@ async function sweepStaleTaskAttachmentDirectories({
|
|
|
7405
7269
|
now = Date.now(),
|
|
7406
7270
|
maxAgeMs = DEFAULT_STALE_AGE_MS
|
|
7407
7271
|
} = {}) {
|
|
7408
|
-
const root =
|
|
7272
|
+
const root = path16.resolve(tempRoot);
|
|
7409
7273
|
if (!Number.isFinite(maxAgeMs) || maxAgeMs <= 0) throw new Error("stale attachment age must be positive");
|
|
7410
7274
|
const entries = await readdir(root, { withFileTypes: true }).catch((error) => {
|
|
7411
7275
|
if (error?.code === "ENOENT") return [];
|
|
@@ -7414,8 +7278,8 @@ async function sweepStaleTaskAttachmentDirectories({
|
|
|
7414
7278
|
let removed = 0;
|
|
7415
7279
|
for (const entry of entries) {
|
|
7416
7280
|
if (!entry.isDirectory() || !entry.name.startsWith(DIRECTORY_PREFIX)) continue;
|
|
7417
|
-
const directory = assertGeneratedDirectory(
|
|
7418
|
-
const markerRaw = await readFile(
|
|
7281
|
+
const directory = assertGeneratedDirectory(path16.join(root, entry.name), root);
|
|
7282
|
+
const markerRaw = await readFile(path16.join(directory, MARKER_FILE), "utf8").catch(() => "");
|
|
7419
7283
|
const marker = parseOwnedMarker(markerRaw, entry.name);
|
|
7420
7284
|
if (!marker) continue;
|
|
7421
7285
|
const directoryStat = await stat(directory);
|
|
@@ -7458,10 +7322,10 @@ async function materializeTaskAttachments(client, task, { tempRoot = os2.tmpdir(
|
|
|
7458
7322
|
const sha256 = createHash3("sha256").update(content).digest("hex");
|
|
7459
7323
|
if (sha256 !== ref.sha256) throw new Error(`attachment ${ref.attachment_id} sha256 mismatch`);
|
|
7460
7324
|
const name = sanitizeTaskAttachmentName(ref.name, index);
|
|
7461
|
-
const filePath =
|
|
7325
|
+
const filePath = path16.join(state.directory, name);
|
|
7462
7326
|
await writeFile(filePath, content, { flag: "wx", mode: 384 });
|
|
7463
7327
|
await chmod(filePath, 384);
|
|
7464
|
-
files.push({ attachmentId: ref.attachment_id, name, mime: ref.mime, sizeBytes: ref.size_bytes, sha256, path:
|
|
7328
|
+
files.push({ attachmentId: ref.attachment_id, name, mime: ref.mime, sizeBytes: ref.size_bytes, sha256, path: path16.resolve(filePath) });
|
|
7465
7329
|
}
|
|
7466
7330
|
return { directory: state.directory, files, manifestMarkdown: buildManifest(files), cleanup: () => cleanupGeneratedDirectory(state) };
|
|
7467
7331
|
} catch (error) {
|
|
@@ -7525,9 +7389,9 @@ async function readSpool(spoolDir = SPOOL_DIR) {
|
|
|
7525
7389
|
}
|
|
7526
7390
|
return out;
|
|
7527
7391
|
}
|
|
7528
|
-
async function readCloudMap(
|
|
7392
|
+
async function readCloudMap(path22) {
|
|
7529
7393
|
try {
|
|
7530
|
-
return JSON.parse(await readFile2(
|
|
7394
|
+
return JSON.parse(await readFile2(path22, "utf8"));
|
|
7531
7395
|
} catch {
|
|
7532
7396
|
return {};
|
|
7533
7397
|
}
|
|
@@ -8051,7 +7915,7 @@ var init_runner_capacity = __esm({
|
|
|
8051
7915
|
});
|
|
8052
7916
|
|
|
8053
7917
|
// ../../scripts/virtual-office/code-runner/agent-auth-probe-process.mjs
|
|
8054
|
-
import { fileURLToPath as
|
|
7918
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
8055
7919
|
async function probeAgentInChild(agent, timeoutMs) {
|
|
8056
7920
|
const stdout = await runProcess2(process.execPath, [probeCli, agent], {
|
|
8057
7921
|
timeout: timeoutMs,
|
|
@@ -8064,7 +7928,7 @@ var init_agent_auth_probe_process = __esm({
|
|
|
8064
7928
|
"../../scripts/virtual-office/code-runner/agent-auth-probe-process.mjs"() {
|
|
8065
7929
|
"use strict";
|
|
8066
7930
|
init_process_runner2();
|
|
8067
|
-
probeCli =
|
|
7931
|
+
probeCli = fileURLToPath4(new URL("./agent-auth-probe-cli.mjs", import.meta.url));
|
|
8068
7932
|
}
|
|
8069
7933
|
});
|
|
8070
7934
|
|
|
@@ -8365,7 +8229,7 @@ var init_shared = __esm({
|
|
|
8365
8229
|
// ../../scripts/virtual-office/code-runner/account-usage/claude.mjs
|
|
8366
8230
|
import fs10 from "node:fs";
|
|
8367
8231
|
import os3 from "node:os";
|
|
8368
|
-
import
|
|
8232
|
+
import path17 from "node:path";
|
|
8369
8233
|
function fileCaptureTime(filePath, explicit, statFn) {
|
|
8370
8234
|
if (typeof explicit === "string" && explicit) return explicit;
|
|
8371
8235
|
try {
|
|
@@ -8379,7 +8243,7 @@ function usageBaseUrl(env2 = process.env) {
|
|
|
8379
8243
|
return String(raw).replace(/\/+$/, "");
|
|
8380
8244
|
}
|
|
8381
8245
|
function readOAuthToken({ homeDir = os3.homedir(), read = readJson, now = Date.now() } = {}) {
|
|
8382
|
-
const creds = read(
|
|
8246
|
+
const creds = read(path17.join(homeDir, ".claude", ".credentials.json"));
|
|
8383
8247
|
const oauth = creds && typeof creds === "object" ? creds.claudeAiOauth : null;
|
|
8384
8248
|
if (!oauth || typeof oauth !== "object") return null;
|
|
8385
8249
|
const token2 = typeof oauth.accessToken === "string" ? oauth.accessToken.trim() : "";
|
|
@@ -8389,7 +8253,7 @@ function readOAuthToken({ homeDir = os3.homedir(), read = readJson, now = Date.n
|
|
|
8389
8253
|
return token2;
|
|
8390
8254
|
}
|
|
8391
8255
|
function readAccountId({ homeDir = os3.homedir(), read = readJson } = {}) {
|
|
8392
|
-
const cfg = read(
|
|
8256
|
+
const cfg = read(path17.join(homeDir, ".claude.json"));
|
|
8393
8257
|
const account = cfg && typeof cfg === "object" ? cfg.oauthAccount : null;
|
|
8394
8258
|
return account && typeof account.accountUuid === "string" ? account.accountUuid : null;
|
|
8395
8259
|
}
|
|
@@ -8499,7 +8363,7 @@ function readClaudeFileUsage({
|
|
|
8499
8363
|
if (age === null || age > MAX_FILE_AGE_MS) return null;
|
|
8500
8364
|
return row;
|
|
8501
8365
|
};
|
|
8502
|
-
const statusPath =
|
|
8366
|
+
const statusPath = path17.join(homeDir, ".claude", "claude-usage.json");
|
|
8503
8367
|
const status = read(statusPath);
|
|
8504
8368
|
if (status && (status.seven_day || status.five_hour)) {
|
|
8505
8369
|
const row = fresh(makeUsageRow({
|
|
@@ -8514,7 +8378,7 @@ function readClaudeFileUsage({
|
|
|
8514
8378
|
}));
|
|
8515
8379
|
if (row) return row;
|
|
8516
8380
|
}
|
|
8517
|
-
const weeklyPath =
|
|
8381
|
+
const weeklyPath = path17.join(homeDir, ".claude", "claude-weekly-usage.json");
|
|
8518
8382
|
const weekly = read(weeklyPath);
|
|
8519
8383
|
if (weekly) {
|
|
8520
8384
|
const row = fresh(makeUsageRow({
|
|
@@ -9790,9 +9654,9 @@ function buildControlHandler({ getStatus, requestStop, allowedOrigin }) {
|
|
|
9790
9654
|
res.end();
|
|
9791
9655
|
return;
|
|
9792
9656
|
}
|
|
9793
|
-
const
|
|
9657
|
+
const path22 = String(req.url || "").split("?")[0];
|
|
9794
9658
|
res.setHeader("content-type", "application/json");
|
|
9795
|
-
if (req.method === "GET" &&
|
|
9659
|
+
if (req.method === "GET" && path22 === "/status") {
|
|
9796
9660
|
let status;
|
|
9797
9661
|
try {
|
|
9798
9662
|
status = getStatus();
|
|
@@ -9803,7 +9667,7 @@ function buildControlHandler({ getStatus, requestStop, allowedOrigin }) {
|
|
|
9803
9667
|
res.end(JSON.stringify({ ok: true, ...status }));
|
|
9804
9668
|
return;
|
|
9805
9669
|
}
|
|
9806
|
-
if (req.method === "POST" &&
|
|
9670
|
+
if (req.method === "POST" && path22 === "/stop") {
|
|
9807
9671
|
if (!isControlOriginAllowed(req.headers.origin, allowedOrigin) || !req.headers["x-vo-control"]) {
|
|
9808
9672
|
res.statusCode = 403;
|
|
9809
9673
|
res.end(JSON.stringify({ ok: false, error: "forbidden" }));
|
|
@@ -9901,6 +9765,19 @@ function resolveEffortMode(mode) {
|
|
|
9901
9765
|
const normalized = String(mode || "").trim().toLowerCase();
|
|
9902
9766
|
return EFFORT_MODE_CONFIG[normalized] || EFFORT_MODE_CONFIG[DEFAULT_MODE];
|
|
9903
9767
|
}
|
|
9768
|
+
function resolveDefaultBudgetUsd(env2 = {}) {
|
|
9769
|
+
const raw = env2?.[DEFAULT_BUDGET_USD_ENV];
|
|
9770
|
+
if (raw === void 0 || raw === null) return null;
|
|
9771
|
+
const parsed = Number(String(raw).trim());
|
|
9772
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return null;
|
|
9773
|
+
return parsed;
|
|
9774
|
+
}
|
|
9775
|
+
function resolveDispatchBudgetUsd({ taskBudgetUsd, env: env2 = {} } = {}) {
|
|
9776
|
+
if (typeof taskBudgetUsd === "number" && Number.isFinite(taskBudgetUsd)) {
|
|
9777
|
+
return taskBudgetUsd;
|
|
9778
|
+
}
|
|
9779
|
+
return resolveDefaultBudgetUsd(env2);
|
|
9780
|
+
}
|
|
9904
9781
|
function composeEffortPrompt(basePrompt, effortConfig) {
|
|
9905
9782
|
const parts = [];
|
|
9906
9783
|
if (effortConfig.thinkingDirective) {
|
|
@@ -9916,15 +9793,16 @@ ${effortConfig.multiAgentInstruction}
|
|
|
9916
9793
|
parts.push(String(basePrompt || "").trim());
|
|
9917
9794
|
return parts.join("\n");
|
|
9918
9795
|
}
|
|
9919
|
-
var RED_TEAM_DIRECTIVE, EFFORT_MODE_CONFIG, DEFAULT_MODE;
|
|
9796
|
+
var RED_TEAM_DIRECTIVE, DEFAULT_BUDGET_USD_ENV, EFFORT_MODE_CONFIG, DEFAULT_MODE;
|
|
9920
9797
|
var init_effort_mode_config = __esm({
|
|
9921
9798
|
"../../scripts/virtual-office/code-runner/effort-mode-config.mjs"() {
|
|
9922
9799
|
"use strict";
|
|
9923
9800
|
RED_TEAM_DIRECTIVE = "Before declaring done, red-team your own work: name the top ways it could be wrong \u2014 especially code that is correct but silently not wired into production callers \u2014 give the failure scenario for each, and state the evidence that rules it out.";
|
|
9801
|
+
DEFAULT_BUDGET_USD_ENV = "VO_CODE_RUNNER_DEFAULT_BUDGET_USD";
|
|
9924
9802
|
EFFORT_MODE_CONFIG = {
|
|
9925
9803
|
fast: {
|
|
9926
9804
|
tier: "cheap",
|
|
9927
|
-
maxBudgetUsd:
|
|
9805
|
+
maxBudgetUsd: null,
|
|
9928
9806
|
permissionMode: "acceptEdits",
|
|
9929
9807
|
maxTurns: 80,
|
|
9930
9808
|
thinkingDirective: RED_TEAM_DIRECTIVE,
|
|
@@ -9932,7 +9810,7 @@ var init_effort_mode_config = __esm({
|
|
|
9932
9810
|
},
|
|
9933
9811
|
standard: {
|
|
9934
9812
|
tier: "mid",
|
|
9935
|
-
maxBudgetUsd:
|
|
9813
|
+
maxBudgetUsd: null,
|
|
9936
9814
|
permissionMode: "acceptEdits",
|
|
9937
9815
|
maxTurns: 200,
|
|
9938
9816
|
thinkingDirective: RED_TEAM_DIRECTIVE,
|
|
@@ -9940,7 +9818,7 @@ var init_effort_mode_config = __esm({
|
|
|
9940
9818
|
},
|
|
9941
9819
|
deep: {
|
|
9942
9820
|
tier: "best",
|
|
9943
|
-
maxBudgetUsd:
|
|
9821
|
+
maxBudgetUsd: null,
|
|
9944
9822
|
permissionMode: "acceptEdits",
|
|
9945
9823
|
maxTurns: 300,
|
|
9946
9824
|
thinkingDirective: `Think step-by-step. Verify assumptions against source code. Check edge cases. ${RED_TEAM_DIRECTIVE}`,
|
|
@@ -9948,7 +9826,7 @@ var init_effort_mode_config = __esm({
|
|
|
9948
9826
|
},
|
|
9949
9827
|
ultra: {
|
|
9950
9828
|
tier: "best",
|
|
9951
|
-
maxBudgetUsd:
|
|
9829
|
+
maxBudgetUsd: null,
|
|
9952
9830
|
permissionMode: "acceptEdits",
|
|
9953
9831
|
maxTurns: 500,
|
|
9954
9832
|
thinkingDirective: `Think step-by-step. Exhaustively verify every assumption against source code and documentation. ${RED_TEAM_DIRECTIVE}`,
|
|
@@ -9956,7 +9834,7 @@ var init_effort_mode_config = __esm({
|
|
|
9956
9834
|
},
|
|
9957
9835
|
ultracode: {
|
|
9958
9836
|
tier: "best",
|
|
9959
|
-
maxBudgetUsd:
|
|
9837
|
+
maxBudgetUsd: null,
|
|
9960
9838
|
permissionMode: "acceptEdits",
|
|
9961
9839
|
maxTurns: 800,
|
|
9962
9840
|
thinkingDirective: `Think step-by-step. Exhaustively verify every assumption against source code and documentation. Build worked examples to validate correctness. ${RED_TEAM_DIRECTIVE}`,
|
|
@@ -9971,22 +9849,22 @@ var init_effort_mode_config = __esm({
|
|
|
9971
9849
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
9972
9850
|
import fs11 from "node:fs";
|
|
9973
9851
|
import os4 from "node:os";
|
|
9974
|
-
import
|
|
9975
|
-
import { fileURLToPath as
|
|
9852
|
+
import path18 from "node:path";
|
|
9853
|
+
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
9976
9854
|
function userCacheRoot() {
|
|
9977
9855
|
try {
|
|
9978
9856
|
const home = os4.homedir();
|
|
9979
|
-
if (home) return
|
|
9857
|
+
if (home) return path18.join(home, ".claude");
|
|
9980
9858
|
} catch {
|
|
9981
9859
|
}
|
|
9982
|
-
return
|
|
9860
|
+
return path18.join(os4.tmpdir(), `vo-model-registry-${randomUUID5()}`);
|
|
9983
9861
|
}
|
|
9984
9862
|
function resolveCacheBaseDir(env2 = process.env, moduleDir = __dirname) {
|
|
9985
9863
|
if (env2.VO_MODEL_REGISTRY_CACHE_DIR) return env2.VO_MODEL_REGISTRY_CACHE_DIR;
|
|
9986
9864
|
if (env2.VO_RUNNER_RUNTIME_ROOT) return env2.VO_RUNNER_RUNTIME_ROOT;
|
|
9987
|
-
const segments = moduleDir.split(
|
|
9865
|
+
const segments = moduleDir.split(path18.sep);
|
|
9988
9866
|
const isRepoCheckout = segments.at(-1) === "virtual-office" && segments.at(-2) === "scripts";
|
|
9989
|
-
return isRepoCheckout ?
|
|
9867
|
+
return isRepoCheckout ? path18.resolve(moduleDir, "..", "..") : userCacheRoot();
|
|
9990
9868
|
}
|
|
9991
9869
|
function uniqueModels(models = []) {
|
|
9992
9870
|
return [...new Set(models.map((model) => String(model || "").trim()).filter(Boolean))];
|
|
@@ -10109,7 +9987,7 @@ function readCache(cacheFile = DEFAULT_CACHE_FILE, nowMs = Date.now(), ttlMs = D
|
|
|
10109
9987
|
}
|
|
10110
9988
|
}
|
|
10111
9989
|
function writeCache(cacheFile = DEFAULT_CACHE_FILE, payload) {
|
|
10112
|
-
fs11.mkdirSync(
|
|
9990
|
+
fs11.mkdirSync(path18.dirname(cacheFile), { recursive: true });
|
|
10113
9991
|
fs11.writeFileSync(cacheFile, JSON.stringify(payload, null, 2));
|
|
10114
9992
|
}
|
|
10115
9993
|
async function fetchRegistryCatalog({
|
|
@@ -10167,13 +10045,13 @@ var __dirname, DEFAULT_CACHE_DIR, DEFAULT_CACHE_FILE, DEFAULT_TTL_MS3, ANTHROPIC
|
|
|
10167
10045
|
var init_model_registry = __esm({
|
|
10168
10046
|
"../../scripts/virtual-office/model-registry.mjs"() {
|
|
10169
10047
|
"use strict";
|
|
10170
|
-
__dirname =
|
|
10171
|
-
DEFAULT_CACHE_DIR =
|
|
10048
|
+
__dirname = path18.dirname(fileURLToPath5(import.meta.url));
|
|
10049
|
+
DEFAULT_CACHE_DIR = path18.join(
|
|
10172
10050
|
resolveCacheBaseDir(),
|
|
10173
10051
|
".virtual-office-cache",
|
|
10174
10052
|
"model-registry"
|
|
10175
10053
|
);
|
|
10176
|
-
DEFAULT_CACHE_FILE =
|
|
10054
|
+
DEFAULT_CACHE_FILE = path18.join(DEFAULT_CACHE_DIR, "catalog.json");
|
|
10177
10055
|
DEFAULT_TTL_MS3 = 60 * 60 * 1e3;
|
|
10178
10056
|
ANTHROPIC_API_VERSION = "2023-06-01";
|
|
10179
10057
|
FAMILY_DEFINITIONS = {
|
|
@@ -10807,9 +10685,9 @@ function operatorTierToRung(tier, difficulty, thresholds) {
|
|
|
10807
10685
|
if (tier === "best" && difficulty >= thresholds.rungBounds.R5) return "R5";
|
|
10808
10686
|
return base;
|
|
10809
10687
|
}
|
|
10810
|
-
function readCodexModelsCache({ path:
|
|
10688
|
+
function readCodexModelsCache({ path: path22 = DEFAULT_CODEX_MODELS_CACHE, read = readFileSync4 } = {}) {
|
|
10811
10689
|
try {
|
|
10812
|
-
const parsed = JSON.parse(read(
|
|
10690
|
+
const parsed = JSON.parse(read(path22, "utf8"));
|
|
10813
10691
|
return Array.isArray(parsed?.models) ? parsed : null;
|
|
10814
10692
|
} catch {
|
|
10815
10693
|
return null;
|
|
@@ -10992,14 +10870,14 @@ var init_role_cost_shadow = __esm({
|
|
|
10992
10870
|
import { readFileSync as readFileSync5, appendFileSync, mkdirSync as mkdirSync4 } from "node:fs";
|
|
10993
10871
|
import { homedir as homedir7 } from "node:os";
|
|
10994
10872
|
import { join as join9, dirname as dirname6 } from "node:path";
|
|
10995
|
-
import { fileURLToPath as
|
|
10873
|
+
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
10996
10874
|
function getAutoRouterMode(env2 = process.env) {
|
|
10997
10875
|
const raw = String(env2.VO_CODE_RUNNER_AUTO_ROUTER || "").trim().toLowerCase();
|
|
10998
10876
|
return MODES.has(raw) ? raw : "off";
|
|
10999
10877
|
}
|
|
11000
10878
|
function loadThresholds() {
|
|
11001
10879
|
if (!cachedThresholds) {
|
|
11002
|
-
const here = dirname6(
|
|
10880
|
+
const here = dirname6(fileURLToPath6(import.meta.url));
|
|
11003
10881
|
cachedThresholds = JSON.parse(readFileSync5(join9(here, "thresholds.json"), "utf8"));
|
|
11004
10882
|
}
|
|
11005
10883
|
return cachedThresholds;
|
|
@@ -11066,15 +10944,15 @@ function formatDecisionReason(decision, maxLen = 480) {
|
|
|
11066
10944
|
const s = `[${decision.routerVersion}] ${decision.taskClass} d=${decision.difficulty} c=${decision.confidence} \u2192 ${decision.rung}/${decision.tier}${decision.effort ? ` effort=${decision.effort}` : ""} turns=${decision.maxTurns} $${decision.maxBudgetUsd}${decision.flags.length ? ` [${decision.flags.join(",")}]` : ""} :: ${decision.reasons.join("; ")}`;
|
|
11067
10945
|
return s.length > maxLen ? `${s.slice(0, maxLen - 1)}\u2026` : s;
|
|
11068
10946
|
}
|
|
11069
|
-
function appendDecisionFallback(decision, { path:
|
|
10947
|
+
function appendDecisionFallback(decision, { path: path22 = DECISION_FALLBACK_PATH, append = appendFileSync, mkdir: mkdir4 = mkdirSync4, task, thresholds, roleCostInputs } = {}) {
|
|
11070
10948
|
try {
|
|
11071
|
-
mkdir4(dirname6(
|
|
11072
|
-
append(
|
|
10949
|
+
mkdir4(dirname6(path22), { recursive: true });
|
|
10950
|
+
append(path22, `${JSON.stringify(decision)}
|
|
11073
10951
|
`, "utf8");
|
|
11074
10952
|
if (isRouterDecision(decision)) {
|
|
11075
10953
|
try {
|
|
11076
10954
|
const records = buildShadowRecords({ decision, task, thresholds: thresholds || loadThresholds(), roleCostInputs });
|
|
11077
|
-
for (const record of records) append(
|
|
10955
|
+
for (const record of records) append(path22, `${JSON.stringify(record)}
|
|
11078
10956
|
`, "utf8");
|
|
11079
10957
|
} catch {
|
|
11080
10958
|
}
|
|
@@ -11160,7 +11038,12 @@ async function resolveEffortDispatch({ client, task, agent = "claude", env: env2
|
|
|
11160
11038
|
permissionMode: env2.VO_CODE_RUNNER_PERMISSION_MODE || effortConfig.permissionMode,
|
|
11161
11039
|
maxTurns: typeof task.max_turns === "number" ? task.max_turns : applying ? decision.maxTurns : effortConfig.maxTurns,
|
|
11162
11040
|
effort,
|
|
11163
|
-
|
|
11041
|
+
// Default dollar ceilings are OFF (2026-08-13). Only an EXPLICIT per-task
|
|
11042
|
+
// budget — or the VO_CODE_RUNNER_DEFAULT_BUDGET_USD override a BYO-API-key
|
|
11043
|
+
// operator sets — produces a `--max-budget-usd` flag. The router's dollar
|
|
11044
|
+
// rung is a default too, so it is suppressed with the rest; the router
|
|
11045
|
+
// still governs tier, effort, and maxTurns (the real runaway bound).
|
|
11046
|
+
maxBudgetUsd: resolveDispatchBudgetUsd({ taskBudgetUsd: task.max_budget_usd, env: env2 }),
|
|
11164
11047
|
prompt: composeEffortPrompt(basePrompt, effortConfig),
|
|
11165
11048
|
routerDecision: decision ? toPersistedRouterDecision(decision, model) : null
|
|
11166
11049
|
};
|
|
@@ -12067,7 +11950,7 @@ var init_inference_task_runner = __esm({
|
|
|
12067
11950
|
// ../../scripts/virtual-office/code-runner/isolation-audit.mjs
|
|
12068
11951
|
import fs12 from "node:fs";
|
|
12069
11952
|
import fsp11 from "node:fs/promises";
|
|
12070
|
-
import
|
|
11953
|
+
import path19 from "node:path";
|
|
12071
11954
|
async function defaultRun(command, args, cwd, options = {}) {
|
|
12072
11955
|
return runProcess2(command, args, { cwd, timeout: 6e4, ...options });
|
|
12073
11956
|
}
|
|
@@ -12080,7 +11963,7 @@ async function canonicalRootForWorktree(worktreeDir, run) {
|
|
|
12080
11963
|
"--path-format=absolute",
|
|
12081
11964
|
"--git-common-dir"
|
|
12082
11965
|
])).trim();
|
|
12083
|
-
const root =
|
|
11966
|
+
const root = path19.dirname(commonDir);
|
|
12084
11967
|
return samePath2(root, worktreeDir) ? null : root;
|
|
12085
11968
|
}
|
|
12086
11969
|
async function snapshot(root, run) {
|
|
@@ -12122,21 +12005,21 @@ async function changedPaths(root, run) {
|
|
|
12122
12005
|
}
|
|
12123
12006
|
async function quarantineCanonicalWrites({ baseline, worktreeDir, taskId, run, now }) {
|
|
12124
12007
|
const paths = await changedPaths(baseline.root, run);
|
|
12125
|
-
const quarantineDir =
|
|
12126
|
-
|
|
12008
|
+
const quarantineDir = path19.join(
|
|
12009
|
+
path19.dirname(worktreeDir),
|
|
12127
12010
|
".canonical-recovery",
|
|
12128
12011
|
`${String(taskId || "unknown").replace(/[^a-z0-9-]/gi, "-")}-${now().toISOString().replace(/[:.]/g, "-")}`
|
|
12129
12012
|
);
|
|
12130
12013
|
await fsp11.mkdir(quarantineDir, { recursive: true });
|
|
12131
12014
|
const patch = await git2(run, baseline.root, ["diff", "--binary", "HEAD"], { raw: true });
|
|
12132
|
-
await fsp11.writeFile(
|
|
12015
|
+
await fsp11.writeFile(path19.join(quarantineDir, "tracked.patch"), patch, "utf8");
|
|
12133
12016
|
for (const relative of paths.untracked) {
|
|
12134
|
-
const source =
|
|
12135
|
-
const target =
|
|
12136
|
-
await fsp11.mkdir(
|
|
12017
|
+
const source = path19.join(baseline.root, relative);
|
|
12018
|
+
const target = path19.join(quarantineDir, "untracked", relative);
|
|
12019
|
+
await fsp11.mkdir(path19.dirname(target), { recursive: true });
|
|
12137
12020
|
await fsp11.copyFile(source, target);
|
|
12138
12021
|
}
|
|
12139
|
-
await fsp11.writeFile(
|
|
12022
|
+
await fsp11.writeFile(path19.join(quarantineDir, "manifest.json"), `${JSON.stringify({
|
|
12140
12023
|
taskId,
|
|
12141
12024
|
canonicalRoot: baseline.root,
|
|
12142
12025
|
canonicalHead: baseline.head,
|
|
@@ -12158,8 +12041,8 @@ async function restoreExactCanonicalPaths(baseline, evidence, run) {
|
|
|
12158
12041
|
]);
|
|
12159
12042
|
}
|
|
12160
12043
|
for (const relative of evidence.untracked) {
|
|
12161
|
-
const target =
|
|
12162
|
-
const prefix = `${
|
|
12044
|
+
const target = path19.resolve(baseline.root, relative);
|
|
12045
|
+
const prefix = `${path19.resolve(baseline.root)}${path19.sep}`;
|
|
12163
12046
|
if (!target.startsWith(prefix) || !fs12.existsSync(target)) continue;
|
|
12164
12047
|
await fsp11.rm(target, { force: true });
|
|
12165
12048
|
}
|
|
@@ -12196,7 +12079,7 @@ var init_isolation_audit = __esm({
|
|
|
12196
12079
|
init_process_runner2();
|
|
12197
12080
|
splitZ2 = (value) => String(value || "").split("\0").map((item) => item.trim()).filter(Boolean);
|
|
12198
12081
|
samePath2 = (left, right) => {
|
|
12199
|
-
const [a, b] = [left, right].map((value) =>
|
|
12082
|
+
const [a, b] = [left, right].map((value) => path19.resolve(value));
|
|
12200
12083
|
return process.platform === "win32" ? a.toLowerCase() === b.toLowerCase() : a === b;
|
|
12201
12084
|
};
|
|
12202
12085
|
}
|
|
@@ -12556,7 +12439,7 @@ var init_publication_outcome = __esm({
|
|
|
12556
12439
|
|
|
12557
12440
|
// ../../scripts/virtual-office/code-runner/committed-scratch-cleanup.mjs
|
|
12558
12441
|
import fsp12 from "node:fs/promises";
|
|
12559
|
-
import
|
|
12442
|
+
import path20 from "node:path";
|
|
12560
12443
|
function defaultRun2(command, args, cwd, options = {}) {
|
|
12561
12444
|
return runProcess2(command, args, { cwd, ...options });
|
|
12562
12445
|
}
|
|
@@ -12564,13 +12447,13 @@ async function resolveSafeScratchTarget(worktreeDir, file) {
|
|
|
12564
12447
|
if (!isAgentScratch(file)) {
|
|
12565
12448
|
throw new Error(`refusing to remove non-scratch publication path: ${file}`);
|
|
12566
12449
|
}
|
|
12567
|
-
const root =
|
|
12568
|
-
const target =
|
|
12569
|
-
const relative =
|
|
12570
|
-
if (!relative || relative.startsWith(`..${
|
|
12450
|
+
const root = path20.resolve(worktreeDir);
|
|
12451
|
+
const target = path20.resolve(root, file);
|
|
12452
|
+
const relative = path20.relative(root, target);
|
|
12453
|
+
if (!relative || relative.startsWith(`..${path20.sep}`) || path20.isAbsolute(relative)) {
|
|
12571
12454
|
throw new Error(`refusing to remove publication scratch outside worktree: ${file}`);
|
|
12572
12455
|
}
|
|
12573
|
-
for (let cursor = target; cursor !== root; cursor =
|
|
12456
|
+
for (let cursor = target; cursor !== root; cursor = path20.dirname(cursor)) {
|
|
12574
12457
|
try {
|
|
12575
12458
|
if ((await fsp12.lstat(cursor)).isSymbolicLink()) {
|
|
12576
12459
|
throw new Error(`refusing to follow symlink while removing publication scratch: ${file}`);
|
|
@@ -12692,7 +12575,7 @@ var init_publication_scope = __esm({
|
|
|
12692
12575
|
// ../../scripts/virtual-office/code-runner/recovery-ledger.mjs
|
|
12693
12576
|
import fs13 from "node:fs";
|
|
12694
12577
|
import fsp13 from "node:fs/promises";
|
|
12695
|
-
import
|
|
12578
|
+
import path21 from "node:path";
|
|
12696
12579
|
function recoveryTaskId(prompt) {
|
|
12697
12580
|
const match = String(prompt || "").match(/VO_RECOVERY_FROM_CODE_TASK:\s*([0-9a-f-]{36})/i);
|
|
12698
12581
|
return match ? match[1].toLowerCase() : null;
|
|
@@ -12706,10 +12589,10 @@ function cloneLeaf(repo) {
|
|
|
12706
12589
|
function recoveryLedgerCandidates(repo, clonesRoot2) {
|
|
12707
12590
|
const leaf = cloneLeaf(repo);
|
|
12708
12591
|
if (!leaf || !clonesRoot2) return [];
|
|
12709
|
-
const canonical =
|
|
12592
|
+
const canonical = path21.join(clonesRoot2, leaf);
|
|
12710
12593
|
return [
|
|
12711
|
-
|
|
12712
|
-
|
|
12594
|
+
path21.join(clonesRoot2, ".agent-worktrees", leaf, "recovery-ledger.jsonl"),
|
|
12595
|
+
path21.join(canonical, ".agent-worktrees", "recovery-ledger.jsonl")
|
|
12713
12596
|
];
|
|
12714
12597
|
}
|
|
12715
12598
|
async function readLedger(file, readFile5) {
|
|
@@ -13445,10 +13328,10 @@ var init_task_worktree_preparation = __esm({
|
|
|
13445
13328
|
// ../../scripts/virtual-office/code-runner-daemon.mjs
|
|
13446
13329
|
var code_runner_daemon_exports = {};
|
|
13447
13330
|
__export(code_runner_daemon_exports, {
|
|
13448
|
-
main: () =>
|
|
13331
|
+
main: () => main
|
|
13449
13332
|
});
|
|
13450
13333
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
13451
|
-
import { fileURLToPath as
|
|
13334
|
+
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
13452
13335
|
function log(msg) {
|
|
13453
13336
|
console.log(`[code-runner ${(/* @__PURE__ */ new Date()).toISOString()}] ${msg}`);
|
|
13454
13337
|
}
|
|
@@ -13488,7 +13371,7 @@ async function processOneTask(client, task, cfg, runnerInstanceId, swarmAdmissio
|
|
|
13488
13371
|
const sandbox = resolveRunnerSandbox(process.env, sel.agent);
|
|
13489
13372
|
await safeProgress(client, id, runnerStagePatch(
|
|
13490
13373
|
"starting_agent",
|
|
13491
|
-
`${cfg.runnerId} spawning ${sel.agent}:${model || "default"} (${tier}, effort ${dispatchMode}; ${sel.agent === "claude" ? `$${effectiveMaxBudgetUsd} hard API-equivalent cap` : "20m wall-clock cap"}${routerMode !== "off" && routerDecision ? `; auto-router ${routerMode}: ${routerDecision.rung}${routerDecision.effort ? ` effort=${routerDecision.effort}` : ""}` : ""})`,
|
|
13374
|
+
`${cfg.runnerId} spawning ${sel.agent}:${model || "default"} (${tier}, effort ${dispatchMode}; ${sel.agent === "claude" ? typeof effectiveMaxBudgetUsd === "number" && effectiveMaxBudgetUsd > 0 ? `$${effectiveMaxBudgetUsd} hard API-equivalent cap` : `no dollar cap, ${effectiveMaxTurns}-turn ceiling` : "20m wall-clock cap"}${routerMode !== "off" && routerDecision ? `; auto-router ${routerMode}: ${routerDecision.rung}${routerDecision.effort ? ` effort=${routerDecision.effort}` : ""}` : ""})`,
|
|
13492
13375
|
routerDecision ? { router_decision: routerDecision } : {}
|
|
13493
13376
|
));
|
|
13494
13377
|
const cap = typeof attemptBudgetUsd === "number" ? attemptBudgetUsd : resolveCodeDispatchCapUsd();
|
|
@@ -13670,7 +13553,7 @@ Closes #${publicationTarget.supersedesPrNumber}` : "";
|
|
|
13670
13553
|
}
|
|
13671
13554
|
}
|
|
13672
13555
|
}
|
|
13673
|
-
async function
|
|
13556
|
+
async function main({ env: env2 = process.env, once: once2 = false } = {}) {
|
|
13674
13557
|
const cfg = loadCodeRunnerConfig(env2, { log });
|
|
13675
13558
|
await sweepStaleTaskAttachmentDirectories().catch((error) => log(`stale attachment cleanup failed: ${error.message}`));
|
|
13676
13559
|
const runnerInstanceId = randomUUID7();
|
|
@@ -13816,7 +13699,7 @@ async function main2({ env: env2 = process.env, once: once2 = false } = {}) {
|
|
|
13816
13699
|
if (controlServer) controlServer.close();
|
|
13817
13700
|
log("stopped");
|
|
13818
13701
|
}
|
|
13819
|
-
var RATE_LIMIT_RESUME_ENABLED, sleep2, safeProgress,
|
|
13702
|
+
var RATE_LIMIT_RESUME_ENABLED, sleep2, safeProgress, invokedDirectly;
|
|
13820
13703
|
var init_code_runner_daemon = __esm({
|
|
13821
13704
|
"../../scripts/virtual-office/code-runner-daemon.mjs"() {
|
|
13822
13705
|
"use strict";
|
|
@@ -13866,11 +13749,11 @@ var init_code_runner_daemon = __esm({
|
|
|
13866
13749
|
RATE_LIMIT_RESUME_ENABLED = process.env.VO_RATE_LIMIT_RESUME !== "0";
|
|
13867
13750
|
sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
13868
13751
|
safeProgress = makeSafeProgress(log);
|
|
13869
|
-
|
|
13752
|
+
invokedDirectly = process.argv[1] && fileURLToPath7(import.meta.url) === process.argv[1] && // Bundle-safe: self-start only when THIS file is the real entry (not inlined into vo-mcp's runner-cli.js ⇒ double-claim).
|
|
13870
13753
|
import.meta.url.endsWith("code-runner-daemon.mjs");
|
|
13871
|
-
if (
|
|
13754
|
+
if (invokedDirectly) {
|
|
13872
13755
|
const once2 = process.argv.includes("--once");
|
|
13873
|
-
|
|
13756
|
+
main({ once: once2 }).catch((err) => {
|
|
13874
13757
|
console.error("[code-runner] fatal:", err);
|
|
13875
13758
|
process.exit(1);
|
|
13876
13759
|
});
|
|
@@ -14237,8 +14120,8 @@ var env = {
|
|
|
14237
14120
|
...pairedOperatorId ? { VO_CODE_RUNNER_OPERATOR_IDS: pairedOperatorId } : {}
|
|
14238
14121
|
};
|
|
14239
14122
|
var once = process.argv.includes("--once");
|
|
14240
|
-
var { main:
|
|
14241
|
-
|
|
14123
|
+
var { main: main2 } = await Promise.resolve().then(() => (init_code_runner_daemon(), code_runner_daemon_exports));
|
|
14124
|
+
main2({ env, once }).catch((err) => {
|
|
14242
14125
|
console.error("[vo-mcp runner] fatal:", err);
|
|
14243
14126
|
process.exit(1);
|
|
14244
14127
|
});
|