@coreplane/switchboard 1.226.1 → 1.227.0
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/assets/deploy/cloudflare-resident/worker.ts +238 -8
- package/dist/assets/deploy/cloudflare-sandbox/Dockerfile +7 -0
- package/dist/assets/deploy/cloudflare-sandbox/runtime-supervisor.sh +67 -0
- package/dist/assets/deploy/cloudflare-sandbox/worker.ts +49 -0
- package/dist/assets/package-lock.json +3 -3
- package/dist/assets/package.json +1 -1
- package/dist/assets/source.json +3 -3
- package/dist/assets/src/core/authz/policy.ts +8 -0
- package/dist/assets/src/core/runEvents.ts +16 -2
- package/dist/assets/src/core/runRecord.ts +61 -0
- package/dist/assets/src/execution/residentRebind.ts +233 -0
- package/dist/assets/src/execution/residentSteps.ts +1 -0
- package/dist/assets/src/execution/sandboxErrors.ts +99 -0
- package/dist/assets/web/dist/.vite/manifest.json +18 -18
- package/dist/assets/web/dist/assets/{ResidentDetailPage-BBOpejGX.js → ResidentDetailPage-Chvll3wy.js} +1 -1
- package/dist/assets/web/dist/assets/{ResidentsIndexPage-B8kFWHpB.js → ResidentsIndexPage-B5f8IwGF.js} +1 -1
- package/dist/assets/web/dist/assets/{RunRoutePage-COWeVtIE.js → RunRoutePage-CRvmCuXh.js} +4 -4
- package/dist/assets/web/dist/assets/{RunsIndexPage-BjH93cKx.js → RunsIndexPage-BTJuKFTv.js} +1 -1
- package/dist/assets/web/dist/assets/{ScheduledPage-grlNKvCA.js → ScheduledPage-BVfgUBvP.js} +1 -1
- package/dist/assets/web/dist/assets/{StatusDot-BQNoaXO6.js → StatusDot-CFXbAw7S.js} +1 -1
- package/dist/assets/web/dist/assets/{Tooltip-DVCeIzaa.js → Tooltip-DcHMtbHJ.js} +1 -1
- package/dist/assets/web/dist/assets/{dist-B5Wfk-oY.js → dist-DKhqHu0V.js} +1 -1
- package/dist/assets/web/dist/assets/{main-CN0U7d6s.js → main-CveRd2yk.js} +2 -2
- package/dist/cli.js +470 -190
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -689,6 +689,13 @@ var init_policy = __esm({
|
|
|
689
689
|
// List-shaped `runs.*`: the grant admits the command; the store predicate narrows the rows.
|
|
690
690
|
{ action: "runs:read", resource: "command", when: [grant("runs:read")] },
|
|
691
691
|
{ action: "runs:write", resource: "command", when: [grant("runs:write")] },
|
|
692
|
+
// ── conversations ────────────────────────────────────────────────────────
|
|
693
|
+
// Who may point the bot at another thread (record 0037). Asked for a
|
|
694
|
+
// pointing actor (`pointingActor`: one membership, the origin channel, no
|
|
695
|
+
// grants), so `member-of` reads: a public channel from anywhere, a private
|
|
696
|
+
// channel only from inside it, an admin's `all` not consulted. The row has
|
|
697
|
+
// no caller until the references dispatch step lands behind its flag.
|
|
698
|
+
{ action: "conversation:read", resource: "channel", when: [MEMBER_OF] },
|
|
692
699
|
// ── review ───────────────────────────────────────────────────────────────
|
|
693
700
|
// `review abridge` spends one Opus-class call and rewrites a stored record:
|
|
694
701
|
// the grant admits the command (admins through `all`, operators by name;
|
|
@@ -872,8 +879,8 @@ function principalOf(actor) {
|
|
|
872
879
|
while (current.onBehalfOf) current = current.onBehalfOf;
|
|
873
880
|
return current;
|
|
874
881
|
}
|
|
875
|
-
function deny(
|
|
876
|
-
return { allow: false, reason };
|
|
882
|
+
function deny(reason2) {
|
|
883
|
+
return { allow: false, reason: reason2 };
|
|
877
884
|
}
|
|
878
885
|
function isKnownActorKind(kind) {
|
|
879
886
|
return ACTOR_KINDS.includes(kind);
|
|
@@ -909,13 +916,13 @@ function authorizeWith(rules, actor, action, resource) {
|
|
|
909
916
|
if (forOrigin.length === 0) return deny("origin-visibility");
|
|
910
917
|
const grants = effectiveGrants(actor);
|
|
911
918
|
const selfId = principalOf(actor).id;
|
|
912
|
-
let
|
|
919
|
+
let reason2;
|
|
913
920
|
for (const rule of forOrigin) {
|
|
914
921
|
const failed = rule.when.find((condition) => !evaluateCondition(condition, grants, selfId, attributes));
|
|
915
922
|
if (!failed) return ALLOW;
|
|
916
|
-
|
|
923
|
+
reason2 ??= FAILURE_REASON[failed.kind];
|
|
917
924
|
}
|
|
918
|
-
return deny(
|
|
925
|
+
return deny(reason2 ?? "no-rule");
|
|
919
926
|
}
|
|
920
927
|
function authorize(actor, action, resource) {
|
|
921
928
|
return authorizeWith(POLICY, actor, action, resource);
|
|
@@ -2856,6 +2863,7 @@ function validateConfig(cfg) {
|
|
|
2856
2863
|
if (cfg.ship !== void 0) validateShip(cfg.ship);
|
|
2857
2864
|
if (cfg.spawn !== void 0) validateSpawn(cfg.spawn);
|
|
2858
2865
|
if (cfg.routing !== void 0) validateRouting(cfg.routing, cfg.providers);
|
|
2866
|
+
if (cfg.references !== void 0) validateReferences(cfg.references);
|
|
2859
2867
|
if (cfg.artifacts !== void 0) validateArtifacts(cfg.artifacts);
|
|
2860
2868
|
if (cfg.harness !== void 0) validateHarness(cfg.harness);
|
|
2861
2869
|
if (cfg.pi !== void 0) validatePi(cfg.pi);
|
|
@@ -2885,6 +2893,14 @@ function validateHarness(harness) {
|
|
|
2885
2893
|
throw new Error(`config.yaml: harness.${preset} must be one of ${HARNESSES.join(", ")}`);
|
|
2886
2894
|
}
|
|
2887
2895
|
}
|
|
2896
|
+
function validateReferences(references) {
|
|
2897
|
+
if (typeof references !== "object" || references === null || Array.isArray(references))
|
|
2898
|
+
throw new Error("config.yaml: references must be a mapping");
|
|
2899
|
+
for (const key of unknownKeys2(references, REFERENCES_KEYS))
|
|
2900
|
+
throw new Error(`config.yaml: references.${key} is not a known key`);
|
|
2901
|
+
if (references.enabled !== void 0 && typeof references.enabled !== "boolean")
|
|
2902
|
+
throw new Error("config.yaml: references.enabled must be true or false");
|
|
2903
|
+
}
|
|
2888
2904
|
function validateRouting(routing, providers) {
|
|
2889
2905
|
if (typeof routing !== "object" || routing === null || Array.isArray(routing))
|
|
2890
2906
|
throw new Error("config.yaml: routing must be a mapping");
|
|
@@ -2993,7 +3009,7 @@ function validateRuntimeOverrides(ro) {
|
|
|
2993
3009
|
}
|
|
2994
3010
|
}
|
|
2995
3011
|
}
|
|
2996
|
-
var MAX_INSTRUCTIONS_LENGTH, CONFIG_KEYS, SELF_IMPROVEMENT_KEYS, BOUNDARY_KEYS, MIN_BOUNDARY_MINUTES, PI_KEYS, PI_COMPACTION_KEYS, ROUTE_ANSWER_MODES, ROUTING_KEYS, SHIP_KEYS, SPAWN_KEYS;
|
|
3012
|
+
var MAX_INSTRUCTIONS_LENGTH, CONFIG_KEYS, SELF_IMPROVEMENT_KEYS, BOUNDARY_KEYS, MIN_BOUNDARY_MINUTES, PI_KEYS, PI_COMPACTION_KEYS, ROUTE_ANSWER_MODES, REFERENCES_KEYS, ROUTING_KEYS, SHIP_KEYS, SPAWN_KEYS;
|
|
2997
3013
|
var init_validate = __esm({
|
|
2998
3014
|
"../../src/config/validate.ts"() {
|
|
2999
3015
|
"use strict";
|
|
@@ -3027,6 +3043,7 @@ var init_validate = __esm({
|
|
|
3027
3043
|
ship: true,
|
|
3028
3044
|
spawn: true,
|
|
3029
3045
|
routing: true,
|
|
3046
|
+
references: true,
|
|
3030
3047
|
harness: true,
|
|
3031
3048
|
pi: true,
|
|
3032
3049
|
slack: true,
|
|
@@ -3046,6 +3063,7 @@ var init_validate = __esm({
|
|
|
3046
3063
|
PI_KEYS = { compaction: true };
|
|
3047
3064
|
PI_COMPACTION_KEYS = { reserveTokens: true, keepRecentTokens: true };
|
|
3048
3065
|
ROUTE_ANSWER_MODES = ["tool", "text"];
|
|
3066
|
+
REFERENCES_KEYS = { enabled: true };
|
|
3049
3067
|
ROUTING_KEYS = { auto: true, model: true, answer: true };
|
|
3050
3068
|
SHIP_KEYS = { maxRounds: true, maxMinutes: true };
|
|
3051
3069
|
SPAWN_KEYS = { maxChildren: true };
|
|
@@ -4117,6 +4135,7 @@ var init_residentSteps = __esm({
|
|
|
4117
4135
|
"for-each-ref": "listing the branches",
|
|
4118
4136
|
checkout: "checking out the branch",
|
|
4119
4137
|
"checkout-update": "updating the checkout",
|
|
4138
|
+
"rebind-checkout": "checking out the thread's own branch",
|
|
4120
4139
|
"rev-parse": "reading the commit",
|
|
4121
4140
|
"cat-file": "checking the mirror for the commit",
|
|
4122
4141
|
"show-ref": "reading the branch tip",
|
|
@@ -5543,10 +5562,10 @@ function describeBase(base, code) {
|
|
|
5543
5562
|
return "none";
|
|
5544
5563
|
}
|
|
5545
5564
|
}
|
|
5546
|
-
function markdownReason(
|
|
5547
|
-
if (
|
|
5548
|
-
return
|
|
5549
|
-
return
|
|
5565
|
+
function markdownReason(reason2) {
|
|
5566
|
+
if (reason2.startsWith("unsure:"))
|
|
5567
|
+
return reason2.replace(/(unclassified path |import )(\S+)/, (_m, pre, p) => `${pre}\`${p}\``);
|
|
5568
|
+
return reason2.replace(/^(\S+?)(?=$| \(imported by |: (production )?dependencies)/, "`$1`").replace(/\(imported by (\S+)\)/, "(imported by `$1`)");
|
|
5550
5569
|
}
|
|
5551
5570
|
function capped(reasons, render3, sep) {
|
|
5552
5571
|
const shown = reasons.slice(0, REASONS_SHOWN).map(render3);
|
|
@@ -5670,19 +5689,19 @@ function servedCommit(body) {
|
|
|
5670
5689
|
return typeof c === "string" && c !== "" ? c : void 0;
|
|
5671
5690
|
}
|
|
5672
5691
|
function decideReady(body, elapsedMs, deadlineMs, identify) {
|
|
5673
|
-
let
|
|
5692
|
+
let reason2;
|
|
5674
5693
|
if (!body) {
|
|
5675
|
-
|
|
5694
|
+
reason2 = "/healthz not answering with JSON (container restarting, or unreachable)";
|
|
5676
5695
|
} else {
|
|
5677
5696
|
const verdict = identify(body);
|
|
5678
5697
|
if (verdict.live) return { kind: "live", ...verdict.identity };
|
|
5679
5698
|
if (body.draining === true && !verdict.sameIdentity) {
|
|
5680
5699
|
const n2 = typeof body.inFlight === "number" ? body.inFlight : "?";
|
|
5681
5700
|
const since = typeof body.drainStartedAt === "string" ? ` since ${body.drainStartedAt}` : "";
|
|
5682
|
-
|
|
5683
|
-
} else
|
|
5701
|
+
reason2 = `old container still draining \u2014 ${n2} run(s) in flight${since}`;
|
|
5702
|
+
} else reason2 = verdict.reason;
|
|
5684
5703
|
}
|
|
5685
|
-
return elapsedMs >= deadlineMs ? { kind: "timeout", reason } : { kind: "waiting", reason };
|
|
5704
|
+
return elapsedMs >= deadlineMs ? { kind: "timeout", reason: reason2 } : { kind: "waiting", reason: reason2 };
|
|
5686
5705
|
}
|
|
5687
5706
|
function sameCommit(a, b) {
|
|
5688
5707
|
const x = a.trim();
|
|
@@ -6289,7 +6308,7 @@ var init_sandboxLiveGate = __esm({
|
|
|
6289
6308
|
PROBE_COMMAND = "echo ok";
|
|
6290
6309
|
PROBE_TIMEOUT_MS = 6e4;
|
|
6291
6310
|
CONTAINER_STARTING = /Container is starting/i;
|
|
6292
|
-
waiting = (
|
|
6311
|
+
waiting = (reason2) => ({ kind: "waiting", reason: reason2 });
|
|
6293
6312
|
isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
6294
6313
|
ANSI_SEQUENCE2 = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
|
|
6295
6314
|
SECTION_GUTTER = /^[\s│├╭╰|]+/;
|
|
@@ -7346,10 +7365,7 @@ async function transferImage(copy, account2, credential, io = {}) {
|
|
|
7346
7365
|
} catch (err2) {
|
|
7347
7366
|
if (err2 instanceof TransferProblem)
|
|
7348
7367
|
return { ok: false, problem: err2.message, ...err2.unauthorized ? { unauthorized: true } : {} };
|
|
7349
|
-
return {
|
|
7350
|
-
ok: false,
|
|
7351
|
-
problem: `copying ${copy.source} failed \u2014 ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
7352
|
-
};
|
|
7368
|
+
return { ok: false, problem: `copying ${copy.source} failed \u2014 ${reason(err2)}` };
|
|
7353
7369
|
}
|
|
7354
7370
|
}
|
|
7355
7371
|
async function transfer(copy, account2, credential, io) {
|
|
@@ -7433,16 +7449,19 @@ async function transfer(copy, account2, credential, io) {
|
|
|
7433
7449
|
if (started.status !== 202 || !startedAt)
|
|
7434
7450
|
throw await refused(`starting the upload of ${short2(blob.digest)} to ${targetName} failed`, started);
|
|
7435
7451
|
let location = resolveLocation(startedAt, `${targetBase}/blobs/uploads/`);
|
|
7436
|
-
const
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7452
|
+
const blobUrl = `${sourceBase}/v2/${repository}/blobs/${blob.digest}`;
|
|
7453
|
+
const chunks = sourceBytes(
|
|
7454
|
+
blob,
|
|
7455
|
+
copy.source,
|
|
7456
|
+
log,
|
|
7457
|
+
(from) => fromSource(`reading ${short2(blob.digest)} from ${copy.source}`, blobUrl, {
|
|
7458
|
+
headers: from > 0 ? { range: `bytes=${from}-` } : {},
|
|
7459
|
+
signal: AbortSignal.timeout(LONG_MS)
|
|
7460
|
+
})
|
|
7440
7461
|
);
|
|
7441
|
-
if (!source2.ok || !source2.body)
|
|
7442
|
-
throw new TransferProblem(`reading ${short2(blob.digest)} from ${copy.source} failed \u2014 ${await said(source2)}`);
|
|
7443
7462
|
const hash = createHash2("sha256");
|
|
7444
7463
|
let index = 0;
|
|
7445
|
-
for await (const { part, bytes: partBytesBuffer } of partsOf(
|
|
7464
|
+
for await (const { part, bytes: partBytesBuffer } of partsOf(chunks, parts, hash, blob, copy.source)) {
|
|
7446
7465
|
index++;
|
|
7447
7466
|
const label = `part ${index}/${parts.length} (${contentRange(part)})`;
|
|
7448
7467
|
const patch = () => doFetch(location, {
|
|
@@ -7513,6 +7532,41 @@ function asBody(bytes) {
|
|
|
7513
7532
|
function sha256(bytes) {
|
|
7514
7533
|
return `sha256:${createHash2("sha256").update(bytes).digest("hex")}`;
|
|
7515
7534
|
}
|
|
7535
|
+
async function* sourceBytes(blob, source2, log, open2) {
|
|
7536
|
+
let consumed = 0;
|
|
7537
|
+
let resumes = 0;
|
|
7538
|
+
for (; ; ) {
|
|
7539
|
+
const res = await open2(consumed);
|
|
7540
|
+
const what = consumed === 0 ? `reading ${short2(blob.digest)} from ${source2}` : `resuming ${short2(blob.digest)} from ${source2} at byte ${consumed}`;
|
|
7541
|
+
if (consumed === 0 ? !res.ok : res.status !== 206) {
|
|
7542
|
+
const words = consumed > 0 && res.status === 200 ? "HTTP 200 where 206 was expected (the source ignored the Range)" : await said(res);
|
|
7543
|
+
void res.body?.cancel().catch(() => {
|
|
7544
|
+
});
|
|
7545
|
+
throw new TransferProblem(`${what} failed \u2014 ${words}`);
|
|
7546
|
+
}
|
|
7547
|
+
const contentRange2 = res.headers.get("content-range");
|
|
7548
|
+
if (consumed > 0 && !contentRange2?.startsWith(`bytes ${consumed}-`))
|
|
7549
|
+
throw new TransferProblem(`${what} failed \u2014 the source answered Content-Range ${contentRange2 ?? "none"}`);
|
|
7550
|
+
if (!res.body) throw new TransferProblem(`${what} failed \u2014 no body`);
|
|
7551
|
+
try {
|
|
7552
|
+
for await (const chunk of res.body) {
|
|
7553
|
+
consumed += chunk.byteLength;
|
|
7554
|
+
yield chunk;
|
|
7555
|
+
}
|
|
7556
|
+
return;
|
|
7557
|
+
} catch (err2) {
|
|
7558
|
+
if (consumed >= blob.size) return;
|
|
7559
|
+
if (resumes >= RESUMES)
|
|
7560
|
+
throw new TransferProblem(
|
|
7561
|
+
`reading ${short2(blob.digest)} from ${source2} broke at byte ${consumed} of ${blob.size} after ${resumes} resumes \u2014 ${reason(err2)}`
|
|
7562
|
+
);
|
|
7563
|
+
resumes++;
|
|
7564
|
+
log(
|
|
7565
|
+
`[images] ${short2(blob.digest)} broke at ${mib(consumed)} of ${mib(blob.size)} (${reason(err2)}) \u2014 resuming from there, ${resumes} of ${RESUMES}`
|
|
7566
|
+
);
|
|
7567
|
+
}
|
|
7568
|
+
}
|
|
7569
|
+
}
|
|
7516
7570
|
async function* partsOf(body, parts, hash, blob, source2) {
|
|
7517
7571
|
let i = 0;
|
|
7518
7572
|
let buffer = parts.length > 0 ? Buffer.allocUnsafe(parts[0].end - parts[0].start) : Buffer.alloc(0);
|
|
@@ -7542,7 +7596,7 @@ async function* partsOf(body, parts, hash, blob, source2) {
|
|
|
7542
7596
|
`${short2(blob.digest)} from ${source2} ended after ${parts[i].start + filled} of its ${blob.size} bytes`
|
|
7543
7597
|
);
|
|
7544
7598
|
}
|
|
7545
|
-
var REGISTRY_ENDPOINTS, SHORT_MS, LONG_MS, TransferProblem, refused, said, MiB, mib, short2;
|
|
7599
|
+
var REGISTRY_ENDPOINTS, SHORT_MS, LONG_MS, RESUMES, TransferProblem, refused, said, reason, MiB, mib, short2;
|
|
7546
7600
|
var init_registryTransferHost = __esm({
|
|
7547
7601
|
"../../src/deploy/registryTransferHost.ts"() {
|
|
7548
7602
|
"use strict";
|
|
@@ -7555,6 +7609,7 @@ var init_registryTransferHost = __esm({
|
|
|
7555
7609
|
};
|
|
7556
7610
|
SHORT_MS = 6e4;
|
|
7557
7611
|
LONG_MS = 30 * 6e4;
|
|
7612
|
+
RESUMES = 3;
|
|
7558
7613
|
TransferProblem = class extends Error {
|
|
7559
7614
|
constructor(message3, unauthorized = false) {
|
|
7560
7615
|
super(message3);
|
|
@@ -7567,6 +7622,11 @@ var init_registryTransferHost = __esm({
|
|
|
7567
7622
|
const text = (await res.text().catch(() => "")).trim();
|
|
7568
7623
|
return `HTTP ${res.status}${text ? `: ${text}` : ""}`;
|
|
7569
7624
|
};
|
|
7625
|
+
reason = (err2) => {
|
|
7626
|
+
if (!(err2 instanceof Error)) return String(err2);
|
|
7627
|
+
const cause = err2.cause instanceof Error ? err2.cause.message : void 0;
|
|
7628
|
+
return cause && cause !== err2.message ? `${err2.message} (${cause})` : err2.message;
|
|
7629
|
+
};
|
|
7570
7630
|
MiB = 1024 * 1024;
|
|
7571
7631
|
mib = (n2) => `${(n2 / MiB).toFixed(n2 >= 10 * MiB ? 0 : 1)} MiB`;
|
|
7572
7632
|
short2 = (digest) => digest.slice(0, 19);
|
|
@@ -7590,9 +7650,9 @@ function imagesHostIO(options = {}) {
|
|
|
7590
7650
|
const transferIO = { ...options.transferIO ?? {}, ...options.log ? { log: options.log } : {} };
|
|
7591
7651
|
const credentials = /* @__PURE__ */ new Map();
|
|
7592
7652
|
const credential = async (account2, replace = false) => {
|
|
7593
|
-
const
|
|
7594
|
-
if (
|
|
7595
|
-
return { ok: true, credential:
|
|
7653
|
+
const held2 = credentials.get(account2);
|
|
7654
|
+
if (held2 && !replace && now() - held2.mintedAt < CREDENTIAL_MINUTES * 6e4 - RENEW_BEFORE_MS)
|
|
7655
|
+
return { ok: true, credential: held2.credential };
|
|
7596
7656
|
const token2 = env[API_TOKEN_ENV];
|
|
7597
7657
|
if (!token2) return { ok: false, problem: apiTokenMissingProblem() };
|
|
7598
7658
|
const minted = await transfer2.mint(account2, token2, transferIO);
|
|
@@ -7994,7 +8054,7 @@ function isHeadMaterial(event) {
|
|
|
7994
8054
|
case "route":
|
|
7995
8055
|
return true;
|
|
7996
8056
|
case "run_note":
|
|
7997
|
-
return event.kind === "mcp_unavailable" || event.kind === "spans_dropped" || event.kind === "cold_sandbox";
|
|
8057
|
+
return event.kind === "mcp_unavailable" || event.kind === "spans_dropped" || event.kind === "cold_sandbox" || event.kind === "rebind_refused";
|
|
7998
8058
|
case "span_start":
|
|
7999
8059
|
return event.name === "request" || event.name === "slack.receive" || event.name.startsWith("dispatch.");
|
|
8000
8060
|
case "span_end":
|
|
@@ -8060,6 +8120,7 @@ var init_runEvents = __esm({
|
|
|
8060
8120
|
"seed",
|
|
8061
8121
|
"description_turn",
|
|
8062
8122
|
"cold_sandbox",
|
|
8123
|
+
"rebind_refused",
|
|
8063
8124
|
"pr_not_opened",
|
|
8064
8125
|
"review_not_posted",
|
|
8065
8126
|
"compacted",
|
|
@@ -9163,12 +9224,12 @@ ${parts}`);
|
|
|
9163
9224
|
});
|
|
9164
9225
|
|
|
9165
9226
|
// ../../src/execution/residentState.ts
|
|
9166
|
-
function degradedIsServiceable(
|
|
9167
|
-
return SERVICEABLE_DEGRADED_REASON.test(
|
|
9227
|
+
function degradedIsServiceable(reason2) {
|
|
9228
|
+
return SERVICEABLE_DEGRADED_REASON.test(reason2 ?? "");
|
|
9168
9229
|
}
|
|
9169
|
-
function isServiceable(state,
|
|
9230
|
+
function isServiceable(state, reason2) {
|
|
9170
9231
|
if (!SERVICEABLE_STATES.has(state)) return false;
|
|
9171
|
-
return state !== "degraded" || degradedIsServiceable(
|
|
9232
|
+
return state !== "degraded" || degradedIsServiceable(reason2);
|
|
9172
9233
|
}
|
|
9173
9234
|
var SERVICEABLE_STATES, SERVICEABLE_DEGRADED_REASON;
|
|
9174
9235
|
var init_residentState = __esm({
|
|
@@ -9280,8 +9341,8 @@ function wakeDecision(probe) {
|
|
|
9280
9341
|
}
|
|
9281
9342
|
return { wait: false, why: `the resident is ${seen}, which no wake recovers from; not waiting` };
|
|
9282
9343
|
}
|
|
9283
|
-
function describeState(state,
|
|
9284
|
-
return
|
|
9344
|
+
function describeState(state, reason2) {
|
|
9345
|
+
return reason2 ? `${state} (${reason2})` : state;
|
|
9285
9346
|
}
|
|
9286
9347
|
function describeProbe(probe) {
|
|
9287
9348
|
return probe.kind === "status" ? describeState(probe.state, probe.reason) : `unreachable (${probe.error})`;
|
|
@@ -9381,8 +9442,8 @@ var init_residentAdmin = __esm({
|
|
|
9381
9442
|
init_secrets2();
|
|
9382
9443
|
RESIDENTS_OFF_MESSAGE = "Resident repo environments aren't configured \u2014 set `execution.resident.baseUrl` in config.yaml.";
|
|
9383
9444
|
NullResidentAdminClient = class {
|
|
9384
|
-
constructor(
|
|
9385
|
-
this.reason =
|
|
9445
|
+
constructor(reason2 = RESIDENTS_OFF_MESSAGE) {
|
|
9446
|
+
this.reason = reason2;
|
|
9386
9447
|
}
|
|
9387
9448
|
reason;
|
|
9388
9449
|
answer() {
|
|
@@ -9431,6 +9492,20 @@ function wakePause(ms, signal2) {
|
|
|
9431
9492
|
signal2?.addEventListener("abort", onAbort, { once: true });
|
|
9432
9493
|
});
|
|
9433
9494
|
}
|
|
9495
|
+
function reboundOf(value) {
|
|
9496
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
9497
|
+
const v = value;
|
|
9498
|
+
if (typeof v.from !== "string" || typeof v.to !== "string" || typeof v.pr !== "number") return void 0;
|
|
9499
|
+
if (!v.from || !v.to || !Number.isSafeInteger(v.pr) || v.pr <= 0) return void 0;
|
|
9500
|
+
return { from: v.from, to: v.to, pr: v.pr };
|
|
9501
|
+
}
|
|
9502
|
+
function rebindRefusedOf(value) {
|
|
9503
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
9504
|
+
const v = value;
|
|
9505
|
+
if (typeof v.to !== "string" || typeof v.pr !== "number" || typeof v.reason !== "string") return void 0;
|
|
9506
|
+
if (!v.to || !v.reason || !Number.isSafeInteger(v.pr) || v.pr <= 0) return void 0;
|
|
9507
|
+
return { to: v.to, pr: v.pr, reason: v.reason, why: typeof v.why === "string" ? v.why : "" };
|
|
9508
|
+
}
|
|
9434
9509
|
async function parseResidentBody(res) {
|
|
9435
9510
|
const text = await res.text();
|
|
9436
9511
|
let data = {};
|
|
@@ -9620,10 +9695,12 @@ var init_resident = __esm({
|
|
|
9620
9695
|
}
|
|
9621
9696
|
/** Bind/reuse this thread's worktree. Legible errors for every named
|
|
9622
9697
|
* refusal the service can answer with. Answers the binding the resident
|
|
9623
|
-
* reported: the bound ref
|
|
9624
|
-
*
|
|
9625
|
-
*
|
|
9626
|
-
*
|
|
9698
|
+
* reported: the bound ref — the resident's word, not the hint's: a differing
|
|
9699
|
+
* refHint is ignored unless `ownPr` names it as the thread's own pull
|
|
9700
|
+
* request and the resident moves a default-bound thread onto it (item 16;
|
|
9701
|
+
* `rebound` / `rebindRefused` say which) — and the sha the worktree is at. A
|
|
9702
|
+
* 200 without both fields is a malformed resident (the attach contract
|
|
9703
|
+
* always carries them) and is an error, never a half-bound executor. */
|
|
9627
9704
|
async attach(span) {
|
|
9628
9705
|
const answer = await this.attachOnce(span);
|
|
9629
9706
|
if (answer.ok) return answer.binding;
|
|
@@ -9640,6 +9717,8 @@ var init_resident = __esm({
|
|
|
9640
9717
|
if (this.opts.readonly) body.readonly = true;
|
|
9641
9718
|
if (this.opts.sha) body.sha = this.opts.sha;
|
|
9642
9719
|
if (this.opts.reuse) body.reuse = true;
|
|
9720
|
+
if (this.opts.ownPr) body.ownPr = this.opts.ownPr;
|
|
9721
|
+
if (this.opts.refByDefault) body.refByDefault = true;
|
|
9643
9722
|
const answered = await this.call("/attach", body, timeoutMs, void 0, span);
|
|
9644
9723
|
const data = answered.data;
|
|
9645
9724
|
const status3 = answered.status === 200 && typeof data.error === "string" && typeof data.status === "number" ? data.status : answered.status;
|
|
@@ -9648,6 +9727,8 @@ var init_resident = __esm({
|
|
|
9648
9727
|
throw new Error(`resident attach: malformed answer for ${this.opts.resource} (missing ref/sha)`);
|
|
9649
9728
|
}
|
|
9650
9729
|
const trace = sanitizeGraftedSteps(data.trace);
|
|
9730
|
+
const rebound = reboundOf(data.rebound);
|
|
9731
|
+
const rebindRefused = rebindRefusedOf(data.rebindRefused);
|
|
9651
9732
|
this.lastBinding = {
|
|
9652
9733
|
ref: data.ref,
|
|
9653
9734
|
sha: data.sha,
|
|
@@ -9655,7 +9736,9 @@ var init_resident = __esm({
|
|
|
9655
9736
|
...typeof data.user === "string" && data.user ? { user: data.user } : {},
|
|
9656
9737
|
...typeof data.container === "string" && data.container ? { container: data.container } : {},
|
|
9657
9738
|
...trace.length > 0 ? { trace } : {},
|
|
9658
|
-
...typeof data.attachMs === "number" && Number.isFinite(data.attachMs) ? { attachMs: data.attachMs } : {}
|
|
9739
|
+
...typeof data.attachMs === "number" && Number.isFinite(data.attachMs) ? { attachMs: data.attachMs } : {},
|
|
9740
|
+
...rebound !== void 0 ? { rebound } : {},
|
|
9741
|
+
...rebindRefused !== void 0 ? { rebindRefused } : {}
|
|
9659
9742
|
};
|
|
9660
9743
|
return { ok: true, binding: this.lastBinding };
|
|
9661
9744
|
}
|
|
@@ -10086,7 +10169,8 @@ async function makeExecutor(opts, ctx, span) {
|
|
|
10086
10169
|
threadKey: ctx.threadKey,
|
|
10087
10170
|
refHint: ctx.ref,
|
|
10088
10171
|
readonly,
|
|
10089
|
-
sha: ctx.headSha
|
|
10172
|
+
sha: ctx.headSha,
|
|
10173
|
+
...ctx.ownPr !== void 0 ? { ownPr: ctx.ownPr } : {}
|
|
10090
10174
|
},
|
|
10091
10175
|
nonWarm,
|
|
10092
10176
|
span
|
|
@@ -10174,7 +10258,7 @@ async function openResident(opts, nonWarm, span) {
|
|
|
10174
10258
|
} catch (err2) {
|
|
10175
10259
|
if (!(err2 instanceof ResidentNeedsRefError) || !err2.defaultRef) throw err2;
|
|
10176
10260
|
byDefault = true;
|
|
10177
|
-
executor = new ResidentExecutor({ ...opts, refHint: err2.defaultRef });
|
|
10261
|
+
executor = new ResidentExecutor({ ...opts, refHint: err2.defaultRef, refByDefault: true });
|
|
10178
10262
|
try {
|
|
10179
10263
|
binding = await executor.attach(span);
|
|
10180
10264
|
} catch (again) {
|
|
@@ -10189,6 +10273,7 @@ async function openResident(opts, nonWarm, span) {
|
|
|
10189
10273
|
}
|
|
10190
10274
|
const where = `${opts.resource.replace(/^repo:/, "")} \xB7 ${binding.ref}@${binding.sha.slice(0, 7)}`;
|
|
10191
10275
|
const why = byDefault ? " (repo default \u2014 no branch named)" : "";
|
|
10276
|
+
const moved = rebindLabel(binding);
|
|
10192
10277
|
return {
|
|
10193
10278
|
executor,
|
|
10194
10279
|
resident: true,
|
|
@@ -10196,9 +10281,17 @@ async function openResident(opts, nonWarm, span) {
|
|
|
10196
10281
|
...binding.trace ? { trace: binding.trace } : {},
|
|
10197
10282
|
...binding.attachMs !== void 0 ? { attachMs: binding.attachMs } : {},
|
|
10198
10283
|
binding,
|
|
10199
|
-
note: nonWarm ? `resident ${nonWarm} \xB7 ${where}${why} \u2014 attached to the last snapshot` : `resident \xB7 ${where}${why}`
|
|
10284
|
+
note: nonWarm ? `resident ${nonWarm} \xB7 ${where}${why}${moved} \u2014 attached to the last snapshot` : `resident \xB7 ${where}${why}${moved}`
|
|
10200
10285
|
};
|
|
10201
10286
|
}
|
|
10287
|
+
function rebindLabel(binding) {
|
|
10288
|
+
if (binding.rebound) return ` \xB7 rebound to ${binding.rebound.to} (this thread's PR #${binding.rebound.pr})`;
|
|
10289
|
+
if (binding.rebindRefused) {
|
|
10290
|
+
const r = binding.rebindRefused;
|
|
10291
|
+
return ` \xB7 rebind to ${r.to} (this thread's PR #${r.pr}) refused: ${r.reason}`;
|
|
10292
|
+
}
|
|
10293
|
+
return "";
|
|
10294
|
+
}
|
|
10202
10295
|
function residentOnboardedProbe(cfg, secrets = processSecrets) {
|
|
10203
10296
|
const token2 = cfg?.baseUrl ? secrets.named(cfg.tokenEnv ?? "RESIDENT_OPERATOR_TOKEN") : void 0;
|
|
10204
10297
|
if (!cfg?.baseUrl || !token2) return void 0;
|
|
@@ -12461,9 +12554,12 @@ function describeIssue(issue, root) {
|
|
|
12461
12554
|
function wrapUntrusted(text) {
|
|
12462
12555
|
return `${UNTRUSTED_PREAMBLE}
|
|
12463
12556
|
${UNTRUSTED_OPEN}
|
|
12464
|
-
${text}
|
|
12557
|
+
${breakFenceMarkers(text)}
|
|
12465
12558
|
${UNTRUSTED_CLOSE}`;
|
|
12466
12559
|
}
|
|
12560
|
+
function breakFenceMarkers(text) {
|
|
12561
|
+
return text.replaceAll(UNTRUSTED_CLOSE, "UNTRUSTED>> >").replaceAll(UNTRUSTED_OPEN, "<< <UNTRUSTED");
|
|
12562
|
+
}
|
|
12467
12563
|
function renderText(cmd, output, opts = {}) {
|
|
12468
12564
|
if (opts.surface === "chat" && cmd.renderChat) return cmd.renderChat(output);
|
|
12469
12565
|
return cmd.render ? cmd.render(output) : renderCompact(cmd.id, output, opts);
|
|
@@ -12588,14 +12684,14 @@ var init_commandRegistry = __esm({
|
|
|
12588
12684
|
});
|
|
12589
12685
|
return fail("not_found", `unknown command: ${id}`);
|
|
12590
12686
|
}
|
|
12591
|
-
const done = (res,
|
|
12687
|
+
const done = (res, reason2) => {
|
|
12592
12688
|
this.audit({
|
|
12593
12689
|
commandId: cmd.id,
|
|
12594
12690
|
callerKind: caller.kind,
|
|
12595
12691
|
callerId: caller.id,
|
|
12596
12692
|
effect: cmd.effect,
|
|
12597
12693
|
outcome: res.ok ? "ok" : res.error,
|
|
12598
|
-
...
|
|
12694
|
+
...reason2 === void 0 ? {} : { reason: reason2 }
|
|
12599
12695
|
});
|
|
12600
12696
|
return res;
|
|
12601
12697
|
};
|
|
@@ -14389,6 +14485,38 @@ function prOfEvents(events) {
|
|
|
14389
14485
|
for (const e of events) if (e.type === "pr_opened") pr = { number: e.number, url: e.url };
|
|
14390
14486
|
return pr;
|
|
14391
14487
|
}
|
|
14488
|
+
function routeOfEvents(events) {
|
|
14489
|
+
const meta = events.find((e) => e.type === "run_meta");
|
|
14490
|
+
if (meta?.type !== "run_meta" || meta.agentSource !== "route") return void 0;
|
|
14491
|
+
const r = events.find((e) => e.type === "route");
|
|
14492
|
+
if (r?.type !== "route") return void 0;
|
|
14493
|
+
return {
|
|
14494
|
+
preset: r.preset,
|
|
14495
|
+
reason: r.reason,
|
|
14496
|
+
model: r.model,
|
|
14497
|
+
...r.parts ? { parts: r.parts.map((p) => ({ preset: p.preset, text: p.text })) } : {},
|
|
14498
|
+
...r.collapsed ? { collapsed: { presets: [...r.collapsed.presets] } } : {}
|
|
14499
|
+
};
|
|
14500
|
+
}
|
|
14501
|
+
function isRunRouteShape(v) {
|
|
14502
|
+
if (typeof v !== "object" || v === null) return false;
|
|
14503
|
+
const r = v;
|
|
14504
|
+
if (typeof r.preset !== "string" || typeof r.reason !== "string" || typeof r.model !== "string") return false;
|
|
14505
|
+
if (r.parts !== void 0) {
|
|
14506
|
+
if (!Array.isArray(r.parts)) return false;
|
|
14507
|
+
for (const p of r.parts) {
|
|
14508
|
+
if (typeof p !== "object" || p === null) return false;
|
|
14509
|
+
const part = p;
|
|
14510
|
+
if (typeof part.preset !== "string" || typeof part.text !== "string") return false;
|
|
14511
|
+
}
|
|
14512
|
+
}
|
|
14513
|
+
if (r.collapsed !== void 0) {
|
|
14514
|
+
const c = r.collapsed;
|
|
14515
|
+
if (typeof c !== "object" || c === null) return false;
|
|
14516
|
+
if (!Array.isArray(c.presets) || !c.presets.every((p) => typeof p === "string")) return false;
|
|
14517
|
+
}
|
|
14518
|
+
return true;
|
|
14519
|
+
}
|
|
14392
14520
|
function isRunPullRequestShape(v) {
|
|
14393
14521
|
if (typeof v !== "object" || v === null) return false;
|
|
14394
14522
|
const p = v;
|
|
@@ -14551,6 +14679,7 @@ function isRunRecord(v) {
|
|
|
14551
14679
|
return false;
|
|
14552
14680
|
if (r.dispositions !== void 0 && !isFindingDispositionsShape(r.dispositions)) return false;
|
|
14553
14681
|
if (r.reviewPost !== void 0 && !isReviewPostShape(r.reviewPost)) return false;
|
|
14682
|
+
if (r.route !== void 0 && !isRunRouteShape(r.route)) return false;
|
|
14554
14683
|
if (r.profile !== void 0 && !isRunProfileRecord(r.profile)) return false;
|
|
14555
14684
|
if (r.pr !== void 0 && !isRunPullRequestShape(r.pr)) return false;
|
|
14556
14685
|
if (r.parentRunId !== void 0 && (typeof r.parentRunId !== "string" || !RUN_ID_PATTERN.test(r.parentRunId)))
|
|
@@ -17473,13 +17602,13 @@ function bridgeMcpTools(server, client, tools, opts) {
|
|
|
17473
17602
|
const bytes = Buffer.byteLength(text, "utf8");
|
|
17474
17603
|
const wrapped = wrapUntrusted(clipped);
|
|
17475
17604
|
if (!ok2) {
|
|
17476
|
-
const
|
|
17605
|
+
const refused6 = classifyError(new Error(`MCP ${server.name}/${t.name} reported an error:
|
|
17477
17606
|
${wrapped}`), {
|
|
17478
17607
|
kind: "refused"
|
|
17479
17608
|
});
|
|
17480
|
-
span?.fail(
|
|
17609
|
+
span?.fail(refused6);
|
|
17481
17610
|
span?.end("error", { ok: ok2, bytes });
|
|
17482
|
-
throw
|
|
17611
|
+
throw refused6;
|
|
17483
17612
|
}
|
|
17484
17613
|
span?.end("ok", { ok: ok2, bytes });
|
|
17485
17614
|
return wrapped;
|
|
@@ -17598,9 +17727,9 @@ var init_source = __esm({
|
|
|
17598
17727
|
tools: bridgeMcpTools(server, client, tools, { budget })
|
|
17599
17728
|
};
|
|
17600
17729
|
} catch (err2) {
|
|
17601
|
-
const
|
|
17730
|
+
const reason2 = redactAndCap(err2 instanceof Error ? err2.message : String(err2), 160);
|
|
17602
17731
|
return {
|
|
17603
|
-
outcome: { server: server.name, unavailable:
|
|
17732
|
+
outcome: { server: server.name, unavailable: reason2 },
|
|
17604
17733
|
tools: []
|
|
17605
17734
|
};
|
|
17606
17735
|
}
|
|
@@ -19725,12 +19854,12 @@ function renderResidentList(data) {
|
|
|
19725
19854
|
const live = obj(rec2.live);
|
|
19726
19855
|
const slug = String(rec2.resource ?? "").replace(/^repo:/, "");
|
|
19727
19856
|
const state = String(live.state ?? "unknown");
|
|
19728
|
-
const
|
|
19857
|
+
const reason2 = String(live.reason ?? "");
|
|
19729
19858
|
const sha = typeof live.sha === "string" && live.sha ? ` \xB7 sha \`${live.sha.slice(0, 8)}\`` : "";
|
|
19730
19859
|
const refreshed = typeof live.lastRefreshAt === "string" && live.lastRefreshAt ? ` \xB7 refreshed ${live.lastRefreshAt}` : "";
|
|
19731
19860
|
const d = obj(live.disk);
|
|
19732
19861
|
const disk = typeof d.usedKiB === "number" && typeof d.totalKiB === "number" ? ` \xB7 disk ${formatDiskGauge({ usedKiB: d.usedKiB, totalKiB: d.totalKiB })}` : "";
|
|
19733
|
-
return `\u2022 \`${slug}\` \u2014 *${state}*${
|
|
19862
|
+
return `\u2022 \`${slug}\` \u2014 *${state}*${reason2 ? ` (${reason2})` : ""} \xB7 ref \`${String(rec2.defaultRef ?? "?")}\`${sha}${refreshed}${disk}`;
|
|
19734
19863
|
});
|
|
19735
19864
|
const out = [`*Resident repos* (${n(data.count)}/${n(data.cap)}):`, ...lines];
|
|
19736
19865
|
const t = data.testOverrides;
|
|
@@ -19754,7 +19883,7 @@ function listWords(words) {
|
|
|
19754
19883
|
async function settleProvisioning(deps, slug) {
|
|
19755
19884
|
const sleep2 = deps.repo.sleep ?? ((ms) => new Promise((resolve12) => setTimeout(resolve12, ms)));
|
|
19756
19885
|
const resource = repoResourceId(slug);
|
|
19757
|
-
const hint = (
|
|
19886
|
+
const hint = (reason2) => /provision-failed at (install|build|test)\b/.test(reason2) ? `Fix the command table with \`repo reconfigure ${slug} --install "\u2026" --build "\u2026" --test "\u2026"\`, then \`repo rebuild ${slug}\`.` : `Not a command-table failure \u2014 retry with \`repo rebuild ${slug}\`; if it recurs, the resident or Cloudflare side is at fault (\`repo list\` shows the live state).`;
|
|
19758
19887
|
for (let elapsed2 = 0; elapsed2 <= SETTLE_MAX_MS; elapsed2 += SETTLE_POLL_MS) {
|
|
19759
19888
|
if (elapsed2 > 0) await sleep2(SETTLE_POLL_MS);
|
|
19760
19889
|
const api = await deps.repo.admin();
|
|
@@ -19780,9 +19909,9 @@ async function settleProvisioning(deps, slug) {
|
|
|
19780
19909
|
if (state === "onboarding") continue;
|
|
19781
19910
|
if (state === "warm") return { ok: true, text: `\u2705 \`${slug}\` is warm \u2014 provisioned and attach-ready.` };
|
|
19782
19911
|
if (state === "down") {
|
|
19783
|
-
const
|
|
19784
|
-
return { ok: false, text: `\u274C \`${slug}\` failed to provision: ${
|
|
19785
|
-
${hint(
|
|
19912
|
+
const reason2 = str4(r.data.reason ?? "no reason recorded");
|
|
19913
|
+
return { ok: false, text: `\u274C \`${slug}\` failed to provision: ${reason2}
|
|
19914
|
+
${hint(reason2)}` };
|
|
19786
19915
|
}
|
|
19787
19916
|
return {
|
|
19788
19917
|
ok: true,
|
|
@@ -20708,6 +20837,7 @@ function ledgerView(row, events) {
|
|
|
20708
20837
|
...m.sourceUrl !== void 0 ? { sourceUrl: m.sourceUrl } : {},
|
|
20709
20838
|
...m.userName !== void 0 ? { userName: m.userName } : {},
|
|
20710
20839
|
...m.parentRunId !== void 0 ? { parentRunId: m.parentRunId } : {},
|
|
20840
|
+
...m.route !== void 0 ? { route: m.route } : {},
|
|
20711
20841
|
...m.parentInstanceId !== void 0 ? { parentInstanceId: m.parentInstanceId } : {},
|
|
20712
20842
|
...m.idempotencyKey !== void 0 ? { idempotencyKey: m.idempotencyKey } : {},
|
|
20713
20843
|
...row.stop ? { stop: { mode: row.stop, state: "stopping" } } : {},
|
|
@@ -22944,6 +23074,7 @@ function reclaimedRunRecord(input) {
|
|
|
22944
23074
|
// included); a row from before profiles existed leaves the record without one.
|
|
22945
23075
|
...row.meta.profile && row.meta.agent ? { profile: { preset: row.meta.agent, ...row.meta.profile } } : {},
|
|
22946
23076
|
...row.meta.parentRunId !== void 0 ? { parentRunId: row.meta.parentRunId } : {},
|
|
23077
|
+
...row.meta.route !== void 0 ? { route: row.meta.route } : {},
|
|
22947
23078
|
...row.meta.seed !== void 0 ? { seed: row.meta.seed } : {},
|
|
22948
23079
|
// The row's place in its session log (item 53): the range stays open on a
|
|
22949
23080
|
// record closed here, since the closer has no turn count to end it with.
|
|
@@ -22979,6 +23110,7 @@ function assembleRunRecord(input) {
|
|
|
22979
23110
|
const atFinish = snap?.events ?? [];
|
|
22980
23111
|
const events = seal && seal.events.length > 0 ? [...atFinish, ...seal.events] : atFinish;
|
|
22981
23112
|
const pr = prOfEvents(events);
|
|
23113
|
+
const route3 = input.route ?? routeOfEvents(events);
|
|
22982
23114
|
const fitted = fitRecordToBudget({
|
|
22983
23115
|
id: run2.id,
|
|
22984
23116
|
...run2.label !== void 0 ? { label: run2.label } : {},
|
|
@@ -23015,6 +23147,7 @@ function assembleRunRecord(input) {
|
|
|
23015
23147
|
...input.reviewHead !== void 0 ? { reviewHead: input.reviewHead } : {},
|
|
23016
23148
|
...input.dispositions !== void 0 ? { dispositions: redactDispositions(input.dispositions) } : {},
|
|
23017
23149
|
...input.reviewPost !== void 0 ? { reviewPost: redactReviewPost(input.reviewPost) } : {},
|
|
23150
|
+
...route3 !== void 0 ? { route: route3 } : {},
|
|
23018
23151
|
...input.profile !== void 0 ? { profile: input.profile } : {},
|
|
23019
23152
|
...input.parentRunId !== void 0 ? { parentRunId: input.parentRunId } : {},
|
|
23020
23153
|
...coordinatorFields(input.coordinator),
|
|
@@ -23038,6 +23171,7 @@ function writeTombstone(deps, ctx) {
|
|
|
23038
23171
|
run: run2,
|
|
23039
23172
|
registry,
|
|
23040
23173
|
resume,
|
|
23174
|
+
route: route3,
|
|
23041
23175
|
parentRunId,
|
|
23042
23176
|
coordinator,
|
|
23043
23177
|
seed
|
|
@@ -23055,6 +23189,7 @@ function writeTombstone(deps, ctx) {
|
|
|
23055
23189
|
channelVisibility,
|
|
23056
23190
|
repo: repoCtx.repo,
|
|
23057
23191
|
profile: profileRecordOf(agent, profile),
|
|
23192
|
+
...route3 !== void 0 ? { route: route3 } : {},
|
|
23058
23193
|
...parentRunId !== void 0 ? { parentRunId } : {},
|
|
23059
23194
|
...coordinator !== void 0 ? { coordinator } : {},
|
|
23060
23195
|
...seed !== void 0 ? { seed } : {},
|
|
@@ -23091,6 +23226,7 @@ function registerFinishRecord(deps, ctx) {
|
|
|
23091
23226
|
reviewHead,
|
|
23092
23227
|
dispositions,
|
|
23093
23228
|
reviewPost,
|
|
23229
|
+
route: route3,
|
|
23094
23230
|
parentRunId,
|
|
23095
23231
|
coordinator,
|
|
23096
23232
|
seed
|
|
@@ -23117,6 +23253,7 @@ function registerFinishRecord(deps, ctx) {
|
|
|
23117
23253
|
...reviewHead !== void 0 ? { reviewHead } : {},
|
|
23118
23254
|
...dispositions !== void 0 ? { dispositions } : {},
|
|
23119
23255
|
...reviewPost !== void 0 ? { reviewPost } : {},
|
|
23256
|
+
...route3 !== void 0 ? { route: route3 } : {},
|
|
23120
23257
|
...parentRunId !== void 0 ? { parentRunId } : {},
|
|
23121
23258
|
...coordinator !== void 0 ? { coordinator } : {},
|
|
23122
23259
|
...seed !== void 0 ? { seed } : {}
|
|
@@ -23666,8 +23803,8 @@ async function mergePullRequest(pr, opts) {
|
|
|
23666
23803
|
return { ok: true, sha };
|
|
23667
23804
|
}
|
|
23668
23805
|
if (res.status === 405 || res.status === 409 || res.status === 422) {
|
|
23669
|
-
const
|
|
23670
|
-
return { ok: false, status: res.status, reason };
|
|
23806
|
+
const reason2 = typeof body?.message === "string" && body.message ? body.message : redactAndCap(text, 300);
|
|
23807
|
+
return { ok: false, status: res.status, reason: reason2 };
|
|
23671
23808
|
}
|
|
23672
23809
|
throw new Error(`merge failed for ${pr.repo}#${pr.number}: HTTP ${res.status} ${redactAndCap(text, 300)}`);
|
|
23673
23810
|
}
|
|
@@ -23980,9 +24117,12 @@ async function resolveRepoContext(msg, history = [], probe, residentSlugs, recor
|
|
|
23980
24117
|
if (head.base) out.baseRef = head.base;
|
|
23981
24118
|
if (head.size) out.prSize = head.size;
|
|
23982
24119
|
if (head.facts) out.prDescription = head.facts;
|
|
23983
|
-
if (inherited.source === "record"
|
|
23984
|
-
out.
|
|
23985
|
-
|
|
24120
|
+
if (inherited.source === "record") {
|
|
24121
|
+
out.prFromRecord = true;
|
|
24122
|
+
if (!ref && head.ref) {
|
|
24123
|
+
out.ref = head.ref;
|
|
24124
|
+
out.refFromPr = true;
|
|
24125
|
+
}
|
|
23986
24126
|
}
|
|
23987
24127
|
} else {
|
|
23988
24128
|
out.prUnpostable = { number: inherited.number, reason: head.reason };
|
|
@@ -23991,6 +24131,10 @@ async function resolveRepoContext(msg, history = [], probe, residentSlugs, recor
|
|
|
23991
24131
|
}
|
|
23992
24132
|
return out;
|
|
23993
24133
|
}
|
|
24134
|
+
function ownPrOf(ctx) {
|
|
24135
|
+
if (!ctx.prFromRecord || !ctx.refFromPr || ctx.pr === void 0 || ctx.ref === void 0) return void 0;
|
|
24136
|
+
return { number: ctx.pr, ref: ctx.ref };
|
|
24137
|
+
}
|
|
23994
24138
|
function inheritedPr(thread, records, repo) {
|
|
23995
24139
|
const turn = thread.pr && thread.pr.repo === repo ? { repo, number: thread.pr.number, source: "turn", at: thread.prAt } : void 0;
|
|
23996
24140
|
const record2 = records?.pr && records.pr.repo === repo ? { repo, number: records.pr.number, source: "record", at: records.pr.at } : void 0;
|
|
@@ -25591,9 +25735,9 @@ var init_diffDigest2 = __esm({
|
|
|
25591
25735
|
const listing = `git diff --numstat ${range} && echo ${NAME_STATUS_MARK} && git diff --name-status ${range}`;
|
|
25592
25736
|
let raw = await ctx.executor.exec(listing);
|
|
25593
25737
|
const incomplete = () => {
|
|
25594
|
-
const
|
|
25595
|
-
ctx.onDigest?.({ complete: false, base: baseName, reason });
|
|
25596
|
-
return `diff_digest: ${
|
|
25738
|
+
const reason2 = "the file listing exceeded the executor's output cap";
|
|
25739
|
+
ctx.onDigest?.({ complete: false, base: baseName, reason: reason2 });
|
|
25740
|
+
return `diff_digest: ${reason2} \u2014 the digest cannot state totals for this change (base \`${baseName}\`). Read the diff file by file (\`git diff --name-only ${baseName}...HEAD\`).`;
|
|
25597
25741
|
};
|
|
25598
25742
|
if (OUTPUT_CUT_RE.test(raw)) return incomplete();
|
|
25599
25743
|
let marker = NAME_STATUS_MARK_LINE.exec(raw);
|
|
@@ -25896,8 +26040,8 @@ ${clip2(c.body.trim(), 2e3)}`).join("\n\n")}` : "";
|
|
|
25896
26040
|
async run(input, ctx) {
|
|
25897
26041
|
const repo = repoOf(input);
|
|
25898
26042
|
if (typeof repo !== "string") return `github_issue_create: ${repo.error}`;
|
|
25899
|
-
const
|
|
25900
|
-
if (
|
|
26043
|
+
const refused6 = writeGate("github_issue_create", ctx, repo);
|
|
26044
|
+
if (refused6) return refused6;
|
|
25901
26045
|
const title = String(input.title ?? "").trim();
|
|
25902
26046
|
if (!title) return "github_issue_create: title is required.";
|
|
25903
26047
|
try {
|
|
@@ -25933,8 +26077,8 @@ ${issue.url}`;
|
|
|
25933
26077
|
async run(input, ctx) {
|
|
25934
26078
|
const repo = repoOf(input);
|
|
25935
26079
|
if (typeof repo !== "string") return `github_issue_update: ${repo.error}`;
|
|
25936
|
-
const
|
|
25937
|
-
if (
|
|
26080
|
+
const refused6 = writeGate("github_issue_update", ctx, repo);
|
|
26081
|
+
if (refused6) return refused6;
|
|
25938
26082
|
const number = numberOf(input);
|
|
25939
26083
|
if (typeof number !== "number") return `github_issue_update: ${number.error}`;
|
|
25940
26084
|
const patch = {
|
|
@@ -25970,8 +26114,8 @@ ${issue.url}`;
|
|
|
25970
26114
|
async run(input, ctx) {
|
|
25971
26115
|
const repo = repoOf(input);
|
|
25972
26116
|
if (typeof repo !== "string") return `github_issue_comment: ${repo.error}`;
|
|
25973
|
-
const
|
|
25974
|
-
if (
|
|
26117
|
+
const refused6 = writeGate("github_issue_comment", ctx, repo);
|
|
26118
|
+
if (refused6) return refused6;
|
|
25975
26119
|
const number = numberOf(input);
|
|
25976
26120
|
if (typeof number !== "number") return `github_issue_comment: ${number.error}`;
|
|
25977
26121
|
const body = String(input.body ?? "").trim();
|
|
@@ -25999,8 +26143,8 @@ ${url}`;
|
|
|
25999
26143
|
async run(input, ctx) {
|
|
26000
26144
|
const repo = repoOf(input);
|
|
26001
26145
|
if (typeof repo !== "string") return `github_issue_delete: ${repo.error}`;
|
|
26002
|
-
const
|
|
26003
|
-
if (
|
|
26146
|
+
const refused6 = writeGate("github_issue_delete", ctx, repo);
|
|
26147
|
+
if (refused6) return refused6;
|
|
26004
26148
|
const number = numberOf(input);
|
|
26005
26149
|
if (typeof number !== "number") return `github_issue_delete: ${number.error}`;
|
|
26006
26150
|
try {
|
|
@@ -26172,22 +26316,22 @@ function watchedChild(io, on) {
|
|
|
26172
26316
|
return watched2;
|
|
26173
26317
|
}
|
|
26174
26318
|
async function spawnChild(deps, parent, request) {
|
|
26175
|
-
const
|
|
26319
|
+
const refused6 = (reason3, message3) => ({ kind: "refused", reason: reason3, message: message3 });
|
|
26176
26320
|
if (parent.depth >= MAX_SPAWN_DEPTH) {
|
|
26177
|
-
return
|
|
26321
|
+
return refused6(
|
|
26178
26322
|
"spawn_depth",
|
|
26179
26323
|
`a child run cannot spawn: this run is itself a child, and a tree is ${MAX_SPAWN_DEPTH} level deep \u2014 the run that started it is the one to ask`
|
|
26180
26324
|
);
|
|
26181
26325
|
}
|
|
26182
26326
|
if (AGENTS[request.preset]?.identity === "write") {
|
|
26183
|
-
return
|
|
26327
|
+
return refused6(
|
|
26184
26328
|
"spawn_identity",
|
|
26185
26329
|
`\`${request.preset}\` runs as a \`write\` identity \u2014 it pushes branches and opens pull requests \u2014 and a spawned child never writes: it reads this conversation and reports; the person who asked starts that work by hand with \`agent:${request.preset}\``
|
|
26186
26330
|
);
|
|
26187
26331
|
}
|
|
26188
26332
|
const minutesLeft = Math.floor(parent.remainingMs / 6e4);
|
|
26189
26333
|
if (minutesLeft < MIN_BOUNDARY_MINUTES) {
|
|
26190
|
-
return
|
|
26334
|
+
return refused6(
|
|
26191
26335
|
"spawn_budget",
|
|
26192
26336
|
`this run has under ${MIN_BOUNDARY_MINUTES} minutes left \u2014 too little to hand a child, which could never run a command in it; wrap up instead`
|
|
26193
26337
|
);
|
|
@@ -26195,13 +26339,13 @@ async function spawnChild(deps, parent, request) {
|
|
|
26195
26339
|
const live = deps.registry.listActive().filter((s) => !s.finished && s.parentRunId === parent.runId).length;
|
|
26196
26340
|
const cap = maxChildrenOf(deps.core.config.config.spawn);
|
|
26197
26341
|
if (live >= cap) {
|
|
26198
|
-
return
|
|
26342
|
+
return refused6(
|
|
26199
26343
|
"spawn_fanout",
|
|
26200
26344
|
`${live} child run${live === 1 ? " is" : "s are"} live already \u2014 the cap is ${cap} (\`spawn.maxChildren\`); wait for one to finish before spawning another`
|
|
26201
26345
|
);
|
|
26202
26346
|
}
|
|
26203
26347
|
if (!parent.io.openThread) {
|
|
26204
|
-
return
|
|
26348
|
+
return refused6(
|
|
26205
26349
|
"spawn_unsupported",
|
|
26206
26350
|
`the ${platformOf(parent.msg.channelId)} channel cannot open a thread of its own, so a child run cannot be spawned from it`
|
|
26207
26351
|
);
|
|
@@ -26210,7 +26354,7 @@ async function spawnChild(deps, parent, request) {
|
|
|
26210
26354
|
try {
|
|
26211
26355
|
opened = await parent.io.openThread(childThreadLead(parent, request));
|
|
26212
26356
|
} catch (err2) {
|
|
26213
|
-
return
|
|
26357
|
+
return refused6("spawn_failed", `the channel could not open the child's thread: ${describe3(err2)}`);
|
|
26214
26358
|
}
|
|
26215
26359
|
const child = {
|
|
26216
26360
|
channelId: parent.msg.channelId,
|
|
@@ -26265,10 +26409,10 @@ async function spawnChild(deps, parent, request) {
|
|
|
26265
26409
|
...opened.thread.sourceUrl !== void 0 ? { url: opened.thread.sourceUrl } : {}
|
|
26266
26410
|
};
|
|
26267
26411
|
}
|
|
26268
|
-
if (first.kind === "threw") return
|
|
26269
|
-
const
|
|
26270
|
-
console.log(`[spawn] ${parent.msg.threadKey} run ${parent.runId}: ${request.preset} child not started (${
|
|
26271
|
-
return
|
|
26412
|
+
if (first.kind === "threw") return refused6("spawn_failed", describe3(first.err));
|
|
26413
|
+
const reason2 = first.outcome.refusal ?? "spawn_failed";
|
|
26414
|
+
console.log(`[spawn] ${parent.msg.threadKey} run ${parent.runId}: ${request.preset} child not started (${reason2})`);
|
|
26415
|
+
return refused6(reason2, lastReply ?? `the child ended (${first.outcome.status}) before it started`);
|
|
26272
26416
|
}
|
|
26273
26417
|
function spawnCapabilityFor(deps, parent) {
|
|
26274
26418
|
const outcomes = /* @__PURE__ */ new Map();
|
|
@@ -28169,8 +28313,8 @@ function attachRule(attachers) {
|
|
|
28169
28313
|
"A request that asks for a file, a screenshot, a recording or an attachment to be posted, attached or sent back routes there too, however read-only the rest of it sounds; a read-only preset can describe a file but never post one."
|
|
28170
28314
|
].join(" ");
|
|
28171
28315
|
}
|
|
28172
|
-
function tidyReason(
|
|
28173
|
-
const line3 = oneLine(redactAndCap(
|
|
28316
|
+
function tidyReason(reason2) {
|
|
28317
|
+
const line3 = oneLine(redactAndCap(reason2, ROUTE_REASON_CAP));
|
|
28174
28318
|
return line3.length > 0 ? line3 : "no reason given";
|
|
28175
28319
|
}
|
|
28176
28320
|
function parseRouteAnswer(raw, allowed2, compound) {
|
|
@@ -28183,21 +28327,21 @@ function parseRouteAnswer(raw, allowed2, compound) {
|
|
|
28183
28327
|
}
|
|
28184
28328
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
28185
28329
|
return { preset: void 0, reason: `not a single JSON object: ${tidyReason(trimmed)}` };
|
|
28186
|
-
const { preset: named, reason, parts } = parsed;
|
|
28330
|
+
const { preset: named, reason: reason2, parts } = parsed;
|
|
28187
28331
|
const preset = typeof named === "string" ? named : Array.isArray(parts) ? COMPOUND_PRESET : void 0;
|
|
28188
28332
|
const inferred = typeof named !== "string" && preset === COMPOUND_PRESET;
|
|
28189
28333
|
if (preset === void 0)
|
|
28190
28334
|
return { preset: void 0, reason: `missing preset in the router's answer: ${tidyReason(trimmed)}` };
|
|
28191
28335
|
const partsAnswer = preset === COMPOUND_PRESET && Array.isArray(parts);
|
|
28192
|
-
if (typeof
|
|
28336
|
+
if (typeof reason2 !== "string" && !partsAnswer)
|
|
28193
28337
|
return { preset: void 0, reason: `missing reason in the router's answer: ${tidyReason(trimmed)}` };
|
|
28194
|
-
const tidy = typeof
|
|
28338
|
+
const tidy = typeof reason2 === "string" ? tidyReason(reason2) : inferred ? "compound inferred from parts" : "no reason given";
|
|
28195
28339
|
if (preset === COMPOUND_PRESET) return parseCompound(parts, tidy, allowed2, compound);
|
|
28196
28340
|
if (!allowed2.includes(preset))
|
|
28197
28341
|
return { preset: void 0, reason: `router said "${tidyReason(preset)}", not a preset the requester may run` };
|
|
28198
28342
|
return { preset, reason: tidy };
|
|
28199
28343
|
}
|
|
28200
|
-
function parseCompound(parts,
|
|
28344
|
+
function parseCompound(parts, reason2, allowed2, offer) {
|
|
28201
28345
|
const rejected = (why) => ({
|
|
28202
28346
|
preset: void 0,
|
|
28203
28347
|
reason: `compound_rejected: ${why}`,
|
|
@@ -28221,8 +28365,8 @@ function parseCompound(parts, reason, allowed2, offer) {
|
|
|
28221
28365
|
out.push({ preset, text: tidy });
|
|
28222
28366
|
}
|
|
28223
28367
|
const writer = out.find((p) => identityOf(p.preset) === "write");
|
|
28224
|
-
if (writer) return { preset: writer.preset, reason, collapsed: { presets: out.map((p) => p.preset) } };
|
|
28225
|
-
return { preset: COMPOUND_PRESET, reason, parts: out };
|
|
28368
|
+
if (writer) return { preset: writer.preset, reason: reason2, collapsed: { presets: out.map((p) => p.preset) } };
|
|
28369
|
+
return { preset: COMPOUND_PRESET, reason: reason2, parts: out };
|
|
28226
28370
|
}
|
|
28227
28371
|
async function route(input, model, opts = {}) {
|
|
28228
28372
|
const { compound: offer, ...rest } = input;
|
|
@@ -28342,8 +28486,8 @@ async function routeRequest(deps, ctx) {
|
|
|
28342
28486
|
}
|
|
28343
28487
|
};
|
|
28344
28488
|
}
|
|
28345
|
-
function routedLabel(
|
|
28346
|
-
return `${ROUTED_LABEL_PREFIX} ${
|
|
28489
|
+
function routedLabel(reason2, collapsed) {
|
|
28490
|
+
return `${ROUTED_LABEL_PREFIX} ${reason2}${collapsed ? ` (compound collapsed: ${collapsed.presets.join("+")})` : ""}`;
|
|
28347
28491
|
}
|
|
28348
28492
|
function routedPartLines(parts) {
|
|
28349
28493
|
return parts.map((p) => {
|
|
@@ -29269,6 +29413,7 @@ async function attachRoundWorkspace(input) {
|
|
|
29269
29413
|
repo: input.round.repo,
|
|
29270
29414
|
ref: input.round.ref,
|
|
29271
29415
|
headSha: input.round.headSha,
|
|
29416
|
+
...input.round.ownPr !== void 0 ? { ownPr: input.round.ownPr } : {},
|
|
29272
29417
|
...input.round.reattach !== void 0 ? { reattach: input.round.reattach } : {}
|
|
29273
29418
|
},
|
|
29274
29419
|
input.span
|
|
@@ -29541,11 +29686,11 @@ ${carriedFooter(carried)}` : buildReviewPostBody(input.answer, verdict);
|
|
|
29541
29686
|
try {
|
|
29542
29687
|
await input.post(target, body);
|
|
29543
29688
|
} catch (err2) {
|
|
29544
|
-
const
|
|
29545
|
-
console.error(`[review-post] ${logKey} failed for ${where}: ${
|
|
29546
|
-
await input.reply(`\u2139\uFE0F Review not posted to ${where}: ${
|
|
29689
|
+
const reason2 = err2 instanceof Error ? err2.message : String(err2);
|
|
29690
|
+
console.error(`[review-post] ${logKey} failed for ${where}: ${reason2}`);
|
|
29691
|
+
await input.reply(`\u2139\uFE0F Review not posted to ${where}: ${reason2} \u2014 this verdict is Slack-only.`).catch(() => {
|
|
29547
29692
|
});
|
|
29548
|
-
return record2({ posted: false, reason });
|
|
29693
|
+
return record2({ posted: false, reason: reason2 });
|
|
29549
29694
|
}
|
|
29550
29695
|
console.log(
|
|
29551
29696
|
`[review-post] ${logKey} \u2192 ${where} (${verdict?.verdict ?? "no verdict"})${carried ? ` carried ${carried.reviewed.slice(0, 7)} \u2192 ${pinned.slice(0, 7)}` : ""}`
|
|
@@ -30600,6 +30745,7 @@ async function reserveRun(deps, ctx) {
|
|
|
30600
30745
|
}
|
|
30601
30746
|
async function attachWorkspace(deps, ctx) {
|
|
30602
30747
|
const { msg, io, refuse: refuse3, card, shell, closeLines, clock: clock3, agent, profile, repoCtx, root, reattach } = ctx;
|
|
30748
|
+
const ownPr = ownPrOf(repoCtx);
|
|
30603
30749
|
let round2;
|
|
30604
30750
|
try {
|
|
30605
30751
|
round2 = await root.span("dispatch.workspace.attach", async (span) => {
|
|
@@ -30625,6 +30771,9 @@ async function attachWorkspace(deps, ctx) {
|
|
|
30625
30771
|
repo: repoCtx.repo,
|
|
30626
30772
|
ref: repoCtx.ref,
|
|
30627
30773
|
headSha: repoCtx.headSha,
|
|
30774
|
+
// The thread's own pull request, when the ref is its head (resident-
|
|
30775
|
+
// repos item 16): the one reason the resident may move a binding.
|
|
30776
|
+
...ownPr !== void 0 ? { ownPr } : {},
|
|
30628
30777
|
...reattach !== void 0 ? { reattach } : {}
|
|
30629
30778
|
},
|
|
30630
30779
|
logKey: msg.threadKey,
|
|
@@ -30804,6 +30953,7 @@ var init_provision = __esm({
|
|
|
30804
30953
|
init_selfDescription();
|
|
30805
30954
|
init_customInstructions();
|
|
30806
30955
|
init_reviewRound();
|
|
30956
|
+
init_repoContext();
|
|
30807
30957
|
init_runEvents();
|
|
30808
30958
|
init_runRecord();
|
|
30809
30959
|
init_inboxMessage();
|
|
@@ -32021,10 +32171,10 @@ var init_bridge2 = __esm({
|
|
|
32021
32171
|
return this.openTools.has(callId);
|
|
32022
32172
|
}
|
|
32023
32173
|
/** End whatever tool spans a stopped pi left open, so no span outlives the run. */
|
|
32024
|
-
closeOpenSpans(
|
|
32174
|
+
closeOpenSpans(reason2) {
|
|
32025
32175
|
for (const [callId, open2] of this.openTools) {
|
|
32026
32176
|
open2.span?.end("error", { callId, ok: false });
|
|
32027
|
-
this.emit({ type: "tool_result", tool: open2.tool, ok: false, callId, summary: redactAndCap(
|
|
32177
|
+
this.emit({ type: "tool_result", tool: open2.tool, ok: false, callId, summary: redactAndCap(reason2) });
|
|
32028
32178
|
}
|
|
32029
32179
|
this.openTools.clear();
|
|
32030
32180
|
this.vetted.clear();
|
|
@@ -32535,7 +32685,7 @@ async function runPiHarnessOpen(deps, run2) {
|
|
|
32535
32685
|
run2.saveFacts?.(facts2);
|
|
32536
32686
|
}
|
|
32537
32687
|
};
|
|
32538
|
-
const
|
|
32688
|
+
const held2 = () => {
|
|
32539
32689
|
if (transport) mirrored = transport.consumedOffset;
|
|
32540
32690
|
save();
|
|
32541
32691
|
};
|
|
@@ -32812,9 +32962,9 @@ ${stagedLine}` : prompt,
|
|
|
32812
32962
|
if (!continuing) mirror.expectSeedEcho();
|
|
32813
32963
|
}
|
|
32814
32964
|
}
|
|
32815
|
-
if (obs.message && await mirror.onMessage(obs.message, bridge.turns))
|
|
32965
|
+
if (obs.message && await mirror.onMessage(obs.message, bridge.turns)) held2();
|
|
32816
32966
|
if (obs.compaction) {
|
|
32817
|
-
if (await mirror.onCompaction(obs.compaction, bridge.turns))
|
|
32967
|
+
if (await mirror.onCompaction(obs.compaction, bridge.turns)) held2();
|
|
32818
32968
|
if (!writeUp && !hardStopped && !catchingUp) {
|
|
32819
32969
|
let notepad;
|
|
32820
32970
|
let unavailable = false;
|
|
@@ -32994,8 +33144,8 @@ var init_harness = __esm({
|
|
|
32994
33144
|
CALL_SEEN_TICK_MS = 50;
|
|
32995
33145
|
CONTINUE_PROMPT = "Continue where you left off: the bot restarted mid-run, so re-check the effects of your last command before relying on them.";
|
|
32996
33146
|
PromptRefused = class extends Error {
|
|
32997
|
-
constructor(
|
|
32998
|
-
super(`pi refused the prompt: ${
|
|
33147
|
+
constructor(reason2) {
|
|
33148
|
+
super(`pi refused the prompt: ${reason2}`);
|
|
32999
33149
|
this.name = "PromptRefused";
|
|
33000
33150
|
}
|
|
33001
33151
|
};
|
|
@@ -33466,9 +33616,9 @@ async function runCodingPrPostStep(input) {
|
|
|
33466
33616
|
});
|
|
33467
33617
|
return opened.created ? `\u{1F500} PR opened: ${opened.htmlUrl} (\`${branch2}\` \u2192 \`${base}\`)` : `\u{1F500} PR updated: ${opened.htmlUrl} \u2014 body re-rendered at \`${headSha.slice(0, 7)}\``;
|
|
33468
33618
|
} catch (err2) {
|
|
33469
|
-
const
|
|
33470
|
-
console.error(`[pr-post] ${logKey} open/edit failed for ${repo} ${branch2}: ${
|
|
33471
|
-
return `\u26A0\uFE0F The branch \`${branch2}\` is pushed but the PR could not be opened: ${
|
|
33619
|
+
const reason2 = err2 instanceof Error ? err2.message : String(err2);
|
|
33620
|
+
console.error(`[pr-post] ${logKey} open/edit failed for ${repo} ${branch2}: ${reason2}`);
|
|
33621
|
+
return `\u26A0\uFE0F The branch \`${branch2}\` is pushed but the PR could not be opened: ${reason2} \u2014 compare & open manually: ${compareUrl}`;
|
|
33472
33622
|
}
|
|
33473
33623
|
}
|
|
33474
33624
|
if (prDescription && pushedBranch && !base) {
|
|
@@ -33722,6 +33872,7 @@ async function runLoop2(deps, ctx) {
|
|
|
33722
33872
|
steer,
|
|
33723
33873
|
wait,
|
|
33724
33874
|
session,
|
|
33875
|
+
route: route3,
|
|
33725
33876
|
parentRunId,
|
|
33726
33877
|
coordinator,
|
|
33727
33878
|
seed
|
|
@@ -34246,6 +34397,7 @@ async function runLoop2(deps, ctx) {
|
|
|
34246
34397
|
...reviewHead !== void 0 ? { reviewHead } : {},
|
|
34247
34398
|
...dispositions !== void 0 ? { dispositions } : {},
|
|
34248
34399
|
...reviewPost !== void 0 ? { reviewPost } : {},
|
|
34400
|
+
...route3 !== void 0 ? { route: route3 } : {},
|
|
34249
34401
|
...parentRunId !== void 0 ? { parentRunId } : {},
|
|
34250
34402
|
...coordinator !== void 0 ? { coordinator } : {},
|
|
34251
34403
|
...seed !== void 0 ? { seed } : {}
|
|
@@ -34373,8 +34525,8 @@ async function shipPreflight(input) {
|
|
|
34373
34525
|
}
|
|
34374
34526
|
const info = await input.repoInfo(repo).catch(() => void 0);
|
|
34375
34527
|
if (info?.allowAutoMerge !== false) {
|
|
34376
|
-
const
|
|
34377
|
-
return refuse2("auto-merge", "not started (auto-merge)", `\u{1F6AB} ${
|
|
34528
|
+
const reason2 = info?.allowAutoMerge === true ? `auto-merge is enabled on \`${repo}\` \u2014 ship's approving LGTM triggers the org auto-approve workflow, and with auto-merge on the PR would merge with no human. Disable auto-merge on the repo to use ship.` : `could not verify that auto-merge is disabled on \`${repo}\` (the repository lookup failed or answered without the setting) \u2014 refusing fail-closed.`;
|
|
34529
|
+
return refuse2("auto-merge", "not started (auto-merge)", `\u{1F6AB} ${reason2}`);
|
|
34378
34530
|
}
|
|
34379
34531
|
const task = shipTaskText(input.requestText, repo);
|
|
34380
34532
|
if (repoCtx.prUnpostable?.reason === "unreachable") {
|
|
@@ -35808,6 +35960,13 @@ function stickyAgentOf(runs, onPi) {
|
|
|
35808
35960
|
if (newest === void 0 || !continuable(newest) || !onPi(newest.agent)) return void 0;
|
|
35809
35961
|
return newest.agent;
|
|
35810
35962
|
}
|
|
35963
|
+
function threadRouteOf(runs, agent) {
|
|
35964
|
+
const newest = runs[0];
|
|
35965
|
+
if (newest === void 0 || !continuable(newest) || newest.agent !== agent || newest.route === void 0)
|
|
35966
|
+
return void 0;
|
|
35967
|
+
const { preset, reason: reason2, model } = newest.route;
|
|
35968
|
+
return { preset, reason: reason2, model };
|
|
35969
|
+
}
|
|
35811
35970
|
function previousRunOf(runs, agent) {
|
|
35812
35971
|
const run2 = runs.find((r) => r.agent === agent && continuable(r));
|
|
35813
35972
|
if (run2 === void 0) return void 0;
|
|
@@ -36042,9 +36201,9 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
36042
36201
|
const receivedAt = trace.receivedAt;
|
|
36043
36202
|
const queuedBeforeMs = msg.originAt !== void 0 ? Math.max(0, receivedAt - msg.originAt) : void 0;
|
|
36044
36203
|
const queued = queuedCaption("behind", opts.queuedBehindMs) ?? queuedCaption("before", queuedBeforeMs);
|
|
36045
|
-
let
|
|
36204
|
+
let refused6 = false;
|
|
36046
36205
|
const refuse3 = (outcome, fn) => {
|
|
36047
|
-
|
|
36206
|
+
refused6 = true;
|
|
36048
36207
|
ended.refusal ??= outcome;
|
|
36049
36208
|
return root.span("dispatch.refuse", fn, { attrs: { outcome } });
|
|
36050
36209
|
};
|
|
@@ -36131,6 +36290,8 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
36131
36290
|
agentSource = "route";
|
|
36132
36291
|
}
|
|
36133
36292
|
const routeEvent = routing.kind === "routed" ? routing.route : routing.rejected;
|
|
36293
|
+
if (routing.kind === "unrouted" && stickyAgent !== void 0 && agentSource === "sticky" && thread)
|
|
36294
|
+
route3 = threadRouteOf(thread, resolved.agentName);
|
|
36134
36295
|
if (resume?.row.meta.route) route3 = resume.row.meta.route;
|
|
36135
36296
|
if ((await authorizeAgent(deps, { msg, io, refuse: refuse3, agentName: resolved.agentName })).kind === "refused")
|
|
36136
36297
|
return ended;
|
|
@@ -36481,6 +36642,12 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
36481
36642
|
if (note) shell.setLabel(`${shell.label} \xB7 ${oneLine(note)}`);
|
|
36482
36643
|
if (note && !resident)
|
|
36483
36644
|
registry.publish(run2.id, { type: "run_note", kind: "cold_sandbox", summary: oneLine(note), at: clock3() });
|
|
36645
|
+
const bound = round2.selection.binding;
|
|
36646
|
+
const kept = bound?.rebindRefused;
|
|
36647
|
+
if (bound && kept) {
|
|
36648
|
+
const summary = `kept on ${bound.ref} \u2014 rebind to ${kept.to} (this thread's PR #${kept.pr}) refused: ${kept.reason}${kept.why ? ` \u2014 ${kept.why}` : ""}`;
|
|
36649
|
+
registry.publish(run2.id, { type: "run_note", kind: "rebind_refused", summary: oneLine(summary), at: clock3() });
|
|
36650
|
+
}
|
|
36484
36651
|
console.log(`[run] ${msg.threadKey} user=${msg.userId} agent=${agent.name} model=${resolved.modelRef}`);
|
|
36485
36652
|
setupCard = void 0;
|
|
36486
36653
|
clearInterval(setupHeartbeat);
|
|
@@ -36502,6 +36669,7 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
36502
36669
|
run: run2,
|
|
36503
36670
|
registry,
|
|
36504
36671
|
resume,
|
|
36672
|
+
...route3 !== void 0 ? { route: route3 } : {},
|
|
36505
36673
|
parentRunId,
|
|
36506
36674
|
coordinator,
|
|
36507
36675
|
seed
|
|
@@ -36592,6 +36760,7 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
36592
36760
|
steer,
|
|
36593
36761
|
wait,
|
|
36594
36762
|
...sessionTools ? { session: sessionTools } : {},
|
|
36763
|
+
...route3 !== void 0 ? { route: route3 } : {},
|
|
36595
36764
|
parentRunId,
|
|
36596
36765
|
coordinator,
|
|
36597
36766
|
seed,
|
|
@@ -36675,7 +36844,7 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
36675
36844
|
const settled = settleThread(deps, { msg, admitted, runLoopStarted, control: registered?.control });
|
|
36676
36845
|
if (settled.kind === "dropped") await tellDropped(root, settled.pending);
|
|
36677
36846
|
const stopMode = settled.kind === "handed-on" ? void 0 : settled.stopMode;
|
|
36678
|
-
ended.status = caught ? "failed" :
|
|
36847
|
+
ended.status = caught ? "failed" : refused6 ? "refused" : stopMode ? "stopped" : "completed";
|
|
36679
36848
|
root.end(caught ? "error" : "ok", { status: ended.status });
|
|
36680
36849
|
if (restartRequest) {
|
|
36681
36850
|
const pending2 = settled.kind === "handed-on" ? settled.pending : [];
|
|
@@ -37340,14 +37509,14 @@ function createLedgerWriteThrough(opts) {
|
|
|
37340
37509
|
return !this.detached;
|
|
37341
37510
|
}
|
|
37342
37511
|
/** One warning, then silence: the run continues untracked. */
|
|
37343
|
-
detach(
|
|
37512
|
+
detach(reason2) {
|
|
37344
37513
|
if (this.detached) return;
|
|
37345
37514
|
this.detached = true;
|
|
37346
37515
|
this.broken = true;
|
|
37347
|
-
warn(`[ledger] ${this.threadKey} run ${this.runId} detached: ${
|
|
37516
|
+
warn(`[ledger] ${this.threadKey} run ${this.runId} detached: ${reason2} \u2014 this run is not resumable`);
|
|
37348
37517
|
this.stopHeartbeat();
|
|
37349
37518
|
live.delete(this);
|
|
37350
|
-
if (
|
|
37519
|
+
if (reason2.includes("(fenced)")) {
|
|
37351
37520
|
this.fencedOut = true;
|
|
37352
37521
|
if (this.onFenced && !this.fencedTold) {
|
|
37353
37522
|
this.fencedTold = true;
|
|
@@ -38447,6 +38616,35 @@ var init_invokedAsScript = __esm({
|
|
|
38447
38616
|
}
|
|
38448
38617
|
});
|
|
38449
38618
|
|
|
38619
|
+
// ../../src/channels/slack/threadTurns.ts
|
|
38620
|
+
function threadTurns(messages, opts) {
|
|
38621
|
+
const kept = [];
|
|
38622
|
+
for (const mm of messages) {
|
|
38623
|
+
if (opts.skipTs !== void 0 && mm.ts === opts.skipTs) continue;
|
|
38624
|
+
const raw = mm.text ?? "";
|
|
38625
|
+
const text = opts.botUserId ? raw.replaceAll(`<@${opts.botUserId}>`, "").trim() : raw;
|
|
38626
|
+
if (STATUS_PREFIXES.some((p) => text.startsWith(p))) continue;
|
|
38627
|
+
const files = mm.bot_id ? void 0 : mm.files;
|
|
38628
|
+
if (!text && !files?.length) continue;
|
|
38629
|
+
const at = mm.ts !== void 0 && Number.isFinite(Number(mm.ts)) ? Math.round(Number(mm.ts) * 1e3) : void 0;
|
|
38630
|
+
kept.push({
|
|
38631
|
+
role: mm.bot_id ? "assistant" : "user",
|
|
38632
|
+
text,
|
|
38633
|
+
...at !== void 0 ? { at } : {},
|
|
38634
|
+
...mm.user !== void 0 ? { user: mm.user } : {},
|
|
38635
|
+
...mm.bot_id !== void 0 ? { botId: mm.bot_id } : {},
|
|
38636
|
+
files
|
|
38637
|
+
});
|
|
38638
|
+
}
|
|
38639
|
+
return kept;
|
|
38640
|
+
}
|
|
38641
|
+
var init_threadTurns = __esm({
|
|
38642
|
+
"../../src/channels/slack/threadTurns.ts"() {
|
|
38643
|
+
"use strict";
|
|
38644
|
+
init_reply();
|
|
38645
|
+
}
|
|
38646
|
+
});
|
|
38647
|
+
|
|
38450
38648
|
// ../../src/core/statusBudget.ts
|
|
38451
38649
|
function createStatusBudget(opts) {
|
|
38452
38650
|
const now = opts.now ?? Date.now;
|
|
@@ -39587,7 +39785,7 @@ var init_slack = __esm({
|
|
|
39587
39785
|
"../../src/channels/slack.ts"() {
|
|
39588
39786
|
"use strict";
|
|
39589
39787
|
init_dispatcher();
|
|
39590
|
-
|
|
39788
|
+
init_threadTurns();
|
|
39591
39789
|
init_statusBudget();
|
|
39592
39790
|
init_requestTrace();
|
|
39593
39791
|
init_clock();
|
|
@@ -39810,18 +40008,7 @@ ${file.text}`));
|
|
|
39810
40008
|
ts: this.ev.threadTs,
|
|
39811
40009
|
limit: 50
|
|
39812
40010
|
})).messages ?? [];
|
|
39813
|
-
const kept =
|
|
39814
|
-
for (const m of thread) {
|
|
39815
|
-
const mm = m;
|
|
39816
|
-
if (mm.ts === this.ev.ts) continue;
|
|
39817
|
-
const raw = mm.text ?? "";
|
|
39818
|
-
const text = this.ev.botUserId ? raw.replaceAll(`<@${this.ev.botUserId}>`, "").trim() : raw;
|
|
39819
|
-
if (STATUS_PREFIXES.some((p) => text.startsWith(p))) continue;
|
|
39820
|
-
const files = mm.bot_id ? void 0 : mm.files;
|
|
39821
|
-
if (!text && !files?.length) continue;
|
|
39822
|
-
const at = mm.ts !== void 0 && Number.isFinite(Number(mm.ts)) ? Math.round(Number(mm.ts) * 1e3) : void 0;
|
|
39823
|
-
kept.push({ role: mm.bot_id ? "assistant" : "user", text, ...at !== void 0 ? { at } : {}, files });
|
|
39824
|
-
}
|
|
40011
|
+
const kept = threadTurns(thread, { skipTs: this.ev.ts, botUserId: this.ev.botUserId });
|
|
39825
40012
|
const imagesByIndex = [];
|
|
39826
40013
|
const documentsByIndex = [];
|
|
39827
40014
|
let imagesLeft = MAX_HISTORY_IMAGES;
|
|
@@ -41340,15 +41527,15 @@ function createResidentsViewHandler(client, shell, trace) {
|
|
|
41340
41527
|
};
|
|
41341
41528
|
bound.residents().then((r) => {
|
|
41342
41529
|
if (r.status !== 200) {
|
|
41343
|
-
const
|
|
41530
|
+
const reason2 = (typeof r.data.error === "string" ? r.data.error : JSON.stringify(r.data)).slice(
|
|
41344
41531
|
0,
|
|
41345
41532
|
UPSTREAM_REASON_MAX
|
|
41346
41533
|
);
|
|
41347
41534
|
if (r.status === 503) {
|
|
41348
|
-
plainEnd(503,
|
|
41535
|
+
plainEnd(503, reason2);
|
|
41349
41536
|
return;
|
|
41350
41537
|
}
|
|
41351
|
-
plainEnd(502, `resident Worker answered ${r.status} to /residents: ${
|
|
41538
|
+
plainEnd(502, `resident Worker answered ${r.status} to /residents: ${reason2}`);
|
|
41352
41539
|
return;
|
|
41353
41540
|
}
|
|
41354
41541
|
const residents = Array.isArray(r.data.residents) ? r.data.residents : [];
|
|
@@ -41430,8 +41617,8 @@ function createCostsViewHandler(service, shell) {
|
|
|
41430
41617
|
res.writeHead(200, WEB_HTML_HEADERS);
|
|
41431
41618
|
res.end(shell(`${report2.label} spend`, { page: "costs", report: report2, groups }));
|
|
41432
41619
|
}).catch((err2) => {
|
|
41433
|
-
const
|
|
41434
|
-
plain2(res, 502, `cost sources unavailable: ${
|
|
41620
|
+
const reason2 = (err2 instanceof Error ? err2.message : String(err2)).slice(0, UPSTREAM_REASON_MAX2);
|
|
41621
|
+
plain2(res, 502, `cost sources unavailable: ${reason2}`);
|
|
41435
41622
|
});
|
|
41436
41623
|
return true;
|
|
41437
41624
|
};
|
|
@@ -41512,8 +41699,8 @@ function createDeliveryViewHandler(deps, shell) {
|
|
|
41512
41699
|
res.writeHead(200, WEB_HTML_HEADERS);
|
|
41513
41700
|
res.end(html);
|
|
41514
41701
|
}).catch((err2) => {
|
|
41515
|
-
const
|
|
41516
|
-
plain3(res, 502, `delivery sources unavailable: ${
|
|
41702
|
+
const reason2 = (err2 instanceof Error ? err2.message : String(err2)).slice(0, UPSTREAM_REASON_MAX3);
|
|
41703
|
+
plain3(res, 502, `delivery sources unavailable: ${reason2}`);
|
|
41517
41704
|
});
|
|
41518
41705
|
return true;
|
|
41519
41706
|
};
|
|
@@ -42797,6 +42984,11 @@ async function launchResumes(deps, resumable, opts) {
|
|
|
42797
42984
|
});
|
|
42798
42985
|
const dispatchFn = opts.dispatchFn ?? (await Promise.resolve().then(() => (init_dispatcher(), dispatcher_exports))).dispatch;
|
|
42799
42986
|
const outcome = { launched: [], closed: [] };
|
|
42987
|
+
const start3 = (row, dispatched, failure2) => {
|
|
42988
|
+
void dispatched.catch(
|
|
42989
|
+
(err2) => warn(`[resume] ${row.runId} ${row.threadKey}: ${failure2}: ${err2 instanceof Error ? err2.message : String(err2)}`)
|
|
42990
|
+
).finally(() => opts.onDone?.(row.runId));
|
|
42991
|
+
};
|
|
42800
42992
|
for (const run2 of resumable) {
|
|
42801
42993
|
const { row } = run2;
|
|
42802
42994
|
const agent = opts.agentFor(row.meta.agent);
|
|
@@ -42819,11 +43011,7 @@ async function launchResumes(deps, resumable, opts) {
|
|
|
42819
43011
|
`[resume] ${row.runId} ${row.threadKey}: restarting from its request (killed while attaching; ${run2.inbox.length} follow-up(s) pending)`
|
|
42820
43012
|
);
|
|
42821
43013
|
outcome.launched.push(row.runId);
|
|
42822
|
-
|
|
42823
|
-
(err2) => warn(
|
|
42824
|
-
`[resume] ${row.runId} ${row.threadKey}: restart dispatch failed: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
42825
|
-
)
|
|
42826
|
-
);
|
|
43014
|
+
start3(row, dispatchFn(deps, restored.msg, io2, { restart: { row, inbox: run2.inbox } }), "restart dispatch failed");
|
|
42827
43015
|
continue;
|
|
42828
43016
|
}
|
|
42829
43017
|
const plan3 = planResume({ transcript: run2.transcript, lastStep: run2.lastStep, tools: knownToolsFor(agent) });
|
|
@@ -42850,11 +43038,7 @@ async function launchResumes(deps, resumable, opts) {
|
|
|
42850
43038
|
plan3.kind === "finish" ? `[resume] ${row.runId} ${row.threadKey}: finishing (the model had answered at step ${plan3.step}; running the post-steps with its answer)` : `[resume] ${row.runId} ${row.threadKey}: resuming (${plan3.stepRecorded ? "settling" : "running fresh"} step ${plan3.step}, ${plan3.settlements.length} call(s), ${Math.round(plan3.remainingMs / 6e4)} min left)`
|
|
42851
43039
|
);
|
|
42852
43040
|
outcome.launched.push(row.runId);
|
|
42853
|
-
|
|
42854
|
-
(err2) => warn(
|
|
42855
|
-
`[resume] ${row.runId} ${row.threadKey}: dispatch failed: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
42856
|
-
)
|
|
42857
|
-
);
|
|
43041
|
+
start3(row, dispatchFn(deps, resumeMessage(row, inputTextOf(run2.events)), io, { resume: ctx }), "dispatch failed");
|
|
42858
43042
|
}
|
|
42859
43043
|
return outcome;
|
|
42860
43044
|
async function closeWith(run2, why) {
|
|
@@ -42864,6 +43048,7 @@ async function launchResumes(deps, resumable, opts) {
|
|
|
42864
43048
|
} catch (err2) {
|
|
42865
43049
|
warn(`[resume] ${run2.row.runId}: could not close: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
42866
43050
|
}
|
|
43051
|
+
opts.onDone?.(run2.row.runId);
|
|
42867
43052
|
}
|
|
42868
43053
|
}
|
|
42869
43054
|
var init_resumeLaunch = __esm({
|
|
@@ -42875,6 +43060,60 @@ var init_resumeLaunch = __esm({
|
|
|
42875
43060
|
}
|
|
42876
43061
|
});
|
|
42877
43062
|
|
|
43063
|
+
// ../../src/core/runLedger/takeover.ts
|
|
43064
|
+
var LedgerTakeover;
|
|
43065
|
+
var init_takeover = __esm({
|
|
43066
|
+
"../../src/core/runLedger/takeover.ts"() {
|
|
43067
|
+
"use strict";
|
|
43068
|
+
LedgerTakeover = class {
|
|
43069
|
+
listed = false;
|
|
43070
|
+
waiters = [];
|
|
43071
|
+
/** Handed to the launcher; each leaves when `done` names it. */
|
|
43072
|
+
resuming = /* @__PURE__ */ new Set();
|
|
43073
|
+
/** The latest listing's rows under another generation's lease. */
|
|
43074
|
+
elsewhere = /* @__PURE__ */ new Set();
|
|
43075
|
+
get settled() {
|
|
43076
|
+
return this.listed;
|
|
43077
|
+
}
|
|
43078
|
+
/** No ledger to take over from: settled with nothing pending. */
|
|
43079
|
+
settle() {
|
|
43080
|
+
this.listed = true;
|
|
43081
|
+
for (const wake2 of this.waiters.splice(0)) wake2();
|
|
43082
|
+
}
|
|
43083
|
+
/** One reclaim pass's outcome: its resumable runs join the pending set (until
|
|
43084
|
+
* `done`), its listing of rows live elsewhere replaces the previous one, and
|
|
43085
|
+
* the takeover counts as settled. */
|
|
43086
|
+
take(outcome) {
|
|
43087
|
+
for (const r of outcome.resumable) this.resuming.add(r.row.runId);
|
|
43088
|
+
this.elsewhere = new Set(outcome.liveElsewhere.map((r) => r.runId));
|
|
43089
|
+
this.settle();
|
|
43090
|
+
}
|
|
43091
|
+
/** The run's resume is over — its dispatch settled or the launcher closed it. */
|
|
43092
|
+
done(runId3) {
|
|
43093
|
+
this.resuming.delete(runId3);
|
|
43094
|
+
}
|
|
43095
|
+
pending(runId3) {
|
|
43096
|
+
return this.resuming.has(runId3) || this.elsewhere.has(runId3);
|
|
43097
|
+
}
|
|
43098
|
+
whenSettled(withinMs) {
|
|
43099
|
+
if (this.listed) return Promise.resolve(true);
|
|
43100
|
+
return new Promise((resolve12) => {
|
|
43101
|
+
const timer = setTimeout(() => {
|
|
43102
|
+
const at = this.waiters.indexOf(wake2);
|
|
43103
|
+
if (at >= 0) this.waiters.splice(at, 1);
|
|
43104
|
+
resolve12(false);
|
|
43105
|
+
}, withinMs);
|
|
43106
|
+
const wake2 = () => {
|
|
43107
|
+
clearTimeout(timer);
|
|
43108
|
+
resolve12(true);
|
|
43109
|
+
};
|
|
43110
|
+
this.waiters.push(wake2);
|
|
43111
|
+
});
|
|
43112
|
+
}
|
|
43113
|
+
};
|
|
43114
|
+
}
|
|
43115
|
+
});
|
|
43116
|
+
|
|
42878
43117
|
// ../../src/core/nullChannelIo.ts
|
|
42879
43118
|
function nullChannelIO(logKey, log = console.log) {
|
|
42880
43119
|
let children = 0;
|
|
@@ -42954,18 +43193,18 @@ function presentedBearer(headers) {
|
|
|
42954
43193
|
return apiKey ? apiKey : void 0;
|
|
42955
43194
|
}
|
|
42956
43195
|
function decideDoor(method, path, headers, bearers) {
|
|
42957
|
-
const
|
|
43196
|
+
const refused6 = (shape2, status3, code, message3, runId3) => ({
|
|
42958
43197
|
ok: false,
|
|
42959
43198
|
code,
|
|
42960
43199
|
response: refusalResponse(shape2, status3, code, message3),
|
|
42961
43200
|
...runId3 !== void 0 ? { runId: runId3 } : {}
|
|
42962
43201
|
});
|
|
42963
43202
|
const shape = proxyShapeOf(path);
|
|
42964
|
-
if (!shape) return
|
|
42965
|
-
if ((method ?? "GET").toUpperCase() !== "POST") return
|
|
43203
|
+
if (!shape) return refused6(void 0, 404, "not_found", "no model proxy at this path");
|
|
43204
|
+
if ((method ?? "GET").toUpperCase() !== "POST") return refused6(shape, 405, "method_not_allowed", "POST only");
|
|
42966
43205
|
const presented = presentedBearer(headers);
|
|
42967
43206
|
if (presented === void 0) {
|
|
42968
|
-
return
|
|
43207
|
+
return refused6(
|
|
42969
43208
|
shape,
|
|
42970
43209
|
401,
|
|
42971
43210
|
"missing_bearer",
|
|
@@ -42976,15 +43215,15 @@ function decideDoor(method, path, headers, bearers) {
|
|
|
42976
43215
|
if (verdict.ok) return { ok: true, shape, grant: verdict.grant, turns: verdict.turns };
|
|
42977
43216
|
switch (verdict.reason) {
|
|
42978
43217
|
case "malformed":
|
|
42979
|
-
return
|
|
43218
|
+
return refused6(shape, 401, "malformed_bearer", "the bearer is not a run bearer");
|
|
42980
43219
|
case "unknown_run":
|
|
42981
|
-
return
|
|
43220
|
+
return refused6(shape, 404, "unknown_run", "the bearer names a run this bot does not hold", verdict.runId);
|
|
42982
43221
|
case "unknown_bearer":
|
|
42983
|
-
return
|
|
43222
|
+
return refused6(shape, 401, "unknown_bearer", "the bearer was not minted for its run", verdict.runId);
|
|
42984
43223
|
case "expired":
|
|
42985
|
-
return
|
|
43224
|
+
return refused6(shape, 403, "expired", "the bearer expired with the run's budget", verdict.runId);
|
|
42986
43225
|
case "revoked":
|
|
42987
|
-
return
|
|
43226
|
+
return refused6(shape, 403, "revoked", "the run ended and its bearer with it", verdict.runId);
|
|
42988
43227
|
}
|
|
42989
43228
|
}
|
|
42990
43229
|
function pinRequest(shape, body, grant2) {
|
|
@@ -43125,9 +43364,9 @@ function meteredStream(source2, hooks) {
|
|
|
43125
43364
|
controller.error(err2);
|
|
43126
43365
|
}
|
|
43127
43366
|
},
|
|
43128
|
-
cancel(
|
|
43129
|
-
settle2(() => hooks.onError(
|
|
43130
|
-
void reader.cancel(
|
|
43367
|
+
cancel(reason2) {
|
|
43368
|
+
settle2(() => hooks.onError(reason2 ?? new Error("cancelled")));
|
|
43369
|
+
void reader.cancel(reason2).catch(() => {
|
|
43131
43370
|
});
|
|
43132
43371
|
}
|
|
43133
43372
|
});
|
|
@@ -43579,8 +43818,8 @@ var init_toolRules = __esm({
|
|
|
43579
43818
|
READ_REACH = /* @__PURE__ */ new Set(["shell", "files", "web", "search", "github-read", "verdict"]);
|
|
43580
43819
|
NONE_REACH = /* @__PURE__ */ new Set();
|
|
43581
43820
|
allowed = { verdict: "allowed" };
|
|
43582
|
-
refused4 = (
|
|
43583
|
-
outside = (
|
|
43821
|
+
refused4 = (reason2) => ({ verdict: "refused", reason: reason2 });
|
|
43822
|
+
outside = (reason2) => ({ verdict: "outside-profile", reason: reason2 });
|
|
43584
43823
|
isRecord5 = (v) => typeof v === "object" && v !== null;
|
|
43585
43824
|
CREDENTIAL_FILE = /(^|[\s/'"`])(\.git\/)?(github-credentials|\.git-credentials)($|[\s'"`|;&])/;
|
|
43586
43825
|
ENV_DUMP = /(^|[;&|(]\s*)((printenv|env)(\s+-[A-Za-z0-9-]+)*|export\s+-p|declare\s+-[a-zA-Z]*[px][a-zA-Z]*|set)\s*($|[|;&>)])|\/proc\/(self|\d+)\/environ|process\.env(?![.[\w])/;
|
|
@@ -43618,13 +43857,13 @@ function relayedToolDefinitions(harness) {
|
|
|
43618
43857
|
function authorizeToolCall(harness, ask) {
|
|
43619
43858
|
harness.gateSaw(ask.toolCallId);
|
|
43620
43859
|
const blocked = harness.toolsBlocked();
|
|
43621
|
-
const refuse3 = (
|
|
43860
|
+
const refuse3 = (reason2) => {
|
|
43622
43861
|
harness.emit({
|
|
43623
43862
|
type: "run_note",
|
|
43624
43863
|
kind: "tool_refused",
|
|
43625
|
-
summary: redactAndCap(`${ask.tool} refused: ${
|
|
43864
|
+
summary: redactAndCap(`${ask.tool} refused: ${reason2}`, 300)
|
|
43626
43865
|
});
|
|
43627
|
-
return { allow: false, reason };
|
|
43866
|
+
return { allow: false, reason: reason2 };
|
|
43628
43867
|
};
|
|
43629
43868
|
if (blocked !== void 0) return refuse3(blocked);
|
|
43630
43869
|
if (harness.tools.some((t) => t.name === ask.tool)) return { allow: true };
|
|
@@ -43756,19 +43995,42 @@ function bearerOf(headers) {
|
|
|
43756
43995
|
const m = value ? /^Bearer\s+(\S+)$/i.exec(value.trim()) : null;
|
|
43757
43996
|
return m ? m[1] : void 0;
|
|
43758
43997
|
}
|
|
43759
|
-
function
|
|
43760
|
-
const presented = bearerOf(headers);
|
|
43761
|
-
if (!presented) return { ok: false, response: { status: 401, body: { error: "missing_bearer" } } };
|
|
43998
|
+
function judge2(deps, presented) {
|
|
43762
43999
|
const verdict = deps.bearers.verify(presented);
|
|
43763
44000
|
if (!verdict.ok) {
|
|
43764
44001
|
const status3 = verdict.reason === "unknown_run" ? 404 : verdict.reason === "malformed" ? 401 : verdict.reason === "unknown_bearer" ? 401 : 403;
|
|
43765
|
-
return {
|
|
44002
|
+
return {
|
|
44003
|
+
ok: false,
|
|
44004
|
+
status: status3,
|
|
44005
|
+
reason: verdict.reason,
|
|
44006
|
+
...verdict.reason === "malformed" ? {} : { runId: verdict.runId }
|
|
44007
|
+
};
|
|
43766
44008
|
}
|
|
43767
44009
|
const runId3 = verdict.grant.runId;
|
|
43768
|
-
if (!deps.harnesses.get(runId3))
|
|
43769
|
-
return { ok: false, response: { status: 404, body: { error: "run_not_on_harness" } } };
|
|
44010
|
+
if (!deps.harnesses.get(runId3)) return { ok: false, status: 404, reason: "run_not_on_harness", runId: runId3 };
|
|
43770
44011
|
return { ok: true, runId: runId3 };
|
|
43771
44012
|
}
|
|
44013
|
+
function held(path, reason2, runId3) {
|
|
44014
|
+
const response = path === HARNESS_TOOL_PATH ? { status: 202, body: { pending: true, reason: reason2 } } : { status: 503, body: { error: reason2 }, headers: { "retry-after": String(HELD_RETRY_AFTER_S) } };
|
|
44015
|
+
return { ok: false, response, held: { reason: reason2, ...runId3 !== void 0 ? { runId: runId3 } : {} } };
|
|
44016
|
+
}
|
|
44017
|
+
async function admitHarnessRequest(deps, headers, path) {
|
|
44018
|
+
const presented = bearerOf(headers);
|
|
44019
|
+
if (!presented) return { ok: false, response: { status: 401, body: { error: "missing_bearer" } } };
|
|
44020
|
+
let verdict = judge2(deps, presented);
|
|
44021
|
+
if (verdict.ok) return verdict;
|
|
44022
|
+
if (!RESUME_CAN_OPEN.has(verdict.reason)) return refused5(verdict);
|
|
44023
|
+
if (!deps.takeover.settled) {
|
|
44024
|
+
await deps.takeover.whenSettled(DOOR_HOLD_MS);
|
|
44025
|
+
verdict = judge2(deps, presented);
|
|
44026
|
+
if (verdict.ok) return verdict;
|
|
44027
|
+
if (!RESUME_CAN_OPEN.has(verdict.reason)) return refused5(verdict);
|
|
44028
|
+
if (!deps.takeover.settled) return held(path, "reclaim_pending", verdict.runId);
|
|
44029
|
+
}
|
|
44030
|
+
if (verdict.runId !== void 0 && deps.takeover.pending(verdict.runId))
|
|
44031
|
+
return held(path, "run_resuming", verdict.runId);
|
|
44032
|
+
return refused5(verdict);
|
|
44033
|
+
}
|
|
43772
44034
|
function askOf(body) {
|
|
43773
44035
|
if (typeof body !== "object" || body === null) return void 0;
|
|
43774
44036
|
const b = body;
|
|
@@ -43780,7 +44042,7 @@ async function handleHarnessRequest(deps, req) {
|
|
|
43780
44042
|
const wantsGet = req.path === HARNESS_TOOLS_PATH;
|
|
43781
44043
|
if ((req.method ?? "GET") !== (wantsGet ? "GET" : "POST"))
|
|
43782
44044
|
return { status: 405, body: { error: "method_not_allowed" } };
|
|
43783
|
-
const door = admitHarnessRequest(deps, req.headers);
|
|
44045
|
+
const door = await admitHarnessRequest(deps, req.headers, req.path);
|
|
43784
44046
|
if (!door.ok) return door.response;
|
|
43785
44047
|
const harness = deps.harnesses.get(door.runId);
|
|
43786
44048
|
if (wantsGet) return { status: 200, body: { tools: relayedToolDefinitions(harness) } };
|
|
@@ -43807,14 +44069,17 @@ function createHarnessRoutesHandler(deps) {
|
|
|
43807
44069
|
const log = deps.log ?? ((line3) => console.log(line3));
|
|
43808
44070
|
return (req, res) => {
|
|
43809
44071
|
const json2 = (r) => {
|
|
43810
|
-
res.writeHead(r.status, { "content-type": "application/json", "cache-control": "no-store" });
|
|
44072
|
+
res.writeHead(r.status, { ...r.headers, "content-type": "application/json", "cache-control": "no-store" });
|
|
43811
44073
|
res.end(JSON.stringify(r.body));
|
|
43812
44074
|
};
|
|
43813
44075
|
void (async () => {
|
|
43814
44076
|
const path = (req.url ?? "/").split("?")[0];
|
|
43815
|
-
const door = admitHarnessRequest({ ...deps, log }, req.headers);
|
|
44077
|
+
const door = await admitHarnessRequest({ ...deps, log }, req.headers, path);
|
|
43816
44078
|
if (!door.ok) {
|
|
43817
|
-
|
|
44079
|
+
const word = ROUTE_WORD[path] ?? "other";
|
|
44080
|
+
log(
|
|
44081
|
+
door.held ? `[harness] ${door.response.status} ${word} \u2014 held (${door.held.reason})${door.held.runId ? ` run=${door.held.runId}` : ""}` : `[harness] ${door.response.status} ${word} \u2014 ${String(door.response.body.error)}`
|
|
44082
|
+
);
|
|
43818
44083
|
json2(door.response);
|
|
43819
44084
|
req.resume();
|
|
43820
44085
|
return;
|
|
@@ -43840,22 +44105,30 @@ function createHarnessRoutesHandler(deps) {
|
|
|
43840
44105
|
});
|
|
43841
44106
|
};
|
|
43842
44107
|
}
|
|
43843
|
-
var HARNESS_TOOLS_PATH, HARNESS_AUTHORIZE_PATH, HARNESS_TOOL_PATH, HARNESS_PATHS, MAX_HARNESS_BODY_BYTES, ROUTE_WORD;
|
|
44108
|
+
var HARNESS_TOOLS_PATH, HARNESS_AUTHORIZE_PATH, HARNESS_TOOL_PATH, HARNESS_PATHS, MAX_HARNESS_BODY_BYTES, DOOR_HOLD_MS, HELD_RETRY_AFTER_S, ROUTE_WORD, RESUME_CAN_OPEN, refused5;
|
|
43844
44109
|
var init_harnessRoutes = __esm({
|
|
43845
44110
|
"../../src/channels/harnessRoutes.ts"() {
|
|
43846
44111
|
"use strict";
|
|
43847
44112
|
init_relay();
|
|
44113
|
+
init_drain();
|
|
43848
44114
|
init_http();
|
|
43849
44115
|
HARNESS_TOOLS_PATH = "/harness/tools";
|
|
43850
44116
|
HARNESS_AUTHORIZE_PATH = "/harness/authorize";
|
|
43851
44117
|
HARNESS_TOOL_PATH = "/harness/tool";
|
|
43852
44118
|
HARNESS_PATHS = [HARNESS_TOOLS_PATH, HARNESS_AUTHORIZE_PATH, HARNESS_TOOL_PATH];
|
|
43853
44119
|
MAX_HARNESS_BODY_BYTES = 4 * 1024 * 1024;
|
|
44120
|
+
DOOR_HOLD_MS = HANDOFF_BUDGET_MS + 4e3;
|
|
44121
|
+
HELD_RETRY_AFTER_S = 2;
|
|
43854
44122
|
ROUTE_WORD = {
|
|
43855
44123
|
[HARNESS_TOOLS_PATH]: "tools",
|
|
43856
44124
|
[HARNESS_AUTHORIZE_PATH]: "authorize",
|
|
43857
44125
|
[HARNESS_TOOL_PATH]: "tool"
|
|
43858
44126
|
};
|
|
44127
|
+
RESUME_CAN_OPEN = /* @__PURE__ */ new Set(["unknown_run", "unknown_bearer", "run_not_on_harness"]);
|
|
44128
|
+
refused5 = (j) => ({
|
|
44129
|
+
ok: false,
|
|
44130
|
+
response: { status: j.status, body: { error: j.reason } }
|
|
44131
|
+
});
|
|
43859
44132
|
}
|
|
43860
44133
|
});
|
|
43861
44134
|
|
|
@@ -44714,7 +44987,7 @@ async function merge(body, deps, subject2) {
|
|
|
44714
44987
|
const headSha = normalizeHead(body.headSha);
|
|
44715
44988
|
if (headSha === void 0) return json(400, { ok: false, error: "headSha must be the approved head (7 to 40 hex)" });
|
|
44716
44989
|
const at = (deps.clock ?? systemClock)();
|
|
44717
|
-
const
|
|
44990
|
+
const refused6 = (reason2) => json(200, { ok: true, outcome: "refused", reason: reason2, at });
|
|
44718
44991
|
const instance = await deps.instances.get(id.value);
|
|
44719
44992
|
if (!instance) return json(404, { ok: false, error: "unknown_instance" });
|
|
44720
44993
|
const unit = await unitRowOf(deps, instance, body.unit);
|
|
@@ -44723,12 +44996,12 @@ async function merge(body, deps, subject2) {
|
|
|
44723
44996
|
const log = deps.log ?? console.log;
|
|
44724
44997
|
const actor = resolveActor({ surface: "http", subjectId: subject2 }, deps.grantsFor);
|
|
44725
44998
|
if (!authorize(actor, PLAN_MERGE_ACTION, { type: "command", id: "coordinator.merge" }).allow)
|
|
44726
|
-
return
|
|
44999
|
+
return refused6(
|
|
44727
45000
|
`the runner holds no ${PLAN_MERGE_ACTION} grant (grants["http:${subject2}"] in config.yaml) \u2014 a person merges`
|
|
44728
45001
|
);
|
|
44729
45002
|
const planBranch = parsePlanBranch(row.branch);
|
|
44730
45003
|
if (instance.plan === void 0 || planBranch === void 0 || planBranch.planId !== instance.plan.id)
|
|
44731
|
-
return
|
|
45004
|
+
return refused6(
|
|
44732
45005
|
`\`${row.branch}\` is not a branch of plan \`${instance.plan?.id ?? "(none)"}\` \u2014 waits for a person's merge`
|
|
44733
45006
|
);
|
|
44734
45007
|
const pr = { repo: instance.repo, number: body.prNumber };
|
|
@@ -44742,12 +45015,12 @@ async function merge(body, deps, subject2) {
|
|
|
44742
45015
|
if (facts2 === void 0)
|
|
44743
45016
|
return json(502, { ok: false, error: "github_unavailable", message: `${where} could not be read`, at });
|
|
44744
45017
|
if (isReleasePullRequest(facts2))
|
|
44745
|
-
return
|
|
44746
|
-
if (facts2.state !== "open") return
|
|
45018
|
+
return refused6(`${where} is the release pull request \u2014 always a person's merge, never the runner's`);
|
|
45019
|
+
if (facts2.state !== "open") return refused6(`${where} is ${facts2.state}`);
|
|
44747
45020
|
if (facts2.headRef !== row.branch)
|
|
44748
|
-
return
|
|
45021
|
+
return refused6(`${where} heads \`${facts2.headRef ?? "?"}\`, not the unit's branch \`${row.branch}\``);
|
|
44749
45022
|
if (facts2.headSha === void 0 || !sameCommit2(facts2.headSha, headSha))
|
|
44750
|
-
return
|
|
45023
|
+
return refused6(
|
|
44751
45024
|
`the head of ${where} moved: \`${facts2.headSha?.slice(0, 7) ?? "?"}\` is not the approved \`${headSha.slice(0, 7)}\``
|
|
44752
45025
|
);
|
|
44753
45026
|
const approved = await reviewPostedAt(deps, pr, "approve", headSha);
|
|
@@ -44758,7 +45031,7 @@ async function merge(body, deps, subject2) {
|
|
|
44758
45031
|
message: `the reviews of ${where} could not be read`,
|
|
44759
45032
|
at
|
|
44760
45033
|
});
|
|
44761
|
-
if (!approved) return
|
|
45034
|
+
if (!approved) return refused6(`no approving review by the bot stands on ${where} at \`${headSha.slice(0, 7)}\``);
|
|
44762
45035
|
const checks = await deps.fetchCommitChecks(instance.repo, headSha).catch(() => void 0);
|
|
44763
45036
|
if (checks === void 0)
|
|
44764
45037
|
return json(502, {
|
|
@@ -44767,7 +45040,7 @@ async function merge(body, deps, subject2) {
|
|
|
44767
45040
|
message: `the checks at ${headSha.slice(0, 7)} could not be read`,
|
|
44768
45041
|
at
|
|
44769
45042
|
});
|
|
44770
|
-
if (checks.failed.length > 0) return
|
|
45043
|
+
if (checks.failed.length > 0) return refused6(`CI is red at \`${headSha.slice(0, 7)}\`: ${checks.failed.join(", ")}`);
|
|
44771
45044
|
if (checks.total === 0)
|
|
44772
45045
|
return json(200, {
|
|
44773
45046
|
ok: true,
|
|
@@ -44795,7 +45068,7 @@ async function merge(body, deps, subject2) {
|
|
|
44795
45068
|
log(
|
|
44796
45069
|
`[coordinator] ${instance.id} ${row.unit}: GitHub refused the merge of ${where} (HTTP ${merged.status}): ${merged.reason}`
|
|
44797
45070
|
);
|
|
44798
|
-
return
|
|
45071
|
+
return refused6(`GitHub refused the merge of ${where} (HTTP ${merged.status}): ${merged.reason}`);
|
|
44799
45072
|
}
|
|
44800
45073
|
log(
|
|
44801
45074
|
`[coordinator] ${instance.id} ${row.unit}: merged ${where} at ${headSha.slice(0, 7)} \u2192 ${merged.sha.slice(0, 7)}`
|
|
@@ -45376,6 +45649,7 @@ async function runBot() {
|
|
|
45376
45649
|
);
|
|
45377
45650
|
}
|
|
45378
45651
|
const threadsElsewhere = new ThreadsElsewhere();
|
|
45652
|
+
const takeover = new LedgerTakeover();
|
|
45379
45653
|
const residentAdmin = capabilities.residents ? residentAdminFromConfig(config, processSecrets) : new NullResidentAdminClient();
|
|
45380
45654
|
const residentAdminClient = "unavailable" in residentAdmin ? new NullResidentAdminClient(residentAdmin.unavailable) : residentAdmin;
|
|
45381
45655
|
const spanLog = createSpanLog();
|
|
@@ -45486,7 +45760,7 @@ async function runBot() {
|
|
|
45486
45760
|
secrets: processSecrets,
|
|
45487
45761
|
clock: systemClock
|
|
45488
45762
|
});
|
|
45489
|
-
const harnessRoutes = createHarnessRoutesHandler({ bearers: runBearers, harnesses });
|
|
45763
|
+
const harnessRoutes = createHarnessRoutesHandler({ bearers: runBearers, harnesses, takeover });
|
|
45490
45764
|
const coordinatorAdmin = createAdminCoordinatorHandler({
|
|
45491
45765
|
tokens: processSecrets.get("SWITCHBOARD_INGRESS_TOKENS"),
|
|
45492
45766
|
grantsFor: (id) => config.grantsFor(id),
|
|
@@ -45764,6 +46038,7 @@ async function runBot() {
|
|
|
45764
46038
|
`[resume] ${run2.row.runId} ${run2.row.threadKey} closed interrupted (${why})${closed.ok ? "" : ` \u2014 finish refused (${closed.reason})`}`
|
|
45765
46039
|
);
|
|
45766
46040
|
},
|
|
46041
|
+
onDone: (runId3) => takeover.done(runId3),
|
|
45767
46042
|
log: (l) => console.log(l),
|
|
45768
46043
|
warn: (w) => console.warn(w)
|
|
45769
46044
|
});
|
|
@@ -45776,11 +46051,14 @@ async function runBot() {
|
|
|
45776
46051
|
log: (l) => console.log(l),
|
|
45777
46052
|
warn: (w) => console.warn(w)
|
|
45778
46053
|
});
|
|
46054
|
+
takeover.take(bootReclaim);
|
|
45779
46055
|
await guardCards(bootReclaim);
|
|
45780
46056
|
const client = ledgerReclaim.client;
|
|
45781
46057
|
setForeignLiveCardsSource(
|
|
45782
46058
|
async () => (await client.listLive()).filter((r) => r.ownerGen !== generation && r.leaseUntil > systemClock()).flatMap((r) => r.card ? [r.card] : [])
|
|
45783
46059
|
);
|
|
46060
|
+
} else {
|
|
46061
|
+
takeover.settle();
|
|
45784
46062
|
}
|
|
45785
46063
|
await app.start();
|
|
45786
46064
|
if (ledgerReclaim && bootReclaim) {
|
|
@@ -45791,6 +46069,7 @@ async function runBot() {
|
|
|
45791
46069
|
log: (l) => console.log(l),
|
|
45792
46070
|
warn: (w) => console.warn(w),
|
|
45793
46071
|
onOutcome: async (outcome) => {
|
|
46072
|
+
takeover.take(outcome);
|
|
45794
46073
|
await guardCards(outcome);
|
|
45795
46074
|
await launch(outcome);
|
|
45796
46075
|
}
|
|
@@ -45903,6 +46182,7 @@ var init_index = __esm({
|
|
|
45903
46182
|
init_boot();
|
|
45904
46183
|
init_resumeLaunch();
|
|
45905
46184
|
init_threadsElsewhere();
|
|
46185
|
+
init_takeover();
|
|
45906
46186
|
init_nullChannelIo();
|
|
45907
46187
|
init_registry();
|
|
45908
46188
|
init_trace();
|