toolroll 0.9.73 → 0.9.75
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 +63 -0
- package/THIRD_PARTY_NOTICES.md +40 -0
- package/dist/agent-turns.js +5 -0
- package/dist/agents-live.d.ts +31 -0
- package/dist/agents-live.js +43 -0
- package/dist/assignment.d.ts +3 -0
- package/dist/assignment.js +27 -8
- package/dist/browser/THIRD_PARTY_NOTICES.txt +40 -0
- package/dist/browser/workspace.css +2 -2
- package/dist/browser/workspace.js +31 -30
- package/dist/browser-workspace.d.ts +7 -1
- package/dist/builder.js +1 -1
- package/dist/chat-acceptance.d.ts +4 -1
- package/dist/chat-acceptance.js +13 -3
- package/dist/chat-continuity.js +10 -0
- package/dist/chat-quiet.js +3 -3
- package/dist/cli.js +1 -1
- package/dist/coding-handoff.js +4 -3
- package/dist/coding-ui.js +2 -2
- package/dist/coding-workspace.js +16 -4
- package/dist/contracts/console-api.d.ts +5 -1
- package/dist/contracts/console-api.js +10 -0
- package/dist/control-ui.d.ts +3 -2
- package/dist/control-ui.js +7 -2
- package/dist/demo.js +5 -3
- package/dist/deploy-gate.js +5 -2
- package/dist/desktop-update.d.ts +4 -1
- package/dist/desktop-update.js +43 -9
- package/dist/dispose.js +35 -2
- package/dist/exec.js +13 -16
- package/dist/first-run.d.ts +20 -1
- package/dist/first-run.js +71 -0
- package/dist/flow-card-task.js +3 -2
- package/dist/flow-unattended.d.ts +2 -0
- package/dist/flow-unattended.js +12 -1
- package/dist/integrations.d.ts +4 -3
- package/dist/integrations.js +5 -6
- package/dist/invoke.d.ts +13 -0
- package/dist/invoke.js +21 -12
- package/dist/knowledge-ui.d.ts +4 -1
- package/dist/knowledge-ui.js +10 -5
- package/dist/lead-contract.d.ts +1 -1
- package/dist/lead-contract.js +2 -2
- package/dist/lead-follow.js +3 -1
- package/dist/lead-progress.d.ts +4 -1
- package/dist/lead-progress.js +3 -1
- package/dist/lead.js +4 -0
- package/dist/live-bus.d.ts +2 -0
- package/dist/live-bus.js +1 -0
- package/dist/live-children-read.d.ts +52 -0
- package/dist/live-children-read.js +333 -0
- package/dist/live-children.d.ts +73 -0
- package/dist/live-children.js +318 -0
- package/dist/live-detail.d.ts +4 -3
- package/dist/live-detail.js +9 -5
- package/dist/live-input.js +7 -8
- package/dist/live-main-read.d.ts +19 -0
- package/dist/live-main-read.js +91 -0
- package/dist/live-open.d.ts +28 -0
- package/dist/live-open.js +125 -0
- package/dist/live-records.d.ts +10 -1
- package/dist/live-records.js +16 -5
- package/dist/live.d.ts +54 -22
- package/dist/live.js +218 -69
- package/dist/openrouter-models.d.ts +5 -2
- package/dist/openrouter-models.js +7 -4
- package/dist/operate.js +5 -2
- package/dist/peek-cli.d.ts +10 -3
- package/dist/peek-cli.js +17 -8
- package/dist/planner.js +1 -1
- package/dist/project-learning.js +44 -6
- package/dist/project-tools.js +19 -1
- package/dist/provider-limits.d.ts +3 -1
- package/dist/provider-limits.js +5 -2
- package/dist/provider.js +6 -12
- package/dist/pull-request-ui.d.ts +1 -1
- package/dist/pull-request-ui.js +5 -1
- package/dist/push.d.ts +2 -0
- package/dist/push.js +24 -19
- package/dist/read-only-request.d.ts +4 -0
- package/dist/read-only-request.js +15 -0
- package/dist/release-adapters.js +4 -0
- package/dist/release.d.ts +3 -0
- package/dist/release.js +3 -0
- package/dist/repository-context-ui.js +2 -1
- package/dist/repository-context.js +6 -1
- package/dist/result-follow-ups.js +20 -1
- package/dist/result-review.js +5 -1
- package/dist/run-efficiency.d.ts +3 -3
- package/dist/run-efficiency.js +20 -8
- package/dist/scout.d.ts +3 -0
- package/dist/scout.js +5 -3
- package/dist/serve.js +196 -29
- package/dist/server/agents-live-filed.d.ts +17 -0
- package/dist/server/agents-live-filed.js +97 -0
- package/dist/server/agents-live-lead.d.ts +47 -0
- package/dist/server/agents-live-lead.js +116 -0
- package/dist/server/agents-live-room.d.ts +23 -0
- package/dist/server/agents-live-room.js +91 -0
- package/dist/server/chat.js +115 -53
- package/dist/server/chrome.js +2 -2
- package/dist/server/console.css +68 -40
- package/dist/server/http.d.ts +5 -0
- package/dist/server/last-checks.d.ts +17 -0
- package/dist/server/last-checks.js +22 -0
- package/dist/server/live.d.ts +4 -0
- package/dist/server/live.js +42 -2
- package/dist/server/pages.js +98 -4
- package/dist/server/people-tokens.js +7 -4
- package/dist/server/render-chat.d.ts +15 -1
- package/dist/server/render-chat.js +14 -7
- package/dist/server/render-pages.d.ts +10 -5
- package/dist/server/render-pages.js +83 -74
- package/dist/server/render-results.d.ts +11 -2
- package/dist/server/render-results.js +54 -12
- package/dist/server/render-settings.js +3 -3
- package/dist/server/render-tasks.js +13 -3
- package/dist/server/route-table.js +19 -2
- package/dist/server/runtime.d.ts +17 -2
- package/dist/server/settings.js +85 -32
- package/dist/server/task-views.js +1 -2
- package/dist/server/tasks.js +70 -43
- package/dist/storage-ui.d.ts +2 -0
- package/dist/storage-ui.js +1 -1
- package/dist/storage.js +2 -1
- package/dist/store.d.ts +34 -1
- package/dist/store.js +108 -11
- package/dist/stream-scope.d.ts +18 -0
- package/dist/stream-scope.js +28 -0
- package/dist/subagent-work.js +3 -0
- package/dist/subscription-chat.js +5 -3
- package/dist/task-status.d.ts +28 -1
- package/dist/task-status.js +93 -11
- package/dist/teardown-git.d.ts +27 -1
- package/dist/teardown-git.js +185 -39
- package/dist/telegram-progress.js +4 -4
- package/dist/telegram-status.js +8 -3
- package/dist/tool-secret-store.js +8 -0
- package/dist/toolroll-update-ui.d.ts +2 -0
- package/dist/toolroll-update-ui.js +4 -3
- package/dist/toolroll-update.js +10 -9
- package/dist/work-index.js +29 -12
- package/dist/workspace-ui.d.ts +5 -0
- package/dist/workspace-ui.js +38 -10
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,68 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.9.75 — 2026-10-27
|
|
4
|
+
|
|
5
|
+
- **Opening a page only shows it.** Pages no longer run checks, tidy up or
|
|
6
|
+
call out as you open them. Sign-ins, integrations, update checks, storage
|
|
7
|
+
and Codex's tools are checked in the background, and Models, Updates,
|
|
8
|
+
Storage, Pull requests, Tools, Project setup and the GitHub listing show
|
|
9
|
+
their last answer and when it was checked, with a **Check now** button to
|
|
10
|
+
ask again. On a coding session, **Review for shipping** and the changes
|
|
11
|
+
view are buttons, so a link preview or prefetch can't run them. Reading a
|
|
12
|
+
checkout an agent wrote never runs that checkout's own git settings.
|
|
13
|
+
- **Reading an agent's checkout can't be raced into running a filter.** Git
|
|
14
|
+
reads the checkout through a private copy of its settings taken once, so a
|
|
15
|
+
filter the agent adds to its git config and `.git/info/attributes` after
|
|
16
|
+
that copy never runs.
|
|
17
|
+
- **The task card never contradicts itself.** One answer to "did the
|
|
18
|
+
approved check pass" across the task page, the road, the Tasks list, the
|
|
19
|
+
result page and chat. A check whose saved log can't be read is never
|
|
20
|
+
shown as passed, and a check whose command was approved again since it ran
|
|
21
|
+
says so: "The check command changed since this check; run checks again."
|
|
22
|
+
- **Lead-filed runs nest under the lead on Agents → Live.** Runs your own
|
|
23
|
+
lead filed sit under its tile. Once its turn has gone, they stay grouped
|
|
24
|
+
under a quiet "Filed by lead chat" header. The lead's full screen lists
|
|
25
|
+
every task it filed. Only you see what your lead filed.
|
|
26
|
+
- **The lead passes asks to a helper instead of answering for them.** "Ask
|
|
27
|
+
Maya to …" now reaches Maya even when she seems to lack a tool or the
|
|
28
|
+
knowledge for it; she says so herself or asks you first.
|
|
29
|
+
- **A helper's "can't" reaches whoever asked.** When a helper can't do
|
|
30
|
+
something asked at its desk, its note (or its reason) goes back to the
|
|
31
|
+
person or agent who asked, instead of waiting in an inbox.
|
|
32
|
+
- Database: schema v136 (unchanged).
|
|
33
|
+
|
|
34
|
+
## 0.9.74 — 2026-10-27
|
|
35
|
+
|
|
36
|
+
- **Agents → Live: every agent and subagent at a glance.** A read-only grid
|
|
37
|
+
of everything running, on desktop and phone: what each agent is doing
|
|
38
|
+
right now, how long it has run and its latest lines. Subagents get their
|
|
39
|
+
own tiles nested under their parent; they appear when they start and show
|
|
40
|
+
Done for 30 seconds before leaving. A quiet agent reads **Needs you** with
|
|
41
|
+
a thin amber outline. Click a tile's title to open it full screen (Escape
|
|
42
|
+
brings you back). Your own lead chats show as lead tiles. Nothing on the
|
|
43
|
+
page acts, and the grid holds still while you look at it. Terminals you
|
|
44
|
+
drive yourself stay off the grid; one line links to Live terminals. Only a
|
|
45
|
+
signed-in browser can read it: tokens are refused.
|
|
46
|
+
- **Visiting a page starts nothing.** Opening Chat, a task, a result or a
|
|
47
|
+
project shows the page with a ready composer; your first message starts
|
|
48
|
+
the conversation. A retry or double submit lands in the conversation it
|
|
49
|
+
started. Link previews and prefetches can't start one.
|
|
50
|
+
- **A cleaner console.** One status chip everywhere, framed panels on the
|
|
51
|
+
Board, Settings, Knowledge and Projects, and a road on every task (Plan →
|
|
52
|
+
You approve → Build → Checks → Ready) built only from what happened.
|
|
53
|
+
Attempts show as a timeline and warnings as plain notices. Amber now means
|
|
54
|
+
only "waits on you". Built from ReUI's free, MIT-licensed components
|
|
55
|
+
(credited in THIRD_PARTY_NOTICES.md).
|
|
56
|
+
- **The old task list is retired.** `/tasks` now opens Work, which gained a
|
|
57
|
+
state filter (`/work?state=`), templates (`/tasks/new?template=`) and keeps
|
|
58
|
+
your draft when a filing is refused.
|
|
59
|
+
- **Rerunning a failed release check keeps your approval.**
|
|
60
|
+
`toolroll task regate` queues the same approved commit again instead of
|
|
61
|
+
re-filing it, and `toolroll release` waits for the rerun and uses it. A
|
|
62
|
+
changed commit, scope or approval still refuses.
|
|
63
|
+
- Database: schema v136 (each run's "Show commands" answer is kept for the
|
|
64
|
+
live view).
|
|
65
|
+
|
|
3
66
|
## 0.9.73 — 2026-10-25
|
|
4
67
|
|
|
5
68
|
- **Carry release approvals when checks aren't sandboxed.** A project whose
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -321,6 +321,46 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
321
321
|
SOFTWARE.
|
|
322
322
|
|
|
323
323
|
|
|
324
|
+
## ReUI — MIT
|
|
325
|
+
|
|
326
|
+
Components in `src/browser/components/ui/` adapt free, MIT-licensed ReUI
|
|
327
|
+
primitives and examples (the Radix base) from:
|
|
328
|
+
https://github.com/keenthemes/reui/tree/067aa0d/registry-reui/bases/radix/reui
|
|
329
|
+
|
|
330
|
+
Source inspected 27 October 2026, revision `067aa0d`. Files copied by hand (the
|
|
331
|
+
shadcn CLI and ReUI's registry CSS variables are not used) and cut to Toolroll's
|
|
332
|
+
tokens:
|
|
333
|
+
|
|
334
|
+
- `badge.tsx` — the light badge and its status-dot example (`c-badge-22`): one
|
|
335
|
+
20px chip size and a decorative dot on the existing tones, plus a "Needs you"
|
|
336
|
+
tone. The style variants, solid fills and focus/invert tones are omitted.
|
|
337
|
+
- `frame.tsx` — the well of panels: one geometry (a raised well, hairline,
|
|
338
|
+
concentric panel corners) with the style variants, spacing scale, stacking
|
|
339
|
+
modes and panel shadows omitted; `FramePanel` can render as its child.
|
|
340
|
+
- `alert.tsx` — cut to a neutral and a destructive tone with an icon column;
|
|
341
|
+
the info, warning, success and invert tones, the title/action slots and the
|
|
342
|
+
style variants are omitted.
|
|
343
|
+
- `timeline.tsx` — cut to a read-only vertical list (item, indicator on a
|
|
344
|
+
hairline rail, content, date); the active-step context, horizontal mode and
|
|
345
|
+
styled indicators are omitted.
|
|
346
|
+
- `stepper.tsx` — its read-only horizontal layout (indicator, separator,
|
|
347
|
+
title, `aria-current="step"`) is followed by the task page's road
|
|
348
|
+
(`src/browser/first-run.tsx` `Journey`); no stepper source is copied, and
|
|
349
|
+
the controlled state, keyboard navigation and triggers are omitted.
|
|
350
|
+
|
|
351
|
+
No ReUI Pro blocks, icons or templates are included.
|
|
352
|
+
|
|
353
|
+
MIT License
|
|
354
|
+
|
|
355
|
+
Copyright (c) 2025 Keenthemes Inc
|
|
356
|
+
|
|
357
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
358
|
+
|
|
359
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
360
|
+
|
|
361
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
362
|
+
|
|
363
|
+
|
|
324
364
|
## Integration logos: Simple Icons (CC0 1.0) and svgl (MIT)
|
|
325
365
|
|
|
326
366
|
The integration logos in `src/brand-icons.ts` are generated by
|
package/dist/agent-turns.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import { topLevelEvent } from "./stream-scope.js";
|
|
1
2
|
/** What one stream event says about the turn; null when it says nothing. */
|
|
2
3
|
export function turnSignalOf(event) {
|
|
3
4
|
const type = typeof event["type"] === "string" ? event["type"] : "";
|
|
5
|
+
// A subagent's events are not the parent's turn: its result never marks the parent idle or clears its open tools,
|
|
6
|
+
// and its init or words never mark it busy (stream-scope.ts).
|
|
7
|
+
if (!topLevelEvent(event))
|
|
8
|
+
return null;
|
|
4
9
|
switch (type) {
|
|
5
10
|
// Claude stream-json: the session starts, the assistant speaks or calls a tool, a tool answers; then one result.
|
|
6
11
|
case "system": return event["subtype"] === "init" ? "busy" : null;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type AgentsLiveRun, type Store } from "./store.js";
|
|
2
|
+
/** An ended agent stays on the grid this long, then leaves (it remains on the List). */
|
|
3
|
+
export declare const LIVE_ENDED_KEEP_MS: number;
|
|
4
|
+
export type AgentLiveState = "working" | "needs-you" | "done" | "failed" | "stopped" | "parked";
|
|
5
|
+
export type AgentLiveTile = {
|
|
6
|
+
runId: number;
|
|
7
|
+
role: AgentsLiveRun["role"];
|
|
8
|
+
taskId: string;
|
|
9
|
+
title: string;
|
|
10
|
+
project: string | null;
|
|
11
|
+
agent: string;
|
|
12
|
+
model: string | null;
|
|
13
|
+
startedAt: string;
|
|
14
|
+
endedAt: string | null;
|
|
15
|
+
state: AgentLiveState;
|
|
16
|
+
/** Why it needs you: it has been quiet (the board's Stuck rule) or it asked a question. */
|
|
17
|
+
why: "quiet" | "question" | null;
|
|
18
|
+
/** Since when it has been quiet, when that is why. */
|
|
19
|
+
quietSince: string | null;
|
|
20
|
+
/** Its output is on this computer (another runner's can't be read here). */
|
|
21
|
+
local: boolean;
|
|
22
|
+
/** A repair's build: the tile it nests under. */
|
|
23
|
+
parentRun: number | null;
|
|
24
|
+
/** The task's own page, for a task this console keeps (an outside tracker's task has none here). */
|
|
25
|
+
taskHref: string | null;
|
|
26
|
+
};
|
|
27
|
+
/** The grid's tiles for one viewer: `canSee` is the caller's proof (ceiling and account access) for each run. */
|
|
28
|
+
export declare function agentsLiveOf(store: Store, now: Date, viewer: {
|
|
29
|
+
canSee: (run: AgentsLiveRun) => boolean;
|
|
30
|
+
localRunner: string | undefined;
|
|
31
|
+
}): AgentLiveTile[];
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Agents view's Live grid (docs/plans/agents-view.md §1, §2.5): which agents are running now (every role) and
|
|
3
|
+
* which ended in the last ten minutes, with the facts a tile shows. Store facts only — it verifies nothing, grants
|
|
4
|
+
* nothing, and reads no live file; visibility is proved by the caller's `canSee` for each run.
|
|
5
|
+
*/
|
|
6
|
+
import { attemptKeyOf, agentNowForRun, openAgentQuestions } from "./agent-board.js";
|
|
7
|
+
import { agentsLiveRuns } from "./store.js";
|
|
8
|
+
/** An ended agent stays on the grid this long, then leaves (it remains on the List). */
|
|
9
|
+
export const LIVE_ENDED_KEEP_MS = 10 * 60_000;
|
|
10
|
+
const stateOf = (outcome) => outcome === null ? "working" : outcome === "built" || outcome === "no-change" ? "done" : outcome === "parked" ? "parked" : outcome === "interrupted" ? "stopped" : "failed";
|
|
11
|
+
/** The grid's tiles for one viewer: `canSee` is the caller's proof (ceiling and account access) for each run. */
|
|
12
|
+
export function agentsLiveOf(store, now, viewer) {
|
|
13
|
+
const tiles = [];
|
|
14
|
+
for (const run of agentsLiveRuns(store, new Date(now.getTime() - LIVE_ENDED_KEEP_MS))) {
|
|
15
|
+
if (!viewer.canSee(run))
|
|
16
|
+
continue;
|
|
17
|
+
let state = stateOf(run.outcome);
|
|
18
|
+
let why = null, quietSince = null;
|
|
19
|
+
if (state === "working") {
|
|
20
|
+
try {
|
|
21
|
+
const key = attemptKeyOf(store, run.id);
|
|
22
|
+
const facts = key === null ? null : agentNowForRun(store, run.id, key);
|
|
23
|
+
if (run.role === "builder" && openAgentQuestions(store, run.taskRef).length > 0)
|
|
24
|
+
why = "question";
|
|
25
|
+
else if (facts !== null && facts.stuckAt !== null) {
|
|
26
|
+
why = "quiet";
|
|
27
|
+
quietSince = facts.stuckAt;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch { /* display state: no word yet */ }
|
|
31
|
+
if (why !== null)
|
|
32
|
+
state = "needs-you";
|
|
33
|
+
}
|
|
34
|
+
tiles.push({
|
|
35
|
+
runId: run.id, role: run.role, taskId: run.taskId, title: run.title, project: run.repo, agent: run.provider, model: run.model,
|
|
36
|
+
startedAt: run.startedAt, endedAt: run.finishedAt, state, why, quietSince,
|
|
37
|
+
local: viewer.localRunner !== undefined && run.runner === viewer.localRunner,
|
|
38
|
+
parentRun: run.role === "repair" ? run.parentRun : null,
|
|
39
|
+
taskHref: run.builtIn ? `/t/${encodeURIComponent(run.taskId)}` : null,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return tiles;
|
|
43
|
+
}
|
package/dist/assignment.d.ts
CHANGED
|
@@ -28,6 +28,9 @@ export type AssignmentChecks = {
|
|
|
28
28
|
batch?: ChecksBatch | null;
|
|
29
29
|
/** Checks Off: the passing full release check that contains this commit (release-coverage.ts), read now, never sealed. */
|
|
30
30
|
release?: ReleaseCoverage | null;
|
|
31
|
+
/** Why a saved check can't be read, when it is the project's check command approved again since it ran (its files
|
|
32
|
+
* are intact; running checks again settles it). Presentation only, never sealed. */
|
|
33
|
+
cause?: "command-changed" | null;
|
|
31
34
|
};
|
|
32
35
|
export type AssignmentReceipt = {
|
|
33
36
|
digest: string;
|
package/dist/assignment.js
CHANGED
|
@@ -21,7 +21,7 @@ import { requiredCheckCommandFor, runCheckLevel } from "./check-levels.js";
|
|
|
21
21
|
import { followUpChecksOf, withFollowUps } from "./result-follow-ups.js";
|
|
22
22
|
import { buildReviewOf, findingWords } from "./review-switch.js";
|
|
23
23
|
import { NEEDS, WAITS, processNeedOf, resultHoldUpSentence } from "./needs-you.js";
|
|
24
|
-
import { assignmentStageOf, checkBackingOf, completionBlockersOf, requirementWordOf } from "./task-status.js";
|
|
24
|
+
import { assignmentStageOf, checkBackingOf, completionBlockersOf, receiptChecksOf, requirementWordOf } from "./task-status.js";
|
|
25
25
|
import { releaseCoverageOf } from "./release-coverage.js";
|
|
26
26
|
import { leadClaimOf } from "./lead-voice.js";
|
|
27
27
|
/** Status-first handoff for routine reads. Fetch get_assignment only when
|
|
@@ -53,7 +53,7 @@ function olderStoreSafe(read, absent) {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
/** A check as the receipt digest seals it: presentation-only fields (check-levels.ts) left out. */
|
|
56
|
-
const sealedChecks = ({ level: _level, running: _running, batch: _batch, release: _release, ...proof }) => proof;
|
|
56
|
+
const sealedChecks = ({ level: _level, running: _running, batch: _batch, release: _release, cause: _cause, ...proof }) => proof;
|
|
57
57
|
const OWNER_ACTION = "assignment claimed";
|
|
58
58
|
const CHECK_ACTION = COMPLETION_ACTION;
|
|
59
59
|
const actorOf = (owner) => `${owner.kind}:${owner.id}`;
|
|
@@ -87,7 +87,7 @@ function ownerOf(store, rootId, repo) {
|
|
|
87
87
|
// Report the recorded check outcome, never turn a model verdict into a check.
|
|
88
88
|
// Follow-up checks on the same commit (Run checks) upgrade a pass and show a failure.
|
|
89
89
|
export function assignmentChecksForRun(store, root, runId, now) {
|
|
90
|
-
const own = buildChecks(store, root, runId);
|
|
90
|
+
const own = recordedFailureStands(store, runId, buildChecks(store, root, runId));
|
|
91
91
|
const run = store.getRun(runId);
|
|
92
92
|
const followUps = followUpChecksOf(store, runId, now, root);
|
|
93
93
|
if (followUps.length === 0)
|
|
@@ -106,6 +106,18 @@ export function assignmentChecksForRun(store, root, runId, now) {
|
|
|
106
106
|
...(changed ? { status: read.status, level: read.level, exitCode: read.exitCode, logArtifactId: latest?.logArtifactId ?? own.logArtifactId,
|
|
107
107
|
detail: read.status === "passed" ? `${words} passed.` : `${words} failed (exit ${read.exitCode}).` } : {}) };
|
|
108
108
|
}
|
|
109
|
+
/** A failure the builder recorded (run_check) stands when its saved receipt can't be read now or says nothing ran:
|
|
110
|
+
* fail closed, every surface reads the same known failure and its exit code (task-status.ts approvedCheckOf). */
|
|
111
|
+
function recordedFailureStands(store, runId, own) {
|
|
112
|
+
if (own.status !== "unavailable" && own.status !== "not-run")
|
|
113
|
+
return own;
|
|
114
|
+
const recorded = olderStoreSafe(() => store.runCheckFor(runId), null);
|
|
115
|
+
if (recorded?.status !== "failed")
|
|
116
|
+
return own;
|
|
117
|
+
return { ...own, status: "failed", exitCode: recorded.exitCode,
|
|
118
|
+
detail: `${own.level === "quick" ? "Quick checks" : "Checks"} failed${recorded.exitCode === null ? "" : ` (exit ${recorded.exitCode})`}. ${own.detail}` };
|
|
119
|
+
}
|
|
120
|
+
const COMMAND_MISSING_OR_CHANGED = "The original approved verification command is missing or changed.";
|
|
109
121
|
function buildChecks(store, root, runId) {
|
|
110
122
|
const level = runCheckLevel(store, runId);
|
|
111
123
|
const unavailable = (detail) => ({ status: "unavailable", exitCode: null, command: null, logArtifactId: null, detail, level });
|
|
@@ -113,8 +125,13 @@ function buildChecks(store, root, runId) {
|
|
|
113
125
|
return unavailable("Saved checks are unavailable.");
|
|
114
126
|
try {
|
|
115
127
|
const gate = verificationEvidence(store, root, runId);
|
|
116
|
-
if (!gate.ok)
|
|
117
|
-
|
|
128
|
+
if (!gate.ok) {
|
|
129
|
+
// The approved command changed since this check ran: nothing is missing, the check just no longer binds to it.
|
|
130
|
+
const run = store.getRun(runId), repo = run === null ? null : store.refById(run.taskRef)?.repo ?? null;
|
|
131
|
+
const live = repo === null ? null : store.liveVerifyCommand(repo);
|
|
132
|
+
const changed = gate.problem === COMMAND_MISSING_OR_CHANGED && live !== null && run !== null && live.approvedAt > run.startedAt;
|
|
133
|
+
return changed ? { ...unavailable(gate.problem), cause: "command-changed" } : unavailable(gate.problem);
|
|
134
|
+
}
|
|
118
135
|
const receipt = gate.bytes === null ? null : JSON.parse(gate.bytes);
|
|
119
136
|
if (receipt === null)
|
|
120
137
|
return { ...unavailable(level === "off" ? "Checks were off for this build." : "No machine check is recorded."), status: "not-run" };
|
|
@@ -390,10 +407,12 @@ function readinessOf(store, receipt, repo, review) {
|
|
|
390
407
|
const high = review === null || review.sentBackAs !== null || review.state !== "reviewed" ? 0 : review.high.length;
|
|
391
408
|
const checkRequired = olderStoreSafe(() => requiredCheckCommandFor(store, repo, receipt.taskId, receipt.checks.level), null) !== null;
|
|
392
409
|
const matrix = receipt.proof?.matrix ?? [];
|
|
393
|
-
|
|
394
|
-
const
|
|
410
|
+
// The approved check as every surface reads it: a recorded pass the saved receipt can't show doesn't count.
|
|
411
|
+
const checks = receiptChecksOf(receipt);
|
|
412
|
+
const backing = checkBackingOf(checks);
|
|
413
|
+
const verdict = shownVerdictOf(receipt.proof?.verdict ?? null, { checkFailed: !report && checks?.status === "failed", highFindings: high,
|
|
395
414
|
reviewPending: review?.state === "pending", criteriaPassed: matrix.every(row => requirementWordOf(row, null, backing) === "Met") });
|
|
396
|
-
const blockers = completionBlockersOf({ report, checks
|
|
415
|
+
const blockers = completionBlockersOf({ report, checks, checkRequired, matrix, verdict: receipt.proof?.verdict ?? null,
|
|
397
416
|
accepted: receipt.proofAcceptance !== null, high });
|
|
398
417
|
return { verdict, checksOff: !report && receipt.checks.level === "off", blockers };
|
|
399
418
|
}
|
|
@@ -321,6 +321,46 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
321
321
|
SOFTWARE.
|
|
322
322
|
|
|
323
323
|
|
|
324
|
+
## ReUI — MIT
|
|
325
|
+
|
|
326
|
+
Components in `src/browser/components/ui/` adapt free, MIT-licensed ReUI
|
|
327
|
+
primitives and examples (the Radix base) from:
|
|
328
|
+
https://github.com/keenthemes/reui/tree/067aa0d/registry-reui/bases/radix/reui
|
|
329
|
+
|
|
330
|
+
Source inspected 27 October 2026, revision `067aa0d`. Files copied by hand (the
|
|
331
|
+
shadcn CLI and ReUI's registry CSS variables are not used) and cut to Toolroll's
|
|
332
|
+
tokens:
|
|
333
|
+
|
|
334
|
+
- `badge.tsx` — the light badge and its status-dot example (`c-badge-22`): one
|
|
335
|
+
20px chip size and a decorative dot on the existing tones, plus a "Needs you"
|
|
336
|
+
tone. The style variants, solid fills and focus/invert tones are omitted.
|
|
337
|
+
- `frame.tsx` — the well of panels: one geometry (a raised well, hairline,
|
|
338
|
+
concentric panel corners) with the style variants, spacing scale, stacking
|
|
339
|
+
modes and panel shadows omitted; `FramePanel` can render as its child.
|
|
340
|
+
- `alert.tsx` — cut to a neutral and a destructive tone with an icon column;
|
|
341
|
+
the info, warning, success and invert tones, the title/action slots and the
|
|
342
|
+
style variants are omitted.
|
|
343
|
+
- `timeline.tsx` — cut to a read-only vertical list (item, indicator on a
|
|
344
|
+
hairline rail, content, date); the active-step context, horizontal mode and
|
|
345
|
+
styled indicators are omitted.
|
|
346
|
+
- `stepper.tsx` — its read-only horizontal layout (indicator, separator,
|
|
347
|
+
title, `aria-current="step"`) is followed by the task page's road
|
|
348
|
+
(`src/browser/first-run.tsx` `Journey`); no stepper source is copied, and
|
|
349
|
+
the controlled state, keyboard navigation and triggers are omitted.
|
|
350
|
+
|
|
351
|
+
No ReUI Pro blocks, icons or templates are included.
|
|
352
|
+
|
|
353
|
+
MIT License
|
|
354
|
+
|
|
355
|
+
Copyright (c) 2025 Keenthemes Inc
|
|
356
|
+
|
|
357
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
358
|
+
|
|
359
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
360
|
+
|
|
361
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
362
|
+
|
|
363
|
+
|
|
324
364
|
## Integration logos: Simple Icons (CC0 1.0) and svgl (MIT)
|
|
325
365
|
|
|
326
366
|
The integration logos in `src/brand-icons.ts` are generated by
|