toolroll 0.9.91 → 0.9.93
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 +41 -0
- package/dist/approval-authority.d.ts +9 -1
- package/dist/approval-authority.js +15 -2
- package/dist/assignment-status.d.ts +1 -1
- package/dist/assignment-ui.js +2 -2
- package/dist/assignment.js +11 -3
- package/dist/browser/workspace.css +1 -1
- package/dist/browser/workspace.js +30 -30
- package/dist/browser-crew.js +2 -2
- package/dist/browser-workspace.d.ts +3 -5
- package/dist/build-review.js +2 -0
- package/dist/builder.js +21 -2
- package/dist/chat-actions.d.ts +11 -3
- package/dist/chat-actions.js +47 -2
- package/dist/chat-decide.js +2 -0
- package/dist/chat-review.d.ts +2 -1
- package/dist/chat-review.js +2 -2
- package/dist/check-facts.d.ts +124 -0
- package/dist/check-facts.js +272 -0
- package/dist/check-report.d.ts +5 -0
- package/dist/check-report.js +4 -3
- package/dist/cli.js +5 -0
- package/dist/contracts/chat-actions.d.ts +10 -0
- package/dist/contracts/chat-actions.js +4 -0
- package/dist/contracts/console-api.d.ts +3 -2
- package/dist/contracts/console-api.js +5 -2
- package/dist/contracts/release-check.d.ts +25 -1
- package/dist/contracts/release-check.js +19 -0
- package/dist/contracts/route-results.d.ts +121 -0
- package/dist/contracts/route-results.js +71 -0
- package/dist/contracts/route.d.ts +343 -5
- package/dist/contracts/route.js +36 -7
- package/dist/contracts/store-json.d.ts +2 -0
- package/dist/desktop-update.d.ts +2 -2
- package/dist/desktop-update.js +13 -9
- package/dist/dispose.js +6 -0
- package/dist/eval-hooks.d.ts +55 -0
- package/dist/eval-hooks.js +227 -4
- package/dist/flaky.d.ts +17 -0
- package/dist/flaky.js +9 -0
- package/dist/flow-engine.js +1 -1
- package/dist/flow-pull-request.js +1 -1
- package/dist/lead-doors.js +4 -2
- package/dist/lead-tools.js +10 -2
- package/dist/local-owner.d.ts +1 -1
- package/dist/local-owner.js +11 -0
- package/dist/memory-cli.d.ts +3 -0
- package/dist/memory-cli.js +3 -3
- package/dist/memory-pass.js +5 -1
- package/dist/model-choices.d.ts +7 -3
- package/dist/model-choices.js +26 -11
- package/dist/models-cli.d.ts +205 -0
- package/dist/models-cli.js +143 -4
- package/dist/models-ui.d.ts +57 -0
- package/dist/models-ui.js +44 -1
- package/dist/needs-you.d.ts +7 -7
- package/dist/needs-you.js +12 -10
- package/dist/operate-remote-arguments.js +4 -4
- package/dist/operate-remote.js +1 -1
- package/dist/operate.js +191 -23
- package/dist/phase-routing.d.ts +82 -2
- package/dist/phase-routing.js +132 -18
- package/dist/project-delete.d.ts +4 -0
- package/dist/project-delete.js +16 -4
- package/dist/project-memory.d.ts +8 -0
- package/dist/project-memory.js +20 -1
- package/dist/pull-request-flow.js +1 -1
- package/dist/push.d.ts +10 -3
- package/dist/push.js +22 -6
- package/dist/release-adapters.js +11 -1
- package/dist/release-approval.d.ts +191 -0
- package/dist/release-approval.js +382 -0
- package/dist/release-auto.js +22 -4
- package/dist/release-card.d.ts +73 -4
- package/dist/release-card.js +168 -23
- package/dist/release-cli.js +9 -1
- package/dist/release.d.ts +30 -0
- package/dist/release.js +42 -3
- package/dist/result-actions.d.ts +4 -0
- package/dist/result-actions.js +3 -0
- package/dist/result-acts.d.ts +3 -3
- package/dist/result-acts.js +1 -1
- package/dist/route-hooks.d.ts +54 -0
- package/dist/route-hooks.js +179 -0
- package/dist/route-results.d.ts +70 -0
- package/dist/route-results.js +340 -0
- package/dist/route-rules.d.ts +324 -0
- package/dist/route-rules.js +781 -0
- package/dist/route-savings.d.ts +136 -0
- package/dist/route-savings.js +193 -0
- package/dist/route-store.d.ts +300 -0
- package/dist/route-store.js +598 -0
- package/dist/scope.d.ts +3 -1
- package/dist/scope.js +4 -1
- package/dist/server/guards.js +1 -0
- package/dist/server/pages-assets.js +1 -1
- package/dist/server/render-chat.js +2 -2
- package/dist/server/render-release.d.ts +17 -0
- package/dist/server/render-release.js +84 -0
- package/dist/server/render-results.d.ts +0 -2
- package/dist/server/render-results.js +4 -6
- package/dist/server/render-tasks.d.ts +7 -0
- package/dist/server/render-tasks.js +16 -3
- package/dist/server/route-table.d.ts +1 -1
- package/dist/server/route-table.js +19 -1
- package/dist/server/settings.d.ts +2 -1
- package/dist/server/settings.js +87 -1
- package/dist/server/task-views.js +6 -0
- package/dist/server/tasks.d.ts +15 -0
- package/dist/server/tasks.js +105 -20
- package/dist/settings-proofs.js +2 -0
- package/dist/spend-ui.d.ts +11 -0
- package/dist/spend-ui.js +49 -2
- package/dist/stop-proof.d.ts +67 -0
- package/dist/stop-proof.js +293 -0
- package/dist/store.d.ts +106 -31
- package/dist/store.js +653 -128
- package/dist/surface.js +17 -5
- package/dist/task-outcome-cli.js +24 -2
- package/dist/toolroll-update-ui.js +2 -2
- package/dist/toolroll-update.js +4 -2
- package/dist/work-index.js +7 -9
- package/dist/work-summary.d.ts +2 -2
- package/package.json +1 -1
package/dist/surface.js
CHANGED
|
@@ -116,12 +116,12 @@ const GUIDE_ROWS = [
|
|
|
116
116
|
notableReasons: ["usage", "ambiguous", "drift", "timeout", "check-failed", "ci-failed", "tree-mismatch", "conflict", "mixed-runtime", "gate-held", "after-swap"] },
|
|
117
117
|
operator("demo", "a seeded throwaway sandbox"),
|
|
118
118
|
...KNOWLEDGE_DESCRIPTORS.map(spec => ({ invocation: `knowledge ${spec.action}`, synopsis: spec.synopsis, audience: "audience" in spec ? spec.audience : "agent", agentMayInvoke: !("audience" in spec), mutation: spec.mutation, flags: spec.flags, ...(spec.takesQuery ? { positionals: [{ name: "query", required: true, meaning: "search text or source file for impact" }] } : {}) })),
|
|
119
|
-
...MEMORY_DESCRIPTORS.map(spec => ({ invocation: `memory ${spec.action}`, synopsis: spec.synopsis, audience: "agent", agentMayInvoke:
|
|
119
|
+
...MEMORY_DESCRIPTORS.map(spec => ({ invocation: `memory ${spec.action}`, synopsis: spec.synopsis, audience: "audience" in spec ? spec.audience : "agent", agentMayInvoke: !("audience" in spec), mutation: spec.mutation, flags: spec.flags, ...(spec.takesQuery ? { positionals: [{ name: "query", required: true, meaning: "search text, a decision id, or the decision sentence" }] } : {}) })),
|
|
120
120
|
// Flow writes carry an approver's credential: an agent runs them only as the person asked, after showing the preview.
|
|
121
121
|
// Letting a flow run on its own raises authority: the owner's own password ceremony, never an agent's act.
|
|
122
122
|
...FLOWS_DESCRIPTORS.map(spec => ({ invocation: `flows ${spec.action}`, synopsis: spec.synopsis, audience: "audience" in spec ? spec.audience : "agent", agentMayInvoke: !("audience" in spec), mutation: spec.mutation, flags: spec.flags,
|
|
123
123
|
...("positionals" in spec ? { positionals: spec.positionals.map(name => ({ name, required: true, meaning: name === "flow" ? "a flow id from flows list" : name === "card" ? "a card id from flows show" : name === "on|off" ? "on signs the grant, off revokes it" : "a trigger id from flows show, or for trigger add its settings as JSON, a JSON file, or -" })) } : {}) })),
|
|
124
|
-
...MODELS_DESCRIPTORS.map(spec => ({ invocation: `models ${spec.action}`, synopsis: spec.synopsis, audience: "agent", agentMayInvoke: true, mutation: spec.mutation, flags: spec.flags, ...(spec.takesQuery ? { positionals: [{ name: "target", required: true, meaning: "the CLI to update, or on/off" }] } : {}) })),
|
|
124
|
+
...MODELS_DESCRIPTORS.map(spec => ({ invocation: `models ${spec.action}`, synopsis: spec.synopsis, audience: "agent", agentMayInvoke: true, mutation: spec.mutation, flags: spec.flags, ...(spec.takesQuery ? { positionals: [{ name: "target", required: true, meaning: "positional" in spec ? spec.positional : "the CLI to update, or on/off" }] } : {}) })),
|
|
125
125
|
// ---- the queue (agent surface) ----
|
|
126
126
|
{ invocation: "status", synopsis: "running work, queued reasons, results to review, the latest release check and plan windows", audience: "agent", agentMayInvoke: true, mutation: "none", flags: [jsonFlag, dbFlag] },
|
|
127
127
|
{ invocation: 'health', synopsis: 'recent server latency, event-loop delay, SQLite writes and live streams from the saved connection; instance operators only', audience: 'agent', agentMayInvoke: true, mutation: 'none', flags: [jsonFlag, { name: 'profile', takesValue: true, meaning: 'saved server connection' }] },
|
|
@@ -315,7 +315,7 @@ const GUIDE_ROWS = [
|
|
|
315
315
|
{ name: "days", takesValue: true, meaning: "also finished tasks untouched this many days (1–365, default 14)" },
|
|
316
316
|
{ name: "except", takesValue: true, meaning: "comma-separated tasks from the list to leave out" }],
|
|
317
317
|
notableReasons: ["usage", "not-an-approver", "empty"] },
|
|
318
|
-
operator("run settle", "
|
|
318
|
+
operator("run settle", "have Toolroll check again whether a finished run stopped: it looks at this computer's processes itself, stops only leftovers proven the run's, and settles the run when none is left (nobody vouches; --why is ignored)"),
|
|
319
319
|
operator("task resume", "resume the exact stopped attempt (--run <id>): refuses until it is quiescent, lifts only that stop's hold, approves nothing — the next pass re-proves the scope and inherits the draft with fresh proof"),
|
|
320
320
|
// ---- leases (runner surface) ----
|
|
321
321
|
{ invocation: "claim", synopsis: "take one ready, approved task; answers with a lease", audience: "agent", agentMayInvoke: true, mutation: "keyed",
|
|
@@ -460,6 +460,11 @@ const REMOTE_NO = [
|
|
|
460
460
|
"serve", "serve check-public", "watch", "up", "onboard", "daemon", "background on", "background off", "background show", "stop", "open", "welcome", "password set", "doctor", "bridge", "setup show", "setup clear",
|
|
461
461
|
// Provider keys and model tools on this machine.
|
|
462
462
|
"providers", "keys status", "keys set", "keys clear", "keys verify", "keys auth", "models check", "models update", "models watch",
|
|
463
|
+
// Result records read with this machine's sign-in: project access, never a token's narrower scope.
|
|
464
|
+
"models results",
|
|
465
|
+
// Earned rules (results routing): the project's own results, and its rules' doors, with this machine's sign-in; a
|
|
466
|
+
// remote token never changes which models run (the rule door refuses it in the write too).
|
|
467
|
+
"models suggestions", "models accept", "models dismiss", "models turn-off", "models keep", "models try", "models stop",
|
|
463
468
|
// Publication and release.
|
|
464
469
|
"publish", "publish status", "publish merge", "publish refire", "publish unblock", "publish rearm", "publish grant", "publish revoke",
|
|
465
470
|
// A repository's authority grants on this machine.
|
|
@@ -474,7 +479,9 @@ const REMOTE_NO = [
|
|
|
474
479
|
const REMOTE_STEP_UP = [
|
|
475
480
|
"proposals", "decide", "task regate", "task approve", "task accept", "task merge", "run settle",
|
|
476
481
|
// Putting tasks away and restoring them: a person's act, in the console or on the server's machine.
|
|
477
|
-
"task archive", "task restore", "task tidy", "knowledge apply",
|
|
482
|
+
"task archive", "task restore", "task tidy", "knowledge apply",
|
|
483
|
+
// Changing project memory: a person's own password, never a token (the lead only proposes it in chat).
|
|
484
|
+
"memory decide", "memory retire", "memory apply",
|
|
478
485
|
"flows card approve", "flows card send-back", "flows script approve", "flows unattended",
|
|
479
486
|
"approver list", "approver add", "people list", "people invite", "people projects", "people revoke",
|
|
480
487
|
// A person's own API tokens: a password step-up on the server's machine, or the console. Never with a token.
|
|
@@ -491,7 +498,7 @@ const REMOTE_YES = [
|
|
|
491
498
|
"config show", "verify show", "intake show", "intake run", "intake preview", "intake pr-comments", "template list", "template show",
|
|
492
499
|
"webhook status", "review show", "chat-approval show", "chat-approval off",
|
|
493
500
|
"knowledge search", "knowledge impact", "knowledge refresh",
|
|
494
|
-
"memory search", "memory decisions", "memory show", "memory
|
|
501
|
+
"memory search", "memory decisions", "memory show", "memory review", "memory status",
|
|
495
502
|
"flows list", "flows show", "flows export", "flows create", "flows edit", "flows trigger add", "flows trigger pause", "flows trigger resume",
|
|
496
503
|
"flows trigger remove", "flows card add", "flows archive",
|
|
497
504
|
"models status", "models list",
|
|
@@ -530,6 +537,11 @@ const LOCAL_ALLOW = {
|
|
|
530
537
|
"task archive": "archive-task",
|
|
531
538
|
"task restore": "archive-task",
|
|
532
539
|
"repos add": "add-project",
|
|
540
|
+
// Results routing: lowering only (route-store.ts proveRuleDoor checks the act is exactly this one).
|
|
541
|
+
"models suggestions": "read",
|
|
542
|
+
"models turn-off": "routing-turn-off",
|
|
543
|
+
"models dismiss": "dismiss-suggestion",
|
|
544
|
+
"models stop": "trial-stop",
|
|
533
545
|
};
|
|
534
546
|
/** Every guide row's local-owner mark, by invocation: `allow` with its act, else `deny`. Exported for the inventory test. */
|
|
535
547
|
export const LOCAL_POLICY = new Map(GUIDE_ROWS.map(row => [row.invocation,
|
package/dist/task-outcome-cli.js
CHANGED
|
@@ -4,11 +4,13 @@ import { assignmentOf, checkAssignmentAsOperator } from './assignment.js';
|
|
|
4
4
|
import { assignmentForCoordinator, coordinatorToken } from './assignment-adapters.js';
|
|
5
5
|
import { authenticateCoordinator } from './coordinator.js';
|
|
6
6
|
import { reproveApprover } from './principal.js';
|
|
7
|
-
import { authenticateApprover, personProof } from './scope.js';
|
|
7
|
+
import { authenticateApprover, machineActing, personProof } from './scope.js';
|
|
8
|
+
import { currentActor } from './actor.js';
|
|
8
9
|
import { requestResultChanges } from './result-actions.js';
|
|
9
10
|
import { commentSourceKey, revisionSourceOf } from './result-review.js';
|
|
10
11
|
import { envelopeJson } from './envelope.js';
|
|
11
12
|
import { completeAndOpenPullRequest, mergeAsPerson, MERGE_NEEDS_PERSON, newestPullRequestOf, publishingOf, pullRequestViewOf } from './pull-request-flow.js';
|
|
13
|
+
import { proveRunStopped } from './stop-proof.js';
|
|
12
14
|
export async function runTaskOutcomeCommand(action, positional, flags, context) {
|
|
13
15
|
const command = `task ${action}`;
|
|
14
16
|
const emit = (result, lines) => {
|
|
@@ -35,6 +37,10 @@ export async function runTaskOutcomeCommand(action, positional, flags, context)
|
|
|
35
37
|
if (credential.token === null && operator === null)
|
|
36
38
|
return fail('unauthenticated', 'Sign in with up, or supply --as and --token. Agents can use --token-file or --token-env with a scoped credential.');
|
|
37
39
|
const { store, now, evidenceRoot } = context;
|
|
40
|
+
// A result whose build Toolroll hasn't yet proven stopped: it looks now (stop-proof.ts), so completing never waits
|
|
41
|
+
// on a person to confirm it, only on Toolroll's own check (a refusal says "stopping" until it lands).
|
|
42
|
+
if (action === 'complete')
|
|
43
|
+
await proveTaskBuildsStopped(store, task, () => now);
|
|
38
44
|
return store.transact(() => {
|
|
39
45
|
const coordinator = credential.token === null ? null : authenticateCoordinator(store, credential.token);
|
|
40
46
|
if (coordinator !== null && !coordinator.ok)
|
|
@@ -110,7 +116,9 @@ export async function runTaskOutcomeCommand(action, positional, flags, context)
|
|
|
110
116
|
// The shared action returns exact replays before stale-family checks. An
|
|
111
117
|
// older result cannot create another child once a newer revision is current.
|
|
112
118
|
const revised = requestResultChanges(store, evidenceRoot, { run: run.id, source, actor, repos,
|
|
113
|
-
batch: '', note: feedback, path: '', line: '', request: key, allowMode: operator !== null
|
|
119
|
+
batch: '', note: feedback, path: '', line: '', request: key, allowMode: operator !== null,
|
|
120
|
+
// A verified approver's own words; a scoped credential or the lead's token is the lead; a remote API run a machine.
|
|
121
|
+
origin: coordinator !== null || currentActor()?.lead === true ? 'lead' : machineActing() ? 'machine' : 'person' }, now);
|
|
114
122
|
if (!revised.ok)
|
|
115
123
|
return fail(revised.status === 400 ? 'usage' : 'stale-result', revised.message);
|
|
116
124
|
const scope = store.getScope(revised.id);
|
|
@@ -169,3 +177,17 @@ export function pullRequestLines(view) {
|
|
|
169
177
|
return [];
|
|
170
178
|
return [` pull request: ${view.prUrl ?? 'opening'} · ${view.label}`, ` ${view.detail}`, ...(view.mergeCommit === null ? [] : [` merge commit: ${view.mergeCommit}`])];
|
|
171
179
|
}
|
|
180
|
+
/** Toolroll's own stop proof for every finished build of a task's family whose stop it can prove here. Best effort: a
|
|
181
|
+
* failure leaves the completion's own refusal to say what is still unproven. */
|
|
182
|
+
async function proveTaskBuildsStopped(store, task, clock) {
|
|
183
|
+
try {
|
|
184
|
+
const family = store.taskFamilyOf(task, null, true);
|
|
185
|
+
const refs = family === null ? [store.lookupRef(task)?.id].filter((one) => one !== undefined) : family.versions.map(version => version.refId);
|
|
186
|
+
for (const ref of refs)
|
|
187
|
+
for (const run of store.runsFor(ref)) {
|
|
188
|
+
if (run.outcome !== null && store.stopQuiescenceFact(run.id)?.cause !== undefined)
|
|
189
|
+
await proveRunStopped(store, run.id, clock);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
catch { /* the completion below refuses with what is still unproven */ }
|
|
193
|
+
}
|
|
@@ -24,7 +24,7 @@ export function updateStepsHtml(j, running, options = {}) {
|
|
|
24
24
|
const items = UPDATE_STEPS.map((step, i) => {
|
|
25
25
|
const state = j.phase === "complete" || i < last ? "done" : i > last ? "waiting" : failed ? "failed" : finished ? "waiting" : "now";
|
|
26
26
|
// Only where it adds something: which work it waits for, or what went wrong.
|
|
27
|
-
const detail = state === "now" && step === "draining" && j.waiting ? html `${j.waiting.on}.${j.waiting.action ? html `
|
|
27
|
+
const detail = state === "now" && step === "draining" && j.waiting ? html `${j.waiting.on}.${j.waiting.action ? html ` To have Toolroll check again, run <code class="k-mono">${j.waiting.action}</code>.` : ""}`
|
|
28
28
|
: (state === "now" && step === "draining") || (state === "failed" && j.phase === "rolling-back") ? html `${j.detail}` : "";
|
|
29
29
|
return settingsRecord({ title: STEP_WORDS[step], sub: detail, when: STEP_CHIP[state], attrs: { "data-step": step, "data-state": state } });
|
|
30
30
|
});
|
|
@@ -43,7 +43,7 @@ function outcomeHtml(j) {
|
|
|
43
43
|
// Stopped on a finished run it can't show has ended: what is in the way and the one command, nothing more.
|
|
44
44
|
if (j.phase === "refused" && j.waiting) {
|
|
45
45
|
return settingsSection({ id: "update-outcome", title: `Update to ${j.to.version} stopped: run #${j.waiting.run} is in the way`,
|
|
46
|
-
body: html `<div data-update-outcome="stopped">${infoLine(`${j.waiting.on}. New work resumed.`)}${j.waiting.action ? note(html `
|
|
46
|
+
body: html `<div data-update-outcome="stopped">${infoLine(`${j.waiting.on}. New work resumed.`)}${j.waiting.action ? note(html `To have Toolroll check again, run <code class="k-mono">${j.waiting.action}</code>, then update again.`) : note("Update again once it has stopped.")}</div>` });
|
|
47
47
|
}
|
|
48
48
|
const title = j.phase === "refused" ? `Didn't update to ${j.to.version}` : j.phase === "restored" ? `Update to ${j.to.version} didn't finish` : "The update needs attention";
|
|
49
49
|
return settingsSection({ id: "update-outcome", title, state: html ` ${chip("Failed", "failed")}`,
|
package/dist/toolroll-update.js
CHANGED
|
@@ -39,7 +39,7 @@ import { installLaunchdService, launchdPlist, stopLaunchdService, writeFileDurab
|
|
|
39
39
|
import { LAPTOP_LABEL_DARWIN, LAPTOP_LABEL_LINUX, unitFlag } from "./laptop-service.js";
|
|
40
40
|
import { processGone, readRunnerProcessRecord, realProcessProbe, recordStandsFor, RUNNER_PROCESS_DIR } from "./runner-process.js";
|
|
41
41
|
import { NAME } from "./names.js";
|
|
42
|
-
import { orphanKey, updateSafeSchema, V117_RENAMED_COLUMNS, V117_RENAMED_TABLES, V118_MERGED_TABLES, V119_ADDED_COLUMNS, V120_ADDED_COLUMNS, V121_ADDED_COLUMNS, V122_ADDED_COLUMNS, V123_ADDED_COLUMNS, V125_ADDED_COLUMNS, V126_ADDED_COLUMNS, V128_ADDED_COLUMNS, V129_ADDED_COLUMNS, V134_ADDED_COLUMNS, V135_ADDED_COLUMNS, V138_ADDED_COLUMNS, V143_ADDED_COLUMNS, V147_ADDED_COLUMNS } from "./store.js";
|
|
42
|
+
import { orphanKey, updateSafeSchema, V117_RENAMED_COLUMNS, V117_RENAMED_TABLES, V118_MERGED_TABLES, V119_ADDED_COLUMNS, V120_ADDED_COLUMNS, V121_ADDED_COLUMNS, V122_ADDED_COLUMNS, V123_ADDED_COLUMNS, V125_ADDED_COLUMNS, V126_ADDED_COLUMNS, V128_ADDED_COLUMNS, V129_ADDED_COLUMNS, V134_ADDED_COLUMNS, V135_ADDED_COLUMNS, V138_ADDED_COLUMNS, V143_ADDED_COLUMNS, V147_ADDED_COLUMNS, V148_ADDED_COLUMNS } from "./store.js";
|
|
43
43
|
import { isNewer, REGISTRY } from "./releases.js";
|
|
44
44
|
import { markNeverIndex } from "./never-index.js";
|
|
45
45
|
import { readRuntimeUpdateJournal, RUNTIME_PHASES, RUNTIME_UPDATE_STEPS, stagedStartedAt, updaterStartingOf } from "./contracts/update-journal.js";
|
|
@@ -413,7 +413,9 @@ const HISTORY_RULES = {
|
|
|
413
413
|
// v128: a lead message's pending flag reads waiting exactly for a team queue's unadmitted operator message.
|
|
414
414
|
// v147: an account's password flag reads set (1), a browser session reads full with no local binding or key, and the
|
|
415
415
|
// console record reads no key epoch.
|
|
416
|
-
|
|
416
|
+
// v148: a run's execution class and a revision's origin read none (NULL), and a project's suggestion switch reads on.
|
|
417
|
+
// v149 adds tables only (the learning-loops records): no saved row changes, so no rule is needed for it.
|
|
418
|
+
...Object.fromEntries(Object.entries(addedColumns(V119_ADDED_COLUMNS, V120_ADDED_COLUMNS, V121_ADDED_COLUMNS, V122_ADDED_COLUMNS, V123_ADDED_COLUMNS, V125_ADDED_COLUMNS, V126_ADDED_COLUMNS, V128_ADDED_COLUMNS, V129_ADDED_COLUMNS, V134_ADDED_COLUMNS, V135_ADDED_COLUMNS, V138_ADDED_COLUMNS, V143_ADDED_COLUMNS, V147_ADDED_COLUMNS, V148_ADDED_COLUMNS))
|
|
417
419
|
.map(([table, rule]) => [table, { ...EARLIER_RULES[table], ...rule }])),
|
|
418
420
|
};
|
|
419
421
|
/** The tables a migration may remove whole (v115's removed features). */
|
package/dist/work-index.js
CHANGED
|
@@ -41,7 +41,7 @@ const AGENT_ASK = `(SELECT q.id FROM agent_question q JOIN run qr ON qr.id=q.run
|
|
|
41
41
|
const GATE_PAUSE_ON_TASK = pauseOnTaskProviders('p', 'c.ref_id');
|
|
42
42
|
/** Index codes that wait on a person, as their need (needs-you.ts); dispatch codes come from task-status's own table. */
|
|
43
43
|
const INDEX_NEED = {
|
|
44
|
-
'earlier-active': 'earlier-version', 'process-needs-attention': '
|
|
44
|
+
'earlier-active': 'earlier-version', 'process-needs-attention': 'stop-unproven', 'invalid-scope': 'define-task', 'decision-queue': 'questions',
|
|
45
45
|
};
|
|
46
46
|
/** Every index code that can wait on a person. */
|
|
47
47
|
const PERSON_CODES = ['history-problem', 'earlier-active', 'ready-to-check', 'waiting-decision', 'decision-queue', 'result-needs-attention',
|
|
@@ -572,7 +572,7 @@ function itemOf(row, principal, probe, leadName, readiness, readable = false) {
|
|
|
572
572
|
const code = String(row['code']), id = String(row['id']);
|
|
573
573
|
const custody = code === 'process-needs-attention' || (code === 'result-needs-attention' && n(row, 'custody_unresolved') === 1);
|
|
574
574
|
const process = custody && probe !== undefined ? processNeedOf(probe(id)) : null;
|
|
575
|
-
const waiting = process !== null && 'wait' in process;
|
|
575
|
+
const waiting = (process !== null && 'wait' in process) || (custody && probe === undefined);
|
|
576
576
|
const need = n(row, 'needs') === 1 && !waiting, running = n(row, 'family_running') === 1;
|
|
577
577
|
// The lead's claim (lead-voice.ts): the row still reads its own stage, worded "<name> is on it".
|
|
578
578
|
const lead = n(row, 'lead_claim') === 1 ? 'on-it' : n(row, 'lead_claim') === 2 ? 'lapsed' : null;
|
|
@@ -647,14 +647,11 @@ function itemOf(row, principal, probe, leadName, readiness, readable = false) {
|
|
|
647
647
|
actionCode = 'open-result';
|
|
648
648
|
actionLabel = 'Open result';
|
|
649
649
|
}
|
|
650
|
+
// Toolroll proves a build stopped itself; only a stop it can't prove from here offers "Check again", never a vouch.
|
|
650
651
|
if (process !== null && 'need' in process) {
|
|
651
|
-
actionCode = '
|
|
652
|
+
actionCode = 'recheck-stopped';
|
|
652
653
|
actionLabel = NEEDS[process.need].action.label;
|
|
653
654
|
}
|
|
654
|
-
else if (custody && probe === undefined) {
|
|
655
|
-
actionCode = 'confirm-stopped';
|
|
656
|
-
actionLabel = NEEDS['confirm-stopped'].action.label;
|
|
657
|
-
}
|
|
658
655
|
if (code === 'signed-out') {
|
|
659
656
|
actionCode = 'sign-in';
|
|
660
657
|
actionLabel = NEEDS['sign-in'].action.label;
|
|
@@ -668,7 +665,7 @@ function itemOf(row, principal, probe, leadName, readiness, readable = false) {
|
|
|
668
665
|
target: { taskId: successor ?? (code === 'earlier-active' ? s(row, 'earlier_id') ?? id : actionCode === 'answer-decision' ? s(row, 'question_task') ?? id : id),
|
|
669
666
|
runId: actionCode === 'answer-decision' ? n(row, 'question_run') || null : actionCode === 'answer-agent' ? n(row, 'agent_ask_run') || null : actionCode === 'inspect-run' && code === 'running' ? n(row, 'live_run') || null : actionCode === 'open-result' || actionCode === 'inspect-run' ? n(row, 'result_id') || null
|
|
670
667
|
: actionCode === 'reconcile-run' ? n(row, 'unfinished') || null : ['resume-run', 'inspect-stop'].includes(actionCode) ? n(row, 'stop_run') || null
|
|
671
|
-
: actionCode === '
|
|
668
|
+
: actionCode === 'recheck-stopped' ? process?.build ?? (n(row, 'result_id') || null) : null,
|
|
672
669
|
decisionId: actionCode === 'answer-decision' ? n(row, 'question_id') || null : null },
|
|
673
670
|
access: read ? 'read' : principal === 'operator' ? 'operator-control' : ['answer-decision', 'answer-agent', 'write-scope', 'unhold'].includes(actionCode) ? 'proposal-only' : 'operator-handoff',
|
|
674
671
|
retry: actionCode === 'reconcile-run' ? 'reconcile-before-retry' : read ? 'read-again' : 'refresh-before-acting' };
|
|
@@ -676,7 +673,8 @@ function itemOf(row, principal, probe, leadName, readiness, readable = false) {
|
|
|
676
673
|
const coded = stageOfCode(code, { needsPerson: personNeed, planning: s(row, 'live_role') === 'planner', operatorHold: s(row, 'hold_kind') === 'operator' });
|
|
677
674
|
const reading = process !== null
|
|
678
675
|
? 'wait' in process ? { stage: 'waiting', wait: process.wait } : { stage: 'needs-you', need: process.need }
|
|
679
|
-
|
|
676
|
+
// Not read here (no process probe): Toolroll's own stop check settles it, so it waits on no one.
|
|
677
|
+
: custody ? { stage: 'waiting', wait: 'build-checking' }
|
|
680
678
|
: coded.stage === 'needs-you' && (coded.need === undefined || coded.need === 'other') && INDEX_NEED[code] !== undefined ? { stage: 'needs-you', need: INDEX_NEED[code] } : coded;
|
|
681
679
|
const checkStatus = s(row, 'check_status'), verdict = s(row, 'proof_verdict');
|
|
682
680
|
const finished = reading.stage === 'finished' || reading.stage === 'complete';
|
package/dist/work-summary.d.ts
CHANGED
|
@@ -8,9 +8,9 @@ export type WorkTarget = {
|
|
|
8
8
|
decisionId: number | null;
|
|
9
9
|
};
|
|
10
10
|
export type WorkAction = {
|
|
11
|
-
/** `
|
|
11
|
+
/** `recheck-stopped`: Toolroll looks again whether a finished build stopped (nobody vouches for it);
|
|
12
12
|
* `sign-in`: the agent's sign-in, in Settings; `answer-agent`: Reply to a running agent's question on the Agents board. */
|
|
13
|
-
code: DispatchAction | "inspect-task" | "inspect-run" | "inspect-stop" | "inspect-decisions" | "reconcile-run" | "open-pr" | "
|
|
13
|
+
code: DispatchAction | "inspect-task" | "inspect-run" | "inspect-stop" | "inspect-decisions" | "reconcile-run" | "open-pr" | "recheck-stopped" | "sign-in" | "answer-agent";
|
|
14
14
|
label: string;
|
|
15
15
|
target: WorkTarget;
|
|
16
16
|
access: "read" | "operator-control" | "proposal-only" | "operator-handoff";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolroll",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.93",
|
|
4
4
|
"description": "A control plane for unattended coding agents — queue tasks, walk away, come back to pull requests. Agents build in leased worktrees, never touch your default branch, and interrupt you only for decisions that need a human.",
|
|
5
5
|
"directories": {
|
|
6
6
|
"doc": "docs"
|