@coreplane/switchboard 1.216.1 → 1.217.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/package.json +1 -1
- package/dist/assets/deploy/cloudflare-docs/package.json +1 -1
- package/dist/assets/deploy/cloudflare-memory/package.json +1 -1
- package/dist/assets/deploy/cloudflare-resident/package.json +1 -1
- package/dist/assets/deploy/cloudflare-sandbox/package.json +1 -1
- package/dist/assets/package-lock.json +5676 -7966
- package/dist/assets/package.json +2 -2
- package/dist/assets/source.json +3 -3
- package/dist/assets/src/core/runEvents.ts +7 -0
- package/dist/assets/src/core/runLedger/types.ts +13 -0
- package/dist/assets/src/core/runRecord.ts +4 -2
- package/dist/assets/web/dist/.vite/manifest.json +18 -18
- package/dist/assets/web/dist/assets/{ResidentDetailPage-CvwjhjlG.js → ResidentDetailPage-CWyEd5fq.js} +1 -1
- package/dist/assets/web/dist/assets/{ResidentsIndexPage-DoN6XuNx.js → ResidentsIndexPage-DqFqRTWb.js} +1 -1
- package/dist/assets/web/dist/assets/{RunRoutePage-FzLNexjF.js → RunRoutePage-CghwVr_X.js} +3 -3
- package/dist/assets/web/dist/assets/{RunsIndexPage-DhSUbF9k.js → RunsIndexPage-BcYehvW5.js} +1 -1
- package/dist/assets/web/dist/assets/{ScheduledPage-Bq0Yg4nT.js → ScheduledPage-mKa20Qdd.js} +1 -1
- package/dist/assets/web/dist/assets/{StatusDot-D8Wwt1KC.js → StatusDot-QMofJG-E.js} +1 -1
- package/dist/assets/web/dist/assets/{Tooltip-DpDK7jWZ.js → Tooltip-D-zVPexc.js} +1 -1
- package/dist/assets/web/dist/assets/dist-D43zKxNV.js +1542 -0
- package/dist/assets/web/dist/assets/{main-BFkEOy3K.js → main-ClTMtz8n.js} +2 -2
- package/dist/cli.js +771 -283
- package/package.json +1 -1
- package/dist/assets/web/dist/assets/dist-B7BVkB7x.js +0 -1547
package/dist/cli.js
CHANGED
|
@@ -2167,8 +2167,8 @@ var init_effort = __esm({
|
|
|
2167
2167
|
});
|
|
2168
2168
|
|
|
2169
2169
|
// ../../src/core/dashboardAuthConfig.ts
|
|
2170
|
-
function resolveDashboardAuthMode(
|
|
2171
|
-
if (
|
|
2170
|
+
function resolveDashboardAuthMode(configured3, accessConfigured) {
|
|
2171
|
+
if (configured3 !== void 0) return configured3;
|
|
2172
2172
|
return accessConfigured ? "access" : "none";
|
|
2173
2173
|
}
|
|
2174
2174
|
function tokenSubjectOf(actor) {
|
|
@@ -7582,6 +7582,159 @@ var init_imagesHost = __esm({
|
|
|
7582
7582
|
}
|
|
7583
7583
|
});
|
|
7584
7584
|
|
|
7585
|
+
// ../../src/deploy/artifactsBucket.ts
|
|
7586
|
+
function lifecycleRulesFor(retentionDays) {
|
|
7587
|
+
if (!Number.isInteger(retentionDays) || retentionDays < 1) {
|
|
7588
|
+
throw new Error(`retentionDays must be an integer >= 1, got ${String(retentionDays)}`);
|
|
7589
|
+
}
|
|
7590
|
+
return [
|
|
7591
|
+
{
|
|
7592
|
+
id: EXPIRE_RULE_ID,
|
|
7593
|
+
enabled: true,
|
|
7594
|
+
conditions: { prefix: "" },
|
|
7595
|
+
deleteObjectsTransition: { condition: { type: "Age", maxAge: retentionDays * DAY_SECONDS } }
|
|
7596
|
+
},
|
|
7597
|
+
{
|
|
7598
|
+
id: ABORT_RULE_ID,
|
|
7599
|
+
enabled: true,
|
|
7600
|
+
conditions: { prefix: "" },
|
|
7601
|
+
abortMultipartUploadsTransition: { condition: { type: "Age", maxAge: ABORT_MULTIPART_AFTER_DAYS * DAY_SECONDS } }
|
|
7602
|
+
}
|
|
7603
|
+
];
|
|
7604
|
+
}
|
|
7605
|
+
function describeRules(rules) {
|
|
7606
|
+
return rules.map((r) => {
|
|
7607
|
+
const days = (s) => `${s / DAY_SECONDS} day${s === DAY_SECONDS ? "" : "s"}`;
|
|
7608
|
+
if (r.deleteObjectsTransition)
|
|
7609
|
+
return `${r.id}: delete every object ${days(r.deleteObjectsTransition.condition.maxAge)} after it was written`;
|
|
7610
|
+
if (r.abortMultipartUploadsTransition)
|
|
7611
|
+
return `${r.id}: abort an incomplete multipart upload after ${days(r.abortMultipartUploadsTransition.condition.maxAge)}`;
|
|
7612
|
+
return `${r.id}: (no transition)`;
|
|
7613
|
+
});
|
|
7614
|
+
}
|
|
7615
|
+
function rulesMatch(readBack, wanted) {
|
|
7616
|
+
const rules = Array.isArray(readBack?.rules) ? readBack.rules : null;
|
|
7617
|
+
if (!rules) return { ok: false, problem: "the read-back carries no `rules` array" };
|
|
7618
|
+
const problems = [];
|
|
7619
|
+
for (const want of wanted) {
|
|
7620
|
+
const got = rules.find((r) => r?.id === want.id);
|
|
7621
|
+
if (!got) {
|
|
7622
|
+
problems.push(`rule ${want.id} is missing`);
|
|
7623
|
+
continue;
|
|
7624
|
+
}
|
|
7625
|
+
if (got.enabled !== true) problems.push(`rule ${want.id} is not enabled`);
|
|
7626
|
+
const wantAge = want.deleteObjectsTransition?.condition.maxAge ?? want.abortMultipartUploadsTransition?.condition.maxAge;
|
|
7627
|
+
const gotAge = got.deleteObjectsTransition?.condition?.maxAge ?? got.abortMultipartUploadsTransition?.condition?.maxAge;
|
|
7628
|
+
if (gotAge !== wantAge) problems.push(`rule ${want.id} has maxAge ${String(gotAge)}, not ${String(wantAge)}`);
|
|
7629
|
+
}
|
|
7630
|
+
return problems.length === 0 ? { ok: true } : { ok: false, problem: problems.join("; ") };
|
|
7631
|
+
}
|
|
7632
|
+
function privacyOf(managed, custom) {
|
|
7633
|
+
const open = [];
|
|
7634
|
+
if (managed.enabled) open.push(`the managed r2.dev domain ${managed.domain} is enabled`);
|
|
7635
|
+
for (const d of custom) if (d.enabled) open.push(`the custom domain ${d.domain} is enabled`);
|
|
7636
|
+
return open.length === 0 ? { private: true, open: [] } : { private: false, open };
|
|
7637
|
+
}
|
|
7638
|
+
function bucketTokenMissingProblem() {
|
|
7639
|
+
return `${API_TOKEN_ENV} is not set \u2014 the bucket's lifecycle rules and domain settings are read and written with a Cloudflare API token holding Workers R2 Storage: Edit (Read suffices for \`artifacts check\`); the bot's ARTIFACTS_R2_* token cannot do this and is never used here`;
|
|
7640
|
+
}
|
|
7641
|
+
function bucketCallProblem(method, url, status3, text) {
|
|
7642
|
+
const words = text.trim().slice(0, 300);
|
|
7643
|
+
const permission = status3 === 401 || status3 === 403 ? ` \u2014 the token lacks the permission (Workers R2 Storage: ${method === "GET" ? "Read" : "Edit"} on this account)` : "";
|
|
7644
|
+
return `${method} ${url} answered HTTP ${status3}${permission}${words ? `: ${words}` : ""}`;
|
|
7645
|
+
}
|
|
7646
|
+
function artifactsBucketHost(options = {}) {
|
|
7647
|
+
const env = options.env ?? process.env;
|
|
7648
|
+
const fetchImpl = options.fetch ?? fetch;
|
|
7649
|
+
const call2 = async (method, path, body) => {
|
|
7650
|
+
const token2 = env[API_TOKEN_ENV]?.trim();
|
|
7651
|
+
if (!token2) return { ok: false, problem: bucketTokenMissingProblem() };
|
|
7652
|
+
const url = `${API}${path}`;
|
|
7653
|
+
let res;
|
|
7654
|
+
try {
|
|
7655
|
+
res = await fetchImpl(url, {
|
|
7656
|
+
method,
|
|
7657
|
+
headers: {
|
|
7658
|
+
authorization: `Bearer ${token2}`,
|
|
7659
|
+
...body !== void 0 ? { "content-type": "application/json" } : {}
|
|
7660
|
+
},
|
|
7661
|
+
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
7662
|
+
});
|
|
7663
|
+
} catch (err2) {
|
|
7664
|
+
return { ok: false, problem: `${method} ${url} failed \u2014 ${err2 instanceof Error ? err2.message : String(err2)}` };
|
|
7665
|
+
}
|
|
7666
|
+
const text = await res.text().catch(() => "");
|
|
7667
|
+
if (!res.ok) return { ok: false, problem: bucketCallProblem(method, url, res.status, text) };
|
|
7668
|
+
let envelope;
|
|
7669
|
+
try {
|
|
7670
|
+
envelope = JSON.parse(text);
|
|
7671
|
+
} catch {
|
|
7672
|
+
return { ok: false, problem: `${method} ${url} answered HTTP ${res.status} with a body that is not JSON` };
|
|
7673
|
+
}
|
|
7674
|
+
if (envelope.success !== true) {
|
|
7675
|
+
const errors = Array.isArray(envelope.errors) ? envelope.errors.map((e) => e?.message ?? JSON.stringify(e)).join("; ") : "no error given";
|
|
7676
|
+
return { ok: false, problem: `${method} ${url} answered success: false \u2014 ${errors}` };
|
|
7677
|
+
}
|
|
7678
|
+
return { ok: true, value: envelope.result };
|
|
7679
|
+
};
|
|
7680
|
+
const bucketPath = (account2, bucket, tail) => `/accounts/${encodeURIComponent(account2)}/r2/buckets/${encodeURIComponent(bucket)}/${tail}`;
|
|
7681
|
+
return {
|
|
7682
|
+
async putLifecycle(account2, bucket, rules) {
|
|
7683
|
+
const r = await call2("PUT", bucketPath(account2, bucket, "lifecycle"), { rules });
|
|
7684
|
+
return r.ok ? { ok: true, value: void 0 } : r;
|
|
7685
|
+
},
|
|
7686
|
+
getLifecycle(account2, bucket) {
|
|
7687
|
+
return call2("GET", bucketPath(account2, bucket, "lifecycle"));
|
|
7688
|
+
},
|
|
7689
|
+
async managedDomain(account2, bucket) {
|
|
7690
|
+
const r = await call2("GET", bucketPath(account2, bucket, "domains/managed"));
|
|
7691
|
+
if (!r.ok) return r;
|
|
7692
|
+
const v = r.value;
|
|
7693
|
+
if (!v || typeof v.domain !== "string" || typeof v.enabled !== "boolean") {
|
|
7694
|
+
return {
|
|
7695
|
+
ok: false,
|
|
7696
|
+
problem: `the managed-domain answer has no domain/enabled: ${JSON.stringify(r.value).slice(0, 200)}`
|
|
7697
|
+
};
|
|
7698
|
+
}
|
|
7699
|
+
return { ok: true, value: { domain: v.domain, enabled: v.enabled } };
|
|
7700
|
+
},
|
|
7701
|
+
async customDomains(account2, bucket) {
|
|
7702
|
+
const r = await call2("GET", bucketPath(account2, bucket, "domains/custom"));
|
|
7703
|
+
if (!r.ok) return r;
|
|
7704
|
+
const list = r.value?.domains;
|
|
7705
|
+
if (!Array.isArray(list)) {
|
|
7706
|
+
return {
|
|
7707
|
+
ok: false,
|
|
7708
|
+
problem: `the custom-domains answer has no domains array: ${JSON.stringify(r.value).slice(0, 200)}`
|
|
7709
|
+
};
|
|
7710
|
+
}
|
|
7711
|
+
const domains = [];
|
|
7712
|
+
for (const d of list) {
|
|
7713
|
+
if (typeof d?.domain !== "string" || typeof d.enabled !== "boolean") {
|
|
7714
|
+
return {
|
|
7715
|
+
ok: false,
|
|
7716
|
+
problem: `a custom domain entry has no domain/enabled: ${JSON.stringify(d).slice(0, 200)}`
|
|
7717
|
+
};
|
|
7718
|
+
}
|
|
7719
|
+
domains.push({ domain: d.domain, enabled: d.enabled });
|
|
7720
|
+
}
|
|
7721
|
+
return { ok: true, value: domains };
|
|
7722
|
+
}
|
|
7723
|
+
};
|
|
7724
|
+
}
|
|
7725
|
+
var ABORT_MULTIPART_AFTER_DAYS, DAY_SECONDS, EXPIRE_RULE_ID, ABORT_RULE_ID, API;
|
|
7726
|
+
var init_artifactsBucket = __esm({
|
|
7727
|
+
"../../src/deploy/artifactsBucket.ts"() {
|
|
7728
|
+
"use strict";
|
|
7729
|
+
init_imagesHost();
|
|
7730
|
+
ABORT_MULTIPART_AFTER_DAYS = 1;
|
|
7731
|
+
DAY_SECONDS = 86400;
|
|
7732
|
+
EXPIRE_RULE_ID = "switchboard-artifacts-expire";
|
|
7733
|
+
ABORT_RULE_ID = "switchboard-artifacts-abort-multipart";
|
|
7734
|
+
API = "https://api.cloudflare.com/client/v4";
|
|
7735
|
+
}
|
|
7736
|
+
});
|
|
7737
|
+
|
|
7585
7738
|
// ../../src/deploy/secrets.ts
|
|
7586
7739
|
import { z as z3 } from "zod";
|
|
7587
7740
|
function isOptionalOn(secret2, worker) {
|
|
@@ -7842,6 +7995,7 @@ var init_runEvents = __esm({
|
|
|
7842
7995
|
"mcp_unavailable",
|
|
7843
7996
|
"follow_up",
|
|
7844
7997
|
"resumed",
|
|
7998
|
+
"seed",
|
|
7845
7999
|
"description_turn",
|
|
7846
8000
|
"cold_sandbox",
|
|
7847
8001
|
"pr_not_opened",
|
|
@@ -9290,6 +9444,7 @@ var init_resident = __esm({
|
|
|
9290
9444
|
ref: data.ref,
|
|
9291
9445
|
sha: data.sha,
|
|
9292
9446
|
...typeof data.workspace === "string" && data.workspace ? { workspace: data.workspace } : {},
|
|
9447
|
+
...typeof data.user === "string" && data.user ? { user: data.user } : {},
|
|
9293
9448
|
...trace.length > 0 ? { trace } : {},
|
|
9294
9449
|
...typeof data.attachMs === "number" && Number.isFinite(data.attachMs) ? { attachMs: data.attachMs } : {}
|
|
9295
9450
|
};
|
|
@@ -11996,8 +12151,110 @@ var init_commandRegistry = __esm({
|
|
|
11996
12151
|
}
|
|
11997
12152
|
});
|
|
11998
12153
|
|
|
11999
|
-
// ../../src/core/commands/
|
|
12154
|
+
// ../../src/core/commands/artifacts.ts
|
|
12000
12155
|
import { z as z5 } from "zod";
|
|
12156
|
+
async function configured2(deps) {
|
|
12157
|
+
const cfg = await deps.artifacts.config();
|
|
12158
|
+
if (!cfg) {
|
|
12159
|
+
throw new CommandError(
|
|
12160
|
+
"unavailable",
|
|
12161
|
+
"artifacts: is not configured \u2014 name the bucket under `artifacts.r2` in config.yaml before managing it (docs/how-to/store-run-artifacts.md)"
|
|
12162
|
+
);
|
|
12163
|
+
}
|
|
12164
|
+
return cfg;
|
|
12165
|
+
}
|
|
12166
|
+
function registerArtifactsCommands(registry) {
|
|
12167
|
+
for (const cmd of artifactsCommands) registry.register(cmd);
|
|
12168
|
+
}
|
|
12169
|
+
var defineCommand2, lifecycleOptions, artifactsLifecycle, artifactsCheck, artifactsCommands;
|
|
12170
|
+
var init_artifacts = __esm({
|
|
12171
|
+
"../../src/core/commands/artifacts.ts"() {
|
|
12172
|
+
"use strict";
|
|
12173
|
+
init_config();
|
|
12174
|
+
init_artifactsBucket();
|
|
12175
|
+
init_commandRegistry();
|
|
12176
|
+
defineCommand2 = commandDefiner();
|
|
12177
|
+
lifecycleOptions = z5.object({
|
|
12178
|
+
dryRun: flag.optional().describe("print the rules that would be applied and touch nothing")
|
|
12179
|
+
});
|
|
12180
|
+
artifactsLifecycle = defineCommand2({
|
|
12181
|
+
id: "artifacts.lifecycle",
|
|
12182
|
+
options: lifecycleOptions,
|
|
12183
|
+
action: "deploy:write",
|
|
12184
|
+
effect: "write",
|
|
12185
|
+
surfaces: { chat: false, mcp: false, http: false },
|
|
12186
|
+
describe: "Apply the artifacts bucket's lifecycle rules from config.yaml \u2014 objects expire after `artifacts.retentionDays` (default 30), incomplete multipart uploads abort after one day \u2014 and read them back; `--dry-run` prints the rules and touches nothing. Operator-side: CLOUDFLARE_API_TOKEN with Workers R2 Storage: Edit, never the bot's token.",
|
|
12187
|
+
render: (output) => {
|
|
12188
|
+
const o = output;
|
|
12189
|
+
const lines = describeRules(o.rules).map((l) => ` - ${l}`);
|
|
12190
|
+
const head = o.applied ? `applied ${o.rules.length} lifecycle rule(s) to ${o.bucket} (account ${o.account}) and read them back equal:` : `dry run \u2014 would apply ${o.rules.length} lifecycle rule(s) to ${o.bucket} (account ${o.account}); nothing touched:`;
|
|
12191
|
+
return [head, ...lines].join("\n");
|
|
12192
|
+
},
|
|
12193
|
+
handler: async ({ options, deps }) => {
|
|
12194
|
+
const cfg = await configured2(deps);
|
|
12195
|
+
const retentionDays = cfg.retentionDays ?? ARTIFACT_DEFAULTS.retentionDays;
|
|
12196
|
+
const rules = lifecycleRulesFor(retentionDays);
|
|
12197
|
+
const { accountId: account2, bucket } = cfg.r2;
|
|
12198
|
+
const out = { account: account2, bucket, retentionDays, rules, applied: false, readBack: false };
|
|
12199
|
+
if (options.dryRun) return out;
|
|
12200
|
+
const put = await deps.artifacts.bucket.putLifecycle(account2, bucket, rules);
|
|
12201
|
+
if (!put.ok)
|
|
12202
|
+
throw new CommandError("unavailable", `applying the lifecycle rules to ${bucket} failed \u2014 ${put.problem}`);
|
|
12203
|
+
const read = await deps.artifacts.bucket.getLifecycle(account2, bucket);
|
|
12204
|
+
if (!read.ok)
|
|
12205
|
+
throw new CommandError(
|
|
12206
|
+
"unavailable",
|
|
12207
|
+
`the rules were applied to ${bucket} but reading them back failed \u2014 ${read.problem}; run \`artifacts lifecycle\` again to confirm`
|
|
12208
|
+
);
|
|
12209
|
+
const match = rulesMatch(read.value, rules);
|
|
12210
|
+
if (!match.ok)
|
|
12211
|
+
throw new CommandError(
|
|
12212
|
+
"unavailable",
|
|
12213
|
+
`the rules were applied to ${bucket} but the read-back differs \u2014 ${match.problem}; the bucket's configuration is not what config.yaml says`
|
|
12214
|
+
);
|
|
12215
|
+
return { ...out, applied: true, readBack: true };
|
|
12216
|
+
}
|
|
12217
|
+
});
|
|
12218
|
+
artifactsCheck = defineCommand2({
|
|
12219
|
+
id: "artifacts.check",
|
|
12220
|
+
action: "deploy:write",
|
|
12221
|
+
effect: "read",
|
|
12222
|
+
surfaces: { chat: false, mcp: false, http: false },
|
|
12223
|
+
describe: "Report whether the artifacts bucket is private: its managed r2.dev domain must be disabled and no custom domain enabled \u2014 the two ways R2 serves a bucket without a signature. Operator-side: CLOUDFLARE_API_TOKEN with Workers R2 Storage: Read, never the bot's token.",
|
|
12224
|
+
render: (output) => {
|
|
12225
|
+
const o = output;
|
|
12226
|
+
if (o.private) {
|
|
12227
|
+
return `${o.bucket} (account ${o.account}) is private: the managed domain ${o.managedDomain.domain} is disabled and ${o.customDomains.length === 0 ? "no custom domain is attached" : `none of its ${o.customDomains.length} custom domain(s) is enabled`}`;
|
|
12228
|
+
}
|
|
12229
|
+
return [`${o.bucket} (account ${o.account}) is NOT private:`, ...o.open.map((l) => ` - ${l}`)].join("\n");
|
|
12230
|
+
},
|
|
12231
|
+
handler: async ({ deps }) => {
|
|
12232
|
+
const cfg = await configured2(deps);
|
|
12233
|
+
const { accountId: account2, bucket } = cfg.r2;
|
|
12234
|
+
const managed = await deps.artifacts.bucket.managedDomain(account2, bucket);
|
|
12235
|
+
if (!managed.ok)
|
|
12236
|
+
throw new CommandError("unavailable", `reading ${bucket}'s managed domain failed \u2014 ${managed.problem}`);
|
|
12237
|
+
const custom = await deps.artifacts.bucket.customDomains(account2, bucket);
|
|
12238
|
+
if (!custom.ok)
|
|
12239
|
+
throw new CommandError("unavailable", `reading ${bucket}'s custom domains failed \u2014 ${custom.problem}`);
|
|
12240
|
+
const verdict = privacyOf(managed.value, custom.value);
|
|
12241
|
+
const out = {
|
|
12242
|
+
account: account2,
|
|
12243
|
+
bucket,
|
|
12244
|
+
private: verdict.private,
|
|
12245
|
+
open: [...verdict.open],
|
|
12246
|
+
managedDomain: managed.value,
|
|
12247
|
+
customDomains: custom.value
|
|
12248
|
+
};
|
|
12249
|
+
return out;
|
|
12250
|
+
}
|
|
12251
|
+
});
|
|
12252
|
+
artifactsCommands = [artifactsLifecycle, artifactsCheck];
|
|
12253
|
+
}
|
|
12254
|
+
});
|
|
12255
|
+
|
|
12256
|
+
// ../../src/core/commands/config.ts
|
|
12257
|
+
import { z as z6 } from "zod";
|
|
12001
12258
|
function targetChannel(caller, channel) {
|
|
12002
12259
|
const target = channel ?? caller.origin?.channelId;
|
|
12003
12260
|
if (!target) throw new CommandError("invalid_input", "channel: required on this surface \u2014 pass --channel <id>");
|
|
@@ -12017,7 +12274,7 @@ function summarizeScope(s) {
|
|
|
12017
12274
|
function registerConfigCommands(registry) {
|
|
12018
12275
|
for (const cmd of configCommands) registry.register(cmd);
|
|
12019
12276
|
}
|
|
12020
|
-
var
|
|
12277
|
+
var defineCommand3, scopeArg, channelOption, effort, effortLevels, modelRef, boundaryOption, who, configShow, configSet, configClear, quote, configInstructions, configCommands;
|
|
12021
12278
|
var init_config4 = __esm({
|
|
12022
12279
|
"../../src/core/commands/config.ts"() {
|
|
12023
12280
|
"use strict";
|
|
@@ -12027,25 +12284,25 @@ var init_config4 = __esm({
|
|
|
12027
12284
|
init_effort();
|
|
12028
12285
|
init_authorize();
|
|
12029
12286
|
init_commandRegistry();
|
|
12030
|
-
|
|
12287
|
+
defineCommand3 = commandDefiner();
|
|
12031
12288
|
scopeArg = {
|
|
12032
12289
|
name: "scope",
|
|
12033
|
-
schema:
|
|
12290
|
+
schema: z6.enum(["channel", "me"]),
|
|
12034
12291
|
describe: "`channel` (everyone here) or `me` (your own runs)"
|
|
12035
12292
|
};
|
|
12036
|
-
channelOption =
|
|
12037
|
-
effort =
|
|
12293
|
+
channelOption = z6.string().optional().describe("target channel (default: the channel you are speaking in)");
|
|
12294
|
+
effort = z6.enum(EFFORT_LEVELS);
|
|
12038
12295
|
effortLevels = `<${EFFORT_LEVELS.join("|")}>`;
|
|
12039
|
-
modelRef =
|
|
12040
|
-
boundaryOption =
|
|
12041
|
-
maxMinutes:
|
|
12042
|
-
maxIdentity:
|
|
12043
|
-
machines:
|
|
12296
|
+
modelRef = z6.string().min(1);
|
|
12297
|
+
boundaryOption = z6.object({
|
|
12298
|
+
maxMinutes: z6.coerce.number().int().min(MIN_BOUNDARY_MINUTES).optional().describe(`cap the wall-clock budget of every run in this scope (minutes, >= ${MIN_BOUNDARY_MINUTES})`),
|
|
12299
|
+
maxIdentity: z6.enum(IDENTITIES).optional().describe(`cap the identity runs may act as <${IDENTITIES.join("|")}> \u2014 a preset above it is refused`),
|
|
12300
|
+
machines: z6.string().optional().describe(`the machine classes runs may execute on, comma-separated from ${MACHINE_CLASSES.join(", ")}`)
|
|
12044
12301
|
}).optional();
|
|
12045
12302
|
who = (scope) => scope === "channel" ? "channel" : "your";
|
|
12046
|
-
configShow =
|
|
12303
|
+
configShow = defineCommand3({
|
|
12047
12304
|
id: "config.show",
|
|
12048
|
-
options:
|
|
12305
|
+
options: z6.object({ channel: channelOption }),
|
|
12049
12306
|
action: "config:read",
|
|
12050
12307
|
effect: "read",
|
|
12051
12308
|
describe: "The effective agent/model/effort for you in this channel, the defaults, both scopes, and what is restricted.",
|
|
@@ -12059,15 +12316,15 @@ var init_config4 = __esm({
|
|
|
12059
12316
|
return description;
|
|
12060
12317
|
}
|
|
12061
12318
|
});
|
|
12062
|
-
configSet =
|
|
12319
|
+
configSet = defineCommand3({
|
|
12063
12320
|
id: "config.set",
|
|
12064
12321
|
args: [scopeArg],
|
|
12065
|
-
options:
|
|
12066
|
-
agent:
|
|
12322
|
+
options: z6.object({
|
|
12323
|
+
agent: z6.string().min(1).optional().describe("force which agent handles requests in this scope"),
|
|
12067
12324
|
model: modelRef.optional().describe("force a model (provider/model) regardless of agent"),
|
|
12068
|
-
models:
|
|
12325
|
+
models: z6.record(z6.string(), modelRef).optional().describe("per-agent model: --models.<agent> provider/model"),
|
|
12069
12326
|
effort: effort.optional().describe(`force a model effort ${effortLevels}`),
|
|
12070
|
-
efforts:
|
|
12327
|
+
efforts: z6.record(z6.string(), effort).optional().describe(`per-agent effort: --efforts.<agent> ${effortLevels}`),
|
|
12071
12328
|
boundary: boundaryOption,
|
|
12072
12329
|
channel: channelOption
|
|
12073
12330
|
}),
|
|
@@ -12134,10 +12391,10 @@ var init_config4 = __esm({
|
|
|
12134
12391
|
return { scope: args.scope, effective: summarizeScope(effective) };
|
|
12135
12392
|
}
|
|
12136
12393
|
});
|
|
12137
|
-
configClear =
|
|
12394
|
+
configClear = defineCommand3({
|
|
12138
12395
|
id: "config.clear",
|
|
12139
12396
|
args: [scopeArg],
|
|
12140
|
-
options:
|
|
12397
|
+
options: z6.object({ channel: channelOption }),
|
|
12141
12398
|
action: "config:write",
|
|
12142
12399
|
effect: "write",
|
|
12143
12400
|
describe: "Drop every runtime override of a channel (gated) or of yourself; static config.yaml values show through again.",
|
|
@@ -12154,18 +12411,18 @@ var init_config4 = __esm({
|
|
|
12154
12411
|
}
|
|
12155
12412
|
});
|
|
12156
12413
|
quote = (text) => `> ${text.replace(/\n/g, "\n> ")}`;
|
|
12157
|
-
configInstructions =
|
|
12414
|
+
configInstructions = defineCommand3({
|
|
12158
12415
|
id: "config.instructions",
|
|
12159
12416
|
args: [
|
|
12160
12417
|
scopeArg,
|
|
12161
12418
|
{
|
|
12162
12419
|
name: "text",
|
|
12163
|
-
schema:
|
|
12420
|
+
schema: z6.string().optional(),
|
|
12164
12421
|
describe: 'the instructions; omit to show the current text, pass "" to clear',
|
|
12165
12422
|
rest: true
|
|
12166
12423
|
}
|
|
12167
12424
|
],
|
|
12168
|
-
options:
|
|
12425
|
+
options: z6.object({ channel: channelOption }),
|
|
12169
12426
|
action: "config:write",
|
|
12170
12427
|
effect: "write",
|
|
12171
12428
|
describe: "Custom instructions for a channel (gated) or for yourself \u2014 advisory prompt content that never changes agent, model, or permissions.",
|
|
@@ -12226,7 +12483,7 @@ ${quote(current ?? "")}`;
|
|
|
12226
12483
|
|
|
12227
12484
|
// ../../src/core/commands/contract.ts
|
|
12228
12485
|
import { basename, dirname as dirname8, join as join10 } from "node:path";
|
|
12229
|
-
import { z as
|
|
12486
|
+
import { z as z7 } from "zod";
|
|
12230
12487
|
function repoRootOfPlan(planPath) {
|
|
12231
12488
|
const plans = dirname8(planPath);
|
|
12232
12489
|
const docs = dirname8(plans);
|
|
@@ -12244,24 +12501,24 @@ function renderOutput(output) {
|
|
|
12244
12501
|
function registerContractCommands(registry) {
|
|
12245
12502
|
for (const cmd of contractCommands) registry.register(cmd);
|
|
12246
12503
|
}
|
|
12247
|
-
var
|
|
12504
|
+
var defineCommand4, SPECS_DIR, RULES_FILES, contractRender, contractCommands;
|
|
12248
12505
|
var init_contract2 = __esm({
|
|
12249
12506
|
"../../src/core/commands/contract.ts"() {
|
|
12250
12507
|
"use strict";
|
|
12251
12508
|
init_commandRegistry();
|
|
12252
12509
|
init_contract();
|
|
12253
|
-
|
|
12510
|
+
defineCommand4 = commandDefiner();
|
|
12254
12511
|
SPECS_DIR = join10("docs", "reference", "specs");
|
|
12255
12512
|
RULES_FILES = ["AGENTS.md", "CLAUDE.md"];
|
|
12256
|
-
contractRender =
|
|
12513
|
+
contractRender = defineCommand4({
|
|
12257
12514
|
id: "contract.render",
|
|
12258
|
-
options:
|
|
12259
|
-
plan:
|
|
12260
|
-
unit:
|
|
12261
|
-
root:
|
|
12262
|
-
branch:
|
|
12263
|
-
onto:
|
|
12264
|
-
maxChars:
|
|
12515
|
+
options: z7.object({
|
|
12516
|
+
plan: z7.string().min(1).describe("path of the plan record (docs/plans/<file>.md)"),
|
|
12517
|
+
unit: z7.string().regex(/^U\d+$/, "expected a unit id like U<n>").describe("the unit to render, as its heading spells it (U<n>)"),
|
|
12518
|
+
root: z7.string().min(1).optional().describe("the repository root the specs and rules are read under (default: the root the plan path implies)"),
|
|
12519
|
+
branch: z7.string().min(1).optional().describe("the unit's branch, named in the first instruction"),
|
|
12520
|
+
onto: z7.string().min(1).optional().describe("the merged parent the branch is rebased onto"),
|
|
12521
|
+
maxChars: z7.coerce.number().int().positive().optional().describe(`the rendered block's budget in characters (default ${DEFAULT_CONTRACT_MAX_CHARS})`)
|
|
12265
12522
|
}),
|
|
12266
12523
|
action: "contract:read",
|
|
12267
12524
|
effect: "read",
|
|
@@ -13908,7 +14165,7 @@ var init_runRecord = __esm({
|
|
|
13908
14165
|
RUN_STATUSES = ["completed", "stopped_soft", "stopped_hard", "failed", "interrupted"];
|
|
13909
14166
|
RUN_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
13910
14167
|
REVIEW_HEAD_PATTERN = /^[0-9a-f]{7,40}$/;
|
|
13911
|
-
RUN_SEEDS = ["channel", "parent"];
|
|
14168
|
+
RUN_SEEDS = ["channel", "parent", "session"];
|
|
13912
14169
|
SESSION_KEY_PATTERN = /^[A-Za-z0-9_.:@+/-]{1,512}$/;
|
|
13913
14170
|
isIndex = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0;
|
|
13914
14171
|
MACHINE_CLASSES_IN_RECORD = {
|
|
@@ -13953,11 +14210,11 @@ var init_runRecord = __esm({
|
|
|
13953
14210
|
});
|
|
13954
14211
|
|
|
13955
14212
|
// ../../src/core/commands/delivery.ts
|
|
13956
|
-
import { z as
|
|
14213
|
+
import { z as z8 } from "zod";
|
|
13957
14214
|
function registerDeliveryCommands(registry) {
|
|
13958
14215
|
for (const cmd of deliveryCommands) registry.register(cmd);
|
|
13959
14216
|
}
|
|
13960
|
-
var
|
|
14217
|
+
var defineCommand5, REPO_SLUG3, ISO_DAY3, asJson, deliveryReport, deliveryCommands;
|
|
13961
14218
|
var init_delivery2 = __esm({
|
|
13962
14219
|
"../../src/core/commands/delivery.ts"() {
|
|
13963
14220
|
"use strict";
|
|
@@ -13965,16 +14222,16 @@ var init_delivery2 = __esm({
|
|
|
13965
14222
|
init_commandRegistry();
|
|
13966
14223
|
init_delivery();
|
|
13967
14224
|
init_runRecord();
|
|
13968
|
-
|
|
14225
|
+
defineCommand5 = commandDefiner();
|
|
13969
14226
|
REPO_SLUG3 = /^(?!\.+\/)[\w.-]+\/(?!\.+$)[\w.-]+$/;
|
|
13970
14227
|
ISO_DAY3 = /^\d{4}-\d{2}-\d{2}$/;
|
|
13971
14228
|
asJson = (v) => v;
|
|
13972
|
-
deliveryReport =
|
|
14229
|
+
deliveryReport = defineCommand5({
|
|
13973
14230
|
id: "delivery.report",
|
|
13974
|
-
options:
|
|
13975
|
-
repo:
|
|
13976
|
-
since:
|
|
13977
|
-
weeks:
|
|
14231
|
+
options: z8.object({
|
|
14232
|
+
repo: z8.string().regex(REPO_SLUG3).optional().describe("the repository (`owner/name`); default: the first under `delivery.repos`"),
|
|
14233
|
+
since: z8.string().regex(ISO_DAY3).optional().describe("the first day of the range (`YYYY-MM-DD`, UTC); the range ends today"),
|
|
14234
|
+
weeks: z8.coerce.number().int().min(1).max(MAX_WEEKS).optional().describe(
|
|
13978
14235
|
`Monday-start weeks back from this one (default 4, at most ${MAX_WEEKS}); --since, when given, decides instead`
|
|
13979
14236
|
),
|
|
13980
14237
|
fresh: flag.optional().describe("read GitHub now instead of the repository's snapshot, and refresh the snapshot")
|
|
@@ -14019,7 +14276,7 @@ var init_delivery2 = __esm({
|
|
|
14019
14276
|
});
|
|
14020
14277
|
|
|
14021
14278
|
// ../../src/core/commands/deploy.ts
|
|
14022
|
-
import { z as
|
|
14279
|
+
import { z as z9 } from "zod";
|
|
14023
14280
|
function toOptions(o, dryRun, affected) {
|
|
14024
14281
|
return {
|
|
14025
14282
|
only: o.only,
|
|
@@ -14129,7 +14386,7 @@ async function copyImages(copies, account2, deps) {
|
|
|
14129
14386
|
function registerDeployCommands(registry) {
|
|
14130
14387
|
for (const cmd of deployCommands) registry.register(cmd);
|
|
14131
14388
|
}
|
|
14132
|
-
var
|
|
14389
|
+
var defineCommand6, workerList, positiveInt, gitRef, deployOptions, planJson, deployPlan, allOptions, copiedImage, listCopies, deployAll, restartOptions, deployRestart, initOptions, deployInit, configOptions, deployConfig, secretNames, secretsOptions, deploySecrets, imagesOptions, deployImages, deployCommands;
|
|
14133
14390
|
var init_deploy = __esm({
|
|
14134
14391
|
"../../src/core/commands/deploy.ts"() {
|
|
14135
14392
|
"use strict";
|
|
@@ -14142,16 +14399,16 @@ var init_deploy = __esm({
|
|
|
14142
14399
|
init_wranglerTemplate();
|
|
14143
14400
|
init_secrets();
|
|
14144
14401
|
init_commandRegistry();
|
|
14145
|
-
|
|
14146
|
-
workerList =
|
|
14402
|
+
defineCommand6 = commandDefiner();
|
|
14403
|
+
workerList = z9.string().transform(
|
|
14147
14404
|
(s) => s.split(",").map((x) => x.trim()).filter(Boolean)
|
|
14148
14405
|
).refine(
|
|
14149
14406
|
(names) => names.every((n2) => DEPLOY_ORDER.includes(n2)),
|
|
14150
14407
|
`expected a comma list of Workers (${DEPLOY_ORDER.join(", ")})`
|
|
14151
14408
|
).transform((names) => [...new Set(names)]);
|
|
14152
|
-
positiveInt =
|
|
14153
|
-
gitRef =
|
|
14154
|
-
deployOptions =
|
|
14409
|
+
positiveInt = z9.coerce.number().int().positive();
|
|
14410
|
+
gitRef = z9.string().regex(/^[A-Za-z0-9_./^~@{}][A-Za-z0-9_./^~@{}-]{0,199}$/, "expected a git revision (a sha, tag, branch, or HEAD^)");
|
|
14411
|
+
deployOptions = z9.object({
|
|
14155
14412
|
only: workerList.optional().describe(
|
|
14156
14413
|
`deploy only these Workers (comma list of ${DEPLOY_ORDER.join(", ")}); with --affected, only those of them that are affected`
|
|
14157
14414
|
),
|
|
@@ -14170,7 +14427,7 @@ var init_deploy = __esm({
|
|
|
14170
14427
|
poll: positiveInt.optional().describe("seconds between preflight retries (default 60)")
|
|
14171
14428
|
});
|
|
14172
14429
|
planJson = (plan3) => plan3;
|
|
14173
|
-
deployPlan =
|
|
14430
|
+
deployPlan = defineCommand6({
|
|
14174
14431
|
id: "deploy.plan",
|
|
14175
14432
|
options: deployOptions,
|
|
14176
14433
|
action: "deploy:read",
|
|
@@ -14186,7 +14443,7 @@ var init_deploy = __esm({
|
|
|
14186
14443
|
});
|
|
14187
14444
|
copiedImage = (c) => ({ kind: c.kind, source: c.source, target: c.target });
|
|
14188
14445
|
listCopies = (copies) => copies.map((c) => `${c.kind} \u2190 ${c.source}`).join(", ");
|
|
14189
|
-
deployAll =
|
|
14446
|
+
deployAll = defineCommand6({
|
|
14190
14447
|
id: "deploy.all",
|
|
14191
14448
|
options: allOptions,
|
|
14192
14449
|
action: "deploy:write",
|
|
@@ -14237,15 +14494,15 @@ ${formatDeployResults(result.results, result.notAttempted)}`
|
|
|
14237
14494
|
return output(result.results, copies, []);
|
|
14238
14495
|
}
|
|
14239
14496
|
});
|
|
14240
|
-
restartOptions =
|
|
14241
|
-
only:
|
|
14497
|
+
restartOptions = z9.object({
|
|
14498
|
+
only: z9.enum(["bot"]).optional().describe("the Worker to restart \u2014 only `bot` has a long-lived container (default bot)"),
|
|
14242
14499
|
force: flag.optional().describe(
|
|
14243
14500
|
"restart even when the bot cannot be consulted (no JSON on /healthz) \u2014 the fail-closed cases; runs in flight never refuse, they hand off"
|
|
14244
14501
|
),
|
|
14245
14502
|
waitMax: positiveInt.optional().describe("minutes to wait out a refusal (the bot not answering with JSON) before giving up (default 10)"),
|
|
14246
14503
|
poll: positiveInt.optional().describe("seconds between retries while refused (default 60)")
|
|
14247
14504
|
});
|
|
14248
|
-
deployRestart =
|
|
14505
|
+
deployRestart = defineCommand6({
|
|
14249
14506
|
id: "deploy.restart",
|
|
14250
14507
|
options: restartOptions,
|
|
14251
14508
|
action: "deploy:write",
|
|
@@ -14286,12 +14543,12 @@ ${formatDeployResults(result.results, result.notAttempted)}`
|
|
|
14286
14543
|
};
|
|
14287
14544
|
}
|
|
14288
14545
|
});
|
|
14289
|
-
initOptions =
|
|
14546
|
+
initOptions = z9.object({
|
|
14290
14547
|
check: flag.optional().describe(
|
|
14291
14548
|
"compare only: report each rendered file that differs from the one on disk and fail when any does (the `deploy:check` gate); nothing is written"
|
|
14292
14549
|
)
|
|
14293
14550
|
});
|
|
14294
|
-
deployInit =
|
|
14551
|
+
deployInit = defineCommand6({
|
|
14295
14552
|
id: "deploy.init",
|
|
14296
14553
|
options: initOptions,
|
|
14297
14554
|
action: "deploy:write",
|
|
@@ -14338,12 +14595,12 @@ ${formatDeployResults(result.results, result.notAttempted)}`
|
|
|
14338
14595
|
return output;
|
|
14339
14596
|
}
|
|
14340
14597
|
});
|
|
14341
|
-
configOptions =
|
|
14342
|
-
source:
|
|
14598
|
+
configOptions = z9.object({
|
|
14599
|
+
source: z9.string().min(1).optional().describe(
|
|
14343
14600
|
"read the config from this source instead of the profile's configSource (a path, github://owner/repo/path@ref, or op://Vault/Item/field)"
|
|
14344
14601
|
)
|
|
14345
14602
|
});
|
|
14346
|
-
deployConfig =
|
|
14603
|
+
deployConfig = defineCommand6({
|
|
14347
14604
|
id: "deploy.config",
|
|
14348
14605
|
options: configOptions,
|
|
14349
14606
|
action: "deploy:write",
|
|
@@ -14378,21 +14635,21 @@ the bot reads it on its next start: \`deploy restart\``;
|
|
|
14378
14635
|
return output;
|
|
14379
14636
|
}
|
|
14380
14637
|
});
|
|
14381
|
-
secretNames =
|
|
14638
|
+
secretNames = z9.string().transform(
|
|
14382
14639
|
(s) => s.split(",").map((x) => x.trim()).filter(Boolean)
|
|
14383
14640
|
).refine(
|
|
14384
14641
|
(names) => names.length > 0 && names.every((n2) => /^[A-Z][A-Z0-9_]*$/.test(n2)),
|
|
14385
14642
|
"expected a comma list of secret names (SCREAMING_SNAKE)"
|
|
14386
14643
|
).transform((names) => [...new Set(names)]);
|
|
14387
|
-
secretsOptions =
|
|
14644
|
+
secretsOptions = z9.object({
|
|
14388
14645
|
only: secretNames.optional().describe("put only these secrets (comma list of names from deploy/secrets.manifest.json)")
|
|
14389
14646
|
});
|
|
14390
|
-
deploySecrets =
|
|
14647
|
+
deploySecrets = defineCommand6({
|
|
14391
14648
|
id: "deploy.secrets",
|
|
14392
14649
|
args: [
|
|
14393
14650
|
{
|
|
14394
14651
|
name: "worker",
|
|
14395
|
-
schema:
|
|
14652
|
+
schema: z9.enum(DEPLOY_ORDER),
|
|
14396
14653
|
describe: `the Worker to provision (${DEPLOY_ORDER.join(", ")})`
|
|
14397
14654
|
}
|
|
14398
14655
|
],
|
|
@@ -14454,12 +14711,12 @@ the bot reads it on its next start: \`deploy restart\``;
|
|
|
14454
14711
|
return output;
|
|
14455
14712
|
}
|
|
14456
14713
|
});
|
|
14457
|
-
imagesOptions =
|
|
14714
|
+
imagesOptions = z9.object({
|
|
14458
14715
|
dryRun: flag.optional().describe(
|
|
14459
14716
|
"say which images the account registry already holds at the version and which would be copied; nothing is copied"
|
|
14460
14717
|
)
|
|
14461
14718
|
});
|
|
14462
|
-
deployImages =
|
|
14719
|
+
deployImages = defineCommand6({
|
|
14463
14720
|
id: "deploy.images",
|
|
14464
14721
|
options: imagesOptions,
|
|
14465
14722
|
action: "deploy:write",
|
|
@@ -14510,25 +14767,25 @@ the bot reads it on its next start: \`deploy restart\``;
|
|
|
14510
14767
|
});
|
|
14511
14768
|
|
|
14512
14769
|
// ../../src/core/commands/env.ts
|
|
14513
|
-
import { z as
|
|
14770
|
+
import { z as z10 } from "zod";
|
|
14514
14771
|
function registerEnvCommands(registry) {
|
|
14515
14772
|
for (const cmd of envCommands) registry.register(cmd);
|
|
14516
14773
|
}
|
|
14517
|
-
var
|
|
14774
|
+
var defineCommand7, envBootstrap, envCommands;
|
|
14518
14775
|
var init_env = __esm({
|
|
14519
14776
|
"../../src/core/commands/env.ts"() {
|
|
14520
14777
|
"use strict";
|
|
14521
14778
|
init_bootstrap();
|
|
14522
14779
|
init_commandRegistry();
|
|
14523
|
-
|
|
14524
|
-
envBootstrap =
|
|
14780
|
+
defineCommand7 = commandDefiner();
|
|
14781
|
+
envBootstrap = defineCommand7({
|
|
14525
14782
|
id: "env.bootstrap",
|
|
14526
|
-
options:
|
|
14527
|
-
env:
|
|
14528
|
-
service:
|
|
14783
|
+
options: z10.object({
|
|
14784
|
+
env: z10.string().min(1).describe("environment to materialize (UAT only; anything else is refused)"),
|
|
14785
|
+
service: z10.string().min(1).describe("which downstream service's toolchain env to fill"),
|
|
14529
14786
|
apply: flag.optional().describe("resolve the refs and WRITE the chmod-600 env file (default: dry-run)"),
|
|
14530
|
-
out:
|
|
14531
|
-
manifest:
|
|
14787
|
+
out: z10.string().min(1).optional().describe("env-file path (default .agent-env/<service>.<env>.env)"),
|
|
14788
|
+
manifest: z10.string().min(1).optional().describe(`manifest path (default ${DEFAULT_MANIFEST_PATH})`)
|
|
14532
14789
|
}),
|
|
14533
14790
|
action: "env:write",
|
|
14534
14791
|
effect: "write",
|
|
@@ -15262,7 +15519,7 @@ var init_selfImprovement = __esm({
|
|
|
15262
15519
|
});
|
|
15263
15520
|
|
|
15264
15521
|
// ../../src/core/commands/friction.ts
|
|
15265
|
-
import { z as
|
|
15522
|
+
import { z as z11 } from "zod";
|
|
15266
15523
|
async function ledgerOf(deps) {
|
|
15267
15524
|
let ledger;
|
|
15268
15525
|
try {
|
|
@@ -15290,7 +15547,7 @@ function inProgressHint(diagnosis, finished) {
|
|
|
15290
15547
|
function registerFrictionCommands(registry) {
|
|
15291
15548
|
for (const cmd of frictionCommands) registry.register(cmd);
|
|
15292
15549
|
}
|
|
15293
|
-
var
|
|
15550
|
+
var defineCommand8, positiveInt2, repoSlug, NO_LEDGER_MESSAGE, NO_REPO_MESSAGE, asJson2, render, visibleRuns, frictionReport, frictionPropose, frictionAnalyze, frictionCommands;
|
|
15294
15551
|
var init_friction = __esm({
|
|
15295
15552
|
"../../src/core/commands/friction.ts"() {
|
|
15296
15553
|
"use strict";
|
|
@@ -15301,19 +15558,19 @@ var init_friction = __esm({
|
|
|
15301
15558
|
init_runEventLines();
|
|
15302
15559
|
init_runFriction();
|
|
15303
15560
|
init_selfImprovement();
|
|
15304
|
-
|
|
15305
|
-
positiveInt2 =
|
|
15306
|
-
repoSlug =
|
|
15561
|
+
defineCommand8 = commandDefiner();
|
|
15562
|
+
positiveInt2 = z11.coerce.number().int().positive();
|
|
15563
|
+
repoSlug = z11.string().refine((s) => /^[\w.-]+\/[\w.-]+$/.test(s), "expected an owner/name slug");
|
|
15307
15564
|
NO_LEDGER_MESSAGE = "Run history is not configured in this deployment (`runHistory`), so there are no recent runs to analyze.";
|
|
15308
15565
|
NO_REPO_MESSAGE = "Set `selfImprovement.repo` (an `owner/name`) in config.yaml to tell `friction propose` where to file issues.";
|
|
15309
15566
|
asJson2 = (r) => r;
|
|
15310
15567
|
render = (output) => formatSelfImprovementReport(output);
|
|
15311
15568
|
visibleRuns = (caller) => predicateFor(caller.actor, "runs:read", "run");
|
|
15312
|
-
frictionReport =
|
|
15569
|
+
frictionReport = defineCommand8({
|
|
15313
15570
|
id: "friction.report",
|
|
15314
15571
|
enabledWhen: (caps) => caps.runHistory,
|
|
15315
|
-
options:
|
|
15316
|
-
sinceMs:
|
|
15572
|
+
options: z11.object({
|
|
15573
|
+
sinceMs: z11.coerce.number().int().nonnegative().optional().describe("only runs finished at or after this epoch ms"),
|
|
15317
15574
|
limit: positiveInt2.optional().describe("newest n runs (default: the ledger's retained window)"),
|
|
15318
15575
|
minRuns: positiveInt2.optional().describe("distinct runs a pattern must recur in (default selfImprovement.minRuns, else 2)")
|
|
15319
15576
|
}),
|
|
@@ -15339,10 +15596,10 @@ var init_friction = __esm({
|
|
|
15339
15596
|
});
|
|
15340
15597
|
}
|
|
15341
15598
|
});
|
|
15342
|
-
frictionPropose =
|
|
15599
|
+
frictionPropose = defineCommand8({
|
|
15343
15600
|
id: "friction.propose",
|
|
15344
15601
|
enabledWhen: (caps) => caps.runHistory,
|
|
15345
|
-
options:
|
|
15602
|
+
options: z11.object({
|
|
15346
15603
|
dryRun: flag.optional().describe("compute and report everything, file nothing"),
|
|
15347
15604
|
top: positiveInt2.optional().describe("proposals filed per pass (default selfImprovement.top, else 3)"),
|
|
15348
15605
|
minRuns: positiveInt2.optional().describe("distinct runs a pattern must recur in (default selfImprovement.minRuns, else 2)"),
|
|
@@ -15374,17 +15631,17 @@ var init_friction = __esm({
|
|
|
15374
15631
|
}
|
|
15375
15632
|
}
|
|
15376
15633
|
});
|
|
15377
|
-
frictionAnalyze =
|
|
15634
|
+
frictionAnalyze = defineCommand8({
|
|
15378
15635
|
id: "friction.analyze",
|
|
15379
15636
|
args: [
|
|
15380
15637
|
{
|
|
15381
15638
|
name: "source",
|
|
15382
|
-
schema:
|
|
15639
|
+
schema: z11.string().optional(),
|
|
15383
15640
|
describe: "a saved run stream: JSON lines of run events or a curl'ed /runs/:id/events SSE capture (default: stdin)"
|
|
15384
15641
|
}
|
|
15385
15642
|
],
|
|
15386
|
-
options:
|
|
15387
|
-
slowMs:
|
|
15643
|
+
options: z11.object({
|
|
15644
|
+
slowMs: z11.coerce.number().nonnegative().optional().describe("a tool call slower than this many ms is a slow-tool finding"),
|
|
15388
15645
|
inProgress: flag.optional().describe("the capture was taken mid-run: a trailing call without a result is still executing, not a dead run")
|
|
15389
15646
|
}),
|
|
15390
15647
|
action: "friction:read",
|
|
@@ -15437,7 +15694,7 @@ var init_friction = __esm({
|
|
|
15437
15694
|
});
|
|
15438
15695
|
|
|
15439
15696
|
// ../../src/core/commandSurface.ts
|
|
15440
|
-
import { z as
|
|
15697
|
+
import { z as z12 } from "zod";
|
|
15441
15698
|
function camelToKebab(s) {
|
|
15442
15699
|
return s.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
|
|
15443
15700
|
}
|
|
@@ -15509,7 +15766,7 @@ function isBooleanSchema(schema) {
|
|
|
15509
15766
|
return false;
|
|
15510
15767
|
}
|
|
15511
15768
|
function jsonSchemaOf(schema) {
|
|
15512
|
-
const out =
|
|
15769
|
+
const out = z12.toJSONSchema(unwrap(schema), { io: "input" });
|
|
15513
15770
|
delete out.$schema;
|
|
15514
15771
|
return out;
|
|
15515
15772
|
}
|
|
@@ -15521,7 +15778,7 @@ function jsonSchemaFor(cmd) {
|
|
|
15521
15778
|
if (!acceptsUndefined(arg.schema)) required.push(arg.name);
|
|
15522
15779
|
}
|
|
15523
15780
|
if (cmd.options) {
|
|
15524
|
-
const opts =
|
|
15781
|
+
const opts = z12.toJSONSchema(cmd.options, { io: "input" });
|
|
15525
15782
|
Object.assign(properties, opts.properties ?? {});
|
|
15526
15783
|
required.push(...opts.required ?? []);
|
|
15527
15784
|
}
|
|
@@ -15761,17 +16018,17 @@ function chatCommandList(commands) {
|
|
|
15761
16018
|
function registerHelpCommands(registry) {
|
|
15762
16019
|
for (const cmd of helpCommands) registry.register(cmd);
|
|
15763
16020
|
}
|
|
15764
|
-
var
|
|
16021
|
+
var defineCommand9, COMMANDS_REFERENCE_URL, DIRECTIVES_HELP, helpShow, helpCommandsList, helpCommands;
|
|
15765
16022
|
var init_help = __esm({
|
|
15766
16023
|
"../../src/core/commands/help.ts"() {
|
|
15767
16024
|
"use strict";
|
|
15768
16025
|
init_commandRegistry();
|
|
15769
16026
|
init_commandSurface();
|
|
15770
16027
|
init_docsLink();
|
|
15771
|
-
|
|
16028
|
+
defineCommand9 = commandDefiner();
|
|
15772
16029
|
COMMANDS_REFERENCE_URL = `${PROJECT_DOCS_URL}/reference/slack-commands`;
|
|
15773
16030
|
DIRECTIVES_HELP = "`agent:review model:anthropic/claude-opus-5 effort:low budget:20 look at PR 42` (effort: low | medium | high \u2014 lower = faster turns; budget: whole minutes, at least 2 \u2014 narrows this run's wall clock, never widens it)";
|
|
15774
|
-
helpShow =
|
|
16031
|
+
helpShow = defineCommand9({
|
|
15775
16032
|
id: "help.show",
|
|
15776
16033
|
action: "help:read",
|
|
15777
16034
|
effect: "read",
|
|
@@ -15782,7 +16039,7 @@ var init_help = __esm({
|
|
|
15782
16039
|
commandsReference: COMMANDS_REFERENCE_URL
|
|
15783
16040
|
})
|
|
15784
16041
|
});
|
|
15785
|
-
helpCommandsList =
|
|
16042
|
+
helpCommandsList = defineCommand9({
|
|
15786
16043
|
id: "help.commands",
|
|
15787
16044
|
action: "help:read",
|
|
15788
16045
|
effect: "read",
|
|
@@ -17519,7 +17776,7 @@ var init_service = __esm({
|
|
|
17519
17776
|
});
|
|
17520
17777
|
|
|
17521
17778
|
// ../../src/core/commands/mcp.ts
|
|
17522
|
-
import { z as
|
|
17779
|
+
import { z as z13 } from "zod";
|
|
17523
17780
|
async function serviceOf(deps) {
|
|
17524
17781
|
const svc = await deps.mcp.service();
|
|
17525
17782
|
if ("unavailable" in svc) throw new CommandError("unavailable", svc.unavailable);
|
|
@@ -17613,7 +17870,7 @@ function renderShow(output) {
|
|
|
17613
17870
|
function registerMcpCommands(registry) {
|
|
17614
17871
|
for (const cmd of MCP_COMMANDS) registry.register(cmd);
|
|
17615
17872
|
}
|
|
17616
|
-
var
|
|
17873
|
+
var defineCommand10, serverName, serverUrl, scopeOption, channelOption2, nameArg, mcpList, mcpAdd, mcpConnect, mcpShow, mcpRemove, MCP_COMMANDS;
|
|
17617
17874
|
var init_mcp = __esm({
|
|
17618
17875
|
"../../src/core/commands/mcp.ts"() {
|
|
17619
17876
|
"use strict";
|
|
@@ -17621,18 +17878,18 @@ var init_mcp = __esm({
|
|
|
17621
17878
|
init_service();
|
|
17622
17879
|
init_authorize();
|
|
17623
17880
|
init_commandRegistry();
|
|
17624
|
-
|
|
17625
|
-
serverName =
|
|
17626
|
-
serverUrl =
|
|
17627
|
-
scopeOption =
|
|
17881
|
+
defineCommand10 = commandDefiner();
|
|
17882
|
+
serverName = z13.string().refine((s) => MCP_SERVER_NAME_PATTERN.test(s), "expected a slug: lowercase letters, digits, dashes (\u2264 32 chars)");
|
|
17883
|
+
serverUrl = z13.string().refine((s) => /^https?:\/\/\S+$/.test(s), "expected an http(s) URL");
|
|
17884
|
+
scopeOption = z13.enum(["me", "channel", "org"]).optional().describe(
|
|
17628
17885
|
"whose server: yours (`me`, default), this channel's (`channel`, channel-config rights), or org-wide (`org`, admins)"
|
|
17629
17886
|
);
|
|
17630
|
-
channelOption2 =
|
|
17887
|
+
channelOption2 = z13.string().optional().describe("target channel for `--scope channel` and for `list` (default: the channel you are speaking in)");
|
|
17631
17888
|
nameArg = { name: "name", schema: serverName, describe: "the server's name (see `mcp list`)" };
|
|
17632
|
-
mcpList =
|
|
17889
|
+
mcpList = defineCommand10({
|
|
17633
17890
|
id: "mcp.list",
|
|
17634
17891
|
enabledWhen: (caps) => caps.mcp,
|
|
17635
|
-
options:
|
|
17892
|
+
options: z13.object({ channel: channelOption2 }),
|
|
17636
17893
|
action: "mcp:read",
|
|
17637
17894
|
effect: "read",
|
|
17638
17895
|
describe: "External MCP servers your runs in this channel can use \u2014 org-wide, this channel's, and your own \u2014 with state and agents; never a credential.",
|
|
@@ -17644,7 +17901,7 @@ var init_mcp = __esm({
|
|
|
17644
17901
|
return { servers };
|
|
17645
17902
|
}
|
|
17646
17903
|
});
|
|
17647
|
-
mcpAdd =
|
|
17904
|
+
mcpAdd = defineCommand10({
|
|
17648
17905
|
id: "mcp.add",
|
|
17649
17906
|
enabledWhen: (caps) => caps.mcp,
|
|
17650
17907
|
args: [
|
|
@@ -17654,15 +17911,15 @@ var init_mcp = __esm({
|
|
|
17654
17911
|
describe: "a short slug for the server (becomes the tool prefix mcp__<name>__)"
|
|
17655
17912
|
}
|
|
17656
17913
|
],
|
|
17657
|
-
options:
|
|
17914
|
+
options: z13.object({
|
|
17658
17915
|
url: serverUrl.describe("the server's Streamable-HTTP endpoint (https://\u2026/mcp)"),
|
|
17659
17916
|
scope: scopeOption,
|
|
17660
|
-
agents:
|
|
17917
|
+
agents: z13.string().transform(
|
|
17661
17918
|
(s) => s.split(",").map((a) => a.trim()).filter(Boolean)
|
|
17662
17919
|
).optional().describe(
|
|
17663
17920
|
"comma-separated agents that may use it (default general,research; only org servers may name coding/review/ship)"
|
|
17664
17921
|
),
|
|
17665
|
-
auth:
|
|
17922
|
+
auth: z13.enum(["oauth", "bearer", "none"]).optional().describe(
|
|
17666
17923
|
"how the server authenticates: `oauth` (you sign in on a one-time link), `bearer` (you paste a token on a one-time link), or `none`; omit to detect it from the server"
|
|
17667
17924
|
),
|
|
17668
17925
|
channel: channelOption2
|
|
@@ -17687,11 +17944,11 @@ var init_mcp = __esm({
|
|
|
17687
17944
|
);
|
|
17688
17945
|
}
|
|
17689
17946
|
});
|
|
17690
|
-
mcpConnect =
|
|
17947
|
+
mcpConnect = defineCommand10({
|
|
17691
17948
|
id: "mcp.connect",
|
|
17692
17949
|
enabledWhen: (caps) => caps.mcp,
|
|
17693
17950
|
args: [nameArg],
|
|
17694
|
-
options:
|
|
17951
|
+
options: z13.object({ scope: scopeOption, channel: channelOption2 }),
|
|
17695
17952
|
action: "mcp:write",
|
|
17696
17953
|
effect: "write",
|
|
17697
17954
|
describe: "A fresh one-time link to sign in to an OAuth server or enter (or replace) a bearer server's token \u2014 only you can complete it; it expires in 10 minutes.",
|
|
@@ -17705,11 +17962,11 @@ var init_mcp = __esm({
|
|
|
17705
17962
|
return await via(() => svc.connect(actor, target, args.name));
|
|
17706
17963
|
}
|
|
17707
17964
|
});
|
|
17708
|
-
mcpShow =
|
|
17965
|
+
mcpShow = defineCommand10({
|
|
17709
17966
|
id: "mcp.show",
|
|
17710
17967
|
enabledWhen: (caps) => caps.mcp,
|
|
17711
17968
|
args: [nameArg],
|
|
17712
|
-
options:
|
|
17969
|
+
options: z13.object({ scope: scopeOption, channel: channelOption2 }),
|
|
17713
17970
|
action: "mcp:read",
|
|
17714
17971
|
effect: "read",
|
|
17715
17972
|
describe: "One MCP server's entry plus a live probe of the tools it offers (names, read-only flags); never a credential.",
|
|
@@ -17725,11 +17982,11 @@ var init_mcp = __esm({
|
|
|
17725
17982
|
return await via(() => svc.show(actor, target, args.name));
|
|
17726
17983
|
}
|
|
17727
17984
|
});
|
|
17728
|
-
mcpRemove =
|
|
17985
|
+
mcpRemove = defineCommand10({
|
|
17729
17986
|
id: "mcp.remove",
|
|
17730
17987
|
enabledWhen: (caps) => caps.mcp,
|
|
17731
17988
|
args: [nameArg],
|
|
17732
|
-
options:
|
|
17989
|
+
options: z13.object({ scope: scopeOption, channel: channelOption2 }),
|
|
17733
17990
|
action: "mcp:write",
|
|
17734
17991
|
effect: "write",
|
|
17735
17992
|
describe: "Remove an MCP server you added and its stored credential (yours freely; channel ones need channel-config rights, org-wide ones admin rights).",
|
|
@@ -18167,7 +18424,7 @@ var init_llmOutput = __esm({
|
|
|
18167
18424
|
});
|
|
18168
18425
|
|
|
18169
18426
|
// ../../src/core/memory/reflection.ts
|
|
18170
|
-
import { z as
|
|
18427
|
+
import { z as z14 } from "zod";
|
|
18171
18428
|
function shouldReflect(input) {
|
|
18172
18429
|
if (input.agentName !== void 0 && NO_REFLECT_AGENTS.has(input.agentName)) return false;
|
|
18173
18430
|
return input.toolCalls > 0 || input.historyTurns >= REFLECT_MIN_TURNS;
|
|
@@ -18386,7 +18643,7 @@ var init_reflection = __esm({
|
|
|
18386
18643
|
"Output raw JSON with no code fence and no prose."
|
|
18387
18644
|
].join("\n");
|
|
18388
18645
|
SUMMARY_INHERITANCE = ["user", "repo", "channel"];
|
|
18389
|
-
REFLECTION_ENVELOPE = jsonOutput(
|
|
18646
|
+
REFLECTION_ENVELOPE = jsonOutput(z14.object({ facts: z14.array(z14.unknown()), summary: z14.unknown().optional() }), {
|
|
18390
18647
|
name: "reflection-envelope"
|
|
18391
18648
|
});
|
|
18392
18649
|
SCOPE_KINDS = ["org", "user", "repo", "channel"];
|
|
@@ -18506,11 +18763,11 @@ var init_workerStore = __esm({
|
|
|
18506
18763
|
});
|
|
18507
18764
|
|
|
18508
18765
|
// ../../src/core/memory/buildStore.ts
|
|
18509
|
-
function resolveScopeCap(
|
|
18510
|
-
if (
|
|
18511
|
-
if (Number.isInteger(
|
|
18766
|
+
function resolveScopeCap(configured3, warn) {
|
|
18767
|
+
if (configured3 === void 0) return DEFAULT_SCOPE_CAP;
|
|
18768
|
+
if (Number.isInteger(configured3) && configured3 >= 1 && configured3 <= MAX_SCOPE_CAP) return configured3;
|
|
18512
18769
|
warn(
|
|
18513
|
-
`memory.maxRecordsPerScope must be an integer between 1 and ${MAX_SCOPE_CAP} (got ${String(
|
|
18770
|
+
`memory.maxRecordsPerScope must be an integer between 1 and ${MAX_SCOPE_CAP} (got ${String(configured3)}) \u2014 using the default ${DEFAULT_SCOPE_CAP}.`
|
|
18514
18771
|
);
|
|
18515
18772
|
return DEFAULT_SCOPE_CAP;
|
|
18516
18773
|
}
|
|
@@ -18618,7 +18875,7 @@ var init_memory = __esm({
|
|
|
18618
18875
|
});
|
|
18619
18876
|
|
|
18620
18877
|
// ../../src/core/commands/memory.ts
|
|
18621
|
-
import { z as
|
|
18878
|
+
import { z as z15 } from "zod";
|
|
18622
18879
|
function scopeKeyOfMemoryId(id) {
|
|
18623
18880
|
const m = /^mem:(.+):\d+$/.exec(id);
|
|
18624
18881
|
return m ? m[1] : void 0;
|
|
@@ -18672,18 +18929,18 @@ _(limit ${limit} reached \u2014 there may be more; narrow with words or raise \`
|
|
|
18672
18929
|
function registerMemoryCommands(registry) {
|
|
18673
18930
|
for (const cmd of memoryCommands) registry.register(cmd);
|
|
18674
18931
|
}
|
|
18675
|
-
var
|
|
18932
|
+
var defineCommand11, MEMORY_LIST_LIMIT, MEMORY_LIST_MAX_LIMIT, MEMORY_OFF_MESSAGE, memoryId, repoScopeKey, channelScopeKey, isSharedScope, LIST_SCOPES, memoryList, memoryForget, memoryCommands;
|
|
18676
18933
|
var init_memory2 = __esm({
|
|
18677
18934
|
"../../src/core/commands/memory.ts"() {
|
|
18678
18935
|
"use strict";
|
|
18679
18936
|
init_authorize();
|
|
18680
18937
|
init_commandRegistry();
|
|
18681
18938
|
init_memory();
|
|
18682
|
-
|
|
18939
|
+
defineCommand11 = commandDefiner();
|
|
18683
18940
|
MEMORY_LIST_LIMIT = 20;
|
|
18684
18941
|
MEMORY_LIST_MAX_LIMIT = 50;
|
|
18685
18942
|
MEMORY_OFF_MESSAGE = "Memory is off in this deployment (`memory.enabled` is not set), so there is nothing to list or forget.";
|
|
18686
|
-
memoryId =
|
|
18943
|
+
memoryId = z15.string().refine(
|
|
18687
18944
|
(id) => scopeKeyOfMemoryId(id) !== void 0,
|
|
18688
18945
|
"expected a memory id like mem:<scope>:<n> (see `memory list`)"
|
|
18689
18946
|
);
|
|
@@ -18691,21 +18948,21 @@ var init_memory2 = __esm({
|
|
|
18691
18948
|
channelScopeKey = (channelId) => deriveScopeKey("channel", { channelId });
|
|
18692
18949
|
isSharedScope = (key, keys) => key === keys.org || key.startsWith("repo:") || key.startsWith("channel:");
|
|
18693
18950
|
LIST_SCOPES = ["me", "org", "repo", "channel", "all"];
|
|
18694
|
-
memoryList =
|
|
18951
|
+
memoryList = defineCommand11({
|
|
18695
18952
|
id: "memory.list",
|
|
18696
18953
|
enabledWhen: (caps) => caps.memory,
|
|
18697
18954
|
args: [
|
|
18698
18955
|
{
|
|
18699
18956
|
name: "query",
|
|
18700
|
-
schema:
|
|
18957
|
+
schema: z15.string().optional(),
|
|
18701
18958
|
describe: "words a record must mention (whole-token match)",
|
|
18702
18959
|
rest: true
|
|
18703
18960
|
}
|
|
18704
18961
|
],
|
|
18705
|
-
options:
|
|
18706
|
-
scope:
|
|
18707
|
-
limit:
|
|
18708
|
-
repo:
|
|
18962
|
+
options: z15.object({
|
|
18963
|
+
scope: z15.enum(LIST_SCOPES).optional().describe("which scopes to list (default all: yours, this repo's, this channel's, and the shared org scope)"),
|
|
18964
|
+
limit: z15.coerce.number().int().min(1).max(MEMORY_LIST_MAX_LIMIT).optional().describe(`records per scope (default ${MEMORY_LIST_LIMIT}, max ${MEMORY_LIST_MAX_LIMIT})`),
|
|
18965
|
+
repo: z15.string().refine((s) => /^[\w.-]+\/[\w.-]+$/.test(s), "expected an owner/name slug").optional().describe("the repo whose scope to list (default: the repo this thread is bound to)")
|
|
18709
18966
|
}),
|
|
18710
18967
|
action: "memory:read",
|
|
18711
18968
|
effect: "read",
|
|
@@ -18759,7 +19016,7 @@ var init_memory2 = __esm({
|
|
|
18759
19016
|
};
|
|
18760
19017
|
}
|
|
18761
19018
|
});
|
|
18762
|
-
memoryForget =
|
|
19019
|
+
memoryForget = defineCommand11({
|
|
18763
19020
|
id: "memory.forget",
|
|
18764
19021
|
enabledWhen: (caps) => caps.memory,
|
|
18765
19022
|
args: [{ name: "id", schema: memoryId, describe: "the record id (`mem:<scope>:<n>`, from `memory list`)" }],
|
|
@@ -18894,7 +19151,7 @@ var init_residentDiskBudget = __esm({
|
|
|
18894
19151
|
});
|
|
18895
19152
|
|
|
18896
19153
|
// ../../src/core/commands/repo.ts
|
|
18897
|
-
import { z as
|
|
19154
|
+
import { z as z16 } from "zod";
|
|
18898
19155
|
async function adminOf(deps, span) {
|
|
18899
19156
|
const api = await deps.repo.admin();
|
|
18900
19157
|
if ("unavailable" in api) throw new CommandError("unavailable", api.unavailable);
|
|
@@ -19002,7 +19259,7 @@ ${clipOpOutput(text)}
|
|
|
19002
19259
|
\`\`\`` : `${icon} ${str4(o.summary)}`;
|
|
19003
19260
|
}
|
|
19004
19261
|
function defineOp(op) {
|
|
19005
|
-
return
|
|
19262
|
+
return defineCommand12({
|
|
19006
19263
|
id: `repo.${op}`,
|
|
19007
19264
|
// The op needs a backend: the resident service, or the local workspace (`defaultOperations`).
|
|
19008
19265
|
enabledWhen: (caps) => caps.residents || caps.execution === "local",
|
|
@@ -19060,7 +19317,7 @@ function defineOp(op) {
|
|
|
19060
19317
|
function registerRepoCommands(registry) {
|
|
19061
19318
|
for (const cmd of repoCommands) registry.register(cmd);
|
|
19062
19319
|
}
|
|
19063
|
-
var
|
|
19320
|
+
var defineCommand12, DEFAULT_COMMANDS, DEFAULT_REF, SETTLE_POLL_MS, SETTLE_MAX_MS, repoSlug2, gitRef2, command, slugArg, n, obj, str4, repoList, repoOnboard, COMMAND_KEYS, dryRunOptions, repoOffboard, repoRebuild, repoReconfigure, NO_OPS_BACKEND_MESSAGE, repoTest, repoBuild, repoCommands;
|
|
19064
19321
|
var init_repo = __esm({
|
|
19065
19322
|
"../../src/core/commands/repo.ts"() {
|
|
19066
19323
|
"use strict";
|
|
@@ -19068,19 +19325,19 @@ var init_repo = __esm({
|
|
|
19068
19325
|
init_residentAdmin();
|
|
19069
19326
|
init_repoToolchain();
|
|
19070
19327
|
init_residentDiskBudget();
|
|
19071
|
-
|
|
19328
|
+
defineCommand12 = commandDefiner();
|
|
19072
19329
|
DEFAULT_COMMANDS = NPM_FALLBACK_COMMANDS;
|
|
19073
19330
|
DEFAULT_REF = "main";
|
|
19074
19331
|
SETTLE_POLL_MS = 1e4;
|
|
19075
19332
|
SETTLE_MAX_MS = 12 * 6e4;
|
|
19076
|
-
repoSlug2 =
|
|
19077
|
-
gitRef2 =
|
|
19078
|
-
command =
|
|
19333
|
+
repoSlug2 = z16.string().refine((s) => parseSlug(s) !== void 0, "expected a GitHub owner/name slug").transform((s) => parseSlug(s));
|
|
19334
|
+
gitRef2 = z16.string().refine((s) => validRef(s) !== void 0, "expected a plausible git branch ref (e.g. main)");
|
|
19335
|
+
command = z16.string().min(1);
|
|
19079
19336
|
slugArg = { name: "slug", schema: repoSlug2, describe: "GitHub owner/name of the repo" };
|
|
19080
19337
|
n = (v) => String(typeof v === "number" ? v : v ?? "?");
|
|
19081
19338
|
obj = (v) => typeof v === "object" && v !== null && !Array.isArray(v) ? v : {};
|
|
19082
19339
|
str4 = (v) => typeof v === "string" ? v : String(v ?? "?");
|
|
19083
|
-
repoList =
|
|
19340
|
+
repoList = defineCommand12({
|
|
19084
19341
|
id: "repo.list",
|
|
19085
19342
|
enabledWhen: (caps) => caps.residents,
|
|
19086
19343
|
action: "repo:read",
|
|
@@ -19097,11 +19354,11 @@ var init_repo = __esm({
|
|
|
19097
19354
|
return res.data;
|
|
19098
19355
|
}
|
|
19099
19356
|
});
|
|
19100
|
-
repoOnboard =
|
|
19357
|
+
repoOnboard = defineCommand12({
|
|
19101
19358
|
id: "repo.onboard",
|
|
19102
19359
|
enabledWhen: (caps) => caps.residents,
|
|
19103
19360
|
args: [slugArg],
|
|
19104
|
-
options:
|
|
19361
|
+
options: z16.object({
|
|
19105
19362
|
ref: gitRef2.optional().describe(`default branch to keep warm (default ${DEFAULT_REF})`),
|
|
19106
19363
|
test: command.optional().describe(
|
|
19107
19364
|
"the repo's test command (default: detected from the repo root \u2014 `<pm> test`, or a no-op without a test script)"
|
|
@@ -19188,10 +19445,10 @@ var init_repo = __esm({
|
|
|
19188
19445
|
settle: (output, { deps }) => settleProvisioning(deps, str4(output.slug))
|
|
19189
19446
|
});
|
|
19190
19447
|
COMMAND_KEYS = ["install", "build", "test"];
|
|
19191
|
-
dryRunOptions =
|
|
19448
|
+
dryRunOptions = z16.object({
|
|
19192
19449
|
dryRun: flag.optional().describe("compute and return the itemized plan without executing")
|
|
19193
19450
|
});
|
|
19194
|
-
repoOffboard =
|
|
19451
|
+
repoOffboard = defineCommand12({
|
|
19195
19452
|
id: "repo.offboard",
|
|
19196
19453
|
enabledWhen: (caps) => caps.residents,
|
|
19197
19454
|
args: [slugArg],
|
|
@@ -19225,7 +19482,7 @@ var init_repo = __esm({
|
|
|
19225
19482
|
return { ...r.data, slug: args.slug, dryRun };
|
|
19226
19483
|
}
|
|
19227
19484
|
});
|
|
19228
|
-
repoRebuild =
|
|
19485
|
+
repoRebuild = defineCommand12({
|
|
19229
19486
|
id: "repo.rebuild",
|
|
19230
19487
|
enabledWhen: (caps) => caps.residents,
|
|
19231
19488
|
args: [slugArg],
|
|
@@ -19264,11 +19521,11 @@ var init_repo = __esm({
|
|
|
19264
19521
|
return { ...r.data, slug: args.slug, dryRun };
|
|
19265
19522
|
}
|
|
19266
19523
|
});
|
|
19267
|
-
repoReconfigure =
|
|
19524
|
+
repoReconfigure = defineCommand12({
|
|
19268
19525
|
id: "repo.reconfigure",
|
|
19269
19526
|
enabledWhen: (caps) => caps.residents,
|
|
19270
19527
|
args: [slugArg],
|
|
19271
|
-
options:
|
|
19528
|
+
options: z16.object({
|
|
19272
19529
|
ref: gitRef2.optional().describe("new default branch"),
|
|
19273
19530
|
test: command.optional().describe("new test command"),
|
|
19274
19531
|
build: command.optional().describe("new build command"),
|
|
@@ -20238,7 +20495,7 @@ var init_runsService = __esm({
|
|
|
20238
20495
|
});
|
|
20239
20496
|
|
|
20240
20497
|
// ../../src/core/commands/review.ts
|
|
20241
|
-
import { z as
|
|
20498
|
+
import { z as z17 } from "zod";
|
|
20242
20499
|
function artifactJson(a) {
|
|
20243
20500
|
return {
|
|
20244
20501
|
...a.model !== void 0 ? { model: a.model } : {},
|
|
@@ -20307,7 +20564,7 @@ function refused2(err2) {
|
|
|
20307
20564
|
function registerReviewCommands(registry) {
|
|
20308
20565
|
for (const cmd of reviewCommands) registry.register(cmd);
|
|
20309
20566
|
}
|
|
20310
|
-
var
|
|
20567
|
+
var defineCommand13, runId, ABRIDGE_OFF_MESSAGE, reviewAbridge, reviewCommands;
|
|
20311
20568
|
var init_review = __esm({
|
|
20312
20569
|
"../../src/core/commands/review.ts"() {
|
|
20313
20570
|
"use strict";
|
|
@@ -20316,17 +20573,17 @@ var init_review = __esm({
|
|
|
20316
20573
|
init_reviewAbridge();
|
|
20317
20574
|
init_runRecord();
|
|
20318
20575
|
init_runsService();
|
|
20319
|
-
|
|
20320
|
-
runId =
|
|
20576
|
+
defineCommand13 = commandDefiner();
|
|
20577
|
+
runId = z17.string().regex(RUN_ID_PATTERN);
|
|
20321
20578
|
ABRIDGE_OFF_MESSAGE = "The abridged reading diff is off in this deployment: it needs the `meat` binary on the bot host, the Anthropic provider's credential, `review.readingDiff.provider` not `off`, and run history to store it.";
|
|
20322
|
-
reviewAbridge =
|
|
20579
|
+
reviewAbridge = defineCommand13({
|
|
20323
20580
|
id: "review.abridge",
|
|
20324
20581
|
// Hidden unless the abridging can happen here (the binary, the credential,
|
|
20325
20582
|
// the switch) AND there is a record to append to.
|
|
20326
20583
|
enabledWhen: (caps) => caps.runHistory && caps.readingDiffAbridge,
|
|
20327
20584
|
args: [{ name: "id", schema: runId, describe: "run id of a finished PR review" }],
|
|
20328
|
-
options:
|
|
20329
|
-
model:
|
|
20585
|
+
options: z17.object({
|
|
20586
|
+
model: z17.string().min(1).optional().describe("meat's model (default review.readingDiff.meatModel, else claude-opus-5)"),
|
|
20330
20587
|
force: flag.optional().describe("recompute even when an abridged diff is already stored, or retry a failed one"),
|
|
20331
20588
|
wait: flag.optional().describe("block until the abridging finishes and answer the outcome instead of `running`")
|
|
20332
20589
|
}),
|
|
@@ -20358,7 +20615,7 @@ var init_review = __esm({
|
|
|
20358
20615
|
});
|
|
20359
20616
|
|
|
20360
20617
|
// ../../src/core/commands/runs.ts
|
|
20361
|
-
import { z as
|
|
20618
|
+
import { z as z18 } from "zod";
|
|
20362
20619
|
function unwrap2(res) {
|
|
20363
20620
|
if (res.ok) return res.value;
|
|
20364
20621
|
throw new CommandError(res.error, res.error === "not_found" ? "run not found" : "run already finished");
|
|
@@ -20399,7 +20656,7 @@ function wrapEvent(e) {
|
|
|
20399
20656
|
function registerRunsCommands(registry) {
|
|
20400
20657
|
for (const cmd of runsCommands) registry.register(cmd);
|
|
20401
20658
|
}
|
|
20402
|
-
var
|
|
20659
|
+
var defineCommand14, runId2, positiveInt3, idArg, logDenied, asJson3, runsList, runsGet, runsEvents, runsFriction, runsStop, runsCommands;
|
|
20403
20660
|
var init_runs = __esm({
|
|
20404
20661
|
"../../src/core/commands/runs.ts"() {
|
|
20405
20662
|
"use strict";
|
|
@@ -20408,21 +20665,24 @@ var init_runs = __esm({
|
|
|
20408
20665
|
init_commandRegistry();
|
|
20409
20666
|
init_runRecord();
|
|
20410
20667
|
init_runsService();
|
|
20411
|
-
|
|
20412
|
-
runId2 =
|
|
20413
|
-
positiveInt3 =
|
|
20668
|
+
defineCommand14 = commandDefiner();
|
|
20669
|
+
runId2 = z18.string().regex(RUN_ID_PATTERN);
|
|
20670
|
+
positiveInt3 = z18.coerce.number().int().positive();
|
|
20414
20671
|
idArg = { name: "id", schema: runId2, describe: "run id" };
|
|
20415
20672
|
logDenied = (entry) => console.log(JSON.stringify({ audit: "authz", ...entry }));
|
|
20416
20673
|
asJson3 = (v) => v;
|
|
20417
|
-
runsList =
|
|
20674
|
+
runsList = defineCommand14({
|
|
20418
20675
|
id: "runs.list",
|
|
20419
|
-
options:
|
|
20420
|
-
status:
|
|
20421
|
-
agent:
|
|
20422
|
-
channel:
|
|
20423
|
-
|
|
20676
|
+
options: z18.object({
|
|
20677
|
+
status: z18.enum(["active", "finished", "all"]).default("active").describe("which runs: live (default), persisted, or both"),
|
|
20678
|
+
agent: z18.string().min(1).optional().describe("only runs of this agent"),
|
|
20679
|
+
channel: z18.string().min(1).optional().describe("only runs in this platform-namespaced channel (`slack:C0123`, `http:ops`)"),
|
|
20680
|
+
thread: z18.string().min(1).optional().describe(
|
|
20681
|
+
"only runs in this thread, newest first (`slack:C0123:1712.34` \u2014 a thread's story, its sessions' runs)"
|
|
20682
|
+
),
|
|
20683
|
+
sinceMs: z18.coerce.number().int().nonnegative().optional().describe("only runs started at or after this epoch ms"),
|
|
20424
20684
|
limit: positiveInt3.max(RUN_LIST_MAX_LIMIT).optional().describe(`page size (max ${RUN_LIST_MAX_LIMIT})`),
|
|
20425
|
-
before:
|
|
20685
|
+
before: z18.coerce.number().int().nonnegative().optional().describe("page cursor: runs finished before this epoch ms"),
|
|
20426
20686
|
beforeId: runId2.optional().describe("page cursor tie-breaker: the last id of the previous page")
|
|
20427
20687
|
}),
|
|
20428
20688
|
action: "runs:read",
|
|
@@ -20430,14 +20690,17 @@ var init_runs = __esm({
|
|
|
20430
20690
|
describe: "List runs (live and persisted, newest first) \u2014 metadata only, never message text.",
|
|
20431
20691
|
handler: async ({ options, caller, deps }) => {
|
|
20432
20692
|
const visibleTo = predicateFor(caller.actor, "runs:read", "run");
|
|
20433
|
-
|
|
20693
|
+
const { thread, ...rest } = options;
|
|
20694
|
+
return asJson3(
|
|
20695
|
+
await (await deps.runs()).listRuns({ ...rest, ...thread !== void 0 ? { threadKey: thread } : {}, visibleTo })
|
|
20696
|
+
);
|
|
20434
20697
|
}
|
|
20435
20698
|
});
|
|
20436
|
-
runsGet =
|
|
20699
|
+
runsGet = defineCommand14({
|
|
20437
20700
|
id: "runs.get",
|
|
20438
20701
|
args: [idArg],
|
|
20439
|
-
options:
|
|
20440
|
-
include:
|
|
20702
|
+
options: z18.object({
|
|
20703
|
+
include: z18.enum(["messages"]).optional().describe("add the run's events, free text wrapped as untrusted content")
|
|
20441
20704
|
}),
|
|
20442
20705
|
action: "runs:read",
|
|
20443
20706
|
effect: "read",
|
|
@@ -20457,11 +20720,11 @@ var init_runs = __esm({
|
|
|
20457
20720
|
return asJson3(view);
|
|
20458
20721
|
}
|
|
20459
20722
|
});
|
|
20460
|
-
runsEvents =
|
|
20723
|
+
runsEvents = defineCommand14({
|
|
20461
20724
|
id: "runs.events",
|
|
20462
20725
|
args: [idArg],
|
|
20463
|
-
options:
|
|
20464
|
-
afterSeq:
|
|
20726
|
+
options: z18.object({
|
|
20727
|
+
afterSeq: z18.coerce.number().int().nonnegative().optional().describe("events with seq greater than this"),
|
|
20465
20728
|
limit: positiveInt3.max(MAX_EVENTS_PAGE).optional().describe(`page size (max ${MAX_EVENTS_PAGE})`)
|
|
20466
20729
|
}),
|
|
20467
20730
|
action: "runs:read",
|
|
@@ -20475,7 +20738,7 @@ var init_runs = __esm({
|
|
|
20475
20738
|
return asJson3({ ...page2, events: page2.events.map(wrapEvent) });
|
|
20476
20739
|
}
|
|
20477
20740
|
});
|
|
20478
|
-
runsFriction =
|
|
20741
|
+
runsFriction = defineCommand14({
|
|
20479
20742
|
id: "runs.friction",
|
|
20480
20743
|
args: [idArg],
|
|
20481
20744
|
action: "runs:read",
|
|
@@ -20488,10 +20751,10 @@ var init_runs = __esm({
|
|
|
20488
20751
|
return asJson3(unwrap2(await runs.getRunFriction(args.id)));
|
|
20489
20752
|
}
|
|
20490
20753
|
});
|
|
20491
|
-
runsStop =
|
|
20754
|
+
runsStop = defineCommand14({
|
|
20492
20755
|
id: "runs.stop",
|
|
20493
20756
|
args: [idArg],
|
|
20494
|
-
options:
|
|
20757
|
+
options: z18.object({ mode: z18.enum(["soft", "hard"]).describe("soft = finish the current step; hard = abort now") }),
|
|
20495
20758
|
action: "runs:write",
|
|
20496
20759
|
effect: "write",
|
|
20497
20760
|
describe: "Request a live run to stop (`--mode soft` = finish the current step; `hard` = abort now). Records the caller as the actor.",
|
|
@@ -20515,16 +20778,16 @@ var init_runs = __esm({
|
|
|
20515
20778
|
function registerScheduleCommands(registry) {
|
|
20516
20779
|
for (const cmd of scheduleCommands) registry.register(cmd);
|
|
20517
20780
|
}
|
|
20518
|
-
var
|
|
20781
|
+
var defineCommand15, ACTION_LABEL, utc, scheduleList, scheduleCommands;
|
|
20519
20782
|
var init_schedule = __esm({
|
|
20520
20783
|
"../../src/core/commands/schedule.ts"() {
|
|
20521
20784
|
"use strict";
|
|
20522
20785
|
init_commandRegistry();
|
|
20523
20786
|
init_schedules();
|
|
20524
|
-
|
|
20787
|
+
defineCommand15 = commandDefiner();
|
|
20525
20788
|
ACTION_LABEL = { healthz: "keep-alive", watchdog: "resident watchdog" };
|
|
20526
20789
|
utc = (ms) => `${new Date(ms).toISOString().slice(0, 16).replace("T", " ")} UTC`;
|
|
20527
|
-
scheduleList =
|
|
20790
|
+
scheduleList = defineCommand15({
|
|
20528
20791
|
id: "schedule.list",
|
|
20529
20792
|
enabledWhen: (caps) => caps.schedules,
|
|
20530
20793
|
action: "schedule:read",
|
|
@@ -20788,7 +21051,7 @@ var init_plan2 = __esm({
|
|
|
20788
21051
|
});
|
|
20789
21052
|
|
|
20790
21053
|
// ../../src/core/commands/setup.ts
|
|
20791
|
-
import { z as
|
|
21054
|
+
import { z as z19 } from "zod";
|
|
20792
21055
|
async function gatherAnswers(o, setup) {
|
|
20793
21056
|
const ask = setup.prompt;
|
|
20794
21057
|
const given = (v) => v !== void 0;
|
|
@@ -20858,33 +21121,33 @@ function capabilityLine(c) {
|
|
|
20858
21121
|
function registerSetupCommands(registry) {
|
|
20859
21122
|
for (const cmd of setupCommands) registry.register(cmd);
|
|
20860
21123
|
}
|
|
20861
|
-
var
|
|
21124
|
+
var defineCommand16, secret, digits, workerName, hostname2, httpUrl, account, initOptions2, DEFAULT_NAME, setupInit, ASK, setupCommands;
|
|
20862
21125
|
var init_setup = __esm({
|
|
20863
21126
|
"../../src/core/commands/setup.ts"() {
|
|
20864
21127
|
"use strict";
|
|
20865
21128
|
init_plan2();
|
|
20866
21129
|
init_commandRegistry();
|
|
20867
21130
|
init_deploy();
|
|
20868
|
-
|
|
20869
|
-
secret =
|
|
20870
|
-
digits =
|
|
20871
|
-
workerName =
|
|
20872
|
-
hostname2 =
|
|
20873
|
-
httpUrl =
|
|
20874
|
-
account =
|
|
20875
|
-
initOptions2 =
|
|
20876
|
-
organization:
|
|
21131
|
+
defineCommand16 = commandDefiner();
|
|
21132
|
+
secret = z19.string().min(1);
|
|
21133
|
+
digits = z19.string().regex(/^\d+$/, "expected a number");
|
|
21134
|
+
workerName = z19.string().regex(/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/, "expected a Worker name: lowercase letters, digits, hyphens");
|
|
21135
|
+
hostname2 = z19.string().regex(/^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/, "expected a bare DNS name (example.com)");
|
|
21136
|
+
httpUrl = z19.string().regex(/^https?:\/\/\S+$/, "expected an http(s) URL");
|
|
21137
|
+
account = z19.string().regex(/^[0-9a-f]{32}$/, "expected a Cloudflare account id: 32 hex characters");
|
|
21138
|
+
initOptions2 = z19.object({
|
|
21139
|
+
organization: z19.string().min(1).optional().describe("the GitHub organization (or user) this installation serves \u2014 config.yaml's `organization`"),
|
|
20877
21140
|
anthropicKey: secret.optional().describe("an Anthropic API key \u2192 ANTHROPIC_API_KEY and the `anthropic` provider"),
|
|
20878
21141
|
openaiCompatible: httpUrl.optional().describe(
|
|
20879
21142
|
"an OpenAI-compatible endpoint's base URL (https://api.openai.com/v1, http://localhost:11434/v1) \u2192 the `openai` provider"
|
|
20880
21143
|
),
|
|
20881
|
-
model:
|
|
21144
|
+
model: z19.string().min(1).optional().describe("with --openai-compatible: the model every agent runs on at that endpoint (openai/<model>)"),
|
|
20882
21145
|
modelKey: secret.optional().describe("with --openai-compatible: the endpoint's key \u2192 OPENAI_API_KEY (a local endpoint needs none)"),
|
|
20883
21146
|
slackAppToken: secret.optional().describe("the Slack app-level token (xapp-\u2026) \u2192 SLACK_APP_TOKEN"),
|
|
20884
21147
|
slackBotToken: secret.optional().describe("the Slack bot token (xoxb-\u2026) \u2192 SLACK_BOT_TOKEN"),
|
|
20885
21148
|
githubAppId: digits.optional().describe("the GitHub App's id \u2192 GITHUB_APP_ID"),
|
|
20886
21149
|
githubInstallationId: digits.optional().describe("the GitHub App's installation id \u2192 GITHUB_APP_INSTALLATION_ID"),
|
|
20887
|
-
githubPrivateKeyFile:
|
|
21150
|
+
githubPrivateKeyFile: z19.string().min(1).optional().describe("path to the GitHub App's private key (PEM) \u2192 GITHUB_APP_PRIVATE_KEY, one quoted line"),
|
|
20888
21151
|
cloudflare: account.optional().describe(
|
|
20889
21152
|
"a Cloudflare account id: also write deploy/profile.json and render the Worker configs (needs --zone; from a checkout's root, or anywhere when this CLI is the published package)"
|
|
20890
21153
|
),
|
|
@@ -20894,7 +21157,7 @@ var init_setup = __esm({
|
|
|
20894
21157
|
dryRun: flag.optional().describe("write nothing; print each file as it would be written, secrets masked")
|
|
20895
21158
|
});
|
|
20896
21159
|
DEFAULT_NAME = "switchboard";
|
|
20897
|
-
setupInit =
|
|
21160
|
+
setupInit = defineCommand16({
|
|
20898
21161
|
id: "setup.init",
|
|
20899
21162
|
options: initOptions2,
|
|
20900
21163
|
action: "setup:write",
|
|
@@ -20994,13 +21257,13 @@ function renderStatus(output) {
|
|
|
20994
21257
|
function registerStatusCommands(registry) {
|
|
20995
21258
|
for (const cmd of statusCommands) registry.register(cmd);
|
|
20996
21259
|
}
|
|
20997
|
-
var
|
|
21260
|
+
var defineCommand17, statusShow, statusCommands;
|
|
20998
21261
|
var init_status = __esm({
|
|
20999
21262
|
"../../src/core/commands/status.ts"() {
|
|
21000
21263
|
"use strict";
|
|
21001
21264
|
init_commandRegistry();
|
|
21002
|
-
|
|
21003
|
-
statusShow =
|
|
21265
|
+
defineCommand17 = commandDefiner();
|
|
21266
|
+
statusShow = defineCommand17({
|
|
21004
21267
|
id: "status.show",
|
|
21005
21268
|
action: "status:read",
|
|
21006
21269
|
effect: "read",
|
|
@@ -21039,6 +21302,7 @@ function registerCoreCommands(registry) {
|
|
|
21039
21302
|
registerSetupCommands(registry);
|
|
21040
21303
|
registerContractCommands(registry);
|
|
21041
21304
|
registerDeliveryCommands(registry);
|
|
21305
|
+
registerArtifactsCommands(registry);
|
|
21042
21306
|
}
|
|
21043
21307
|
function coreCommandGroups() {
|
|
21044
21308
|
const registry = new CommandRegistry({ audit: () => {
|
|
@@ -21050,6 +21314,7 @@ var init_all = __esm({
|
|
|
21050
21314
|
"../../src/core/commands/all.ts"() {
|
|
21051
21315
|
"use strict";
|
|
21052
21316
|
init_commandRegistry();
|
|
21317
|
+
init_artifacts();
|
|
21053
21318
|
init_config4();
|
|
21054
21319
|
init_contract2();
|
|
21055
21320
|
init_delivery2();
|
|
@@ -21333,6 +21598,11 @@ function buildCoreCommands(config, store, wiring) {
|
|
|
21333
21598
|
images: imagesHostIO({ log: (l) => console.log(l), now: wiring.now ?? systemClock }),
|
|
21334
21599
|
cliVersion: cliVersionOnHost
|
|
21335
21600
|
},
|
|
21601
|
+
// `artifacts lifecycle` / `artifacts check`: the config's section and the operator's Cloudflare calls.
|
|
21602
|
+
artifacts: {
|
|
21603
|
+
config: async () => (await cfg()).config.artifacts,
|
|
21604
|
+
bucket: artifactsBucketHost()
|
|
21605
|
+
},
|
|
21336
21606
|
env: { bootstrap: bootstrapOnHost },
|
|
21337
21607
|
status: { snapshot: () => (wiring.status ?? unstampedStatus)() },
|
|
21338
21608
|
// `setup init` writes the operator's working directory — the one the CLI runs in.
|
|
@@ -21366,6 +21636,7 @@ var init_commandCatalogue = __esm({
|
|
|
21366
21636
|
init_clock();
|
|
21367
21637
|
init_run();
|
|
21368
21638
|
init_imagesHost();
|
|
21639
|
+
init_artifactsBucket();
|
|
21369
21640
|
init_secretsHost();
|
|
21370
21641
|
init_host3();
|
|
21371
21642
|
init_executor();
|
|
@@ -21584,6 +21855,12 @@ function runPageLink(id) {
|
|
|
21584
21855
|
if (!base) return void 0;
|
|
21585
21856
|
return `${base.replace(/\/+$/, "")}/runs/${encodeURIComponent(id)}`;
|
|
21586
21857
|
}
|
|
21858
|
+
function artifactLink(id, key, token2) {
|
|
21859
|
+
const page2 = runPageLink(id);
|
|
21860
|
+
if (!page2) return void 0;
|
|
21861
|
+
const path = key.split("/").map(encodeURIComponent).join("/");
|
|
21862
|
+
return `${page2}/artifacts/${path}${token2 ? `?t=${encodeURIComponent(token2)}` : ""}`;
|
|
21863
|
+
}
|
|
21587
21864
|
function stripPlatformPrefix(id) {
|
|
21588
21865
|
const i = id.indexOf(":");
|
|
21589
21866
|
return i === -1 ? id : id.slice(i + 1);
|
|
@@ -24256,7 +24533,8 @@ async function readRequest(ctx) {
|
|
|
24256
24533
|
}
|
|
24257
24534
|
function resolveRun(deps, ctx) {
|
|
24258
24535
|
const { msg, directives, history } = ctx;
|
|
24259
|
-
const
|
|
24536
|
+
const fromTurns = lastThreadDirectives(history);
|
|
24537
|
+
const sticky = ctx.stickyAgent !== void 0 ? { ...fromTurns, agent: ctx.stickyAgent } : fromTurns;
|
|
24260
24538
|
const resolved = deps.config.resolve({
|
|
24261
24539
|
channelId: msg.channelId,
|
|
24262
24540
|
userId: msg.userId,
|
|
@@ -24916,9 +25194,24 @@ function providerRouteModel(provider, model, opts = {}) {
|
|
|
24916
25194
|
return result.content.filter((p) => p.type === "text").map((p) => p.text).join("");
|
|
24917
25195
|
};
|
|
24918
25196
|
}
|
|
25197
|
+
function resolveRouted(deps, msg, directives, sticky, preset) {
|
|
25198
|
+
return deps.config.resolve({
|
|
25199
|
+
channelId: msg.channelId,
|
|
25200
|
+
userId: msg.userId,
|
|
25201
|
+
request: {
|
|
25202
|
+
agent: preset,
|
|
25203
|
+
model: directives.model ?? sticky.model,
|
|
25204
|
+
effort: directives.effort ?? sticky.effort
|
|
25205
|
+
}
|
|
25206
|
+
});
|
|
25207
|
+
}
|
|
24919
25208
|
async function routeRequest(deps, ctx) {
|
|
24920
|
-
const { msg, directives, sticky, agentSource, threadLive, root } = ctx;
|
|
25209
|
+
const { msg, directives, sticky, agentSource, threadLive, root, carried } = ctx;
|
|
24921
25210
|
const cfg = deps.config.config;
|
|
25211
|
+
if (carried) {
|
|
25212
|
+
console.log(`[route] ${msg.threadKey} routed to ${carried.preset} as before the restart: ${carried.reason}`);
|
|
25213
|
+
return { kind: "routed", resolved: resolveRouted(deps, msg, directives, sticky, carried.preset), route: carried };
|
|
25214
|
+
}
|
|
24922
25215
|
if (!routingOn(cfg) || agentSource !== "default" || threadLive) return { kind: "unrouted" };
|
|
24923
25216
|
const modelRef2 = cfg.routing?.model ?? cfg.defaults.models["general"];
|
|
24924
25217
|
if (!modelRef2) {
|
|
@@ -24959,15 +25252,7 @@ async function routeRequest(deps, ctx) {
|
|
|
24959
25252
|
console.log(`[route] ${msg.threadKey} not routed (${decision.reason}) \u2014 running ${cfg.defaults.agent}`);
|
|
24960
25253
|
return decision.compoundRejected ? { kind: "unrouted", rejected: { preset: cfg.defaults.agent, reason: decision.reason, model: modelRef2 } } : { kind: "unrouted" };
|
|
24961
25254
|
}
|
|
24962
|
-
const resolved = deps.
|
|
24963
|
-
channelId: msg.channelId,
|
|
24964
|
-
userId: msg.userId,
|
|
24965
|
-
request: {
|
|
24966
|
-
agent: decision.preset,
|
|
24967
|
-
model: directives.model ?? sticky.model,
|
|
24968
|
-
effort: directives.effort ?? sticky.effort
|
|
24969
|
-
}
|
|
24970
|
-
});
|
|
25255
|
+
const resolved = resolveRouted(deps, msg, directives, sticky, decision.preset);
|
|
24971
25256
|
const { parts, collapsed } = decision;
|
|
24972
25257
|
console.log(
|
|
24973
25258
|
`[route] ${msg.threadKey} routed to ${decision.preset} on ${modelRef2}${parts ? ` (${parts.length} parts)` : ""}${collapsed ? ` (compound collapsed: ${collapsed.presets.join("+")})` : ""}: ${decision.reason}`
|
|
@@ -25074,7 +25359,7 @@ var init_tracingExecutor = __esm({
|
|
|
25074
25359
|
});
|
|
25075
25360
|
|
|
25076
25361
|
// ../../src/core/prDescription.ts
|
|
25077
|
-
import { z as
|
|
25362
|
+
import { z as z20 } from "zod";
|
|
25078
25363
|
function parsePrDescription(input) {
|
|
25079
25364
|
return PrDescriptionSchema.parse(input);
|
|
25080
25365
|
}
|
|
@@ -25362,34 +25647,34 @@ var init_prDescription = __esm({
|
|
|
25362
25647
|
"../../src/core/prDescription.ts"() {
|
|
25363
25648
|
"use strict";
|
|
25364
25649
|
init_redact();
|
|
25365
|
-
line2 =
|
|
25366
|
-
prose =
|
|
25367
|
-
TourAnchorSchema =
|
|
25650
|
+
line2 = z20.string().trim().min(1).refine((s) => !/[\r\n]/.test(s), "must be a single line (no embedded newlines)");
|
|
25651
|
+
prose = z20.string().trim().min(1);
|
|
25652
|
+
TourAnchorSchema = z20.object({
|
|
25368
25653
|
// Repo-relative: no leading `/`, no `..` SEGMENT (a filename like `a..b.ts` is fine).
|
|
25369
|
-
path:
|
|
25370
|
-
from:
|
|
25371
|
-
to:
|
|
25654
|
+
path: z20.string().trim().min(1).refine((p) => !p.startsWith("/") && !p.split("/").includes(".."), "path must be repo-relative"),
|
|
25655
|
+
from: z20.number().int().positive(),
|
|
25656
|
+
to: z20.number().int().positive()
|
|
25372
25657
|
}).refine((a) => a.to >= a.from, "to must be >= from");
|
|
25373
|
-
TourStepSchema =
|
|
25658
|
+
TourStepSchema = z20.object({
|
|
25374
25659
|
title: line2,
|
|
25375
25660
|
description: prose,
|
|
25376
25661
|
lookFor: prose.optional(),
|
|
25377
25662
|
anchor: TourAnchorSchema
|
|
25378
25663
|
});
|
|
25379
|
-
PrDescriptionSchema =
|
|
25664
|
+
PrDescriptionSchema = z20.object({
|
|
25380
25665
|
/** The PR title's single source. Metadata for the PR's own title field —
|
|
25381
25666
|
* never rendered into the body (GitHub shows the title itself). */
|
|
25382
25667
|
title: line2,
|
|
25383
25668
|
tldr: prose,
|
|
25384
25669
|
whatWhy: prose,
|
|
25385
|
-
tour:
|
|
25670
|
+
tour: z20.array(TourStepSchema).min(1),
|
|
25386
25671
|
/** Every touched file the Tour steps did not cover, one line each. */
|
|
25387
|
-
remaining:
|
|
25388
|
-
decisions:
|
|
25672
|
+
remaining: z20.array(z20.object({ path: line2, note: prose })),
|
|
25673
|
+
decisions: z20.array(z20.object({ title: line2, rationale: prose })).min(1),
|
|
25389
25674
|
risks: prose,
|
|
25390
|
-
validation:
|
|
25675
|
+
validation: z20.object({
|
|
25391
25676
|
summary: prose.optional(),
|
|
25392
|
-
criteria:
|
|
25677
|
+
criteria: z20.array(z20.object({ criterion: prose, proof: prose })).min(1)
|
|
25393
25678
|
})
|
|
25394
25679
|
});
|
|
25395
25680
|
REPO_RE = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
|
|
@@ -26161,10 +26446,11 @@ async function attachThroughStore(path, name, lead, artifacts, ctx) {
|
|
|
26161
26446
|
}
|
|
26162
26447
|
ctx.publish?.({ type: "artifact", direction: "out", key, name, size, contentType });
|
|
26163
26448
|
if (!ctx.uploadTicket) {
|
|
26164
|
-
const
|
|
26449
|
+
const link = artifacts.artifactUrl?.(key);
|
|
26450
|
+
const where = link ? ` \u2014 ${link}` : ` is on the run page as ${key}`;
|
|
26165
26451
|
await artifacts.reply(`${lead}
|
|
26166
|
-
\u{1F4CE} ${name} (${size} bytes)
|
|
26167
|
-
return `attached ${name} (${size} bytes) to the run page; this conversation's channel takes no file uploads, so the lead and the
|
|
26452
|
+
\u{1F4CE} ${name} (${size} bytes)${where}`);
|
|
26453
|
+
return `attached ${name} (${size} bytes) to the run page as ${key}; this conversation's channel takes no file uploads, so the lead and the file's link were posted instead`;
|
|
26168
26454
|
}
|
|
26169
26455
|
const kept = "the file is kept on the run page";
|
|
26170
26456
|
let ticket;
|
|
@@ -26631,7 +26917,7 @@ var init_runs2 = __esm({
|
|
|
26631
26917
|
});
|
|
26632
26918
|
|
|
26633
26919
|
// ../../src/tools/workspace.ts
|
|
26634
|
-
import { z as
|
|
26920
|
+
import { z as z21 } from "zod";
|
|
26635
26921
|
var bashTool, readFileTool, writeFileTool, NAME_STATUS_MARK, NAME_STATUS_MARK_LINE, OUTPUT_CUT_RE, diffDigestTool, submitVerdictTool, submitDispositionsTool, submitPrDescriptionTool, handoffEntry, submitHandoffTool, updateStatusTool, TOOLSETS;
|
|
26636
26922
|
var init_workspace = __esm({
|
|
26637
26923
|
"../../src/tools/workspace.ts"() {
|
|
@@ -26930,7 +27216,7 @@ ${raw.trim()}`;
|
|
|
26930
27216
|
try {
|
|
26931
27217
|
desc = parsePrDescription(input);
|
|
26932
27218
|
} catch (err2) {
|
|
26933
|
-
const detail = err2 instanceof
|
|
27219
|
+
const detail = err2 instanceof z21.ZodError ? err2.issues.map((i) => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ") : String(err2);
|
|
26934
27220
|
return `error: invalid PR description \u2014 ${detail}`;
|
|
26935
27221
|
}
|
|
26936
27222
|
ctx.onPrDescription?.(desc);
|
|
@@ -29213,7 +29499,8 @@ async function reserveRun(deps, ctx) {
|
|
|
29213
29499
|
root,
|
|
29214
29500
|
parentRunId,
|
|
29215
29501
|
coordinator,
|
|
29216
|
-
seed
|
|
29502
|
+
seed,
|
|
29503
|
+
route: route3
|
|
29217
29504
|
} = ctx;
|
|
29218
29505
|
if (!resume && !restart) {
|
|
29219
29506
|
const requestRow = durableInboxMessage(msg, msg.text, receivedAt);
|
|
@@ -29242,6 +29529,7 @@ async function reserveRun(deps, ctx) {
|
|
|
29242
29529
|
...parentRunId !== void 0 ? { parentRunId } : {},
|
|
29243
29530
|
...coordinatorFields(coordinator),
|
|
29244
29531
|
...seed !== void 0 ? { seed } : {},
|
|
29532
|
+
...route3 !== void 0 ? { route: route3 } : {},
|
|
29245
29533
|
request: requestRow
|
|
29246
29534
|
},
|
|
29247
29535
|
card: card.handle ?? null,
|
|
@@ -29472,7 +29760,9 @@ async function claimRun(deps, ctx) {
|
|
|
29472
29760
|
root,
|
|
29473
29761
|
parentRunId,
|
|
29474
29762
|
coordinator,
|
|
29475
|
-
seed
|
|
29763
|
+
seed,
|
|
29764
|
+
route: route3,
|
|
29765
|
+
seedLog
|
|
29476
29766
|
} = ctx;
|
|
29477
29767
|
const { resident, binding } = selection;
|
|
29478
29768
|
let ledgerRun = ctx.ledgerRun;
|
|
@@ -29503,6 +29793,7 @@ async function claimRun(deps, ctx) {
|
|
|
29503
29793
|
...parentRunId !== void 0 ? { parentRunId } : {},
|
|
29504
29794
|
...coordinatorFields(coordinator),
|
|
29505
29795
|
...seed !== void 0 ? { seed } : {},
|
|
29796
|
+
...route3 !== void 0 ? { route: route3 } : {},
|
|
29506
29797
|
selection: resident === true ? "resident" : "sandbox",
|
|
29507
29798
|
...binding?.workspace !== void 0 ? { workspace: binding.workspace } : {},
|
|
29508
29799
|
...requestRow !== void 0 ? { request: requestRow } : {}
|
|
@@ -29516,8 +29807,9 @@ async function claimRun(deps, ctx) {
|
|
|
29516
29807
|
({ name, description, inputSchema }) => ({ name, description, inputSchema })
|
|
29517
29808
|
),
|
|
29518
29809
|
// The seed carries the EFFECTIVE budget, so a resume runs on what
|
|
29519
|
-
// this run was admitted with, not on the preset's own number
|
|
29520
|
-
seed
|
|
29810
|
+
// this run was admitted with, not on the preset's own number — and,
|
|
29811
|
+
// for a seed read from the log, the rows it reuses (session-log item 9).
|
|
29812
|
+
seed: { messages, budgetMs: profile.minutes * 6e4, ...seedLog ? { log: seedLog } : {} },
|
|
29521
29813
|
// A stop asked of another container (`/runs/stop` there) reaches this
|
|
29522
29814
|
// run through its heartbeat and is honored like a local one; a fence
|
|
29523
29815
|
// (another generation took the run) is a hard stop — nothing more may
|
|
@@ -29587,7 +29879,7 @@ function writeFileScripts(path, content) {
|
|
|
29587
29879
|
chunks.push(content.slice(i, i + WRITE_CHUNK_CHARS));
|
|
29588
29880
|
const dir = path.slice(0, path.lastIndexOf("/")) || ".";
|
|
29589
29881
|
return chunks.map(
|
|
29590
|
-
(chunk, i) => i === 0 ? `mkdir -p ${shellQuote(dir)} &&
|
|
29882
|
+
(chunk, i) => i === 0 ? `umask 077 && mkdir -p ${shellQuote(dir)} && printf '%s' ${shellQuote(chunk)} > ${shellQuote(path)}` : `printf '%s' ${shellQuote(chunk)} >> ${shellQuote(path)}`
|
|
29591
29883
|
);
|
|
29592
29884
|
}
|
|
29593
29885
|
function startScript(start3) {
|
|
@@ -29598,7 +29890,7 @@ function startScript(start3) {
|
|
|
29598
29890
|
`pi ${args.map(shellQuote).join(" ")} <&3 2>>${shellQuote(paths.errLog)} | ${LOG_FILTER} >> ${shellQuote(paths.log)}`
|
|
29599
29891
|
].join("; ");
|
|
29600
29892
|
return [
|
|
29601
|
-
`mkdir -p ${shellQuote(paths.dir)} ${shellQuote(paths.sessionDir)} ${shellQuote(paths.commandDir)}`,
|
|
29893
|
+
`(umask 077 && mkdir -p ${shellQuote(paths.dir)} ${shellQuote(paths.sessionDir)} ${shellQuote(paths.commandDir)})`,
|
|
29602
29894
|
`rm -f ${shellQuote(paths.fifo)}`,
|
|
29603
29895
|
`mkfifo -m 600 ${shellQuote(paths.fifo)}`,
|
|
29604
29896
|
`: > ${shellQuote(paths.log)}`,
|
|
@@ -29626,6 +29918,9 @@ function killScript(pid) {
|
|
|
29626
29918
|
function tailScript(path, bytes) {
|
|
29627
29919
|
return `tail -c ${bytes} ${shellQuote(path)} 2>/dev/null || true`;
|
|
29628
29920
|
}
|
|
29921
|
+
function removeScript(dir) {
|
|
29922
|
+
return `rm -rf ${shellQuote(dir)}`;
|
|
29923
|
+
}
|
|
29629
29924
|
function stdoutOf(operation, out) {
|
|
29630
29925
|
const exit = parseExitPrefix(out);
|
|
29631
29926
|
if (exit.failed) throw new PiContainerError(operation, out);
|
|
@@ -29694,6 +29989,9 @@ var init_container = __esm({
|
|
|
29694
29989
|
return "";
|
|
29695
29990
|
}
|
|
29696
29991
|
}
|
|
29992
|
+
async remove(paths) {
|
|
29993
|
+
stdoutOf("remove", await this.exec(removeScript(paths.dir)));
|
|
29994
|
+
}
|
|
29697
29995
|
exec(script, env) {
|
|
29698
29996
|
return this.executor.exec(script, { timeoutMs: OP_TIMEOUT_MS, ...env ? { env } : {} });
|
|
29699
29997
|
}
|
|
@@ -30370,8 +30668,8 @@ function piBuiltinToolsFor(identity2) {
|
|
|
30370
30668
|
function piThinkingLevel(effort2) {
|
|
30371
30669
|
return effort2;
|
|
30372
30670
|
}
|
|
30373
|
-
function piRunPaths(runId3
|
|
30374
|
-
const dir =
|
|
30671
|
+
function piRunPaths(runId3) {
|
|
30672
|
+
const dir = `/tmp/switchboard-pi-${runId3}`;
|
|
30375
30673
|
return {
|
|
30376
30674
|
dir,
|
|
30377
30675
|
agentDir: `${dir}/agent`,
|
|
@@ -30618,7 +30916,7 @@ async function runPiHarness(deps, run2) {
|
|
|
30618
30916
|
emit({ type: "run_note", kind, summary, ...mode ? { mode } : {} });
|
|
30619
30917
|
};
|
|
30620
30918
|
const bridge = new PiBridge({ emit, onProgress: run2.onProgress, agentSpan, clock: clock3 });
|
|
30621
|
-
const paths = piRunPaths(run2.runId
|
|
30919
|
+
const paths = piRunPaths(run2.runId);
|
|
30622
30920
|
const remainingMs = run2.resume?.remainingMs ?? run2.agent.maxMinutes * 6e4;
|
|
30623
30921
|
const deadline = now() + remainingMs;
|
|
30624
30922
|
const warnAt = deadline - Math.min(3 * 6e4, run2.agent.maxMinutes * 15e3);
|
|
@@ -30890,6 +31188,8 @@ async function runPiHarness(deps, run2) {
|
|
|
30890
31188
|
forget();
|
|
30891
31189
|
if (pid !== void 0) await container.kill(pid).catch(() => {
|
|
30892
31190
|
});
|
|
31191
|
+
await container.remove(paths).catch(() => {
|
|
31192
|
+
});
|
|
30893
31193
|
agentSpan?.end(hardStopped || bypass ? "error" : "ok");
|
|
30894
31194
|
}
|
|
30895
31195
|
}
|
|
@@ -31564,12 +31864,11 @@ async function runLoop2(deps, ctx) {
|
|
|
31564
31864
|
const uploadTicket = io.uploadTicket?.bind(io);
|
|
31565
31865
|
const nextStagedIndex = ctx.stagingIndex ?? stagingIndex();
|
|
31566
31866
|
let artifactSeq = 0;
|
|
31567
|
-
const runUrl = runPageLink(run2.id);
|
|
31568
31867
|
const artifacts = deps.artifacts ? {
|
|
31569
31868
|
store: deps.artifacts,
|
|
31570
31869
|
runId: run2.id,
|
|
31571
31870
|
nextSeq: () => ++artifactSeq,
|
|
31572
|
-
|
|
31871
|
+
artifactUrl: (key) => artifactLink(run2.id, key, run2.token),
|
|
31573
31872
|
reply: (text) => io.reply(text)
|
|
31574
31873
|
} : void 0;
|
|
31575
31874
|
const toolContext = {
|
|
@@ -33309,15 +33608,7 @@ var init_settle = __esm({
|
|
|
33309
33608
|
});
|
|
33310
33609
|
|
|
33311
33610
|
// ../../src/core/dispatch/lineage.ts
|
|
33312
|
-
|
|
33313
|
-
let newest;
|
|
33314
|
-
try {
|
|
33315
|
-
const page2 = await service.listRuns({ status: "all", visibleTo: { kind: "all" }, threadKey, limit: 1 });
|
|
33316
|
-
newest = page2.runs[0];
|
|
33317
|
-
} catch (err2) {
|
|
33318
|
-
console.warn(`[lineage] ${threadKey}: thread read failed \u2014 ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
33319
|
-
return void 0;
|
|
33320
|
-
}
|
|
33611
|
+
function lineageOf(newest) {
|
|
33321
33612
|
if (newest === void 0 || newest.parentRunId === void 0) return void 0;
|
|
33322
33613
|
return {
|
|
33323
33614
|
parentRunId: newest.parentRunId,
|
|
@@ -33374,6 +33665,161 @@ var init_lineage = __esm({
|
|
|
33374
33665
|
}
|
|
33375
33666
|
});
|
|
33376
33667
|
|
|
33668
|
+
// ../../src/core/runLedger/sessionLog.ts
|
|
33669
|
+
function sessionKey(threadKey, agent) {
|
|
33670
|
+
return `${threadKey}:${agent ?? "-"}`;
|
|
33671
|
+
}
|
|
33672
|
+
function requestIndex(seed) {
|
|
33673
|
+
for (let i = seed.length - 1; i >= 0; i--) if (seed[i].role === "user") return i;
|
|
33674
|
+
return 0;
|
|
33675
|
+
}
|
|
33676
|
+
var DEFAULT_SESSION_LOG_MAX_BYTES;
|
|
33677
|
+
var init_sessionLog = __esm({
|
|
33678
|
+
"../../src/core/runLedger/sessionLog.ts"() {
|
|
33679
|
+
"use strict";
|
|
33680
|
+
init_runRecord();
|
|
33681
|
+
init_runRecord();
|
|
33682
|
+
DEFAULT_SESSION_LOG_MAX_BYTES = DEFAULT_RETENTION_POLICY.sessionLogMaxBytes;
|
|
33683
|
+
}
|
|
33684
|
+
});
|
|
33685
|
+
|
|
33686
|
+
// ../../src/core/dispatch/thread.ts
|
|
33687
|
+
async function readThread(service, threadKey) {
|
|
33688
|
+
try {
|
|
33689
|
+
const page2 = await service.listRuns({
|
|
33690
|
+
status: "all",
|
|
33691
|
+
visibleTo: { kind: "all" },
|
|
33692
|
+
threadKey,
|
|
33693
|
+
limit: THREAD_READ_LIMIT
|
|
33694
|
+
});
|
|
33695
|
+
return page2.runs;
|
|
33696
|
+
} catch (err2) {
|
|
33697
|
+
console.warn(`[thread] ${threadKey}: thread read failed \u2014 ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
33698
|
+
return void 0;
|
|
33699
|
+
}
|
|
33700
|
+
}
|
|
33701
|
+
function continuable(run2) {
|
|
33702
|
+
return run2.finished && run2.session !== void 0 && run2.agent !== void 0;
|
|
33703
|
+
}
|
|
33704
|
+
function stickyAgentOf(runs, onPi) {
|
|
33705
|
+
const newest = runs[0];
|
|
33706
|
+
if (newest === void 0 || !continuable(newest) || !onPi(newest.agent)) return void 0;
|
|
33707
|
+
return newest.agent;
|
|
33708
|
+
}
|
|
33709
|
+
function previousRunOf(runs, agent) {
|
|
33710
|
+
const run2 = runs.find((r) => r.agent === agent && continuable(r));
|
|
33711
|
+
if (run2 === void 0) return void 0;
|
|
33712
|
+
return {
|
|
33713
|
+
...run2.finishedAt !== void 0 ? { finishedAt: run2.finishedAt } : {},
|
|
33714
|
+
broken: run2.session.range === "broken"
|
|
33715
|
+
};
|
|
33716
|
+
}
|
|
33717
|
+
var THREAD_READ_LIMIT;
|
|
33718
|
+
var init_thread = __esm({
|
|
33719
|
+
"../../src/core/dispatch/thread.ts"() {
|
|
33720
|
+
"use strict";
|
|
33721
|
+
THREAD_READ_LIMIT = 8;
|
|
33722
|
+
}
|
|
33723
|
+
});
|
|
33724
|
+
|
|
33725
|
+
// ../../src/core/dispatch/seed.ts
|
|
33726
|
+
function sessionSeed(input) {
|
|
33727
|
+
const { tail, previous, history, request } = input;
|
|
33728
|
+
const { from, transcript } = tail;
|
|
33729
|
+
if (from === 0 && transcript.turns === 0) return void 0;
|
|
33730
|
+
const notes = [];
|
|
33731
|
+
const messages = [];
|
|
33732
|
+
const compactions = transcript.compactions;
|
|
33733
|
+
const afterCompaction = compactions.reduce((n2, c) => Math.max(n2, c.before), 0);
|
|
33734
|
+
let start3 = -1;
|
|
33735
|
+
for (let i = afterCompaction; i < transcript.messages.length; i++) {
|
|
33736
|
+
const m = transcript.messages[i];
|
|
33737
|
+
if (m.role === "user" && m.content.some((p) => p.type === "text")) {
|
|
33738
|
+
start3 = i;
|
|
33739
|
+
break;
|
|
33740
|
+
}
|
|
33741
|
+
}
|
|
33742
|
+
const summary = compactions.length ? compactions[compactions.length - 1].entry.summary : void 0;
|
|
33743
|
+
const logFrom = start3 < 0 ? from + transcript.turns : from + start3 + compactions.length;
|
|
33744
|
+
const kept = start3 < 0 ? [] : transcript.messages.slice(start3).map(withoutThinking);
|
|
33745
|
+
if (kept.length === 0) {
|
|
33746
|
+
notes.push(
|
|
33747
|
+
transcript.turns === 0 ? "session seed: the log's newest turn alone is over the seed budget \u2014 the run starts from the request" : "session seed: no user text turn in the tail within the seed budget \u2014 the run starts from the request"
|
|
33748
|
+
);
|
|
33749
|
+
}
|
|
33750
|
+
messages.push(...kept);
|
|
33751
|
+
const last = kept[kept.length - 1];
|
|
33752
|
+
if (last?.role === "assistant") {
|
|
33753
|
+
const calls = last.content.filter((p) => p.type === "tool_use");
|
|
33754
|
+
if (calls.length > 0) {
|
|
33755
|
+
messages.push({
|
|
33756
|
+
role: "user",
|
|
33757
|
+
content: calls.map((c) => ({
|
|
33758
|
+
type: "tool_result",
|
|
33759
|
+
toolUseId: c.id,
|
|
33760
|
+
content: settledResult(c.name),
|
|
33761
|
+
isError: true
|
|
33762
|
+
}))
|
|
33763
|
+
});
|
|
33764
|
+
}
|
|
33765
|
+
}
|
|
33766
|
+
if (previous?.broken) messages.push({ role: "user", content: [{ type: "text", text: GAP_MARKER }] });
|
|
33767
|
+
if (previous?.finishedAt === void 0) {
|
|
33768
|
+
notes.push(
|
|
33769
|
+
"session seed: the previous run's end is unknown, so the lines written since could not be told apart \u2014 only the request follows the tail"
|
|
33770
|
+
);
|
|
33771
|
+
} else {
|
|
33772
|
+
const end = previous.finishedAt;
|
|
33773
|
+
for (const h of history) {
|
|
33774
|
+
if (h.role !== "user" || h.at === void 0 || h.at <= end) continue;
|
|
33775
|
+
messages.push({ role: "user", content: turnContent(h.text, h.images, h.documents) });
|
|
33776
|
+
}
|
|
33777
|
+
}
|
|
33778
|
+
messages.push({ role: "user", content: turnContent(request.text, request.images, request.documents) });
|
|
33779
|
+
return {
|
|
33780
|
+
messages,
|
|
33781
|
+
log: { from: logFrom, turns: kept.length },
|
|
33782
|
+
...summary !== void 0 ? { summary } : {},
|
|
33783
|
+
notes
|
|
33784
|
+
};
|
|
33785
|
+
}
|
|
33786
|
+
async function sessionSeedFor(input) {
|
|
33787
|
+
const key = sessionKey(input.threadKey, input.agent);
|
|
33788
|
+
let tail;
|
|
33789
|
+
try {
|
|
33790
|
+
tail = await input.ledger.readSessionTail(key, SEED_BUDGET_BYTES);
|
|
33791
|
+
} catch (err2) {
|
|
33792
|
+
const why = err2 instanceof Error ? err2.message : String(err2);
|
|
33793
|
+
return { notes: [`session seed: the log ${key} could not be read (${why}) \u2014 the run seeds from the channel`] };
|
|
33794
|
+
}
|
|
33795
|
+
const seed = sessionSeed({
|
|
33796
|
+
tail,
|
|
33797
|
+
previous: previousRunOf(input.thread, input.agent),
|
|
33798
|
+
history: input.history,
|
|
33799
|
+
request: input.request
|
|
33800
|
+
});
|
|
33801
|
+
return seed ? { seed, notes: seed.notes } : { notes: [] };
|
|
33802
|
+
}
|
|
33803
|
+
function withoutThinking(message2) {
|
|
33804
|
+
if (message2.role !== "assistant") return message2;
|
|
33805
|
+
const content = message2.content.filter((p) => p.type !== "thinking" && p.type !== "redacted_thinking");
|
|
33806
|
+
if (content.length === message2.content.length) return message2;
|
|
33807
|
+
return { ...message2, content: content.length ? content : [{ type: "text", text: "(reasoning omitted)" }] };
|
|
33808
|
+
}
|
|
33809
|
+
var SEED_BUDGET_TOKENS, SEED_BUDGET_BYTES, GAP_MARKER, settledResult;
|
|
33810
|
+
var init_seed = __esm({
|
|
33811
|
+
"../../src/core/dispatch/seed.ts"() {
|
|
33812
|
+
"use strict";
|
|
33813
|
+
init_sessionLog();
|
|
33814
|
+
init_messages();
|
|
33815
|
+
init_thread();
|
|
33816
|
+
SEED_BUDGET_TOKENS = 6e4;
|
|
33817
|
+
SEED_BUDGET_BYTES = SEED_BUDGET_TOKENS * 4;
|
|
33818
|
+
GAP_MARKER = "[The log of this conversation ends short of what the previous run saw: its connection to the ledger broke, so its later turns and its final reply are not here.]";
|
|
33819
|
+
settledResult = (toolName) => `The run that made this call ended before this ${toolName} call's result was recorded; its effects are unknown \u2014 re-check them before repeating it.`;
|
|
33820
|
+
}
|
|
33821
|
+
});
|
|
33822
|
+
|
|
33377
33823
|
// ../../src/core/runEnding.ts
|
|
33378
33824
|
function createRunEnding(deps) {
|
|
33379
33825
|
const log = deps.log ?? console.error;
|
|
@@ -33511,7 +33957,8 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
33511
33957
|
const { directives, history } = await readRequest({ msg, io, root });
|
|
33512
33958
|
if (await answerOperation(deps, { msg, io, ending, trace, directives, history })) return ended;
|
|
33513
33959
|
const runsService = deps.runs ?? createRunsService({ registry, store: deps.runStore });
|
|
33514
|
-
const
|
|
33960
|
+
const thread = opts.parent || opts.coordinator || resume || restart || history.length === 0 ? void 0 : await readThread(runsService, msg.threadKey);
|
|
33961
|
+
const lineage = lineageOf(thread?.[0]);
|
|
33515
33962
|
const parent = opts.parent ?? (lineage ? lineageParent(lineage) : void 0);
|
|
33516
33963
|
const tellLineage = async (heard) => {
|
|
33517
33964
|
if (!lineage) return;
|
|
@@ -33522,18 +33969,40 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
33522
33969
|
heard
|
|
33523
33970
|
);
|
|
33524
33971
|
};
|
|
33525
|
-
const
|
|
33972
|
+
const harnessBlock = deps.config.config.harness;
|
|
33973
|
+
const onPi = (name) => {
|
|
33974
|
+
const def = AGENTS[name];
|
|
33975
|
+
return def !== void 0 && effectiveHarness(def, harnessBlock) === "pi";
|
|
33976
|
+
};
|
|
33977
|
+
const stickyAgent = thread ? stickyAgentOf(thread, onPi) : void 0;
|
|
33978
|
+
const settled = resolveRun(deps, {
|
|
33979
|
+
msg,
|
|
33980
|
+
directives,
|
|
33981
|
+
history,
|
|
33982
|
+
...stickyAgent !== void 0 ? { stickyAgent } : {}
|
|
33983
|
+
});
|
|
33526
33984
|
const { sticky } = settled;
|
|
33527
33985
|
let { resolved, agentSource } = settled;
|
|
33528
33986
|
let route3;
|
|
33529
33987
|
const threadLive = admission.get(msg.threadKey) !== void 0 || !resume && !restart && deps.threadsElsewhere.get(msg.threadKey) !== void 0;
|
|
33530
|
-
const routing = await routeRequest(deps, {
|
|
33988
|
+
const routing = await routeRequest(deps, {
|
|
33989
|
+
msg,
|
|
33990
|
+
directives,
|
|
33991
|
+
sticky,
|
|
33992
|
+
agentSource,
|
|
33993
|
+
threadLive,
|
|
33994
|
+
root,
|
|
33995
|
+
// A restart is the same run under the same card: the row's decision
|
|
33996
|
+
// (run-history item 35) is the route, re-resolved, never re-asked.
|
|
33997
|
+
...restart?.row.meta.route ? { carried: restart.row.meta.route } : {}
|
|
33998
|
+
});
|
|
33531
33999
|
if (routing.kind === "routed") {
|
|
33532
34000
|
resolved = routing.resolved;
|
|
33533
34001
|
route3 = routing.route;
|
|
33534
34002
|
agentSource = "route";
|
|
33535
34003
|
}
|
|
33536
34004
|
const routeEvent = routing.kind === "routed" ? routing.route : routing.rejected;
|
|
34005
|
+
if (resume?.row.meta.route) route3 = resume.row.meta.route;
|
|
33537
34006
|
if ((await authorizeAgent(deps, { msg, io, refuse: refuse3, agentName: resolved.agentName })).kind === "refused")
|
|
33538
34007
|
return ended;
|
|
33539
34008
|
const agent = resolved.agentName === "ship" ? shipPresetFor(deps.config.config.ship) : getAgent(resolved.agentName);
|
|
@@ -33649,8 +34118,23 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
33649
34118
|
}
|
|
33650
34119
|
const contractBlock = opts.contract ? renderContract(opts.contract, { maxChars: DEFAULT_CONTRACT_MAX_CHARS }).text : void 0;
|
|
33651
34120
|
const requestText = route3?.parts ? compoundBrief(directives.text, route3.parts) : directives.text;
|
|
33652
|
-
const
|
|
33653
|
-
|
|
34121
|
+
const fromSession = !resume && !opts.seed && thread && effectiveHarness(agent, harnessBlock) === "pi" ? await sessionSeedFor({
|
|
34122
|
+
ledger: deps.runLedger,
|
|
34123
|
+
threadKey: msg.threadKey,
|
|
34124
|
+
agent: agent.name,
|
|
34125
|
+
thread,
|
|
34126
|
+
history,
|
|
34127
|
+
request: {
|
|
34128
|
+
text: requestText,
|
|
34129
|
+
...msg.images ? { images: msg.images } : {},
|
|
34130
|
+
...msg.documents ? { documents: msg.documents } : {}
|
|
34131
|
+
}
|
|
34132
|
+
}) : void 0;
|
|
34133
|
+
const session = fromSession?.seed;
|
|
34134
|
+
const seedNotes = fromSession?.notes ?? [];
|
|
34135
|
+
const seed = opts.seed ? "parent" : session ? "session" : "channel";
|
|
34136
|
+
const seedTurns = opts.seed ?? (session ? textTurnsOf(session.messages.slice(0, -1)) : void 0);
|
|
34137
|
+
const built = session ? session.messages : buildMessages(opts.seed ?? history, requestText, msg.images, msg.documents);
|
|
33654
34138
|
const messages = resume ? resume.plan.messages : contractBlock !== void 0 && agent.name !== "review" ? withContractInFirstUserTurn(built, contractBlock) : built;
|
|
33655
34139
|
const headPreflight = await authorizePrHead({
|
|
33656
34140
|
msg,
|
|
@@ -33688,12 +34172,14 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
33688
34172
|
parentRunId,
|
|
33689
34173
|
coordinator,
|
|
33690
34174
|
seed,
|
|
33691
|
-
...
|
|
34175
|
+
...seedTurns ? { seedTurns } : {},
|
|
33692
34176
|
agentSource,
|
|
33693
34177
|
...routeEvent ? { route: routeEvent } : {}
|
|
33694
34178
|
});
|
|
33695
34179
|
const { run: run2, runId: runId3, channelVisibility, liveUrl, publishText, publishMeta } = registration;
|
|
33696
34180
|
registered = run2;
|
|
34181
|
+
for (const summary of seedNotes)
|
|
34182
|
+
registry.publish(run2.id, { type: "run_note", kind: "seed", summary: oneLine(summary), at: clock3() });
|
|
33697
34183
|
await tellLineage({ kind: "started", runId: runId3 });
|
|
33698
34184
|
const staged = !resume && deps.artifacts && msg.staged && msg.staged.length > 0 ? msg.staged : [];
|
|
33699
34185
|
const nextStagedIndex = stagingIndex();
|
|
@@ -33717,6 +34203,7 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
33717
34203
|
restart,
|
|
33718
34204
|
card,
|
|
33719
34205
|
hooks: reservationHooks,
|
|
34206
|
+
route: route3,
|
|
33720
34207
|
admitted,
|
|
33721
34208
|
root,
|
|
33722
34209
|
parentRunId,
|
|
@@ -33852,11 +34339,13 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
33852
34339
|
resume,
|
|
33853
34340
|
ledgerRun,
|
|
33854
34341
|
card,
|
|
34342
|
+
route: route3,
|
|
33855
34343
|
clock: clock3,
|
|
33856
34344
|
root,
|
|
33857
34345
|
parentRunId,
|
|
33858
34346
|
coordinator,
|
|
33859
|
-
seed
|
|
34347
|
+
seed,
|
|
34348
|
+
...session ? { seedLog: session.log } : {}
|
|
33860
34349
|
});
|
|
33861
34350
|
const { spawn: spawn7, runs, steer, wait } = runToolCapabilities(
|
|
33862
34351
|
{ core: deps, dispatch, registry, clock: clock3 },
|
|
@@ -34037,6 +34526,9 @@ var init_dispatcher = __esm({
|
|
|
34037
34526
|
init_codingChild();
|
|
34038
34527
|
init_settle();
|
|
34039
34528
|
init_lineage();
|
|
34529
|
+
init_seed();
|
|
34530
|
+
init_thread();
|
|
34531
|
+
init_select();
|
|
34040
34532
|
init_spawn();
|
|
34041
34533
|
init_runsService();
|
|
34042
34534
|
init_runRegistry();
|
|
@@ -34438,24 +34930,6 @@ var init_flusher = __esm({
|
|
|
34438
34930
|
}
|
|
34439
34931
|
});
|
|
34440
34932
|
|
|
34441
|
-
// ../../src/core/runLedger/sessionLog.ts
|
|
34442
|
-
function sessionKey(threadKey, agent) {
|
|
34443
|
-
return `${threadKey}:${agent ?? "-"}`;
|
|
34444
|
-
}
|
|
34445
|
-
function requestIndex(seed) {
|
|
34446
|
-
for (let i = seed.length - 1; i >= 0; i--) if (seed[i].role === "user") return i;
|
|
34447
|
-
return 0;
|
|
34448
|
-
}
|
|
34449
|
-
var DEFAULT_SESSION_LOG_MAX_BYTES;
|
|
34450
|
-
var init_sessionLog = __esm({
|
|
34451
|
-
"../../src/core/runLedger/sessionLog.ts"() {
|
|
34452
|
-
"use strict";
|
|
34453
|
-
init_runRecord();
|
|
34454
|
-
init_runRecord();
|
|
34455
|
-
DEFAULT_SESSION_LOG_MAX_BYTES = DEFAULT_RETENTION_POLICY.sessionLogMaxBytes;
|
|
34456
|
-
}
|
|
34457
|
-
});
|
|
34458
|
-
|
|
34459
34933
|
// ../../src/core/runLedger/types.ts
|
|
34460
34934
|
var LEASE_MS, HEARTBEAT_MS, APPEND_FLUSH_MS, APPEND_FLUSH_EVENTS, TRANSCRIPT_REQUEST_BYTES, TRANSCRIPT_PART_BYTES, ATTACHMENT_REF_BYTES, GEN_PATTERN;
|
|
34461
34935
|
var init_types5 = __esm({
|
|
@@ -34508,7 +34982,15 @@ function createLedgerWriteThrough(opts) {
|
|
|
34508
34982
|
if (opts2.seed) {
|
|
34509
34983
|
const key = sessionKey(req.threadKey, req.meta.agent);
|
|
34510
34984
|
const next = await ledger.sessionTail(key);
|
|
34511
|
-
|
|
34985
|
+
let seedFrom = next;
|
|
34986
|
+
if (opts2.log) {
|
|
34987
|
+
if (opts2.log.from + opts2.log.turns === next) seedFrom = opts2.log.from;
|
|
34988
|
+
else
|
|
34989
|
+
warn(
|
|
34990
|
+
`[ledger] ${req.threadKey} run ${req.runId}: the seed names log rows ${opts2.log.from}..${opts2.log.from + opts2.log.turns - 1} but the log's tail is ${next} \u2014 the whole seed is written as new rows`
|
|
34991
|
+
);
|
|
34992
|
+
}
|
|
34993
|
+
session = { key, seedFrom, request: seedFrom + requestIndex(opts2.seed), range: { from: next } };
|
|
34512
34994
|
}
|
|
34513
34995
|
const result = await ledger.claim({
|
|
34514
34996
|
runId: req.runId,
|
|
@@ -34669,7 +35151,8 @@ function createLedgerWriteThrough(opts) {
|
|
|
34669
35151
|
* closes `interrupted`. */
|
|
34670
35152
|
async seed(messages, budgetMs) {
|
|
34671
35153
|
const base = this.session?.seedFrom ?? 0;
|
|
34672
|
-
const
|
|
35154
|
+
const reused = this.session && this.session.range !== "broken" ? this.session.range.from - this.session.seedFrom : 0;
|
|
35155
|
+
const turns = messages.slice(reused).map((message2, i) => ({ idx: base + reused + i, message: message2 }));
|
|
34673
35156
|
try {
|
|
34674
35157
|
const seeded = await ledger.seed(this.runId, gen, turns, this.session?.key);
|
|
34675
35158
|
if (!seeded.ok) {
|
|
@@ -34839,7 +35322,7 @@ function createLedgerWriteThrough(opts) {
|
|
|
34839
35322
|
const seed = req.seed?.messages;
|
|
34840
35323
|
if (reserved instanceof TrackedRun) {
|
|
34841
35324
|
if (!reserved.tracked()) return void 0;
|
|
34842
|
-
const claimed3 = await claim(req, seed ? { seed } : {});
|
|
35325
|
+
const claimed3 = await claim(req, seed ? { seed, ...req.seed?.log ? { log: req.seed.log } : {} } : {});
|
|
34843
35326
|
if (claimed3.outcome === "fenced") {
|
|
34844
35327
|
reserved.detach("promotion refused (fenced)");
|
|
34845
35328
|
return void 0;
|
|
@@ -34853,7 +35336,7 @@ function createLedgerWriteThrough(opts) {
|
|
|
34853
35336
|
if (req.seed) await reserved.seed(req.seed.messages, req.seed.budgetMs);
|
|
34854
35337
|
return reserved;
|
|
34855
35338
|
}
|
|
34856
|
-
const claimed2 = await claim(req, seed ? { seed } : {});
|
|
35339
|
+
const claimed2 = await claim(req, seed ? { seed, ...req.seed?.log ? { log: req.seed.log } : {} } : {});
|
|
34857
35340
|
if (claimed2.outcome === "fenced") {
|
|
34858
35341
|
warn(`[ledger] ${req.threadKey} not tracked: run ${req.runId} is live under another generation`);
|
|
34859
35342
|
return void 0;
|
|
@@ -34902,6 +35385,7 @@ function createLedgerWriteThrough(opts) {
|
|
|
34902
35385
|
return [];
|
|
34903
35386
|
}
|
|
34904
35387
|
},
|
|
35388
|
+
readSessionTail: (key, maxBytes) => ledger.readSessionTail(key, maxBytes),
|
|
34905
35389
|
async handoff() {
|
|
34906
35390
|
const candidates = [...live].filter((r) => r.resumable && r.tracked() && !r.handedOff);
|
|
34907
35391
|
if (candidates.length === 0) return { marked: [] };
|
|
@@ -34952,6 +35436,9 @@ var init_writeThrough = __esm({
|
|
|
34952
35436
|
async readInbox(_runId, _afterSeq) {
|
|
34953
35437
|
return [];
|
|
34954
35438
|
}
|
|
35439
|
+
async readSessionTail(_key, _maxBytes) {
|
|
35440
|
+
return { from: 0, transcript: { complete: true, turns: 0, messages: [], compactions: [] } };
|
|
35441
|
+
}
|
|
34955
35442
|
async handoff() {
|
|
34956
35443
|
return { marked: [] };
|
|
34957
35444
|
}
|
|
@@ -36865,7 +37352,8 @@ ${file.text}`));
|
|
|
36865
37352
|
if (STATUS_PREFIXES.some((p) => text.startsWith(p))) continue;
|
|
36866
37353
|
const files = mm.bot_id ? void 0 : mm.files;
|
|
36867
37354
|
if (!text && !files?.length) continue;
|
|
36868
|
-
|
|
37355
|
+
const at = mm.ts !== void 0 && Number.isFinite(Number(mm.ts)) ? Math.round(Number(mm.ts) * 1e3) : void 0;
|
|
37356
|
+
kept.push({ role: mm.bot_id ? "assistant" : "user", text, ...at !== void 0 ? { at } : {}, files });
|
|
36869
37357
|
}
|
|
36870
37358
|
const imagesByIndex = [];
|
|
36871
37359
|
const documentsByIndex = [];
|
|
@@ -36892,11 +37380,11 @@ ${file.text}`));
|
|
|
36892
37380
|
}
|
|
36893
37381
|
}
|
|
36894
37382
|
for (let i = 0; i < kept.length; i++) {
|
|
36895
|
-
const { role, text } = kept[i];
|
|
37383
|
+
const { role, text, at } = kept[i];
|
|
36896
37384
|
const images = imagesByIndex[i];
|
|
36897
37385
|
const documents = documentsByIndex[i];
|
|
36898
37386
|
if (!text && !images && !documents) continue;
|
|
36899
|
-
items.push({ role, text, images, documents });
|
|
37387
|
+
items.push({ role, text, ...at !== void 0 ? { at } : {}, images, documents });
|
|
36900
37388
|
}
|
|
36901
37389
|
} catch {
|
|
36902
37390
|
}
|
|
@@ -39724,8 +40212,8 @@ function prUrlOf(events) {
|
|
|
39724
40212
|
for (const e of events) if (e.type === "pr_opened" && typeof e.url === "string") url = e.url;
|
|
39725
40213
|
return url;
|
|
39726
40214
|
}
|
|
39727
|
-
function routedOf(events) {
|
|
39728
|
-
return events.some((e) => e.type === "run_meta" && e.agentSource === "route");
|
|
40215
|
+
function routedOf(meta, events) {
|
|
40216
|
+
return meta.route !== void 0 || events.some((e) => e.type === "run_meta" && e.agentSource === "route");
|
|
39729
40217
|
}
|
|
39730
40218
|
async function reclaimRuns(opts) {
|
|
39731
40219
|
const { ledger, gen } = opts;
|
|
@@ -39801,7 +40289,7 @@ async function reclaimRuns(opts) {
|
|
|
39801
40289
|
events: events.length,
|
|
39802
40290
|
...row.meta.agent !== void 0 ? { agent: row.meta.agent } : {},
|
|
39803
40291
|
...prUrl2 !== void 0 ? { prUrl: prUrl2 } : {},
|
|
39804
|
-
...routedOf(events) ? { routed: true } : {},
|
|
40292
|
+
...routedOf(row.meta, events) ? { routed: true } : {},
|
|
39805
40293
|
...status3 === "interrupted" ? { note: closureNote(row.meta.agent, prUrl2) } : {}
|
|
39806
40294
|
});
|
|
39807
40295
|
log(
|