@coreplane/switchboard 1.216.2 → 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/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 +731 -273
- 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",
|
|
@@ -11997,8 +12151,110 @@ var init_commandRegistry = __esm({
|
|
|
11997
12151
|
}
|
|
11998
12152
|
});
|
|
11999
12153
|
|
|
12000
|
-
// ../../src/core/commands/
|
|
12154
|
+
// ../../src/core/commands/artifacts.ts
|
|
12001
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";
|
|
12002
12258
|
function targetChannel(caller, channel) {
|
|
12003
12259
|
const target = channel ?? caller.origin?.channelId;
|
|
12004
12260
|
if (!target) throw new CommandError("invalid_input", "channel: required on this surface \u2014 pass --channel <id>");
|
|
@@ -12018,7 +12274,7 @@ function summarizeScope(s) {
|
|
|
12018
12274
|
function registerConfigCommands(registry) {
|
|
12019
12275
|
for (const cmd of configCommands) registry.register(cmd);
|
|
12020
12276
|
}
|
|
12021
|
-
var
|
|
12277
|
+
var defineCommand3, scopeArg, channelOption, effort, effortLevels, modelRef, boundaryOption, who, configShow, configSet, configClear, quote, configInstructions, configCommands;
|
|
12022
12278
|
var init_config4 = __esm({
|
|
12023
12279
|
"../../src/core/commands/config.ts"() {
|
|
12024
12280
|
"use strict";
|
|
@@ -12028,25 +12284,25 @@ var init_config4 = __esm({
|
|
|
12028
12284
|
init_effort();
|
|
12029
12285
|
init_authorize();
|
|
12030
12286
|
init_commandRegistry();
|
|
12031
|
-
|
|
12287
|
+
defineCommand3 = commandDefiner();
|
|
12032
12288
|
scopeArg = {
|
|
12033
12289
|
name: "scope",
|
|
12034
|
-
schema:
|
|
12290
|
+
schema: z6.enum(["channel", "me"]),
|
|
12035
12291
|
describe: "`channel` (everyone here) or `me` (your own runs)"
|
|
12036
12292
|
};
|
|
12037
|
-
channelOption =
|
|
12038
|
-
effort =
|
|
12293
|
+
channelOption = z6.string().optional().describe("target channel (default: the channel you are speaking in)");
|
|
12294
|
+
effort = z6.enum(EFFORT_LEVELS);
|
|
12039
12295
|
effortLevels = `<${EFFORT_LEVELS.join("|")}>`;
|
|
12040
|
-
modelRef =
|
|
12041
|
-
boundaryOption =
|
|
12042
|
-
maxMinutes:
|
|
12043
|
-
maxIdentity:
|
|
12044
|
-
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(", ")}`)
|
|
12045
12301
|
}).optional();
|
|
12046
12302
|
who = (scope) => scope === "channel" ? "channel" : "your";
|
|
12047
|
-
configShow =
|
|
12303
|
+
configShow = defineCommand3({
|
|
12048
12304
|
id: "config.show",
|
|
12049
|
-
options:
|
|
12305
|
+
options: z6.object({ channel: channelOption }),
|
|
12050
12306
|
action: "config:read",
|
|
12051
12307
|
effect: "read",
|
|
12052
12308
|
describe: "The effective agent/model/effort for you in this channel, the defaults, both scopes, and what is restricted.",
|
|
@@ -12060,15 +12316,15 @@ var init_config4 = __esm({
|
|
|
12060
12316
|
return description;
|
|
12061
12317
|
}
|
|
12062
12318
|
});
|
|
12063
|
-
configSet =
|
|
12319
|
+
configSet = defineCommand3({
|
|
12064
12320
|
id: "config.set",
|
|
12065
12321
|
args: [scopeArg],
|
|
12066
|
-
options:
|
|
12067
|
-
agent:
|
|
12322
|
+
options: z6.object({
|
|
12323
|
+
agent: z6.string().min(1).optional().describe("force which agent handles requests in this scope"),
|
|
12068
12324
|
model: modelRef.optional().describe("force a model (provider/model) regardless of agent"),
|
|
12069
|
-
models:
|
|
12325
|
+
models: z6.record(z6.string(), modelRef).optional().describe("per-agent model: --models.<agent> provider/model"),
|
|
12070
12326
|
effort: effort.optional().describe(`force a model effort ${effortLevels}`),
|
|
12071
|
-
efforts:
|
|
12327
|
+
efforts: z6.record(z6.string(), effort).optional().describe(`per-agent effort: --efforts.<agent> ${effortLevels}`),
|
|
12072
12328
|
boundary: boundaryOption,
|
|
12073
12329
|
channel: channelOption
|
|
12074
12330
|
}),
|
|
@@ -12135,10 +12391,10 @@ var init_config4 = __esm({
|
|
|
12135
12391
|
return { scope: args.scope, effective: summarizeScope(effective) };
|
|
12136
12392
|
}
|
|
12137
12393
|
});
|
|
12138
|
-
configClear =
|
|
12394
|
+
configClear = defineCommand3({
|
|
12139
12395
|
id: "config.clear",
|
|
12140
12396
|
args: [scopeArg],
|
|
12141
|
-
options:
|
|
12397
|
+
options: z6.object({ channel: channelOption }),
|
|
12142
12398
|
action: "config:write",
|
|
12143
12399
|
effect: "write",
|
|
12144
12400
|
describe: "Drop every runtime override of a channel (gated) or of yourself; static config.yaml values show through again.",
|
|
@@ -12155,18 +12411,18 @@ var init_config4 = __esm({
|
|
|
12155
12411
|
}
|
|
12156
12412
|
});
|
|
12157
12413
|
quote = (text) => `> ${text.replace(/\n/g, "\n> ")}`;
|
|
12158
|
-
configInstructions =
|
|
12414
|
+
configInstructions = defineCommand3({
|
|
12159
12415
|
id: "config.instructions",
|
|
12160
12416
|
args: [
|
|
12161
12417
|
scopeArg,
|
|
12162
12418
|
{
|
|
12163
12419
|
name: "text",
|
|
12164
|
-
schema:
|
|
12420
|
+
schema: z6.string().optional(),
|
|
12165
12421
|
describe: 'the instructions; omit to show the current text, pass "" to clear',
|
|
12166
12422
|
rest: true
|
|
12167
12423
|
}
|
|
12168
12424
|
],
|
|
12169
|
-
options:
|
|
12425
|
+
options: z6.object({ channel: channelOption }),
|
|
12170
12426
|
action: "config:write",
|
|
12171
12427
|
effect: "write",
|
|
12172
12428
|
describe: "Custom instructions for a channel (gated) or for yourself \u2014 advisory prompt content that never changes agent, model, or permissions.",
|
|
@@ -12227,7 +12483,7 @@ ${quote(current ?? "")}`;
|
|
|
12227
12483
|
|
|
12228
12484
|
// ../../src/core/commands/contract.ts
|
|
12229
12485
|
import { basename, dirname as dirname8, join as join10 } from "node:path";
|
|
12230
|
-
import { z as
|
|
12486
|
+
import { z as z7 } from "zod";
|
|
12231
12487
|
function repoRootOfPlan(planPath) {
|
|
12232
12488
|
const plans = dirname8(planPath);
|
|
12233
12489
|
const docs = dirname8(plans);
|
|
@@ -12245,24 +12501,24 @@ function renderOutput(output) {
|
|
|
12245
12501
|
function registerContractCommands(registry) {
|
|
12246
12502
|
for (const cmd of contractCommands) registry.register(cmd);
|
|
12247
12503
|
}
|
|
12248
|
-
var
|
|
12504
|
+
var defineCommand4, SPECS_DIR, RULES_FILES, contractRender, contractCommands;
|
|
12249
12505
|
var init_contract2 = __esm({
|
|
12250
12506
|
"../../src/core/commands/contract.ts"() {
|
|
12251
12507
|
"use strict";
|
|
12252
12508
|
init_commandRegistry();
|
|
12253
12509
|
init_contract();
|
|
12254
|
-
|
|
12510
|
+
defineCommand4 = commandDefiner();
|
|
12255
12511
|
SPECS_DIR = join10("docs", "reference", "specs");
|
|
12256
12512
|
RULES_FILES = ["AGENTS.md", "CLAUDE.md"];
|
|
12257
|
-
contractRender =
|
|
12513
|
+
contractRender = defineCommand4({
|
|
12258
12514
|
id: "contract.render",
|
|
12259
|
-
options:
|
|
12260
|
-
plan:
|
|
12261
|
-
unit:
|
|
12262
|
-
root:
|
|
12263
|
-
branch:
|
|
12264
|
-
onto:
|
|
12265
|
-
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})`)
|
|
12266
12522
|
}),
|
|
12267
12523
|
action: "contract:read",
|
|
12268
12524
|
effect: "read",
|
|
@@ -13909,7 +14165,7 @@ var init_runRecord = __esm({
|
|
|
13909
14165
|
RUN_STATUSES = ["completed", "stopped_soft", "stopped_hard", "failed", "interrupted"];
|
|
13910
14166
|
RUN_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
13911
14167
|
REVIEW_HEAD_PATTERN = /^[0-9a-f]{7,40}$/;
|
|
13912
|
-
RUN_SEEDS = ["channel", "parent"];
|
|
14168
|
+
RUN_SEEDS = ["channel", "parent", "session"];
|
|
13913
14169
|
SESSION_KEY_PATTERN = /^[A-Za-z0-9_.:@+/-]{1,512}$/;
|
|
13914
14170
|
isIndex = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0;
|
|
13915
14171
|
MACHINE_CLASSES_IN_RECORD = {
|
|
@@ -13954,11 +14210,11 @@ var init_runRecord = __esm({
|
|
|
13954
14210
|
});
|
|
13955
14211
|
|
|
13956
14212
|
// ../../src/core/commands/delivery.ts
|
|
13957
|
-
import { z as
|
|
14213
|
+
import { z as z8 } from "zod";
|
|
13958
14214
|
function registerDeliveryCommands(registry) {
|
|
13959
14215
|
for (const cmd of deliveryCommands) registry.register(cmd);
|
|
13960
14216
|
}
|
|
13961
|
-
var
|
|
14217
|
+
var defineCommand5, REPO_SLUG3, ISO_DAY3, asJson, deliveryReport, deliveryCommands;
|
|
13962
14218
|
var init_delivery2 = __esm({
|
|
13963
14219
|
"../../src/core/commands/delivery.ts"() {
|
|
13964
14220
|
"use strict";
|
|
@@ -13966,16 +14222,16 @@ var init_delivery2 = __esm({
|
|
|
13966
14222
|
init_commandRegistry();
|
|
13967
14223
|
init_delivery();
|
|
13968
14224
|
init_runRecord();
|
|
13969
|
-
|
|
14225
|
+
defineCommand5 = commandDefiner();
|
|
13970
14226
|
REPO_SLUG3 = /^(?!\.+\/)[\w.-]+\/(?!\.+$)[\w.-]+$/;
|
|
13971
14227
|
ISO_DAY3 = /^\d{4}-\d{2}-\d{2}$/;
|
|
13972
14228
|
asJson = (v) => v;
|
|
13973
|
-
deliveryReport =
|
|
14229
|
+
deliveryReport = defineCommand5({
|
|
13974
14230
|
id: "delivery.report",
|
|
13975
|
-
options:
|
|
13976
|
-
repo:
|
|
13977
|
-
since:
|
|
13978
|
-
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(
|
|
13979
14235
|
`Monday-start weeks back from this one (default 4, at most ${MAX_WEEKS}); --since, when given, decides instead`
|
|
13980
14236
|
),
|
|
13981
14237
|
fresh: flag.optional().describe("read GitHub now instead of the repository's snapshot, and refresh the snapshot")
|
|
@@ -14020,7 +14276,7 @@ var init_delivery2 = __esm({
|
|
|
14020
14276
|
});
|
|
14021
14277
|
|
|
14022
14278
|
// ../../src/core/commands/deploy.ts
|
|
14023
|
-
import { z as
|
|
14279
|
+
import { z as z9 } from "zod";
|
|
14024
14280
|
function toOptions(o, dryRun, affected) {
|
|
14025
14281
|
return {
|
|
14026
14282
|
only: o.only,
|
|
@@ -14130,7 +14386,7 @@ async function copyImages(copies, account2, deps) {
|
|
|
14130
14386
|
function registerDeployCommands(registry) {
|
|
14131
14387
|
for (const cmd of deployCommands) registry.register(cmd);
|
|
14132
14388
|
}
|
|
14133
|
-
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;
|
|
14134
14390
|
var init_deploy = __esm({
|
|
14135
14391
|
"../../src/core/commands/deploy.ts"() {
|
|
14136
14392
|
"use strict";
|
|
@@ -14143,16 +14399,16 @@ var init_deploy = __esm({
|
|
|
14143
14399
|
init_wranglerTemplate();
|
|
14144
14400
|
init_secrets();
|
|
14145
14401
|
init_commandRegistry();
|
|
14146
|
-
|
|
14147
|
-
workerList =
|
|
14402
|
+
defineCommand6 = commandDefiner();
|
|
14403
|
+
workerList = z9.string().transform(
|
|
14148
14404
|
(s) => s.split(",").map((x) => x.trim()).filter(Boolean)
|
|
14149
14405
|
).refine(
|
|
14150
14406
|
(names) => names.every((n2) => DEPLOY_ORDER.includes(n2)),
|
|
14151
14407
|
`expected a comma list of Workers (${DEPLOY_ORDER.join(", ")})`
|
|
14152
14408
|
).transform((names) => [...new Set(names)]);
|
|
14153
|
-
positiveInt =
|
|
14154
|
-
gitRef =
|
|
14155
|
-
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({
|
|
14156
14412
|
only: workerList.optional().describe(
|
|
14157
14413
|
`deploy only these Workers (comma list of ${DEPLOY_ORDER.join(", ")}); with --affected, only those of them that are affected`
|
|
14158
14414
|
),
|
|
@@ -14171,7 +14427,7 @@ var init_deploy = __esm({
|
|
|
14171
14427
|
poll: positiveInt.optional().describe("seconds between preflight retries (default 60)")
|
|
14172
14428
|
});
|
|
14173
14429
|
planJson = (plan3) => plan3;
|
|
14174
|
-
deployPlan =
|
|
14430
|
+
deployPlan = defineCommand6({
|
|
14175
14431
|
id: "deploy.plan",
|
|
14176
14432
|
options: deployOptions,
|
|
14177
14433
|
action: "deploy:read",
|
|
@@ -14187,7 +14443,7 @@ var init_deploy = __esm({
|
|
|
14187
14443
|
});
|
|
14188
14444
|
copiedImage = (c) => ({ kind: c.kind, source: c.source, target: c.target });
|
|
14189
14445
|
listCopies = (copies) => copies.map((c) => `${c.kind} \u2190 ${c.source}`).join(", ");
|
|
14190
|
-
deployAll =
|
|
14446
|
+
deployAll = defineCommand6({
|
|
14191
14447
|
id: "deploy.all",
|
|
14192
14448
|
options: allOptions,
|
|
14193
14449
|
action: "deploy:write",
|
|
@@ -14238,15 +14494,15 @@ ${formatDeployResults(result.results, result.notAttempted)}`
|
|
|
14238
14494
|
return output(result.results, copies, []);
|
|
14239
14495
|
}
|
|
14240
14496
|
});
|
|
14241
|
-
restartOptions =
|
|
14242
|
-
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)"),
|
|
14243
14499
|
force: flag.optional().describe(
|
|
14244
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"
|
|
14245
14501
|
),
|
|
14246
14502
|
waitMax: positiveInt.optional().describe("minutes to wait out a refusal (the bot not answering with JSON) before giving up (default 10)"),
|
|
14247
14503
|
poll: positiveInt.optional().describe("seconds between retries while refused (default 60)")
|
|
14248
14504
|
});
|
|
14249
|
-
deployRestart =
|
|
14505
|
+
deployRestart = defineCommand6({
|
|
14250
14506
|
id: "deploy.restart",
|
|
14251
14507
|
options: restartOptions,
|
|
14252
14508
|
action: "deploy:write",
|
|
@@ -14287,12 +14543,12 @@ ${formatDeployResults(result.results, result.notAttempted)}`
|
|
|
14287
14543
|
};
|
|
14288
14544
|
}
|
|
14289
14545
|
});
|
|
14290
|
-
initOptions =
|
|
14546
|
+
initOptions = z9.object({
|
|
14291
14547
|
check: flag.optional().describe(
|
|
14292
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"
|
|
14293
14549
|
)
|
|
14294
14550
|
});
|
|
14295
|
-
deployInit =
|
|
14551
|
+
deployInit = defineCommand6({
|
|
14296
14552
|
id: "deploy.init",
|
|
14297
14553
|
options: initOptions,
|
|
14298
14554
|
action: "deploy:write",
|
|
@@ -14339,12 +14595,12 @@ ${formatDeployResults(result.results, result.notAttempted)}`
|
|
|
14339
14595
|
return output;
|
|
14340
14596
|
}
|
|
14341
14597
|
});
|
|
14342
|
-
configOptions =
|
|
14343
|
-
source:
|
|
14598
|
+
configOptions = z9.object({
|
|
14599
|
+
source: z9.string().min(1).optional().describe(
|
|
14344
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)"
|
|
14345
14601
|
)
|
|
14346
14602
|
});
|
|
14347
|
-
deployConfig =
|
|
14603
|
+
deployConfig = defineCommand6({
|
|
14348
14604
|
id: "deploy.config",
|
|
14349
14605
|
options: configOptions,
|
|
14350
14606
|
action: "deploy:write",
|
|
@@ -14379,21 +14635,21 @@ the bot reads it on its next start: \`deploy restart\``;
|
|
|
14379
14635
|
return output;
|
|
14380
14636
|
}
|
|
14381
14637
|
});
|
|
14382
|
-
secretNames =
|
|
14638
|
+
secretNames = z9.string().transform(
|
|
14383
14639
|
(s) => s.split(",").map((x) => x.trim()).filter(Boolean)
|
|
14384
14640
|
).refine(
|
|
14385
14641
|
(names) => names.length > 0 && names.every((n2) => /^[A-Z][A-Z0-9_]*$/.test(n2)),
|
|
14386
14642
|
"expected a comma list of secret names (SCREAMING_SNAKE)"
|
|
14387
14643
|
).transform((names) => [...new Set(names)]);
|
|
14388
|
-
secretsOptions =
|
|
14644
|
+
secretsOptions = z9.object({
|
|
14389
14645
|
only: secretNames.optional().describe("put only these secrets (comma list of names from deploy/secrets.manifest.json)")
|
|
14390
14646
|
});
|
|
14391
|
-
deploySecrets =
|
|
14647
|
+
deploySecrets = defineCommand6({
|
|
14392
14648
|
id: "deploy.secrets",
|
|
14393
14649
|
args: [
|
|
14394
14650
|
{
|
|
14395
14651
|
name: "worker",
|
|
14396
|
-
schema:
|
|
14652
|
+
schema: z9.enum(DEPLOY_ORDER),
|
|
14397
14653
|
describe: `the Worker to provision (${DEPLOY_ORDER.join(", ")})`
|
|
14398
14654
|
}
|
|
14399
14655
|
],
|
|
@@ -14455,12 +14711,12 @@ the bot reads it on its next start: \`deploy restart\``;
|
|
|
14455
14711
|
return output;
|
|
14456
14712
|
}
|
|
14457
14713
|
});
|
|
14458
|
-
imagesOptions =
|
|
14714
|
+
imagesOptions = z9.object({
|
|
14459
14715
|
dryRun: flag.optional().describe(
|
|
14460
14716
|
"say which images the account registry already holds at the version and which would be copied; nothing is copied"
|
|
14461
14717
|
)
|
|
14462
14718
|
});
|
|
14463
|
-
deployImages =
|
|
14719
|
+
deployImages = defineCommand6({
|
|
14464
14720
|
id: "deploy.images",
|
|
14465
14721
|
options: imagesOptions,
|
|
14466
14722
|
action: "deploy:write",
|
|
@@ -14511,25 +14767,25 @@ the bot reads it on its next start: \`deploy restart\``;
|
|
|
14511
14767
|
});
|
|
14512
14768
|
|
|
14513
14769
|
// ../../src/core/commands/env.ts
|
|
14514
|
-
import { z as
|
|
14770
|
+
import { z as z10 } from "zod";
|
|
14515
14771
|
function registerEnvCommands(registry) {
|
|
14516
14772
|
for (const cmd of envCommands) registry.register(cmd);
|
|
14517
14773
|
}
|
|
14518
|
-
var
|
|
14774
|
+
var defineCommand7, envBootstrap, envCommands;
|
|
14519
14775
|
var init_env = __esm({
|
|
14520
14776
|
"../../src/core/commands/env.ts"() {
|
|
14521
14777
|
"use strict";
|
|
14522
14778
|
init_bootstrap();
|
|
14523
14779
|
init_commandRegistry();
|
|
14524
|
-
|
|
14525
|
-
envBootstrap =
|
|
14780
|
+
defineCommand7 = commandDefiner();
|
|
14781
|
+
envBootstrap = defineCommand7({
|
|
14526
14782
|
id: "env.bootstrap",
|
|
14527
|
-
options:
|
|
14528
|
-
env:
|
|
14529
|
-
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"),
|
|
14530
14786
|
apply: flag.optional().describe("resolve the refs and WRITE the chmod-600 env file (default: dry-run)"),
|
|
14531
|
-
out:
|
|
14532
|
-
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})`)
|
|
14533
14789
|
}),
|
|
14534
14790
|
action: "env:write",
|
|
14535
14791
|
effect: "write",
|
|
@@ -15263,7 +15519,7 @@ var init_selfImprovement = __esm({
|
|
|
15263
15519
|
});
|
|
15264
15520
|
|
|
15265
15521
|
// ../../src/core/commands/friction.ts
|
|
15266
|
-
import { z as
|
|
15522
|
+
import { z as z11 } from "zod";
|
|
15267
15523
|
async function ledgerOf(deps) {
|
|
15268
15524
|
let ledger;
|
|
15269
15525
|
try {
|
|
@@ -15291,7 +15547,7 @@ function inProgressHint(diagnosis, finished) {
|
|
|
15291
15547
|
function registerFrictionCommands(registry) {
|
|
15292
15548
|
for (const cmd of frictionCommands) registry.register(cmd);
|
|
15293
15549
|
}
|
|
15294
|
-
var
|
|
15550
|
+
var defineCommand8, positiveInt2, repoSlug, NO_LEDGER_MESSAGE, NO_REPO_MESSAGE, asJson2, render, visibleRuns, frictionReport, frictionPropose, frictionAnalyze, frictionCommands;
|
|
15295
15551
|
var init_friction = __esm({
|
|
15296
15552
|
"../../src/core/commands/friction.ts"() {
|
|
15297
15553
|
"use strict";
|
|
@@ -15302,19 +15558,19 @@ var init_friction = __esm({
|
|
|
15302
15558
|
init_runEventLines();
|
|
15303
15559
|
init_runFriction();
|
|
15304
15560
|
init_selfImprovement();
|
|
15305
|
-
|
|
15306
|
-
positiveInt2 =
|
|
15307
|
-
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");
|
|
15308
15564
|
NO_LEDGER_MESSAGE = "Run history is not configured in this deployment (`runHistory`), so there are no recent runs to analyze.";
|
|
15309
15565
|
NO_REPO_MESSAGE = "Set `selfImprovement.repo` (an `owner/name`) in config.yaml to tell `friction propose` where to file issues.";
|
|
15310
15566
|
asJson2 = (r) => r;
|
|
15311
15567
|
render = (output) => formatSelfImprovementReport(output);
|
|
15312
15568
|
visibleRuns = (caller) => predicateFor(caller.actor, "runs:read", "run");
|
|
15313
|
-
frictionReport =
|
|
15569
|
+
frictionReport = defineCommand8({
|
|
15314
15570
|
id: "friction.report",
|
|
15315
15571
|
enabledWhen: (caps) => caps.runHistory,
|
|
15316
|
-
options:
|
|
15317
|
-
sinceMs:
|
|
15572
|
+
options: z11.object({
|
|
15573
|
+
sinceMs: z11.coerce.number().int().nonnegative().optional().describe("only runs finished at or after this epoch ms"),
|
|
15318
15574
|
limit: positiveInt2.optional().describe("newest n runs (default: the ledger's retained window)"),
|
|
15319
15575
|
minRuns: positiveInt2.optional().describe("distinct runs a pattern must recur in (default selfImprovement.minRuns, else 2)")
|
|
15320
15576
|
}),
|
|
@@ -15340,10 +15596,10 @@ var init_friction = __esm({
|
|
|
15340
15596
|
});
|
|
15341
15597
|
}
|
|
15342
15598
|
});
|
|
15343
|
-
frictionPropose =
|
|
15599
|
+
frictionPropose = defineCommand8({
|
|
15344
15600
|
id: "friction.propose",
|
|
15345
15601
|
enabledWhen: (caps) => caps.runHistory,
|
|
15346
|
-
options:
|
|
15602
|
+
options: z11.object({
|
|
15347
15603
|
dryRun: flag.optional().describe("compute and report everything, file nothing"),
|
|
15348
15604
|
top: positiveInt2.optional().describe("proposals filed per pass (default selfImprovement.top, else 3)"),
|
|
15349
15605
|
minRuns: positiveInt2.optional().describe("distinct runs a pattern must recur in (default selfImprovement.minRuns, else 2)"),
|
|
@@ -15375,17 +15631,17 @@ var init_friction = __esm({
|
|
|
15375
15631
|
}
|
|
15376
15632
|
}
|
|
15377
15633
|
});
|
|
15378
|
-
frictionAnalyze =
|
|
15634
|
+
frictionAnalyze = defineCommand8({
|
|
15379
15635
|
id: "friction.analyze",
|
|
15380
15636
|
args: [
|
|
15381
15637
|
{
|
|
15382
15638
|
name: "source",
|
|
15383
|
-
schema:
|
|
15639
|
+
schema: z11.string().optional(),
|
|
15384
15640
|
describe: "a saved run stream: JSON lines of run events or a curl'ed /runs/:id/events SSE capture (default: stdin)"
|
|
15385
15641
|
}
|
|
15386
15642
|
],
|
|
15387
|
-
options:
|
|
15388
|
-
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"),
|
|
15389
15645
|
inProgress: flag.optional().describe("the capture was taken mid-run: a trailing call without a result is still executing, not a dead run")
|
|
15390
15646
|
}),
|
|
15391
15647
|
action: "friction:read",
|
|
@@ -15438,7 +15694,7 @@ var init_friction = __esm({
|
|
|
15438
15694
|
});
|
|
15439
15695
|
|
|
15440
15696
|
// ../../src/core/commandSurface.ts
|
|
15441
|
-
import { z as
|
|
15697
|
+
import { z as z12 } from "zod";
|
|
15442
15698
|
function camelToKebab(s) {
|
|
15443
15699
|
return s.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
|
|
15444
15700
|
}
|
|
@@ -15510,7 +15766,7 @@ function isBooleanSchema(schema) {
|
|
|
15510
15766
|
return false;
|
|
15511
15767
|
}
|
|
15512
15768
|
function jsonSchemaOf(schema) {
|
|
15513
|
-
const out =
|
|
15769
|
+
const out = z12.toJSONSchema(unwrap(schema), { io: "input" });
|
|
15514
15770
|
delete out.$schema;
|
|
15515
15771
|
return out;
|
|
15516
15772
|
}
|
|
@@ -15522,7 +15778,7 @@ function jsonSchemaFor(cmd) {
|
|
|
15522
15778
|
if (!acceptsUndefined(arg.schema)) required.push(arg.name);
|
|
15523
15779
|
}
|
|
15524
15780
|
if (cmd.options) {
|
|
15525
|
-
const opts =
|
|
15781
|
+
const opts = z12.toJSONSchema(cmd.options, { io: "input" });
|
|
15526
15782
|
Object.assign(properties, opts.properties ?? {});
|
|
15527
15783
|
required.push(...opts.required ?? []);
|
|
15528
15784
|
}
|
|
@@ -15762,17 +16018,17 @@ function chatCommandList(commands) {
|
|
|
15762
16018
|
function registerHelpCommands(registry) {
|
|
15763
16019
|
for (const cmd of helpCommands) registry.register(cmd);
|
|
15764
16020
|
}
|
|
15765
|
-
var
|
|
16021
|
+
var defineCommand9, COMMANDS_REFERENCE_URL, DIRECTIVES_HELP, helpShow, helpCommandsList, helpCommands;
|
|
15766
16022
|
var init_help = __esm({
|
|
15767
16023
|
"../../src/core/commands/help.ts"() {
|
|
15768
16024
|
"use strict";
|
|
15769
16025
|
init_commandRegistry();
|
|
15770
16026
|
init_commandSurface();
|
|
15771
16027
|
init_docsLink();
|
|
15772
|
-
|
|
16028
|
+
defineCommand9 = commandDefiner();
|
|
15773
16029
|
COMMANDS_REFERENCE_URL = `${PROJECT_DOCS_URL}/reference/slack-commands`;
|
|
15774
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)";
|
|
15775
|
-
helpShow =
|
|
16031
|
+
helpShow = defineCommand9({
|
|
15776
16032
|
id: "help.show",
|
|
15777
16033
|
action: "help:read",
|
|
15778
16034
|
effect: "read",
|
|
@@ -15783,7 +16039,7 @@ var init_help = __esm({
|
|
|
15783
16039
|
commandsReference: COMMANDS_REFERENCE_URL
|
|
15784
16040
|
})
|
|
15785
16041
|
});
|
|
15786
|
-
helpCommandsList =
|
|
16042
|
+
helpCommandsList = defineCommand9({
|
|
15787
16043
|
id: "help.commands",
|
|
15788
16044
|
action: "help:read",
|
|
15789
16045
|
effect: "read",
|
|
@@ -17520,7 +17776,7 @@ var init_service = __esm({
|
|
|
17520
17776
|
});
|
|
17521
17777
|
|
|
17522
17778
|
// ../../src/core/commands/mcp.ts
|
|
17523
|
-
import { z as
|
|
17779
|
+
import { z as z13 } from "zod";
|
|
17524
17780
|
async function serviceOf(deps) {
|
|
17525
17781
|
const svc = await deps.mcp.service();
|
|
17526
17782
|
if ("unavailable" in svc) throw new CommandError("unavailable", svc.unavailable);
|
|
@@ -17614,7 +17870,7 @@ function renderShow(output) {
|
|
|
17614
17870
|
function registerMcpCommands(registry) {
|
|
17615
17871
|
for (const cmd of MCP_COMMANDS) registry.register(cmd);
|
|
17616
17872
|
}
|
|
17617
|
-
var
|
|
17873
|
+
var defineCommand10, serverName, serverUrl, scopeOption, channelOption2, nameArg, mcpList, mcpAdd, mcpConnect, mcpShow, mcpRemove, MCP_COMMANDS;
|
|
17618
17874
|
var init_mcp = __esm({
|
|
17619
17875
|
"../../src/core/commands/mcp.ts"() {
|
|
17620
17876
|
"use strict";
|
|
@@ -17622,18 +17878,18 @@ var init_mcp = __esm({
|
|
|
17622
17878
|
init_service();
|
|
17623
17879
|
init_authorize();
|
|
17624
17880
|
init_commandRegistry();
|
|
17625
|
-
|
|
17626
|
-
serverName =
|
|
17627
|
-
serverUrl =
|
|
17628
|
-
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(
|
|
17629
17885
|
"whose server: yours (`me`, default), this channel's (`channel`, channel-config rights), or org-wide (`org`, admins)"
|
|
17630
17886
|
);
|
|
17631
|
-
channelOption2 =
|
|
17887
|
+
channelOption2 = z13.string().optional().describe("target channel for `--scope channel` and for `list` (default: the channel you are speaking in)");
|
|
17632
17888
|
nameArg = { name: "name", schema: serverName, describe: "the server's name (see `mcp list`)" };
|
|
17633
|
-
mcpList =
|
|
17889
|
+
mcpList = defineCommand10({
|
|
17634
17890
|
id: "mcp.list",
|
|
17635
17891
|
enabledWhen: (caps) => caps.mcp,
|
|
17636
|
-
options:
|
|
17892
|
+
options: z13.object({ channel: channelOption2 }),
|
|
17637
17893
|
action: "mcp:read",
|
|
17638
17894
|
effect: "read",
|
|
17639
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.",
|
|
@@ -17645,7 +17901,7 @@ var init_mcp = __esm({
|
|
|
17645
17901
|
return { servers };
|
|
17646
17902
|
}
|
|
17647
17903
|
});
|
|
17648
|
-
mcpAdd =
|
|
17904
|
+
mcpAdd = defineCommand10({
|
|
17649
17905
|
id: "mcp.add",
|
|
17650
17906
|
enabledWhen: (caps) => caps.mcp,
|
|
17651
17907
|
args: [
|
|
@@ -17655,15 +17911,15 @@ var init_mcp = __esm({
|
|
|
17655
17911
|
describe: "a short slug for the server (becomes the tool prefix mcp__<name>__)"
|
|
17656
17912
|
}
|
|
17657
17913
|
],
|
|
17658
|
-
options:
|
|
17914
|
+
options: z13.object({
|
|
17659
17915
|
url: serverUrl.describe("the server's Streamable-HTTP endpoint (https://\u2026/mcp)"),
|
|
17660
17916
|
scope: scopeOption,
|
|
17661
|
-
agents:
|
|
17917
|
+
agents: z13.string().transform(
|
|
17662
17918
|
(s) => s.split(",").map((a) => a.trim()).filter(Boolean)
|
|
17663
17919
|
).optional().describe(
|
|
17664
17920
|
"comma-separated agents that may use it (default general,research; only org servers may name coding/review/ship)"
|
|
17665
17921
|
),
|
|
17666
|
-
auth:
|
|
17922
|
+
auth: z13.enum(["oauth", "bearer", "none"]).optional().describe(
|
|
17667
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"
|
|
17668
17924
|
),
|
|
17669
17925
|
channel: channelOption2
|
|
@@ -17688,11 +17944,11 @@ var init_mcp = __esm({
|
|
|
17688
17944
|
);
|
|
17689
17945
|
}
|
|
17690
17946
|
});
|
|
17691
|
-
mcpConnect =
|
|
17947
|
+
mcpConnect = defineCommand10({
|
|
17692
17948
|
id: "mcp.connect",
|
|
17693
17949
|
enabledWhen: (caps) => caps.mcp,
|
|
17694
17950
|
args: [nameArg],
|
|
17695
|
-
options:
|
|
17951
|
+
options: z13.object({ scope: scopeOption, channel: channelOption2 }),
|
|
17696
17952
|
action: "mcp:write",
|
|
17697
17953
|
effect: "write",
|
|
17698
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.",
|
|
@@ -17706,11 +17962,11 @@ var init_mcp = __esm({
|
|
|
17706
17962
|
return await via(() => svc.connect(actor, target, args.name));
|
|
17707
17963
|
}
|
|
17708
17964
|
});
|
|
17709
|
-
mcpShow =
|
|
17965
|
+
mcpShow = defineCommand10({
|
|
17710
17966
|
id: "mcp.show",
|
|
17711
17967
|
enabledWhen: (caps) => caps.mcp,
|
|
17712
17968
|
args: [nameArg],
|
|
17713
|
-
options:
|
|
17969
|
+
options: z13.object({ scope: scopeOption, channel: channelOption2 }),
|
|
17714
17970
|
action: "mcp:read",
|
|
17715
17971
|
effect: "read",
|
|
17716
17972
|
describe: "One MCP server's entry plus a live probe of the tools it offers (names, read-only flags); never a credential.",
|
|
@@ -17726,11 +17982,11 @@ var init_mcp = __esm({
|
|
|
17726
17982
|
return await via(() => svc.show(actor, target, args.name));
|
|
17727
17983
|
}
|
|
17728
17984
|
});
|
|
17729
|
-
mcpRemove =
|
|
17985
|
+
mcpRemove = defineCommand10({
|
|
17730
17986
|
id: "mcp.remove",
|
|
17731
17987
|
enabledWhen: (caps) => caps.mcp,
|
|
17732
17988
|
args: [nameArg],
|
|
17733
|
-
options:
|
|
17989
|
+
options: z13.object({ scope: scopeOption, channel: channelOption2 }),
|
|
17734
17990
|
action: "mcp:write",
|
|
17735
17991
|
effect: "write",
|
|
17736
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).",
|
|
@@ -18168,7 +18424,7 @@ var init_llmOutput = __esm({
|
|
|
18168
18424
|
});
|
|
18169
18425
|
|
|
18170
18426
|
// ../../src/core/memory/reflection.ts
|
|
18171
|
-
import { z as
|
|
18427
|
+
import { z as z14 } from "zod";
|
|
18172
18428
|
function shouldReflect(input) {
|
|
18173
18429
|
if (input.agentName !== void 0 && NO_REFLECT_AGENTS.has(input.agentName)) return false;
|
|
18174
18430
|
return input.toolCalls > 0 || input.historyTurns >= REFLECT_MIN_TURNS;
|
|
@@ -18387,7 +18643,7 @@ var init_reflection = __esm({
|
|
|
18387
18643
|
"Output raw JSON with no code fence and no prose."
|
|
18388
18644
|
].join("\n");
|
|
18389
18645
|
SUMMARY_INHERITANCE = ["user", "repo", "channel"];
|
|
18390
|
-
REFLECTION_ENVELOPE = jsonOutput(
|
|
18646
|
+
REFLECTION_ENVELOPE = jsonOutput(z14.object({ facts: z14.array(z14.unknown()), summary: z14.unknown().optional() }), {
|
|
18391
18647
|
name: "reflection-envelope"
|
|
18392
18648
|
});
|
|
18393
18649
|
SCOPE_KINDS = ["org", "user", "repo", "channel"];
|
|
@@ -18507,11 +18763,11 @@ var init_workerStore = __esm({
|
|
|
18507
18763
|
});
|
|
18508
18764
|
|
|
18509
18765
|
// ../../src/core/memory/buildStore.ts
|
|
18510
|
-
function resolveScopeCap(
|
|
18511
|
-
if (
|
|
18512
|
-
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;
|
|
18513
18769
|
warn(
|
|
18514
|
-
`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}.`
|
|
18515
18771
|
);
|
|
18516
18772
|
return DEFAULT_SCOPE_CAP;
|
|
18517
18773
|
}
|
|
@@ -18619,7 +18875,7 @@ var init_memory = __esm({
|
|
|
18619
18875
|
});
|
|
18620
18876
|
|
|
18621
18877
|
// ../../src/core/commands/memory.ts
|
|
18622
|
-
import { z as
|
|
18878
|
+
import { z as z15 } from "zod";
|
|
18623
18879
|
function scopeKeyOfMemoryId(id) {
|
|
18624
18880
|
const m = /^mem:(.+):\d+$/.exec(id);
|
|
18625
18881
|
return m ? m[1] : void 0;
|
|
@@ -18673,18 +18929,18 @@ _(limit ${limit} reached \u2014 there may be more; narrow with words or raise \`
|
|
|
18673
18929
|
function registerMemoryCommands(registry) {
|
|
18674
18930
|
for (const cmd of memoryCommands) registry.register(cmd);
|
|
18675
18931
|
}
|
|
18676
|
-
var
|
|
18932
|
+
var defineCommand11, MEMORY_LIST_LIMIT, MEMORY_LIST_MAX_LIMIT, MEMORY_OFF_MESSAGE, memoryId, repoScopeKey, channelScopeKey, isSharedScope, LIST_SCOPES, memoryList, memoryForget, memoryCommands;
|
|
18677
18933
|
var init_memory2 = __esm({
|
|
18678
18934
|
"../../src/core/commands/memory.ts"() {
|
|
18679
18935
|
"use strict";
|
|
18680
18936
|
init_authorize();
|
|
18681
18937
|
init_commandRegistry();
|
|
18682
18938
|
init_memory();
|
|
18683
|
-
|
|
18939
|
+
defineCommand11 = commandDefiner();
|
|
18684
18940
|
MEMORY_LIST_LIMIT = 20;
|
|
18685
18941
|
MEMORY_LIST_MAX_LIMIT = 50;
|
|
18686
18942
|
MEMORY_OFF_MESSAGE = "Memory is off in this deployment (`memory.enabled` is not set), so there is nothing to list or forget.";
|
|
18687
|
-
memoryId =
|
|
18943
|
+
memoryId = z15.string().refine(
|
|
18688
18944
|
(id) => scopeKeyOfMemoryId(id) !== void 0,
|
|
18689
18945
|
"expected a memory id like mem:<scope>:<n> (see `memory list`)"
|
|
18690
18946
|
);
|
|
@@ -18692,21 +18948,21 @@ var init_memory2 = __esm({
|
|
|
18692
18948
|
channelScopeKey = (channelId) => deriveScopeKey("channel", { channelId });
|
|
18693
18949
|
isSharedScope = (key, keys) => key === keys.org || key.startsWith("repo:") || key.startsWith("channel:");
|
|
18694
18950
|
LIST_SCOPES = ["me", "org", "repo", "channel", "all"];
|
|
18695
|
-
memoryList =
|
|
18951
|
+
memoryList = defineCommand11({
|
|
18696
18952
|
id: "memory.list",
|
|
18697
18953
|
enabledWhen: (caps) => caps.memory,
|
|
18698
18954
|
args: [
|
|
18699
18955
|
{
|
|
18700
18956
|
name: "query",
|
|
18701
|
-
schema:
|
|
18957
|
+
schema: z15.string().optional(),
|
|
18702
18958
|
describe: "words a record must mention (whole-token match)",
|
|
18703
18959
|
rest: true
|
|
18704
18960
|
}
|
|
18705
18961
|
],
|
|
18706
|
-
options:
|
|
18707
|
-
scope:
|
|
18708
|
-
limit:
|
|
18709
|
-
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)")
|
|
18710
18966
|
}),
|
|
18711
18967
|
action: "memory:read",
|
|
18712
18968
|
effect: "read",
|
|
@@ -18760,7 +19016,7 @@ var init_memory2 = __esm({
|
|
|
18760
19016
|
};
|
|
18761
19017
|
}
|
|
18762
19018
|
});
|
|
18763
|
-
memoryForget =
|
|
19019
|
+
memoryForget = defineCommand11({
|
|
18764
19020
|
id: "memory.forget",
|
|
18765
19021
|
enabledWhen: (caps) => caps.memory,
|
|
18766
19022
|
args: [{ name: "id", schema: memoryId, describe: "the record id (`mem:<scope>:<n>`, from `memory list`)" }],
|
|
@@ -18895,7 +19151,7 @@ var init_residentDiskBudget = __esm({
|
|
|
18895
19151
|
});
|
|
18896
19152
|
|
|
18897
19153
|
// ../../src/core/commands/repo.ts
|
|
18898
|
-
import { z as
|
|
19154
|
+
import { z as z16 } from "zod";
|
|
18899
19155
|
async function adminOf(deps, span) {
|
|
18900
19156
|
const api = await deps.repo.admin();
|
|
18901
19157
|
if ("unavailable" in api) throw new CommandError("unavailable", api.unavailable);
|
|
@@ -19003,7 +19259,7 @@ ${clipOpOutput(text)}
|
|
|
19003
19259
|
\`\`\`` : `${icon} ${str4(o.summary)}`;
|
|
19004
19260
|
}
|
|
19005
19261
|
function defineOp(op) {
|
|
19006
|
-
return
|
|
19262
|
+
return defineCommand12({
|
|
19007
19263
|
id: `repo.${op}`,
|
|
19008
19264
|
// The op needs a backend: the resident service, or the local workspace (`defaultOperations`).
|
|
19009
19265
|
enabledWhen: (caps) => caps.residents || caps.execution === "local",
|
|
@@ -19061,7 +19317,7 @@ function defineOp(op) {
|
|
|
19061
19317
|
function registerRepoCommands(registry) {
|
|
19062
19318
|
for (const cmd of repoCommands) registry.register(cmd);
|
|
19063
19319
|
}
|
|
19064
|
-
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;
|
|
19065
19321
|
var init_repo = __esm({
|
|
19066
19322
|
"../../src/core/commands/repo.ts"() {
|
|
19067
19323
|
"use strict";
|
|
@@ -19069,19 +19325,19 @@ var init_repo = __esm({
|
|
|
19069
19325
|
init_residentAdmin();
|
|
19070
19326
|
init_repoToolchain();
|
|
19071
19327
|
init_residentDiskBudget();
|
|
19072
|
-
|
|
19328
|
+
defineCommand12 = commandDefiner();
|
|
19073
19329
|
DEFAULT_COMMANDS = NPM_FALLBACK_COMMANDS;
|
|
19074
19330
|
DEFAULT_REF = "main";
|
|
19075
19331
|
SETTLE_POLL_MS = 1e4;
|
|
19076
19332
|
SETTLE_MAX_MS = 12 * 6e4;
|
|
19077
|
-
repoSlug2 =
|
|
19078
|
-
gitRef2 =
|
|
19079
|
-
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);
|
|
19080
19336
|
slugArg = { name: "slug", schema: repoSlug2, describe: "GitHub owner/name of the repo" };
|
|
19081
19337
|
n = (v) => String(typeof v === "number" ? v : v ?? "?");
|
|
19082
19338
|
obj = (v) => typeof v === "object" && v !== null && !Array.isArray(v) ? v : {};
|
|
19083
19339
|
str4 = (v) => typeof v === "string" ? v : String(v ?? "?");
|
|
19084
|
-
repoList =
|
|
19340
|
+
repoList = defineCommand12({
|
|
19085
19341
|
id: "repo.list",
|
|
19086
19342
|
enabledWhen: (caps) => caps.residents,
|
|
19087
19343
|
action: "repo:read",
|
|
@@ -19098,11 +19354,11 @@ var init_repo = __esm({
|
|
|
19098
19354
|
return res.data;
|
|
19099
19355
|
}
|
|
19100
19356
|
});
|
|
19101
|
-
repoOnboard =
|
|
19357
|
+
repoOnboard = defineCommand12({
|
|
19102
19358
|
id: "repo.onboard",
|
|
19103
19359
|
enabledWhen: (caps) => caps.residents,
|
|
19104
19360
|
args: [slugArg],
|
|
19105
|
-
options:
|
|
19361
|
+
options: z16.object({
|
|
19106
19362
|
ref: gitRef2.optional().describe(`default branch to keep warm (default ${DEFAULT_REF})`),
|
|
19107
19363
|
test: command.optional().describe(
|
|
19108
19364
|
"the repo's test command (default: detected from the repo root \u2014 `<pm> test`, or a no-op without a test script)"
|
|
@@ -19189,10 +19445,10 @@ var init_repo = __esm({
|
|
|
19189
19445
|
settle: (output, { deps }) => settleProvisioning(deps, str4(output.slug))
|
|
19190
19446
|
});
|
|
19191
19447
|
COMMAND_KEYS = ["install", "build", "test"];
|
|
19192
|
-
dryRunOptions =
|
|
19448
|
+
dryRunOptions = z16.object({
|
|
19193
19449
|
dryRun: flag.optional().describe("compute and return the itemized plan without executing")
|
|
19194
19450
|
});
|
|
19195
|
-
repoOffboard =
|
|
19451
|
+
repoOffboard = defineCommand12({
|
|
19196
19452
|
id: "repo.offboard",
|
|
19197
19453
|
enabledWhen: (caps) => caps.residents,
|
|
19198
19454
|
args: [slugArg],
|
|
@@ -19226,7 +19482,7 @@ var init_repo = __esm({
|
|
|
19226
19482
|
return { ...r.data, slug: args.slug, dryRun };
|
|
19227
19483
|
}
|
|
19228
19484
|
});
|
|
19229
|
-
repoRebuild =
|
|
19485
|
+
repoRebuild = defineCommand12({
|
|
19230
19486
|
id: "repo.rebuild",
|
|
19231
19487
|
enabledWhen: (caps) => caps.residents,
|
|
19232
19488
|
args: [slugArg],
|
|
@@ -19265,11 +19521,11 @@ var init_repo = __esm({
|
|
|
19265
19521
|
return { ...r.data, slug: args.slug, dryRun };
|
|
19266
19522
|
}
|
|
19267
19523
|
});
|
|
19268
|
-
repoReconfigure =
|
|
19524
|
+
repoReconfigure = defineCommand12({
|
|
19269
19525
|
id: "repo.reconfigure",
|
|
19270
19526
|
enabledWhen: (caps) => caps.residents,
|
|
19271
19527
|
args: [slugArg],
|
|
19272
|
-
options:
|
|
19528
|
+
options: z16.object({
|
|
19273
19529
|
ref: gitRef2.optional().describe("new default branch"),
|
|
19274
19530
|
test: command.optional().describe("new test command"),
|
|
19275
19531
|
build: command.optional().describe("new build command"),
|
|
@@ -20239,7 +20495,7 @@ var init_runsService = __esm({
|
|
|
20239
20495
|
});
|
|
20240
20496
|
|
|
20241
20497
|
// ../../src/core/commands/review.ts
|
|
20242
|
-
import { z as
|
|
20498
|
+
import { z as z17 } from "zod";
|
|
20243
20499
|
function artifactJson(a) {
|
|
20244
20500
|
return {
|
|
20245
20501
|
...a.model !== void 0 ? { model: a.model } : {},
|
|
@@ -20308,7 +20564,7 @@ function refused2(err2) {
|
|
|
20308
20564
|
function registerReviewCommands(registry) {
|
|
20309
20565
|
for (const cmd of reviewCommands) registry.register(cmd);
|
|
20310
20566
|
}
|
|
20311
|
-
var
|
|
20567
|
+
var defineCommand13, runId, ABRIDGE_OFF_MESSAGE, reviewAbridge, reviewCommands;
|
|
20312
20568
|
var init_review = __esm({
|
|
20313
20569
|
"../../src/core/commands/review.ts"() {
|
|
20314
20570
|
"use strict";
|
|
@@ -20317,17 +20573,17 @@ var init_review = __esm({
|
|
|
20317
20573
|
init_reviewAbridge();
|
|
20318
20574
|
init_runRecord();
|
|
20319
20575
|
init_runsService();
|
|
20320
|
-
|
|
20321
|
-
runId =
|
|
20576
|
+
defineCommand13 = commandDefiner();
|
|
20577
|
+
runId = z17.string().regex(RUN_ID_PATTERN);
|
|
20322
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.";
|
|
20323
|
-
reviewAbridge =
|
|
20579
|
+
reviewAbridge = defineCommand13({
|
|
20324
20580
|
id: "review.abridge",
|
|
20325
20581
|
// Hidden unless the abridging can happen here (the binary, the credential,
|
|
20326
20582
|
// the switch) AND there is a record to append to.
|
|
20327
20583
|
enabledWhen: (caps) => caps.runHistory && caps.readingDiffAbridge,
|
|
20328
20584
|
args: [{ name: "id", schema: runId, describe: "run id of a finished PR review" }],
|
|
20329
|
-
options:
|
|
20330
|
-
model:
|
|
20585
|
+
options: z17.object({
|
|
20586
|
+
model: z17.string().min(1).optional().describe("meat's model (default review.readingDiff.meatModel, else claude-opus-5)"),
|
|
20331
20587
|
force: flag.optional().describe("recompute even when an abridged diff is already stored, or retry a failed one"),
|
|
20332
20588
|
wait: flag.optional().describe("block until the abridging finishes and answer the outcome instead of `running`")
|
|
20333
20589
|
}),
|
|
@@ -20359,7 +20615,7 @@ var init_review = __esm({
|
|
|
20359
20615
|
});
|
|
20360
20616
|
|
|
20361
20617
|
// ../../src/core/commands/runs.ts
|
|
20362
|
-
import { z as
|
|
20618
|
+
import { z as z18 } from "zod";
|
|
20363
20619
|
function unwrap2(res) {
|
|
20364
20620
|
if (res.ok) return res.value;
|
|
20365
20621
|
throw new CommandError(res.error, res.error === "not_found" ? "run not found" : "run already finished");
|
|
@@ -20400,7 +20656,7 @@ function wrapEvent(e) {
|
|
|
20400
20656
|
function registerRunsCommands(registry) {
|
|
20401
20657
|
for (const cmd of runsCommands) registry.register(cmd);
|
|
20402
20658
|
}
|
|
20403
|
-
var
|
|
20659
|
+
var defineCommand14, runId2, positiveInt3, idArg, logDenied, asJson3, runsList, runsGet, runsEvents, runsFriction, runsStop, runsCommands;
|
|
20404
20660
|
var init_runs = __esm({
|
|
20405
20661
|
"../../src/core/commands/runs.ts"() {
|
|
20406
20662
|
"use strict";
|
|
@@ -20409,21 +20665,24 @@ var init_runs = __esm({
|
|
|
20409
20665
|
init_commandRegistry();
|
|
20410
20666
|
init_runRecord();
|
|
20411
20667
|
init_runsService();
|
|
20412
|
-
|
|
20413
|
-
runId2 =
|
|
20414
|
-
positiveInt3 =
|
|
20668
|
+
defineCommand14 = commandDefiner();
|
|
20669
|
+
runId2 = z18.string().regex(RUN_ID_PATTERN);
|
|
20670
|
+
positiveInt3 = z18.coerce.number().int().positive();
|
|
20415
20671
|
idArg = { name: "id", schema: runId2, describe: "run id" };
|
|
20416
20672
|
logDenied = (entry) => console.log(JSON.stringify({ audit: "authz", ...entry }));
|
|
20417
20673
|
asJson3 = (v) => v;
|
|
20418
|
-
runsList =
|
|
20674
|
+
runsList = defineCommand14({
|
|
20419
20675
|
id: "runs.list",
|
|
20420
|
-
options:
|
|
20421
|
-
status:
|
|
20422
|
-
agent:
|
|
20423
|
-
channel:
|
|
20424
|
-
|
|
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"),
|
|
20425
20684
|
limit: positiveInt3.max(RUN_LIST_MAX_LIMIT).optional().describe(`page size (max ${RUN_LIST_MAX_LIMIT})`),
|
|
20426
|
-
before:
|
|
20685
|
+
before: z18.coerce.number().int().nonnegative().optional().describe("page cursor: runs finished before this epoch ms"),
|
|
20427
20686
|
beforeId: runId2.optional().describe("page cursor tie-breaker: the last id of the previous page")
|
|
20428
20687
|
}),
|
|
20429
20688
|
action: "runs:read",
|
|
@@ -20431,14 +20690,17 @@ var init_runs = __esm({
|
|
|
20431
20690
|
describe: "List runs (live and persisted, newest first) \u2014 metadata only, never message text.",
|
|
20432
20691
|
handler: async ({ options, caller, deps }) => {
|
|
20433
20692
|
const visibleTo = predicateFor(caller.actor, "runs:read", "run");
|
|
20434
|
-
|
|
20693
|
+
const { thread, ...rest } = options;
|
|
20694
|
+
return asJson3(
|
|
20695
|
+
await (await deps.runs()).listRuns({ ...rest, ...thread !== void 0 ? { threadKey: thread } : {}, visibleTo })
|
|
20696
|
+
);
|
|
20435
20697
|
}
|
|
20436
20698
|
});
|
|
20437
|
-
runsGet =
|
|
20699
|
+
runsGet = defineCommand14({
|
|
20438
20700
|
id: "runs.get",
|
|
20439
20701
|
args: [idArg],
|
|
20440
|
-
options:
|
|
20441
|
-
include:
|
|
20702
|
+
options: z18.object({
|
|
20703
|
+
include: z18.enum(["messages"]).optional().describe("add the run's events, free text wrapped as untrusted content")
|
|
20442
20704
|
}),
|
|
20443
20705
|
action: "runs:read",
|
|
20444
20706
|
effect: "read",
|
|
@@ -20458,11 +20720,11 @@ var init_runs = __esm({
|
|
|
20458
20720
|
return asJson3(view);
|
|
20459
20721
|
}
|
|
20460
20722
|
});
|
|
20461
|
-
runsEvents =
|
|
20723
|
+
runsEvents = defineCommand14({
|
|
20462
20724
|
id: "runs.events",
|
|
20463
20725
|
args: [idArg],
|
|
20464
|
-
options:
|
|
20465
|
-
afterSeq:
|
|
20726
|
+
options: z18.object({
|
|
20727
|
+
afterSeq: z18.coerce.number().int().nonnegative().optional().describe("events with seq greater than this"),
|
|
20466
20728
|
limit: positiveInt3.max(MAX_EVENTS_PAGE).optional().describe(`page size (max ${MAX_EVENTS_PAGE})`)
|
|
20467
20729
|
}),
|
|
20468
20730
|
action: "runs:read",
|
|
@@ -20476,7 +20738,7 @@ var init_runs = __esm({
|
|
|
20476
20738
|
return asJson3({ ...page2, events: page2.events.map(wrapEvent) });
|
|
20477
20739
|
}
|
|
20478
20740
|
});
|
|
20479
|
-
runsFriction =
|
|
20741
|
+
runsFriction = defineCommand14({
|
|
20480
20742
|
id: "runs.friction",
|
|
20481
20743
|
args: [idArg],
|
|
20482
20744
|
action: "runs:read",
|
|
@@ -20489,10 +20751,10 @@ var init_runs = __esm({
|
|
|
20489
20751
|
return asJson3(unwrap2(await runs.getRunFriction(args.id)));
|
|
20490
20752
|
}
|
|
20491
20753
|
});
|
|
20492
|
-
runsStop =
|
|
20754
|
+
runsStop = defineCommand14({
|
|
20493
20755
|
id: "runs.stop",
|
|
20494
20756
|
args: [idArg],
|
|
20495
|
-
options:
|
|
20757
|
+
options: z18.object({ mode: z18.enum(["soft", "hard"]).describe("soft = finish the current step; hard = abort now") }),
|
|
20496
20758
|
action: "runs:write",
|
|
20497
20759
|
effect: "write",
|
|
20498
20760
|
describe: "Request a live run to stop (`--mode soft` = finish the current step; `hard` = abort now). Records the caller as the actor.",
|
|
@@ -20516,16 +20778,16 @@ var init_runs = __esm({
|
|
|
20516
20778
|
function registerScheduleCommands(registry) {
|
|
20517
20779
|
for (const cmd of scheduleCommands) registry.register(cmd);
|
|
20518
20780
|
}
|
|
20519
|
-
var
|
|
20781
|
+
var defineCommand15, ACTION_LABEL, utc, scheduleList, scheduleCommands;
|
|
20520
20782
|
var init_schedule = __esm({
|
|
20521
20783
|
"../../src/core/commands/schedule.ts"() {
|
|
20522
20784
|
"use strict";
|
|
20523
20785
|
init_commandRegistry();
|
|
20524
20786
|
init_schedules();
|
|
20525
|
-
|
|
20787
|
+
defineCommand15 = commandDefiner();
|
|
20526
20788
|
ACTION_LABEL = { healthz: "keep-alive", watchdog: "resident watchdog" };
|
|
20527
20789
|
utc = (ms) => `${new Date(ms).toISOString().slice(0, 16).replace("T", " ")} UTC`;
|
|
20528
|
-
scheduleList =
|
|
20790
|
+
scheduleList = defineCommand15({
|
|
20529
20791
|
id: "schedule.list",
|
|
20530
20792
|
enabledWhen: (caps) => caps.schedules,
|
|
20531
20793
|
action: "schedule:read",
|
|
@@ -20789,7 +21051,7 @@ var init_plan2 = __esm({
|
|
|
20789
21051
|
});
|
|
20790
21052
|
|
|
20791
21053
|
// ../../src/core/commands/setup.ts
|
|
20792
|
-
import { z as
|
|
21054
|
+
import { z as z19 } from "zod";
|
|
20793
21055
|
async function gatherAnswers(o, setup) {
|
|
20794
21056
|
const ask = setup.prompt;
|
|
20795
21057
|
const given = (v) => v !== void 0;
|
|
@@ -20859,33 +21121,33 @@ function capabilityLine(c) {
|
|
|
20859
21121
|
function registerSetupCommands(registry) {
|
|
20860
21122
|
for (const cmd of setupCommands) registry.register(cmd);
|
|
20861
21123
|
}
|
|
20862
|
-
var
|
|
21124
|
+
var defineCommand16, secret, digits, workerName, hostname2, httpUrl, account, initOptions2, DEFAULT_NAME, setupInit, ASK, setupCommands;
|
|
20863
21125
|
var init_setup = __esm({
|
|
20864
21126
|
"../../src/core/commands/setup.ts"() {
|
|
20865
21127
|
"use strict";
|
|
20866
21128
|
init_plan2();
|
|
20867
21129
|
init_commandRegistry();
|
|
20868
21130
|
init_deploy();
|
|
20869
|
-
|
|
20870
|
-
secret =
|
|
20871
|
-
digits =
|
|
20872
|
-
workerName =
|
|
20873
|
-
hostname2 =
|
|
20874
|
-
httpUrl =
|
|
20875
|
-
account =
|
|
20876
|
-
initOptions2 =
|
|
20877
|
-
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`"),
|
|
20878
21140
|
anthropicKey: secret.optional().describe("an Anthropic API key \u2192 ANTHROPIC_API_KEY and the `anthropic` provider"),
|
|
20879
21141
|
openaiCompatible: httpUrl.optional().describe(
|
|
20880
21142
|
"an OpenAI-compatible endpoint's base URL (https://api.openai.com/v1, http://localhost:11434/v1) \u2192 the `openai` provider"
|
|
20881
21143
|
),
|
|
20882
|
-
model:
|
|
21144
|
+
model: z19.string().min(1).optional().describe("with --openai-compatible: the model every agent runs on at that endpoint (openai/<model>)"),
|
|
20883
21145
|
modelKey: secret.optional().describe("with --openai-compatible: the endpoint's key \u2192 OPENAI_API_KEY (a local endpoint needs none)"),
|
|
20884
21146
|
slackAppToken: secret.optional().describe("the Slack app-level token (xapp-\u2026) \u2192 SLACK_APP_TOKEN"),
|
|
20885
21147
|
slackBotToken: secret.optional().describe("the Slack bot token (xoxb-\u2026) \u2192 SLACK_BOT_TOKEN"),
|
|
20886
21148
|
githubAppId: digits.optional().describe("the GitHub App's id \u2192 GITHUB_APP_ID"),
|
|
20887
21149
|
githubInstallationId: digits.optional().describe("the GitHub App's installation id \u2192 GITHUB_APP_INSTALLATION_ID"),
|
|
20888
|
-
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"),
|
|
20889
21151
|
cloudflare: account.optional().describe(
|
|
20890
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)"
|
|
20891
21153
|
),
|
|
@@ -20895,7 +21157,7 @@ var init_setup = __esm({
|
|
|
20895
21157
|
dryRun: flag.optional().describe("write nothing; print each file as it would be written, secrets masked")
|
|
20896
21158
|
});
|
|
20897
21159
|
DEFAULT_NAME = "switchboard";
|
|
20898
|
-
setupInit =
|
|
21160
|
+
setupInit = defineCommand16({
|
|
20899
21161
|
id: "setup.init",
|
|
20900
21162
|
options: initOptions2,
|
|
20901
21163
|
action: "setup:write",
|
|
@@ -20995,13 +21257,13 @@ function renderStatus(output) {
|
|
|
20995
21257
|
function registerStatusCommands(registry) {
|
|
20996
21258
|
for (const cmd of statusCommands) registry.register(cmd);
|
|
20997
21259
|
}
|
|
20998
|
-
var
|
|
21260
|
+
var defineCommand17, statusShow, statusCommands;
|
|
20999
21261
|
var init_status = __esm({
|
|
21000
21262
|
"../../src/core/commands/status.ts"() {
|
|
21001
21263
|
"use strict";
|
|
21002
21264
|
init_commandRegistry();
|
|
21003
|
-
|
|
21004
|
-
statusShow =
|
|
21265
|
+
defineCommand17 = commandDefiner();
|
|
21266
|
+
statusShow = defineCommand17({
|
|
21005
21267
|
id: "status.show",
|
|
21006
21268
|
action: "status:read",
|
|
21007
21269
|
effect: "read",
|
|
@@ -21040,6 +21302,7 @@ function registerCoreCommands(registry) {
|
|
|
21040
21302
|
registerSetupCommands(registry);
|
|
21041
21303
|
registerContractCommands(registry);
|
|
21042
21304
|
registerDeliveryCommands(registry);
|
|
21305
|
+
registerArtifactsCommands(registry);
|
|
21043
21306
|
}
|
|
21044
21307
|
function coreCommandGroups() {
|
|
21045
21308
|
const registry = new CommandRegistry({ audit: () => {
|
|
@@ -21051,6 +21314,7 @@ var init_all = __esm({
|
|
|
21051
21314
|
"../../src/core/commands/all.ts"() {
|
|
21052
21315
|
"use strict";
|
|
21053
21316
|
init_commandRegistry();
|
|
21317
|
+
init_artifacts();
|
|
21054
21318
|
init_config4();
|
|
21055
21319
|
init_contract2();
|
|
21056
21320
|
init_delivery2();
|
|
@@ -21334,6 +21598,11 @@ function buildCoreCommands(config, store, wiring) {
|
|
|
21334
21598
|
images: imagesHostIO({ log: (l) => console.log(l), now: wiring.now ?? systemClock }),
|
|
21335
21599
|
cliVersion: cliVersionOnHost
|
|
21336
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
|
+
},
|
|
21337
21606
|
env: { bootstrap: bootstrapOnHost },
|
|
21338
21607
|
status: { snapshot: () => (wiring.status ?? unstampedStatus)() },
|
|
21339
21608
|
// `setup init` writes the operator's working directory — the one the CLI runs in.
|
|
@@ -21367,6 +21636,7 @@ var init_commandCatalogue = __esm({
|
|
|
21367
21636
|
init_clock();
|
|
21368
21637
|
init_run();
|
|
21369
21638
|
init_imagesHost();
|
|
21639
|
+
init_artifactsBucket();
|
|
21370
21640
|
init_secretsHost();
|
|
21371
21641
|
init_host3();
|
|
21372
21642
|
init_executor();
|
|
@@ -21585,6 +21855,12 @@ function runPageLink(id) {
|
|
|
21585
21855
|
if (!base) return void 0;
|
|
21586
21856
|
return `${base.replace(/\/+$/, "")}/runs/${encodeURIComponent(id)}`;
|
|
21587
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
|
+
}
|
|
21588
21864
|
function stripPlatformPrefix(id) {
|
|
21589
21865
|
const i = id.indexOf(":");
|
|
21590
21866
|
return i === -1 ? id : id.slice(i + 1);
|
|
@@ -24257,7 +24533,8 @@ async function readRequest(ctx) {
|
|
|
24257
24533
|
}
|
|
24258
24534
|
function resolveRun(deps, ctx) {
|
|
24259
24535
|
const { msg, directives, history } = ctx;
|
|
24260
|
-
const
|
|
24536
|
+
const fromTurns = lastThreadDirectives(history);
|
|
24537
|
+
const sticky = ctx.stickyAgent !== void 0 ? { ...fromTurns, agent: ctx.stickyAgent } : fromTurns;
|
|
24261
24538
|
const resolved = deps.config.resolve({
|
|
24262
24539
|
channelId: msg.channelId,
|
|
24263
24540
|
userId: msg.userId,
|
|
@@ -25082,7 +25359,7 @@ var init_tracingExecutor = __esm({
|
|
|
25082
25359
|
});
|
|
25083
25360
|
|
|
25084
25361
|
// ../../src/core/prDescription.ts
|
|
25085
|
-
import { z as
|
|
25362
|
+
import { z as z20 } from "zod";
|
|
25086
25363
|
function parsePrDescription(input) {
|
|
25087
25364
|
return PrDescriptionSchema.parse(input);
|
|
25088
25365
|
}
|
|
@@ -25370,34 +25647,34 @@ var init_prDescription = __esm({
|
|
|
25370
25647
|
"../../src/core/prDescription.ts"() {
|
|
25371
25648
|
"use strict";
|
|
25372
25649
|
init_redact();
|
|
25373
|
-
line2 =
|
|
25374
|
-
prose =
|
|
25375
|
-
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({
|
|
25376
25653
|
// Repo-relative: no leading `/`, no `..` SEGMENT (a filename like `a..b.ts` is fine).
|
|
25377
|
-
path:
|
|
25378
|
-
from:
|
|
25379
|
-
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()
|
|
25380
25657
|
}).refine((a) => a.to >= a.from, "to must be >= from");
|
|
25381
|
-
TourStepSchema =
|
|
25658
|
+
TourStepSchema = z20.object({
|
|
25382
25659
|
title: line2,
|
|
25383
25660
|
description: prose,
|
|
25384
25661
|
lookFor: prose.optional(),
|
|
25385
25662
|
anchor: TourAnchorSchema
|
|
25386
25663
|
});
|
|
25387
|
-
PrDescriptionSchema =
|
|
25664
|
+
PrDescriptionSchema = z20.object({
|
|
25388
25665
|
/** The PR title's single source. Metadata for the PR's own title field —
|
|
25389
25666
|
* never rendered into the body (GitHub shows the title itself). */
|
|
25390
25667
|
title: line2,
|
|
25391
25668
|
tldr: prose,
|
|
25392
25669
|
whatWhy: prose,
|
|
25393
|
-
tour:
|
|
25670
|
+
tour: z20.array(TourStepSchema).min(1),
|
|
25394
25671
|
/** Every touched file the Tour steps did not cover, one line each. */
|
|
25395
|
-
remaining:
|
|
25396
|
-
decisions:
|
|
25672
|
+
remaining: z20.array(z20.object({ path: line2, note: prose })),
|
|
25673
|
+
decisions: z20.array(z20.object({ title: line2, rationale: prose })).min(1),
|
|
25397
25674
|
risks: prose,
|
|
25398
|
-
validation:
|
|
25675
|
+
validation: z20.object({
|
|
25399
25676
|
summary: prose.optional(),
|
|
25400
|
-
criteria:
|
|
25677
|
+
criteria: z20.array(z20.object({ criterion: prose, proof: prose })).min(1)
|
|
25401
25678
|
})
|
|
25402
25679
|
});
|
|
25403
25680
|
REPO_RE = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
|
|
@@ -26169,10 +26446,11 @@ async function attachThroughStore(path, name, lead, artifacts, ctx) {
|
|
|
26169
26446
|
}
|
|
26170
26447
|
ctx.publish?.({ type: "artifact", direction: "out", key, name, size, contentType });
|
|
26171
26448
|
if (!ctx.uploadTicket) {
|
|
26172
|
-
const
|
|
26449
|
+
const link = artifacts.artifactUrl?.(key);
|
|
26450
|
+
const where = link ? ` \u2014 ${link}` : ` is on the run page as ${key}`;
|
|
26173
26451
|
await artifacts.reply(`${lead}
|
|
26174
|
-
\u{1F4CE} ${name} (${size} bytes)
|
|
26175
|
-
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`;
|
|
26176
26454
|
}
|
|
26177
26455
|
const kept = "the file is kept on the run page";
|
|
26178
26456
|
let ticket;
|
|
@@ -26639,7 +26917,7 @@ var init_runs2 = __esm({
|
|
|
26639
26917
|
});
|
|
26640
26918
|
|
|
26641
26919
|
// ../../src/tools/workspace.ts
|
|
26642
|
-
import { z as
|
|
26920
|
+
import { z as z21 } from "zod";
|
|
26643
26921
|
var bashTool, readFileTool, writeFileTool, NAME_STATUS_MARK, NAME_STATUS_MARK_LINE, OUTPUT_CUT_RE, diffDigestTool, submitVerdictTool, submitDispositionsTool, submitPrDescriptionTool, handoffEntry, submitHandoffTool, updateStatusTool, TOOLSETS;
|
|
26644
26922
|
var init_workspace = __esm({
|
|
26645
26923
|
"../../src/tools/workspace.ts"() {
|
|
@@ -26938,7 +27216,7 @@ ${raw.trim()}`;
|
|
|
26938
27216
|
try {
|
|
26939
27217
|
desc = parsePrDescription(input);
|
|
26940
27218
|
} catch (err2) {
|
|
26941
|
-
const detail = err2 instanceof
|
|
27219
|
+
const detail = err2 instanceof z21.ZodError ? err2.issues.map((i) => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ") : String(err2);
|
|
26942
27220
|
return `error: invalid PR description \u2014 ${detail}`;
|
|
26943
27221
|
}
|
|
26944
27222
|
ctx.onPrDescription?.(desc);
|
|
@@ -29483,7 +29761,8 @@ async function claimRun(deps, ctx) {
|
|
|
29483
29761
|
parentRunId,
|
|
29484
29762
|
coordinator,
|
|
29485
29763
|
seed,
|
|
29486
|
-
route: route3
|
|
29764
|
+
route: route3,
|
|
29765
|
+
seedLog
|
|
29487
29766
|
} = ctx;
|
|
29488
29767
|
const { resident, binding } = selection;
|
|
29489
29768
|
let ledgerRun = ctx.ledgerRun;
|
|
@@ -29528,8 +29807,9 @@ async function claimRun(deps, ctx) {
|
|
|
29528
29807
|
({ name, description, inputSchema }) => ({ name, description, inputSchema })
|
|
29529
29808
|
),
|
|
29530
29809
|
// The seed carries the EFFECTIVE budget, so a resume runs on what
|
|
29531
|
-
// this run was admitted with, not on the preset's own number
|
|
29532
|
-
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 } : {} },
|
|
29533
29813
|
// A stop asked of another container (`/runs/stop` there) reaches this
|
|
29534
29814
|
// run through its heartbeat and is honored like a local one; a fence
|
|
29535
29815
|
// (another generation took the run) is a hard stop — nothing more may
|
|
@@ -29599,7 +29879,7 @@ function writeFileScripts(path, content) {
|
|
|
29599
29879
|
chunks.push(content.slice(i, i + WRITE_CHUNK_CHARS));
|
|
29600
29880
|
const dir = path.slice(0, path.lastIndexOf("/")) || ".";
|
|
29601
29881
|
return chunks.map(
|
|
29602
|
-
(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)}`
|
|
29603
29883
|
);
|
|
29604
29884
|
}
|
|
29605
29885
|
function startScript(start3) {
|
|
@@ -29610,7 +29890,7 @@ function startScript(start3) {
|
|
|
29610
29890
|
`pi ${args.map(shellQuote).join(" ")} <&3 2>>${shellQuote(paths.errLog)} | ${LOG_FILTER} >> ${shellQuote(paths.log)}`
|
|
29611
29891
|
].join("; ");
|
|
29612
29892
|
return [
|
|
29613
|
-
`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)})`,
|
|
29614
29894
|
`rm -f ${shellQuote(paths.fifo)}`,
|
|
29615
29895
|
`mkfifo -m 600 ${shellQuote(paths.fifo)}`,
|
|
29616
29896
|
`: > ${shellQuote(paths.log)}`,
|
|
@@ -29638,6 +29918,9 @@ function killScript(pid) {
|
|
|
29638
29918
|
function tailScript(path, bytes) {
|
|
29639
29919
|
return `tail -c ${bytes} ${shellQuote(path)} 2>/dev/null || true`;
|
|
29640
29920
|
}
|
|
29921
|
+
function removeScript(dir) {
|
|
29922
|
+
return `rm -rf ${shellQuote(dir)}`;
|
|
29923
|
+
}
|
|
29641
29924
|
function stdoutOf(operation, out) {
|
|
29642
29925
|
const exit = parseExitPrefix(out);
|
|
29643
29926
|
if (exit.failed) throw new PiContainerError(operation, out);
|
|
@@ -29706,6 +29989,9 @@ var init_container = __esm({
|
|
|
29706
29989
|
return "";
|
|
29707
29990
|
}
|
|
29708
29991
|
}
|
|
29992
|
+
async remove(paths) {
|
|
29993
|
+
stdoutOf("remove", await this.exec(removeScript(paths.dir)));
|
|
29994
|
+
}
|
|
29709
29995
|
exec(script, env) {
|
|
29710
29996
|
return this.executor.exec(script, { timeoutMs: OP_TIMEOUT_MS, ...env ? { env } : {} });
|
|
29711
29997
|
}
|
|
@@ -30382,9 +30668,8 @@ function piBuiltinToolsFor(identity2) {
|
|
|
30382
30668
|
function piThinkingLevel(effort2) {
|
|
30383
30669
|
return effort2;
|
|
30384
30670
|
}
|
|
30385
|
-
function piRunPaths(runId3
|
|
30386
|
-
const
|
|
30387
|
-
const dir = `${root}/${runId3}`;
|
|
30671
|
+
function piRunPaths(runId3) {
|
|
30672
|
+
const dir = `/tmp/switchboard-pi-${runId3}`;
|
|
30388
30673
|
return {
|
|
30389
30674
|
dir,
|
|
30390
30675
|
agentDir: `${dir}/agent`,
|
|
@@ -30631,7 +30916,7 @@ async function runPiHarness(deps, run2) {
|
|
|
30631
30916
|
emit({ type: "run_note", kind, summary, ...mode ? { mode } : {} });
|
|
30632
30917
|
};
|
|
30633
30918
|
const bridge = new PiBridge({ emit, onProgress: run2.onProgress, agentSpan, clock: clock3 });
|
|
30634
|
-
const paths = piRunPaths(run2.runId
|
|
30919
|
+
const paths = piRunPaths(run2.runId);
|
|
30635
30920
|
const remainingMs = run2.resume?.remainingMs ?? run2.agent.maxMinutes * 6e4;
|
|
30636
30921
|
const deadline = now() + remainingMs;
|
|
30637
30922
|
const warnAt = deadline - Math.min(3 * 6e4, run2.agent.maxMinutes * 15e3);
|
|
@@ -30903,6 +31188,8 @@ async function runPiHarness(deps, run2) {
|
|
|
30903
31188
|
forget();
|
|
30904
31189
|
if (pid !== void 0) await container.kill(pid).catch(() => {
|
|
30905
31190
|
});
|
|
31191
|
+
await container.remove(paths).catch(() => {
|
|
31192
|
+
});
|
|
30906
31193
|
agentSpan?.end(hardStopped || bypass ? "error" : "ok");
|
|
30907
31194
|
}
|
|
30908
31195
|
}
|
|
@@ -31577,12 +31864,11 @@ async function runLoop2(deps, ctx) {
|
|
|
31577
31864
|
const uploadTicket = io.uploadTicket?.bind(io);
|
|
31578
31865
|
const nextStagedIndex = ctx.stagingIndex ?? stagingIndex();
|
|
31579
31866
|
let artifactSeq = 0;
|
|
31580
|
-
const runUrl = runPageLink(run2.id);
|
|
31581
31867
|
const artifacts = deps.artifacts ? {
|
|
31582
31868
|
store: deps.artifacts,
|
|
31583
31869
|
runId: run2.id,
|
|
31584
31870
|
nextSeq: () => ++artifactSeq,
|
|
31585
|
-
|
|
31871
|
+
artifactUrl: (key) => artifactLink(run2.id, key, run2.token),
|
|
31586
31872
|
reply: (text) => io.reply(text)
|
|
31587
31873
|
} : void 0;
|
|
31588
31874
|
const toolContext = {
|
|
@@ -31651,10 +31937,6 @@ async function runLoop2(deps, ctx) {
|
|
|
31651
31937
|
...ownBranch !== void 0 ? { branch: ownBranch } : {},
|
|
31652
31938
|
protectedBranches
|
|
31653
31939
|
},
|
|
31654
|
-
// The resident runs this thread's commands as its pool user: pi's
|
|
31655
|
-
// files go under that user's own root, never one another thread's
|
|
31656
|
-
// user created (harness-pi.md item 4).
|
|
31657
|
-
...binding?.user ? { user: binding.user } : {},
|
|
31658
31940
|
...round2.selection.backend ? { backend: round2.selection.backend } : {},
|
|
31659
31941
|
span: root,
|
|
31660
31942
|
control: run2.control,
|
|
@@ -33326,15 +33608,7 @@ var init_settle = __esm({
|
|
|
33326
33608
|
});
|
|
33327
33609
|
|
|
33328
33610
|
// ../../src/core/dispatch/lineage.ts
|
|
33329
|
-
|
|
33330
|
-
let newest;
|
|
33331
|
-
try {
|
|
33332
|
-
const page2 = await service.listRuns({ status: "all", visibleTo: { kind: "all" }, threadKey, limit: 1 });
|
|
33333
|
-
newest = page2.runs[0];
|
|
33334
|
-
} catch (err2) {
|
|
33335
|
-
console.warn(`[lineage] ${threadKey}: thread read failed \u2014 ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
33336
|
-
return void 0;
|
|
33337
|
-
}
|
|
33611
|
+
function lineageOf(newest) {
|
|
33338
33612
|
if (newest === void 0 || newest.parentRunId === void 0) return void 0;
|
|
33339
33613
|
return {
|
|
33340
33614
|
parentRunId: newest.parentRunId,
|
|
@@ -33391,6 +33665,161 @@ var init_lineage = __esm({
|
|
|
33391
33665
|
}
|
|
33392
33666
|
});
|
|
33393
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
|
+
|
|
33394
33823
|
// ../../src/core/runEnding.ts
|
|
33395
33824
|
function createRunEnding(deps) {
|
|
33396
33825
|
const log = deps.log ?? console.error;
|
|
@@ -33528,7 +33957,8 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
33528
33957
|
const { directives, history } = await readRequest({ msg, io, root });
|
|
33529
33958
|
if (await answerOperation(deps, { msg, io, ending, trace, directives, history })) return ended;
|
|
33530
33959
|
const runsService = deps.runs ?? createRunsService({ registry, store: deps.runStore });
|
|
33531
|
-
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]);
|
|
33532
33962
|
const parent = opts.parent ?? (lineage ? lineageParent(lineage) : void 0);
|
|
33533
33963
|
const tellLineage = async (heard) => {
|
|
33534
33964
|
if (!lineage) return;
|
|
@@ -33539,7 +33969,18 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
33539
33969
|
heard
|
|
33540
33970
|
);
|
|
33541
33971
|
};
|
|
33542
|
-
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
|
+
});
|
|
33543
33984
|
const { sticky } = settled;
|
|
33544
33985
|
let { resolved, agentSource } = settled;
|
|
33545
33986
|
let route3;
|
|
@@ -33677,8 +34118,23 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
33677
34118
|
}
|
|
33678
34119
|
const contractBlock = opts.contract ? renderContract(opts.contract, { maxChars: DEFAULT_CONTRACT_MAX_CHARS }).text : void 0;
|
|
33679
34120
|
const requestText = route3?.parts ? compoundBrief(directives.text, route3.parts) : directives.text;
|
|
33680
|
-
const
|
|
33681
|
-
|
|
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);
|
|
33682
34138
|
const messages = resume ? resume.plan.messages : contractBlock !== void 0 && agent.name !== "review" ? withContractInFirstUserTurn(built, contractBlock) : built;
|
|
33683
34139
|
const headPreflight = await authorizePrHead({
|
|
33684
34140
|
msg,
|
|
@@ -33716,12 +34172,14 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
33716
34172
|
parentRunId,
|
|
33717
34173
|
coordinator,
|
|
33718
34174
|
seed,
|
|
33719
|
-
...
|
|
34175
|
+
...seedTurns ? { seedTurns } : {},
|
|
33720
34176
|
agentSource,
|
|
33721
34177
|
...routeEvent ? { route: routeEvent } : {}
|
|
33722
34178
|
});
|
|
33723
34179
|
const { run: run2, runId: runId3, channelVisibility, liveUrl, publishText, publishMeta } = registration;
|
|
33724
34180
|
registered = run2;
|
|
34181
|
+
for (const summary of seedNotes)
|
|
34182
|
+
registry.publish(run2.id, { type: "run_note", kind: "seed", summary: oneLine(summary), at: clock3() });
|
|
33725
34183
|
await tellLineage({ kind: "started", runId: runId3 });
|
|
33726
34184
|
const staged = !resume && deps.artifacts && msg.staged && msg.staged.length > 0 ? msg.staged : [];
|
|
33727
34185
|
const nextStagedIndex = stagingIndex();
|
|
@@ -33886,7 +34344,8 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
33886
34344
|
root,
|
|
33887
34345
|
parentRunId,
|
|
33888
34346
|
coordinator,
|
|
33889
|
-
seed
|
|
34347
|
+
seed,
|
|
34348
|
+
...session ? { seedLog: session.log } : {}
|
|
33890
34349
|
});
|
|
33891
34350
|
const { spawn: spawn7, runs, steer, wait } = runToolCapabilities(
|
|
33892
34351
|
{ core: deps, dispatch, registry, clock: clock3 },
|
|
@@ -34067,6 +34526,9 @@ var init_dispatcher = __esm({
|
|
|
34067
34526
|
init_codingChild();
|
|
34068
34527
|
init_settle();
|
|
34069
34528
|
init_lineage();
|
|
34529
|
+
init_seed();
|
|
34530
|
+
init_thread();
|
|
34531
|
+
init_select();
|
|
34070
34532
|
init_spawn();
|
|
34071
34533
|
init_runsService();
|
|
34072
34534
|
init_runRegistry();
|
|
@@ -34468,24 +34930,6 @@ var init_flusher = __esm({
|
|
|
34468
34930
|
}
|
|
34469
34931
|
});
|
|
34470
34932
|
|
|
34471
|
-
// ../../src/core/runLedger/sessionLog.ts
|
|
34472
|
-
function sessionKey(threadKey, agent) {
|
|
34473
|
-
return `${threadKey}:${agent ?? "-"}`;
|
|
34474
|
-
}
|
|
34475
|
-
function requestIndex(seed) {
|
|
34476
|
-
for (let i = seed.length - 1; i >= 0; i--) if (seed[i].role === "user") return i;
|
|
34477
|
-
return 0;
|
|
34478
|
-
}
|
|
34479
|
-
var DEFAULT_SESSION_LOG_MAX_BYTES;
|
|
34480
|
-
var init_sessionLog = __esm({
|
|
34481
|
-
"../../src/core/runLedger/sessionLog.ts"() {
|
|
34482
|
-
"use strict";
|
|
34483
|
-
init_runRecord();
|
|
34484
|
-
init_runRecord();
|
|
34485
|
-
DEFAULT_SESSION_LOG_MAX_BYTES = DEFAULT_RETENTION_POLICY.sessionLogMaxBytes;
|
|
34486
|
-
}
|
|
34487
|
-
});
|
|
34488
|
-
|
|
34489
34933
|
// ../../src/core/runLedger/types.ts
|
|
34490
34934
|
var LEASE_MS, HEARTBEAT_MS, APPEND_FLUSH_MS, APPEND_FLUSH_EVENTS, TRANSCRIPT_REQUEST_BYTES, TRANSCRIPT_PART_BYTES, ATTACHMENT_REF_BYTES, GEN_PATTERN;
|
|
34491
34935
|
var init_types5 = __esm({
|
|
@@ -34538,7 +34982,15 @@ function createLedgerWriteThrough(opts) {
|
|
|
34538
34982
|
if (opts2.seed) {
|
|
34539
34983
|
const key = sessionKey(req.threadKey, req.meta.agent);
|
|
34540
34984
|
const next = await ledger.sessionTail(key);
|
|
34541
|
-
|
|
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 } };
|
|
34542
34994
|
}
|
|
34543
34995
|
const result = await ledger.claim({
|
|
34544
34996
|
runId: req.runId,
|
|
@@ -34699,7 +35151,8 @@ function createLedgerWriteThrough(opts) {
|
|
|
34699
35151
|
* closes `interrupted`. */
|
|
34700
35152
|
async seed(messages, budgetMs) {
|
|
34701
35153
|
const base = this.session?.seedFrom ?? 0;
|
|
34702
|
-
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 }));
|
|
34703
35156
|
try {
|
|
34704
35157
|
const seeded = await ledger.seed(this.runId, gen, turns, this.session?.key);
|
|
34705
35158
|
if (!seeded.ok) {
|
|
@@ -34869,7 +35322,7 @@ function createLedgerWriteThrough(opts) {
|
|
|
34869
35322
|
const seed = req.seed?.messages;
|
|
34870
35323
|
if (reserved instanceof TrackedRun) {
|
|
34871
35324
|
if (!reserved.tracked()) return void 0;
|
|
34872
|
-
const claimed3 = await claim(req, seed ? { seed } : {});
|
|
35325
|
+
const claimed3 = await claim(req, seed ? { seed, ...req.seed?.log ? { log: req.seed.log } : {} } : {});
|
|
34873
35326
|
if (claimed3.outcome === "fenced") {
|
|
34874
35327
|
reserved.detach("promotion refused (fenced)");
|
|
34875
35328
|
return void 0;
|
|
@@ -34883,7 +35336,7 @@ function createLedgerWriteThrough(opts) {
|
|
|
34883
35336
|
if (req.seed) await reserved.seed(req.seed.messages, req.seed.budgetMs);
|
|
34884
35337
|
return reserved;
|
|
34885
35338
|
}
|
|
34886
|
-
const claimed2 = await claim(req, seed ? { seed } : {});
|
|
35339
|
+
const claimed2 = await claim(req, seed ? { seed, ...req.seed?.log ? { log: req.seed.log } : {} } : {});
|
|
34887
35340
|
if (claimed2.outcome === "fenced") {
|
|
34888
35341
|
warn(`[ledger] ${req.threadKey} not tracked: run ${req.runId} is live under another generation`);
|
|
34889
35342
|
return void 0;
|
|
@@ -34932,6 +35385,7 @@ function createLedgerWriteThrough(opts) {
|
|
|
34932
35385
|
return [];
|
|
34933
35386
|
}
|
|
34934
35387
|
},
|
|
35388
|
+
readSessionTail: (key, maxBytes) => ledger.readSessionTail(key, maxBytes),
|
|
34935
35389
|
async handoff() {
|
|
34936
35390
|
const candidates = [...live].filter((r) => r.resumable && r.tracked() && !r.handedOff);
|
|
34937
35391
|
if (candidates.length === 0) return { marked: [] };
|
|
@@ -34982,6 +35436,9 @@ var init_writeThrough = __esm({
|
|
|
34982
35436
|
async readInbox(_runId, _afterSeq) {
|
|
34983
35437
|
return [];
|
|
34984
35438
|
}
|
|
35439
|
+
async readSessionTail(_key, _maxBytes) {
|
|
35440
|
+
return { from: 0, transcript: { complete: true, turns: 0, messages: [], compactions: [] } };
|
|
35441
|
+
}
|
|
34985
35442
|
async handoff() {
|
|
34986
35443
|
return { marked: [] };
|
|
34987
35444
|
}
|
|
@@ -36895,7 +37352,8 @@ ${file.text}`));
|
|
|
36895
37352
|
if (STATUS_PREFIXES.some((p) => text.startsWith(p))) continue;
|
|
36896
37353
|
const files = mm.bot_id ? void 0 : mm.files;
|
|
36897
37354
|
if (!text && !files?.length) continue;
|
|
36898
|
-
|
|
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 });
|
|
36899
37357
|
}
|
|
36900
37358
|
const imagesByIndex = [];
|
|
36901
37359
|
const documentsByIndex = [];
|
|
@@ -36922,11 +37380,11 @@ ${file.text}`));
|
|
|
36922
37380
|
}
|
|
36923
37381
|
}
|
|
36924
37382
|
for (let i = 0; i < kept.length; i++) {
|
|
36925
|
-
const { role, text } = kept[i];
|
|
37383
|
+
const { role, text, at } = kept[i];
|
|
36926
37384
|
const images = imagesByIndex[i];
|
|
36927
37385
|
const documents = documentsByIndex[i];
|
|
36928
37386
|
if (!text && !images && !documents) continue;
|
|
36929
|
-
items.push({ role, text, images, documents });
|
|
37387
|
+
items.push({ role, text, ...at !== void 0 ? { at } : {}, images, documents });
|
|
36930
37388
|
}
|
|
36931
37389
|
} catch {
|
|
36932
37390
|
}
|