toolroll 0.9.71 → 0.9.72
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/CHANGELOG.md +79 -0
- package/dist/agent-fence.d.ts +5 -2
- package/dist/agent-fence.js +5 -2
- package/dist/approval-authority.d.ts +20 -0
- package/dist/approval-authority.js +67 -0
- package/dist/assignment.js +26 -4
- package/dist/browser/workspace.css +1 -1
- package/dist/builder.js +48 -6
- package/dist/chat-decide.js +17 -2
- package/dist/check-access.js +2 -2
- package/dist/check-report.d.ts +109 -0
- package/dist/check-report.js +204 -0
- package/dist/claim.js +1 -1
- package/dist/commit-extract.d.ts +94 -0
- package/dist/commit-extract.js +436 -0
- package/dist/contracts/console-api.d.ts +1 -1
- package/dist/contracts/console-api.js +1 -0
- package/dist/contracts/flow.d.ts +16 -0
- package/dist/contracts/flow.js +3 -0
- package/dist/contracts/release-check.d.ts +335 -0
- package/dist/contracts/release-check.js +159 -0
- package/dist/contracts/release-terms.d.ts +60 -0
- package/dist/contracts/release-terms.js +70 -0
- package/dist/contracts/verification-receipt.d.ts +42 -8
- package/dist/contracts/verification-receipt.js +24 -7
- package/dist/contracts/verification-view.d.ts +1 -0
- package/dist/deploy-gate.d.ts +17 -0
- package/dist/deploy-gate.js +68 -0
- package/dist/dispatch.js +3 -10
- package/dist/dispose.js +4 -1
- package/dist/evidence-pack.d.ts +1 -1
- package/dist/evidence-pack.js +20 -2
- package/dist/evidence.d.ts +1 -0
- package/dist/evidence.js +2 -1
- package/dist/flow-engine.js +5 -1
- package/dist/flow-pull-request.d.ts +5 -2
- package/dist/flow-pull-request.js +14 -5
- package/dist/flow-schedule.js +25 -6
- package/dist/flows-ui.js +7 -1
- package/dist/invoke.d.ts +17 -6
- package/dist/invoke.js +48 -18
- package/dist/lead-status.js +5 -2
- package/dist/live-terminal.d.ts +10 -6
- package/dist/live-terminal.js +55 -14
- package/dist/nightly-check.d.ts +104 -0
- package/dist/nightly-check.js +362 -0
- package/dist/operate.js +39 -2
- package/dist/person-proof.d.ts +2 -0
- package/dist/person-proof.js +14 -0
- package/dist/plan-auto.js +4 -4
- package/dist/planner-source.d.ts +1 -1
- package/dist/project-delete-ui.js +1 -1
- package/dist/proof.js +2 -0
- package/dist/publish.js +156 -144
- package/dist/pull-request-flow.d.ts +2 -0
- package/dist/pull-request-flow.js +24 -2
- package/dist/release-adapters.d.ts +8 -0
- package/dist/release-adapters.js +212 -15
- package/dist/release-authority.d.ts +112 -0
- package/dist/release-authority.js +126 -0
- package/dist/release-carry.d.ts +233 -0
- package/dist/release-carry.js +645 -0
- package/dist/release-cli.d.ts +3 -0
- package/dist/release-cli.js +124 -5
- package/dist/release-coverage.js +3 -0
- package/dist/release-recheck.d.ts +146 -0
- package/dist/release-recheck.js +657 -0
- package/dist/release-view.d.ts +34 -0
- package/dist/release-view.js +27 -0
- package/dist/release.d.ts +131 -1
- package/dist/release.js +562 -244
- package/dist/remote-main.d.ts +2 -0
- package/dist/remote-main.js +1 -1
- package/dist/result-completion.d.ts +6 -0
- package/dist/result-completion.js +15 -1
- package/dist/result-follow-ups.js +29 -1
- package/dist/sandbox-runtime.d.ts +16 -5
- package/dist/sandbox-runtime.js +19 -6
- package/dist/scope.d.ts +115 -5
- package/dist/scope.js +219 -7
- package/dist/server/render-tasks.d.ts +8 -0
- package/dist/server/render-tasks.js +50 -9
- package/dist/server/route-table.js +1 -0
- package/dist/server/task-views.js +4 -0
- package/dist/server/tasks.js +12 -0
- package/dist/store.d.ts +227 -5
- package/dist/store.js +727 -37
- package/dist/task-outcome-cli.js +7 -3
- package/dist/toolroll-update.js +2 -2
- package/dist/verification-evidence.d.ts +25 -1
- package/dist/verification-evidence.js +57 -2
- package/dist/work-index.js +3 -6
- package/package.json +1 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type Store } from "./store.js";
|
|
2
|
+
export type LandedView = {
|
|
3
|
+
sha: string;
|
|
4
|
+
task: string;
|
|
5
|
+
files: {
|
|
6
|
+
path: string;
|
|
7
|
+
added: number;
|
|
8
|
+
deleted: number;
|
|
9
|
+
}[];
|
|
10
|
+
};
|
|
11
|
+
export type ReleaseView = {
|
|
12
|
+
kind: "anchor" | "carried";
|
|
13
|
+
authority: number;
|
|
14
|
+
version: string;
|
|
15
|
+
pr: number;
|
|
16
|
+
state: string;
|
|
17
|
+
/** Whether the release still carries later commits, and why not. */
|
|
18
|
+
carrying: boolean;
|
|
19
|
+
why: string | null;
|
|
20
|
+
approver: string | null;
|
|
21
|
+
anchorTask: string;
|
|
22
|
+
tipTask: string;
|
|
23
|
+
expiresAt: string;
|
|
24
|
+
landed: LandedView[];
|
|
25
|
+
/** Identities a later check of this release must run again and pass (release-recheck.ts). */
|
|
26
|
+
obligations: string[];
|
|
27
|
+
nightly: {
|
|
28
|
+
at: string;
|
|
29
|
+
sha: string;
|
|
30
|
+
outcome: string | null;
|
|
31
|
+
} | null;
|
|
32
|
+
openMainFailures: number;
|
|
33
|
+
};
|
|
34
|
+
export declare function releaseViewOf(store: Store, taskId: string, now: Date, obligations?: (authority: number) => string[]): ReleaseView | null;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a release task's page shows (docs/plans/release-once.md, "What people see"): for the approved task, the release
|
|
3
|
+
* it's approved for, every later commit carried under it, the open check obligations and the last nightly result for
|
|
4
|
+
* main; for a carried task, whose release approval it was carried from. Read-only, from the store.
|
|
5
|
+
*/
|
|
6
|
+
import { liveReleaseOf } from "./scope.js";
|
|
7
|
+
import { releaseAuthorityOfTask, releaseCarries } from "./store.js";
|
|
8
|
+
export function releaseViewOf(store, taskId, now, obligations = () => []) {
|
|
9
|
+
const found = releaseAuthorityOfTask(store, taskId);
|
|
10
|
+
if (found === null)
|
|
11
|
+
return null;
|
|
12
|
+
const a = found.authority;
|
|
13
|
+
const live = liveReleaseOf(store, a.tipTask, "dispatch", now);
|
|
14
|
+
const anchor = store.getScope(a.anchorTask);
|
|
15
|
+
const nightly = store.handle.prepare("SELECT sha, outcome, at FROM nightly_check WHERE repo = ? ORDER BY id DESC LIMIT 1").get(a.repo);
|
|
16
|
+
const open = Number(store.handle.prepare("SELECT COUNT(*) AS n FROM main_check_failure WHERE repo = ? AND cleared_at IS NULL").get(a.repo)?.["n"] ?? 0);
|
|
17
|
+
return {
|
|
18
|
+
kind: found.carry === null ? "anchor" : "carried",
|
|
19
|
+
authority: a.id, version: a.version, pr: a.pr, state: a.state,
|
|
20
|
+
carrying: a.state === "open" && live.applies && live.ok, why: live.applies && !live.ok ? live.why : null,
|
|
21
|
+
approver: anchor?.approvedBy ?? null, anchorTask: a.anchorTask, tipTask: a.tipTask, expiresAt: a.expiresAt,
|
|
22
|
+
landed: releaseCarries(store, a.id).flatMap(carry => carry.commits.map(commit => ({ sha: commit.sha, task: carry.taskId, files: commit.files }))),
|
|
23
|
+
obligations: obligations(a.id),
|
|
24
|
+
nightly: nightly === undefined ? null : { at: String(nightly["at"]), sha: String(nightly["sha"]), outcome: nightly["outcome"] == null ? null : String(nightly["outcome"]) },
|
|
25
|
+
openMainFailures: open,
|
|
26
|
+
};
|
|
27
|
+
}
|
package/dist/release.d.ts
CHANGED
|
@@ -65,6 +65,15 @@ export type GateState = {
|
|
|
65
65
|
basis: string | null;
|
|
66
66
|
role: string | null;
|
|
67
67
|
active: boolean;
|
|
68
|
+
/** The plane's own answer to "did a person give this approval, with a person's proof recorded?" (approval policy
|
|
69
|
+
* §1.5). Absent from a plane too old to say, which is no person's approval. */
|
|
70
|
+
person?: {
|
|
71
|
+
ok: true;
|
|
72
|
+
method: string;
|
|
73
|
+
} | {
|
|
74
|
+
ok: false;
|
|
75
|
+
why: string;
|
|
76
|
+
};
|
|
68
77
|
} | null;
|
|
69
78
|
/** The newest finished build of the task: its sealed result and check. */
|
|
70
79
|
result: {
|
|
@@ -115,7 +124,94 @@ export type HomebrewState = {
|
|
|
115
124
|
} | {
|
|
116
125
|
kind: "missing";
|
|
117
126
|
};
|
|
127
|
+
/** One commit that landed after the approval, with its files and line counts (release_carry). */
|
|
128
|
+
export type LandedCommit = {
|
|
129
|
+
sha: string;
|
|
130
|
+
files: {
|
|
131
|
+
path: string;
|
|
132
|
+
added: number;
|
|
133
|
+
deleted: number;
|
|
134
|
+
}[];
|
|
135
|
+
};
|
|
136
|
+
/** A release's authority record as the coordinator reads it (store.ts release_authority). */
|
|
137
|
+
export type AuthorityView = {
|
|
138
|
+
id: number;
|
|
139
|
+
generation: number;
|
|
140
|
+
state: string;
|
|
141
|
+
tipSha: string;
|
|
142
|
+
tipTask: string;
|
|
143
|
+
version: string;
|
|
144
|
+
pr: number;
|
|
145
|
+
landed: LandedCommit[];
|
|
146
|
+
};
|
|
147
|
+
export type ReleaseAction = "dispatch" | "deploy" | "merge" | "complete";
|
|
148
|
+
export type OperationView = {
|
|
149
|
+
id: string;
|
|
150
|
+
kind: "deploy" | "merge";
|
|
151
|
+
state: "reserved" | "running" | "succeeded" | "failed" | "unknown";
|
|
152
|
+
candidate: string;
|
|
153
|
+
externalRef: string | null;
|
|
154
|
+
reservedAt: string;
|
|
155
|
+
/** Reserved by a person's own deploy run (deploy-browser.mjs), not a coordinator. */
|
|
156
|
+
direct: boolean;
|
|
157
|
+
/** Whether the process that issued it is proven gone (store.ts releaseIssuerGone): read when the view is made. */
|
|
158
|
+
issuerGone: boolean;
|
|
159
|
+
/** A direct deploy's staging folder. */
|
|
160
|
+
stage: string | null;
|
|
161
|
+
};
|
|
162
|
+
/** The release's authority record, through the plane's store (release-once.md). Absent: a plane too old to carry, and
|
|
163
|
+
* every commit asks for a person as before. */
|
|
164
|
+
export type ReleaseAuthorityAdapter = {
|
|
165
|
+
authority(taskId: string): Promise<AuthorityView | null>;
|
|
166
|
+
live(taskId: string, action: ReleaseAction): Promise<{
|
|
167
|
+
applies: boolean;
|
|
168
|
+
ok: boolean;
|
|
169
|
+
why: string | null;
|
|
170
|
+
}>;
|
|
171
|
+
lease(authority: number, owner: string): Promise<{
|
|
172
|
+
ok: true;
|
|
173
|
+
epoch: number;
|
|
174
|
+
} | {
|
|
175
|
+
ok: false;
|
|
176
|
+
why: string;
|
|
177
|
+
}>;
|
|
178
|
+
renew(authority: number, owner: string, epoch: number): Promise<boolean>;
|
|
179
|
+
carry(authority: number, to: string, requestId: string, epoch: number): Promise<{
|
|
180
|
+
ok: true;
|
|
181
|
+
taskId: string;
|
|
182
|
+
} | {
|
|
183
|
+
ok: false;
|
|
184
|
+
message: string;
|
|
185
|
+
}>;
|
|
186
|
+
/** `secret`: proves a deploy run is this reservation's (handed to deploy-browser on stdin). */
|
|
187
|
+
reserve(input: {
|
|
188
|
+
authority: number;
|
|
189
|
+
kind: "deploy" | "merge";
|
|
190
|
+
taskId: string;
|
|
191
|
+
candidate: string;
|
|
192
|
+
epoch: number;
|
|
193
|
+
}): Promise<{
|
|
194
|
+
ok: true;
|
|
195
|
+
operation: string;
|
|
196
|
+
secret?: string;
|
|
197
|
+
} | {
|
|
198
|
+
ok: false;
|
|
199
|
+
why: string;
|
|
200
|
+
}>;
|
|
201
|
+
start(operation: string, epoch: number): Promise<boolean>;
|
|
202
|
+
/** Settle an operation at the epoch this coordinator holds; false: it no longer holds the release. */
|
|
203
|
+
finish(operation: string, outcome: "succeeded" | "failed" | "unknown", facts: {
|
|
204
|
+
detail?: string | null;
|
|
205
|
+
externalRef?: string | null;
|
|
206
|
+
}, epoch: number): Promise<boolean>;
|
|
207
|
+
/** A CI failure after the deploy (Alex's decision): the release stops and needs a person's fresh approval. False when
|
|
208
|
+
* the authority could not be stopped (a stale epoch, a merge already reserved): the coordinator fails closed. */
|
|
209
|
+
needsApproval(authority: number, reason: string, epoch: number): Promise<boolean>;
|
|
210
|
+
operations(authority: number): Promise<OperationView[]>;
|
|
211
|
+
};
|
|
118
212
|
export type ReleaseAdapters = {
|
|
213
|
+
/** One approval per release (release-once.md); absent on a plane that can't carry. */
|
|
214
|
+
release?: ReleaseAuthorityAdapter;
|
|
119
215
|
now(): Date;
|
|
120
216
|
sleep(ms: number): Promise<void>;
|
|
121
217
|
say(line: string): void;
|
|
@@ -147,6 +243,13 @@ export type ReleaseAdapters = {
|
|
|
147
243
|
candidate: string;
|
|
148
244
|
goal: string;
|
|
149
245
|
acceptance: string;
|
|
246
|
+
/** Release terms to file with the scope (task scope --release): the version, pull request and branch. */
|
|
247
|
+
release?: {
|
|
248
|
+
version: string;
|
|
249
|
+
pr: number;
|
|
250
|
+
branch: string;
|
|
251
|
+
noCarry: boolean;
|
|
252
|
+
};
|
|
150
253
|
}): Promise<{
|
|
151
254
|
scopeDigest: string;
|
|
152
255
|
}>;
|
|
@@ -165,6 +268,10 @@ export type ReleaseAdapters = {
|
|
|
165
268
|
run: number;
|
|
166
269
|
worktree: string;
|
|
167
270
|
stage: string;
|
|
271
|
+
operation?: {
|
|
272
|
+
id: string;
|
|
273
|
+
secret: string;
|
|
274
|
+
};
|
|
168
275
|
}): Promise<{
|
|
169
276
|
ok: true;
|
|
170
277
|
runtime: string;
|
|
@@ -177,6 +284,9 @@ export type ReleaseAdapters = {
|
|
|
177
284
|
}): Promise<{
|
|
178
285
|
ok: true;
|
|
179
286
|
} | DeployStop>;
|
|
287
|
+
/** Whether no deployment is at work or half done: no deploy-browser process, no update pause held, and `stage`'s
|
|
288
|
+
* journal (when given) unlocked and at a phase that changed nothing or finished. Null stage: unknown, so false. */
|
|
289
|
+
deploymentIdle(stage: string | null): Promise<boolean>;
|
|
180
290
|
/** Where both CLI names are on PATH now. */
|
|
181
291
|
cliLinks(): Promise<SavedLink[]>;
|
|
182
292
|
/** Point every saved link at `bin` and check each answers `version`; on any failure every link goes back to its
|
|
@@ -187,7 +297,7 @@ export type ReleaseAdapters = {
|
|
|
187
297
|
authenticated(): Promise<boolean>;
|
|
188
298
|
pullRequest(repo: string, branch: string): Promise<PullRequest | null>;
|
|
189
299
|
checks(repo: string, sha: string): Promise<CheckRun[]>;
|
|
190
|
-
merge(repo: string, pr: number, head: string): Promise<string>;
|
|
300
|
+
merge(repo: string, pr: number, head: string, message?: string): Promise<string>;
|
|
191
301
|
tag(repo: string, tag: string): Promise<string | null>;
|
|
192
302
|
createTag(repo: string, tag: string, sha: string): Promise<void>;
|
|
193
303
|
release(repo: string, tag: string): Promise<boolean>;
|
|
@@ -273,6 +383,22 @@ export type ReleaseJournal = {
|
|
|
273
383
|
head: string | null;
|
|
274
384
|
merged: boolean;
|
|
275
385
|
} | null;
|
|
386
|
+
/** The release's authority record (release-once.md), once a person approved terms: the id and generation. */
|
|
387
|
+
authority?: {
|
|
388
|
+
id: number;
|
|
389
|
+
generation: number;
|
|
390
|
+
} | null;
|
|
391
|
+
/** Commits that landed after the approval, carried under it: each with its files and line counts. */
|
|
392
|
+
landed?: LandedCommit[];
|
|
393
|
+
/** The deploy and merge operations this coordinator reserved (store.ts release_operation). */
|
|
394
|
+
operations?: {
|
|
395
|
+
deploy?: string;
|
|
396
|
+
merge?: string;
|
|
397
|
+
};
|
|
398
|
+
/** A pull request check failed after the deploy: nothing continues until a person approves again (--new). */
|
|
399
|
+
needsApproval?: boolean;
|
|
400
|
+
/** This journal's task was picked fresh after a CI failure after the deploy: an id that never existed, never another. */
|
|
401
|
+
freshTask?: boolean;
|
|
276
402
|
/** When each step was about to change something outside this machine: what a resume must look for before acting. */
|
|
277
403
|
intents: Partial<Record<ReleaseStep, string>>;
|
|
278
404
|
stopped: {
|
|
@@ -307,7 +433,11 @@ export type ReleaseOptions = {
|
|
|
307
433
|
/** Start over for a new commit on the branch, keeping the old journal aside. Refused once merging began. */
|
|
308
434
|
fresh?: boolean;
|
|
309
435
|
pollMs?: number;
|
|
436
|
+
/** File the release without carrying later commits: each one asks again. */
|
|
437
|
+
noCarry?: boolean;
|
|
310
438
|
};
|
|
439
|
+
/** Every commit that landed after the approval, in words: the summary and the merge message list them all. */
|
|
440
|
+
export declare function landedWords(landed: readonly LandedCommit[]): string[];
|
|
311
441
|
export declare const journalFile: (stateDir: string, branch: string) => string;
|
|
312
442
|
export declare const resumeCommand: (branch: string, checkout: string) => string;
|
|
313
443
|
/** Whole or not at all: a private temp file, synced, renamed into place, its folder synced. */
|