@coreplane/switchboard 1.256.0 → 1.258.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/config/config.example.yaml +14 -0
- package/dist/assets/deploy/cloudflare-memory/worker.ts +340 -7
- package/dist/assets/deploy/cloudflare-resident/drain.ts +49 -4
- package/dist/assets/deploy/cloudflare-resident/worker.ts +52 -4
- package/dist/assets/package-lock.json +3 -3
- package/dist/assets/package.json +5 -3
- package/dist/assets/project.json +17 -9
- package/dist/assets/source.json +3 -3
- package/dist/assets/src/agents/registry.ts +65 -2
- package/dist/assets/src/core/authz/grants.ts +12 -0
- package/dist/assets/src/core/authz/policy.ts +15 -0
- package/dist/assets/src/core/budgets.ts +66 -18
- package/dist/assets/src/core/coordinator/contract.ts +45 -5
- package/dist/assets/src/core/coordinator/driver.ts +6 -3
- package/dist/assets/src/core/delivery.ts +8 -5
- package/dist/assets/src/core/pipelineStanding.ts +2 -0
- package/dist/assets/src/core/plane/decide.ts +477 -12
- package/dist/assets/src/core/plane/findings.ts +120 -0
- package/dist/assets/src/core/runEvents.ts +54 -14
- package/dist/assets/src/core/runFriction.ts +16 -0
- package/dist/assets/src/core/runLedger/types.ts +16 -3
- package/dist/assets/src/core/runRecord.ts +12 -0
- package/dist/assets/src/core/ship/contract.ts +14 -2
- package/dist/assets/src/core/ship/coordinator.ts +179 -51
- package/dist/assets/src/core/ship/renewal.ts +23 -20
- package/dist/assets/src/core/trace/attrs.ts +1 -1
- package/dist/assets/src/core/untrusted.ts +35 -0
- package/dist/assets/src/execution/residentCredentials.ts +7 -4
- package/dist/assets/web/dist/.vite/manifest.json +97 -72
- package/dist/assets/web/dist/assets/{DeliveryPage-BBAyLwPq.js → DeliveryPage-DadntjSp.js} +1 -1
- package/dist/assets/web/dist/assets/HomePage-BEEpTnVT.js +1 -0
- package/dist/assets/web/dist/assets/{PendingTurnRow-DGINv9XT.js → PendingTurnRow-DBPMLVsm.js} +1 -1
- package/dist/assets/web/dist/assets/PlanePage-DLusMGQ0.js +1 -0
- package/dist/assets/web/dist/assets/{ResidentDetailPage-jYhEeeyu.js → ResidentDetailPage-CPnHnrxy.js} +1 -1
- package/dist/assets/web/dist/assets/{ResidentsIndexPage-DvFmlV4U.js → ResidentsIndexPage-C9hASwHL.js} +1 -1
- package/dist/assets/web/dist/assets/RunFoldRow-OPe7Z0Cz.js +1 -0
- package/dist/assets/web/dist/assets/{RunRoutePage-CvZ-TOT3.js → RunRoutePage-o1xzkTGZ.js} +4 -4
- package/dist/assets/web/dist/assets/RunsIndexPage-0YAClYQh.js +1 -0
- package/dist/assets/web/dist/assets/{ScheduledPage-Viim-bus.js → ScheduledPage-BIdfC0V3.js} +1 -1
- package/dist/assets/web/dist/assets/{SettingsPage-CYUy8McC.js → SettingsPage-CnqWAjl3.js} +1 -1
- package/dist/assets/web/dist/assets/SilentTurn-DGNg0sIZ.js +2 -0
- package/dist/assets/web/dist/assets/SlackMark-CtiHrNjr.js +1 -0
- package/dist/assets/web/dist/assets/{StatusDot-Dv6UMaPy.js → StatusDot-D_D_iJS8.js} +1 -1
- package/dist/assets/web/dist/assets/{Tooltip-Bd-5Rypv.js → Tooltip-DVFmM7on.js} +1 -1
- package/dist/assets/web/dist/assets/UnitRoutePage-7fAXFoB_.js +1 -0
- package/dist/assets/web/dist/assets/budgets-BRLm6oID.js +1 -0
- package/dist/assets/web/dist/assets/{dist-Nl3uaxrP.js → dist-C1VX-_mm.js} +1 -1
- package/dist/assets/web/dist/assets/durationTone-CVpX_yIk.js +1 -0
- package/dist/assets/web/dist/assets/{indexRow-DborJPFp.js → indexRow-BO_GIdF6.js} +1 -1
- package/dist/assets/web/dist/assets/main-Cl7xHG34.js +28 -0
- package/dist/assets/web/dist/assets/main-DGC6WFqS.css +1 -0
- package/dist/assets/web/dist/assets/{sseReplay-DE6wv1Ua.js → sseReplay-BjlKmQsY.js} +1 -1
- package/dist/cli.js +3096 -1136
- package/package.json +1 -1
- package/dist/assets/web/dist/assets/HomePage-BEiStFwW.js +0 -3
- package/dist/assets/web/dist/assets/PlanePage-JEj-lqgz.js +0 -1
- package/dist/assets/web/dist/assets/RunFoldRow-DvWzR1JQ.js +0 -1
- package/dist/assets/web/dist/assets/RunsIndexPage-JqVSDOok.js +0 -1
- package/dist/assets/web/dist/assets/UnitRoutePage-B81wEnKN.js +0 -1
- package/dist/assets/web/dist/assets/budgets-c1eumrqD.js +0 -1
- package/dist/assets/web/dist/assets/durationTone-U_rOqo6r.js +0 -1
- package/dist/assets/web/dist/assets/main-C4QfwybO.css +0 -1
- package/dist/assets/web/dist/assets/main-DRxWlffc.js +0 -28
|
@@ -233,6 +233,26 @@ export interface ChecksSettledPayload {
|
|
|
233
233
|
settledAt: number;
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
+
/** The event the merge watch sends a waiting unit when its pull request
|
|
237
|
+
* merged, whoever merged (record 0071, mechanism three): the unit ends
|
|
238
|
+
* `merged` by other. The type names the unit within the instance, the
|
|
239
|
+
* nudge's alphabet and clip rule. */
|
|
240
|
+
export const PULL_MERGED_EVENT_PREFIX = "pr-merged-";
|
|
241
|
+
export function pullMergedEventType(key: { instanceId: string; unit: string }): string {
|
|
242
|
+
const suffix = `-${key.unit}`;
|
|
243
|
+
const room = 100 - PULL_MERGED_EVENT_PREFIX.length - suffix.length;
|
|
244
|
+
return `${PULL_MERGED_EVENT_PREFIX}${key.instanceId.slice(0, room)}${suffix}`;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/** What the merged event carries — the pull request and the merge's facts;
|
|
248
|
+
* the waiting unit confirms through its own pr-check before it acts. */
|
|
249
|
+
export interface PullMergedPayload {
|
|
250
|
+
repo: string;
|
|
251
|
+
number: number;
|
|
252
|
+
sha: string;
|
|
253
|
+
mergedAt: string;
|
|
254
|
+
}
|
|
255
|
+
|
|
236
256
|
/** What the event carries — ids, a status and a clock; the parent confirms
|
|
237
257
|
* through `read-record` before it acts, so nothing more rides here. */
|
|
238
258
|
export interface RunFinishedPayload {
|
|
@@ -379,17 +399,17 @@ export interface UnitIdle {
|
|
|
379
399
|
wakes: number;
|
|
380
400
|
}
|
|
381
401
|
|
|
382
|
-
/** One unit of the plan an instance runs (a task string is a generated plan of
|
|
383
|
-
* one unit, `U1`): its branch, the units it waits on, and — as the runner
|
|
384
|
-
* reaches it — its thread, its pull request, the round boundaries the card
|
|
385
|
-
* drew and how it ended. One row a person can read for "what happened to this
|
|
386
|
-
* unit". */
|
|
387
402
|
/** What the severity gate caught on a round: the level in force and the gated findings as `id (severity)`. */
|
|
388
403
|
export interface RoundGate {
|
|
389
404
|
level: AddressSeverity;
|
|
390
405
|
findings: string[];
|
|
391
406
|
}
|
|
392
407
|
|
|
408
|
+
/** One unit of the plan an instance runs (a task string is a generated plan of
|
|
409
|
+
* one unit, `U1`): its branch, the units it waits on, and — as the runner
|
|
410
|
+
* reaches it — its thread, its pull request, the round boundaries the card
|
|
411
|
+
* drew and how it ended. One row a person can read for "what happened to this
|
|
412
|
+
* unit". */
|
|
393
413
|
export interface CoordinatorUnit {
|
|
394
414
|
instanceId: string;
|
|
395
415
|
/** `U<n>` as the plan spells it. */
|
|
@@ -606,6 +626,26 @@ export async function sendChecksSettled(
|
|
|
606
626
|
}
|
|
607
627
|
}
|
|
608
628
|
|
|
629
|
+
/** The one send per merged fact the watch observed (record 0071): best effort
|
|
630
|
+
* like `sendRunFinished` — a refusal is answered, never thrown; the waiting
|
|
631
|
+
* unit's bounded wait re-asks its own pr-check on its next chunk. */
|
|
632
|
+
export async function sendPullMerged(
|
|
633
|
+
workflow: WorkflowSender | undefined,
|
|
634
|
+
key: { instanceId: string; unit: string },
|
|
635
|
+
payload: PullMergedPayload,
|
|
636
|
+
): Promise<RunFinishedSend> {
|
|
637
|
+
const instance = key.instanceId;
|
|
638
|
+
if (!workflow) return { kind: "no-binding", instance };
|
|
639
|
+
const type = pullMergedEventType(key);
|
|
640
|
+
try {
|
|
641
|
+
const handle = await workflow.get(instance);
|
|
642
|
+
await handle.sendEvent({ type, payload });
|
|
643
|
+
return { kind: "sent", instance, type };
|
|
644
|
+
} catch (err) {
|
|
645
|
+
return { kind: "failed", instance, type, reason: err instanceof Error ? err.message : String(err) };
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
609
649
|
/** One deploy-roll signal to the child's parent (run-history item 47a): best
|
|
610
650
|
* effort like `sendRunFinished` — a refusal is answered, never thrown; a lost
|
|
611
651
|
* send costs the wait a chunk, never the round. */
|
|
@@ -61,7 +61,7 @@ import {
|
|
|
61
61
|
type UnitEnding,
|
|
62
62
|
type UnitPipelineState,
|
|
63
63
|
stepPrefixOf,
|
|
64
|
-
type
|
|
64
|
+
type LeaseSegmentProgress,
|
|
65
65
|
} from "../ship/coordinator.js";
|
|
66
66
|
import {
|
|
67
67
|
checksSettledEventType,
|
|
@@ -451,12 +451,15 @@ function prCheckReturn(step: string, a: BotAnswer): StepReturn {
|
|
|
451
451
|
* ask's answer carries `retried` instead: whether the re-run was dispatched,
|
|
452
452
|
* so the machine never waits on a head an undispatched re-run left unchanged. */
|
|
453
453
|
function checksReturn(step: string, a: BotAnswer): StepReturn {
|
|
454
|
-
const { ok, checks, retried, at } = a.body;
|
|
454
|
+
const { ok, checks, draft, retried, at } = a.body;
|
|
455
455
|
if (ok !== true) throw new UnreadableAnswer("checks", a, "ok");
|
|
456
456
|
return {
|
|
457
457
|
type: "checks",
|
|
458
458
|
step,
|
|
459
459
|
...(isRoundChecks(checks) ? { checks } : {}),
|
|
460
|
+
// The pull request is a draft (issue 2063): the machine's table holds the
|
|
461
|
+
// unit for the ready event instead of merging or ending without a cause.
|
|
462
|
+
...(draft === true ? { draft: true } : {}),
|
|
460
463
|
...(typeof retried === "boolean" ? { retried } : {}),
|
|
461
464
|
at,
|
|
462
465
|
};
|
|
@@ -691,7 +694,7 @@ async function runUnit(
|
|
|
691
694
|
instanceId: string,
|
|
692
695
|
node: PlanUnitNode,
|
|
693
696
|
plan: PlanFacts,
|
|
694
|
-
session?:
|
|
697
|
+
session?: LeaseSegmentProgress,
|
|
695
698
|
): Promise<UnitEnding> {
|
|
696
699
|
const unit = node.id;
|
|
697
700
|
// A renewal's segment names its steps under the segment (`U10/s2/…`), so
|
|
@@ -186,7 +186,10 @@ export interface WeekRow extends DeliveryIndicators {
|
|
|
186
186
|
prs: number[];
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
|
|
189
|
+
/** One row per board issue the pull requests link — the report's "Issues:"
|
|
190
|
+
* block and the Delivery page's table. The JSON field stays `units` (a served
|
|
191
|
+
* shape older readers hold); only the words are the issue's. */
|
|
192
|
+
export interface IssueRow extends DeliveryIndicators {
|
|
190
193
|
/** The board issue, or null for the pull requests no issue claims. */
|
|
191
194
|
issue: number | null;
|
|
192
195
|
title: string;
|
|
@@ -198,7 +201,7 @@ export interface DeliveryReport {
|
|
|
198
201
|
repo: string;
|
|
199
202
|
range: DeliveryRange;
|
|
200
203
|
weeks: WeekRow[];
|
|
201
|
-
units:
|
|
204
|
+
units: IssueRow[];
|
|
202
205
|
prs: PullRequestRow[];
|
|
203
206
|
totals: DeliveryIndicators;
|
|
204
207
|
identities: DeliveryIdentities;
|
|
@@ -448,7 +451,7 @@ export function buildDeliveryReport(input: DeliveryInput): DeliveryReport {
|
|
|
448
451
|
const key = p.issue?.number ?? null;
|
|
449
452
|
byIssue.set(key, [...(byIssue.get(key) ?? []), p]);
|
|
450
453
|
}
|
|
451
|
-
const units:
|
|
454
|
+
const units: IssueRow[] = [...byIssue.entries()]
|
|
452
455
|
.sort(([a], [b]) => (a === null ? 1 : b === null ? -1 : a - b))
|
|
453
456
|
.map(([issue, rows]) => {
|
|
454
457
|
const first = rows.find((r) => r.issue !== undefined)?.issue;
|
|
@@ -572,7 +575,7 @@ function coverage(report: DeliveryReport): string {
|
|
|
572
575
|
return `the newest ${report.totals.prsMerged} pull requests only${from}`;
|
|
573
576
|
}
|
|
574
577
|
|
|
575
|
-
/** One block per week, then the
|
|
578
|
+
/** One block per week, then the issues — single-spaced lines, so chat carries them as they are. */
|
|
576
579
|
export function renderDeliveryReport(report: DeliveryReport, nowMs: number = systemClock()): string {
|
|
577
580
|
const lines: string[] = [
|
|
578
581
|
[
|
|
@@ -597,7 +600,7 @@ export function renderDeliveryReport(report: DeliveryReport, nowMs: number = sys
|
|
|
597
600
|
);
|
|
598
601
|
}
|
|
599
602
|
if (report.units.length > 0) {
|
|
600
|
-
lines.push("", "
|
|
603
|
+
lines.push("", "Issues:");
|
|
601
604
|
for (const u of report.units) {
|
|
602
605
|
const prs = `${u.prs.length === 1 ? "PR" : "PRs"} ${u.prs.join(", ")}`;
|
|
603
606
|
const who = u.issue === null ? "(no issue)" : `${u.issue} ${u.title}`;
|
|
@@ -99,6 +99,7 @@ export const ROUND_STAGE = {
|
|
|
99
99
|
dequeued: "fix",
|
|
100
100
|
aborted: "hold",
|
|
101
101
|
stopped: "hold",
|
|
102
|
+
held: "hold",
|
|
102
103
|
continued: "continue",
|
|
103
104
|
idle: "idle",
|
|
104
105
|
} as const satisfies Record<ShipRoundOutcome, Stage | "start" | "continue" | "hold">;
|
|
@@ -171,6 +172,7 @@ export const ROUND_OUTCOME_WORDS = {
|
|
|
171
172
|
dequeued: "removed from the merge queue",
|
|
172
173
|
aborted: "aborted",
|
|
173
174
|
stopped: "stopped",
|
|
175
|
+
held: "held",
|
|
174
176
|
continued: "continuing",
|
|
175
177
|
idle: "idle",
|
|
176
178
|
} as const satisfies Record<ShipRoundOutcome, string>;
|